|
1 |
| -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT |
| 1 | +// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
2 | 2 | // file at the top-level directory of this distribution and at
|
3 | 3 | // http://rust-lang.org/COPYRIGHT.
|
4 | 4 | //
|
|
8 | 8 | // option. This file may not be copied, modified, or distributed
|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 |
| -use std::io; |
| 11 | +extern crate sync; |
12 | 12 |
|
13 |
| -struct DummyWriter; |
14 |
| -impl Writer for DummyWriter { |
15 |
| - fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) } |
16 |
| -} |
| 13 | +use std::io; |
| 14 | +use sync::Future; |
17 | 15 |
|
18 | 16 | static ITER: int = 50;
|
19 | 17 | static LIMIT: f64 = 2.0;
|
20 | 18 |
|
21 |
| -fn main() { |
22 |
| - let args = std::os::args(); |
23 |
| - let (w, mut out) = if args.len() < 2 { |
24 |
| - println!("Test mode: do not dump the image because it's not utf8, \ |
25 |
| - which interferes with the test runner."); |
26 |
| - (1000, ~DummyWriter as ~Writer) |
27 |
| - } else { |
28 |
| - (from_str(args[1]).unwrap(), |
29 |
| - ~std::io::stdout() as ~Writer) |
30 |
| - }; |
31 |
| - let h = w; |
32 |
| - let mut byte_acc = 0u8; |
33 |
| - let mut bit_num = 0; |
34 |
| - |
35 |
| - writeln!(out, "P4\n{} {}", w, h); |
36 |
| - |
37 |
| - for y in range(0, h) { |
38 |
| - let y = y as f64; |
39 |
| - for x in range(0, w) { |
40 |
| - let mut z_r = 0f64; |
41 |
| - let mut z_i = 0f64; |
42 |
| - let mut t_r = 0f64; |
43 |
| - let mut t_i = 0f64; |
44 |
| - let c_r = 2.0 * (x as f64) / (w as f64) - 1.5; |
45 |
| - let c_i = 2.0 * (y as f64) / (h as f64) - 1.0; |
46 |
| - |
| 19 | +fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) { |
| 20 | + for chunk_init_r in vec_init_r.chunks(8) { |
| 21 | + let mut cur_byte = 0xff; |
| 22 | + let mut cur_bitmask = 0x80; |
| 23 | + for &init_r in chunk_init_r.iter() { |
| 24 | + let mut cur_r = init_r; |
| 25 | + let mut cur_i = init_i; |
47 | 26 | for _ in range(0, ITER) {
|
48 |
| - if t_r + t_i > LIMIT * LIMIT { |
| 27 | + let r = cur_r; |
| 28 | + let i = cur_i; |
| 29 | + cur_r = r * r - i * i + init_r; |
| 30 | + cur_i = 2.0 * r * i + init_i; |
| 31 | + |
| 32 | + if r * r + i * i > LIMIT * LIMIT { |
| 33 | + cur_byte &= !cur_bitmask; |
49 | 34 | break;
|
50 | 35 | }
|
51 |
| - |
52 |
| - z_i = 2.0 * z_r * z_i + c_i; |
53 |
| - z_r = t_r - t_i + c_r; |
54 |
| - t_r = z_r * z_r; |
55 |
| - t_i = z_i * z_i; |
56 |
| - } |
57 |
| - |
58 |
| - byte_acc <<= 1; |
59 |
| - if t_r + t_i <= LIMIT * LIMIT { |
60 |
| - byte_acc |= 1; |
61 | 36 | }
|
| 37 | + cur_bitmask >>= 1; |
| 38 | + } |
| 39 | + res.push(cur_byte); |
| 40 | + } |
| 41 | +} |
62 | 42 |
|
63 |
| - bit_num += 1; |
| 43 | +fn mandelbrot<W: io::Writer>(w: uint, mut out: W) -> io::IoResult<()> { |
| 44 | + // Ensure w and h are multiples of 8. |
| 45 | + let w = (w + 7) / 8 * 8; |
| 46 | + let h = w; |
| 47 | + let chunk_size = h / 8; |
64 | 48 |
|
65 |
| - if bit_num == 8 { |
66 |
| - out.write_u8(byte_acc); |
67 |
| - byte_acc = 0; |
68 |
| - bit_num = 0; |
69 |
| - } else if x == w - 1 { |
70 |
| - byte_acc <<= 8 - w % 8; |
71 |
| - out.write_u8(byte_acc); |
72 |
| - byte_acc = 0; |
73 |
| - bit_num = 0; |
74 |
| - } |
| 49 | + let data: Vec<Future<Vec<u8>>> = range(0u, 8).map(|i| Future::spawn(proc () { |
| 50 | + let vec_init_r = Vec::from_fn(w, |x| 2.0 * (x as f64) / (w as f64) - 1.5); |
| 51 | + let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8); |
| 52 | + for y in range(i * chunk_size, (i + 1) * chunk_size) { |
| 53 | + let init_i = 2.0 * (y as f64) / (h as f64) - 1.0; |
| 54 | + write_line(init_i, vec_init_r.as_slice(), &mut res); |
75 | 55 | }
|
| 56 | + res |
| 57 | + })).collect(); |
| 58 | + |
| 59 | + try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h)); |
| 60 | + for res in data.move_iter() { |
| 61 | + try!(out.write(res.unwrap().as_slice())); |
76 | 62 | }
|
| 63 | + out.flush() |
| 64 | +} |
77 | 65 |
|
78 |
| - out.flush(); |
| 66 | +fn main() { |
| 67 | + let args = std::os::args(); |
| 68 | + let res = if args.len() < 2 { |
| 69 | + println!("Test mode: do not dump the image because it's not utf8, \ |
| 70 | + which interferes with the test runner."); |
| 71 | + mandelbrot(1000, std::io::util::NullWriter) |
| 72 | + } else { |
| 73 | + mandelbrot(from_str(args[1]).unwrap(), std::io::stdout()) |
| 74 | + }; |
| 75 | + res.unwrap(); |
79 | 76 | }
|
0 commit comments