Skip to content

Commit d97ad62

Browse files
committed
completed integration of colouring program
1 parent 7d73aee commit d97ad62

File tree

4 files changed

+134
-8
lines changed

4 files changed

+134
-8
lines changed

high.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ image_height = 1080
33
rotate = 0
44
approximation_order = 48
55
glitch_tolerance = 0.001
6-
frames = 1
6+
frames = 20
77
frame_offset = 0
88
zoom_scale = 2.0
99
display_glitches = false
1010
auto_adjust_iterations = true
1111
probe_sampling = 3
1212
remove_centre = true
13-
export = "png"
13+
export = "exr"
1414
experimental = true

src/bin/main.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rust_fractal::renderer::FractalRenderer;
2+
use rust_fractal::util::RecolourEXR;
23
use clap::{crate_version, crate_name, crate_description, App, Arg};
34
use config::{Config, File};
45

@@ -10,7 +11,7 @@ fn main() {
1011
.arg(
1112
Arg::new("INPUT")
1213
.value_name("FILE")
13-
.about("Sets the location file to use.")
14+
.about("Sets the location file to use")
1415
.takes_value(true)
1516
.required(false)
1617
)
@@ -19,7 +20,7 @@ fn main() {
1920
.short('o')
2021
.long("options")
2122
.value_name("FILE")
22-
.about("Sets the options file to use.")
23+
.about("Sets the options file to use")
2324
.takes_value(true)
2425
.required(false)
2526
)
@@ -28,9 +29,16 @@ fn main() {
2829
.short('p')
2930
.long("palette")
3031
.value_name("FILE")
31-
.about("Sets the palette file to use.")
32+
.about("Sets the palette file to use")
3233
.takes_value(true)
3334
.required(false)
35+
)
36+
.arg(
37+
Arg::new("colour_exr")
38+
.short('c')
39+
.long("colour_exr")
40+
.about("Colours the EXR files in the output directory")
41+
.required(false)
3442
).get_matches();
3543

3644
let mut settings = Config::default();
@@ -47,7 +55,11 @@ fn main() {
4755
settings.merge(File::with_name(l).required(true)).unwrap();
4856
};
4957

50-
let mut renderer = FractalRenderer::new(settings);
51-
// renderer.render("output/output".to_owned());
52-
renderer.render();
58+
if matches.is_present("colour_exr") {
59+
let colouring = RecolourEXR::new(settings);
60+
colouring.colour();
61+
} else {
62+
let mut renderer = FractalRenderer::new(settings);
63+
renderer.render();
64+
}
5365
}

src/util/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ use std::cmp::{min, max};
44
pub mod data_export;
55
pub mod float_extended;
66
pub mod complex_extended;
7+
pub mod recolour_exr;
78

89
pub use complex_extended::ComplexExtended;
910
pub use float_extended::FloatExtended;
11+
pub use recolour_exr::RecolourEXR;
1012

1113
pub type ComplexFixed<T> = num_complex::Complex<T>;
1214
pub type ComplexArbitrary = rug::Complex;

src/util/recolour_exr.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
use exr::prelude::simple_image::*;
2+
use rayon::prelude::*;
3+
use config::Config;
4+
5+
use std::fs;
6+
use std::time::Instant;
7+
8+
use crate::util::generate_default_palette;
9+
10+
pub struct RecolourEXR {
11+
palette: Vec<(u8, u8, u8)>,
12+
files: Vec<String>,
13+
iteration_division: f32
14+
}
15+
16+
impl RecolourEXR {
17+
pub fn new(settings: Config) -> Self {
18+
let palette = if let Ok(values) = settings.get_array("palette") {
19+
let palette = values.chunks_exact(3).map(|value| {
20+
// We assume the palette is in BGR rather than RGB
21+
(value[2].clone().into_int().unwrap() as u8,
22+
value[1].clone().into_int().unwrap() as u8,
23+
value[0].clone().into_int().unwrap() as u8)
24+
}).collect::<Vec<(u8, u8, u8)>>();
25+
26+
palette
27+
} else {
28+
generate_default_palette()
29+
};
30+
let iteration_division = settings.get_float("iteration_division").unwrap_or(0.1) as f32;
31+
32+
let paths = fs::read_dir("./output/").unwrap();
33+
let mut exr_files = Vec::new();
34+
35+
for path in paths {
36+
let name = path.unwrap()
37+
.path()
38+
.to_owned()
39+
.to_str()
40+
.unwrap()
41+
.to_string();
42+
43+
if name.contains(".exr") {
44+
exr_files.push(name)
45+
}
46+
};
47+
48+
RecolourEXR {
49+
palette,
50+
files: exr_files,
51+
iteration_division
52+
}
53+
}
54+
55+
pub fn colour(&self) {
56+
let colouring_time = Instant::now();
57+
58+
(&self.files).into_par_iter()
59+
.for_each(|exr_file| {
60+
let raw_data = Image::read_from_file(&exr_file, read_options::high()).unwrap();
61+
62+
let mut iterations = Vec::new();
63+
let mut smooth = Vec::new();
64+
65+
for layer in &raw_data.layers {
66+
for channel in &layer.channels {
67+
match &channel.samples {
68+
Samples::F16(f16_vec) => {
69+
smooth = f16_vec.clone();
70+
},
71+
Samples::F32(_) => {},
72+
Samples::U32(u32_vec) => {
73+
iterations = u32_vec.clone();
74+
}
75+
};
76+
}
77+
}
78+
79+
let file_name = exr_file.split(".exr").collect::<Vec<_>>()[0];
80+
let dimensions = raw_data.attributes.display_window.size;
81+
82+
println!("{}.exr", file_name);
83+
84+
let mut rgb_buffer = vec![0u8; iterations.len() * 3];
85+
86+
for i in 0..iterations.len() {
87+
if iterations[i] == 0xFFFFFFFF {
88+
rgb_buffer[3 * i] = 0u8;
89+
rgb_buffer[3 * i + 1] = 0u8;
90+
rgb_buffer[3 * i + 2] = 0u8;
91+
} else {
92+
let temp = (iterations[i] as f32 + smooth[i].to_f32()) / self.iteration_division;
93+
94+
let temp2 = temp.floor() as usize % self.palette.len();
95+
let temp3 = (temp as usize + 1) % self.palette.len();
96+
let temp4 = temp.fract();
97+
98+
let colour1 = self.palette[temp2];
99+
let colour2 = self.palette[temp3];
100+
101+
rgb_buffer[3 * i] = (colour1.0 as f32 + temp4 * (colour2.0 as f32 - colour1.0 as f32)) as u8;
102+
rgb_buffer[3 * i + 1] = (colour1.1 as f32 + temp4 * (colour2.1 as f32 - colour1.1 as f32)) as u8;
103+
rgb_buffer[3 * i + 2] = (colour1.2 as f32 + temp4 * (colour2.2 as f32 - colour1.2 as f32)) as u8;
104+
}
105+
}
106+
107+
image::save_buffer(file_name.to_owned() + ".png", &rgb_buffer, dimensions.x() as u32, dimensions.y() as u32, image::ColorType::Rgb8).unwrap();
108+
});
109+
110+
println!("Recolouring {} images took {} ms.", self.files.len(), colouring_time.elapsed().as_millis());
111+
}
112+
}

0 commit comments

Comments
 (0)