2014-05-03 07:53:52 -05:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2013-11-17 05:04:36 -06:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
2013-08-05 23:11:25 -05:00
|
|
|
|
2014-05-03 07:53:52 -05:00
|
|
|
extern crate sync;
|
2012-12-10 19:32:48 -06:00
|
|
|
|
2014-05-03 07:53:52 -05:00
|
|
|
use std::io;
|
|
|
|
use sync::Future;
|
2013-11-17 05:04:36 -06:00
|
|
|
|
|
|
|
static ITER: int = 50;
|
2013-04-18 23:44:50 -05:00
|
|
|
static LIMIT: f64 = 2.0;
|
2012-02-03 19:46:17 -06:00
|
|
|
|
2014-05-03 07:53:52 -05:00
|
|
|
fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
|
|
|
|
for chunk_init_r in vec_init_r.chunks(8) {
|
|
|
|
let mut cur_byte = 0xff;
|
|
|
|
let mut cur_bitmask = 0x80;
|
|
|
|
for &init_r in chunk_init_r.iter() {
|
|
|
|
let mut cur_r = init_r;
|
|
|
|
let mut cur_i = init_i;
|
2013-11-17 05:04:36 -06:00
|
|
|
for _ in range(0, ITER) {
|
2014-05-03 07:53:52 -05:00
|
|
|
let r = cur_r;
|
|
|
|
let i = cur_i;
|
|
|
|
cur_r = r * r - i * i + init_r;
|
|
|
|
cur_i = 2.0 * r * i + init_i;
|
|
|
|
|
|
|
|
if r * r + i * i > LIMIT * LIMIT {
|
|
|
|
cur_byte &= !cur_bitmask;
|
2013-11-17 05:04:36 -06:00
|
|
|
break;
|
2013-04-18 23:44:50 -05:00
|
|
|
}
|
2013-11-17 05:04:36 -06:00
|
|
|
}
|
2014-05-03 07:53:52 -05:00
|
|
|
cur_bitmask >>= 1;
|
|
|
|
}
|
|
|
|
res.push(cur_byte);
|
|
|
|
}
|
|
|
|
}
|
2013-04-18 23:44:50 -05:00
|
|
|
|
2014-05-03 07:53:52 -05:00
|
|
|
fn mandelbrot<W: io::Writer>(w: uint, mut out: W) -> io::IoResult<()> {
|
|
|
|
// Ensure w and h are multiples of 8.
|
|
|
|
let w = (w + 7) / 8 * 8;
|
|
|
|
let h = w;
|
|
|
|
let chunk_size = h / 8;
|
2013-11-17 05:04:36 -06:00
|
|
|
|
2014-05-03 07:53:52 -05:00
|
|
|
let data: Vec<Future<Vec<u8>>> = range(0u, 8).map(|i| Future::spawn(proc () {
|
|
|
|
let vec_init_r = Vec::from_fn(w, |x| 2.0 * (x as f64) / (w as f64) - 1.5);
|
|
|
|
let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
|
|
|
|
for y in range(i * chunk_size, (i + 1) * chunk_size) {
|
|
|
|
let init_i = 2.0 * (y as f64) / (h as f64) - 1.0;
|
|
|
|
write_line(init_i, vec_init_r.as_slice(), &mut res);
|
2012-02-03 21:50:32 -06:00
|
|
|
}
|
2014-05-03 07:53:52 -05:00
|
|
|
res
|
|
|
|
})).collect();
|
|
|
|
|
|
|
|
try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h));
|
|
|
|
for res in data.move_iter() {
|
|
|
|
try!(out.write(res.unwrap().as_slice()));
|
2012-02-03 21:50:32 -06:00
|
|
|
}
|
2014-05-03 07:53:52 -05:00
|
|
|
out.flush()
|
|
|
|
}
|
2013-11-17 05:04:36 -06:00
|
|
|
|
2014-05-03 07:53:52 -05:00
|
|
|
fn main() {
|
|
|
|
let args = std::os::args();
|
|
|
|
let res = if args.len() < 2 {
|
|
|
|
println!("Test mode: do not dump the image because it's not utf8, \
|
|
|
|
which interferes with the test runner.");
|
|
|
|
mandelbrot(1000, std::io::util::NullWriter)
|
|
|
|
} else {
|
|
|
|
mandelbrot(from_str(args[1]).unwrap(), std::io::stdout())
|
|
|
|
};
|
|
|
|
res.unwrap();
|
2012-02-03 19:46:17 -06:00
|
|
|
}
|