Skip to content

Commit afe23fc

Browse files
committed
added auto iteration which doesn't work for some images
1 parent 2476959 commit afe23fc

File tree

7 files changed

+134
-36
lines changed

7 files changed

+134
-36
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ exr = "^0.8.0"
1414
smallvec = "^1.4.2"
1515
clap = "3.0.0-beta.1"
1616
config = "0.9"
17+
half = "^1.6.0"
1718

1819
[dependencies.rug]
1920
version = "1.10"
@@ -22,6 +23,6 @@ features = ["float", "complex"]
2223

2324
#Additional commands that can improve performance (maybe by around 5-10%)
2425
[profile.release]
25-
#lto = "fat"
26-
#codegen-units = 1
26+
lto = "fat"
27+
codegen-units = 1
2728
#debug = true

assemble_video.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from PIL import Image
99

1010
frames_between_keyframes = 30
11-
maximum_keyframe_number = 15
11+
maximum_keyframe_number = 1040
1212
zoom_scale = 1.4
1313

1414
# log1.1 of 2 is 7.27
@@ -49,10 +49,14 @@
4949
for i in range(0, maximum_keyframe_number):
5050
# Creates 10 second segments
5151
if (i * frames_between_keyframes) % 600 == 0 and i != 0:
52+
# Add current_framebuffer frames
5253
for frame in reversed(framebuffer):
5354
writer.append_data(frame)
55+
5456
segment += 1
57+
5558
framebuffer = []
59+
5660
# Writer for adding frames to the video
5761
writer = imageio.get_writer(f"segment_{segment:08}.mp4", **kargs)
5862
segment_names.append(f"segment_{segment:08}.mp4")
@@ -78,28 +82,28 @@
7882
temp3 = scaled_width - temp1
7983
temp4 = scaled_height - temp2
8084

81-
next_frame = scaled_keyframe.crop((temp1, temp2, temp3, temp4)).resize((width, height), resample=Image.HAMMING)
85+
next_frame = scaled_keyframe.crop((temp1, temp2, temp3, temp4)).resize((width, height), resample=Image.LANCZOS)
8286

8387
framebuffer.append(np.array(next_frame))
84-
print(f"{i * frames_between_keyframes + j + 1}/{maximum_keyframe_number * frames_between_keyframes + 1} {time.time() - t0:.2f}s")
88+
89+
elapsed = time.time() - t0
90+
print(f"{i * frames_between_keyframes + j + 1}/{maximum_keyframe_number * frames_between_keyframes + 1} {elapsed:.2f}s {((i * frames_between_keyframes + j + 1)/elapsed):.2f} fps")
8591

8692
previous_keyframe = scaled_keyframe.resize((width, height), resample=Image.LANCZOS)
8793

8894

8995
framebuffer.append(np.array(previous_keyframe))
9096

91-
print(f"{maximum_keyframe_number * frames_between_keyframes + 1}/{maximum_keyframe_number * frames_between_keyframes + 1} {time.time() - t0:.2f}s")
92-
9397
for frame in reversed(framebuffer):
9498
writer.append_data(frame)
9599

96-
# Command to split up into
97-
# ffmpeg -i invid.mp4 -threads 3 -vcodec copy -f segment -segment_time 2 cam_out_h264%04d.mp4
98-
99100
with open('segments.txt', 'w') as f:
100101
for segment in reversed(segment_names):
101102
f.write(f"file '{segment}'\n")
102103

103104
writer.close()
104105

106+
elapsed = time.time() - t0
107+
print(f"{maximum_keyframe_number * frames_between_keyframes + 1}/{maximum_keyframe_number * frames_between_keyframes + 1} {elapsed:.2f}s {((maximum_keyframe_number * frames_between_keyframes + 1)/elapsed):.2f} fps")
108+
105109
os.system("ffmpeg -y -f concat -safe 0 -i segments.txt -c copy output.mp4")

default.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
image_width = 1920
22
image_height = 1080
3-
frames = 400
4-
export = "raw"
3+
frames = 9999
4+
export = "colour"
55
rotate = 0
66
glitch_tolerance = 0.000001
7-
zoom_scale = 1.4
7+
zoom_scale = 2.0

segments.txt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,52 @@
1+
file 'segment_00000051.mp4'
2+
file 'segment_00000050.mp4'
3+
file 'segment_00000049.mp4'
4+
file 'segment_00000048.mp4'
5+
file 'segment_00000047.mp4'
6+
file 'segment_00000046.mp4'
7+
file 'segment_00000045.mp4'
8+
file 'segment_00000044.mp4'
9+
file 'segment_00000043.mp4'
10+
file 'segment_00000042.mp4'
11+
file 'segment_00000041.mp4'
12+
file 'segment_00000040.mp4'
13+
file 'segment_00000039.mp4'
14+
file 'segment_00000038.mp4'
15+
file 'segment_00000037.mp4'
16+
file 'segment_00000036.mp4'
17+
file 'segment_00000035.mp4'
18+
file 'segment_00000034.mp4'
19+
file 'segment_00000033.mp4'
20+
file 'segment_00000032.mp4'
21+
file 'segment_00000031.mp4'
22+
file 'segment_00000030.mp4'
23+
file 'segment_00000029.mp4'
24+
file 'segment_00000028.mp4'
25+
file 'segment_00000027.mp4'
26+
file 'segment_00000026.mp4'
27+
file 'segment_00000025.mp4'
28+
file 'segment_00000024.mp4'
29+
file 'segment_00000023.mp4'
30+
file 'segment_00000022.mp4'
31+
file 'segment_00000021.mp4'
32+
file 'segment_00000020.mp4'
33+
file 'segment_00000019.mp4'
34+
file 'segment_00000018.mp4'
35+
file 'segment_00000017.mp4'
36+
file 'segment_00000016.mp4'
37+
file 'segment_00000015.mp4'
38+
file 'segment_00000014.mp4'
39+
file 'segment_00000013.mp4'
40+
file 'segment_00000012.mp4'
41+
file 'segment_00000011.mp4'
42+
file 'segment_00000010.mp4'
43+
file 'segment_00000009.mp4'
44+
file 'segment_00000008.mp4'
45+
file 'segment_00000007.mp4'
46+
file 'segment_00000006.mp4'
47+
file 'segment_00000005.mp4'
48+
file 'segment_00000004.mp4'
49+
file 'segment_00000003.mp4'
50+
file 'segment_00000002.mp4'
51+
file 'segment_00000001.mp4'
152
file 'segment_00000000.mp4'

src/renderer.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct FractalRenderer {
1414
image_height: usize,
1515
rotate: f64,
1616
zoom: FloatExtended,
17+
auto_adjust_iterations: bool,
1718
maximum_iteration: usize,
1819
glitch_tolerance: f64,
1920
data_export: DataExport,
@@ -38,14 +39,15 @@ impl FractalRenderer {
3839
let glitch_tolerance = settings.get_float("glitch_tolerance").unwrap_or(0.01);
3940
let remaining_frames = settings.get_int("frames").unwrap_or(1) as usize;
4041
let zoom_scale_factor = settings.get_float("zoom_scale").unwrap_or(2.0);
42+
let display_glitches = settings.get_bool("display_glitches").unwrap_or(false);
43+
let auto_adjust_iterations = settings.get_bool("auto_adjust_iterations").unwrap_or(true);
4144
let data_type = match settings.get_str("export").unwrap_or(String::from("COLOUR")).to_ascii_uppercase().as_ref() {
4245
"RAW" => DataType::RAW,
4346
"COLOUR" => DataType::COLOUR,
4447
"KFB" => DataType::KFB,
4548
"BOTH" => DataType::BOTH,
4649
_ => DataType::COLOUR
4750
};
48-
let display_glitches = false;
4951

5052
let zoom = string_to_extended(&initial_zoom);
5153
let delta_pixel = (-2.0 * (4.0 / image_height as f64 - 2.0) / zoom) / image_height as f64;
@@ -69,6 +71,7 @@ impl FractalRenderer {
6971
image_height,
7072
rotate,
7173
zoom,
74+
auto_adjust_iterations,
7275
maximum_iteration,
7376
glitch_tolerance,
7477
data_export: DataExport::new(image_width, image_height, display_glitches, data_type),
@@ -110,6 +113,7 @@ impl FractalRenderer {
110113

111114
print!("| {:<15}", approximation_time.elapsed().as_millis());
112115
print!("| {:<15}", self.series_approximation.valid_iteration);
116+
print!("| {:<15}", self.maximum_iteration);
113117
std::io::stdout().flush().unwrap();
114118

115119
let packing_time = Instant::now();
@@ -135,10 +139,8 @@ impl FractalRenderer {
135139
})
136140
}
137141

138-
let render_indices = &self.render_indices;
139-
140-
let mut pixel_data = render_indices.into_par_iter()
141-
.filter_map(|index| {
142+
let mut pixel_data = (&self.render_indices).into_par_iter()
143+
.map(|index| {
142144
let i = index % self.image_width;
143145
let j = index / self.image_width;
144146

@@ -151,7 +153,7 @@ impl FractalRenderer {
151153
let point_delta = ComplexExtended::new(element, -self.zoom.exponent);
152154
let new_delta = self.series_approximation.evaluate(point_delta, None);
153155

154-
Some(PixelData {
156+
PixelData {
155157
image_x: i,
156158
image_y: j,
157159
iteration: self.series_approximation.valid_iteration,
@@ -161,7 +163,7 @@ impl FractalRenderer {
161163
derivative_current: ComplexFixed::new(1.0, 0.0),
162164
glitched: false,
163165
escaped: false
164-
})
166+
}
165167
}).collect::<Vec<PixelData>>();
166168

167169
print!("| {:<15}", packing_time.elapsed().as_millis());
@@ -220,13 +222,28 @@ impl FractalRenderer {
220222

221223
pub fn render(&mut self) {
222224
// Print out the status information
223-
println!("{:<6}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}", "Frame", "Zoom", "Approx [ms]", "Skipped [it]", "Packing [ms]", "Iteration [ms]", "Correct [ms]", "Saving [ms]", "Frame [ms]", "TOTAL [ms]");
225+
println!("{:<6}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}| {:<15}", "Frame", "Zoom", "Approx [ms]", "Skipped [it]", "Maximum [it]", "Packing [ms]", "Iteration [ms]", "Correct [ms]", "Saving [ms]", "Frame [ms]", "TOTAL [ms]");
224226

225227
let mut count = 0;
226228
while self.remaining_frames > 0 && self.zoom.to_float() > 0.5 {
227229
self.render_frame(count, format!("output/{:08}_{}", count, extended_to_string(self.zoom)));
228230
self.zoom.mantissa /= self.zoom_scale_factor;
229231
self.zoom.reduce();
232+
233+
if self.auto_adjust_iterations {
234+
// test
235+
let mut temp = self.data_export.iterations.clone();
236+
temp.sort();
237+
238+
// let new_iteration_value = *(&self.data_export.iterations).into_iter().max().unwrap() as usize;
239+
// Set to value of 0.1%
240+
let value = 0.999 * temp.len() as f64;
241+
let new_iteration_value = temp[value as usize] as usize;
242+
self.center_reference.maximum_iteration = new_iteration_value;
243+
self.center_reference.current_iteration = new_iteration_value;
244+
self.maximum_iteration = new_iteration_value;
245+
}
246+
230247
self.remaining_frames -= 1;
231248
count += 1;
232249
}

src/util/data_export.rs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::fs::File;
66
use std::slice;
77

88
use exr::prelude::simple_image;
9+
use half::f16;
910

1011
pub enum DataType {
1112
COLOUR,
@@ -20,7 +21,8 @@ pub struct DataExport {
2021
pub rgb: Vec<u8>,
2122
palette: Vec<(u8, u8, u8)>,
2223
pub iterations: Vec<u32>,
23-
pub smooth: Vec<f32>,
24+
pub smooth_f16: Vec<f16>,
25+
pub smooth_f32: Vec<f32>,
2426
pub display_glitches: bool,
2527
data_type: DataType,
2628
}
@@ -34,20 +36,35 @@ impl DataExport {
3436
image_height,
3537
rgb: vec![0u8; image_width * image_height * 3],
3638
palette: DataExport::generate_colour_palette(),
37-
iterations: Vec::new(),
38-
smooth: Vec::new(),
39+
iterations: vec![0u32; image_width * image_height],
40+
smooth_f16: Vec::new(),
41+
smooth_f32: Vec::new(),
42+
display_glitches,
43+
data_type
44+
}
45+
},
46+
DataType::RAW => {
47+
DataExport {
48+
image_width,
49+
image_height,
50+
rgb: Vec::new(),
51+
palette: Vec::new(),
52+
iterations: vec![0u32; image_width * image_height],
53+
smooth_f16: vec![f16::ZERO; image_width * image_height],
54+
smooth_f32: Vec::new(),
3955
display_glitches,
4056
data_type
4157
}
4258
},
43-
DataType::RAW | DataType::KFB => {
59+
DataType::KFB => {
4460
DataExport {
4561
image_width,
4662
image_height,
4763
rgb: Vec::new(),
4864
palette: Vec::new(),
4965
iterations: vec![0u32; image_width * image_height],
50-
smooth: vec![0.0f32; image_width * image_height],
66+
smooth_f16: Vec::new(),
67+
smooth_f32: vec![0.0f32; image_width * image_height],
5168
display_glitches,
5269
data_type
5370
}
@@ -59,7 +76,8 @@ impl DataExport {
5976
rgb: vec![0u8; image_width * image_height * 3],
6077
palette: DataExport::generate_colour_palette(),
6178
iterations: vec![0u32; image_width * image_height],
62-
smooth: vec![0.0f32; image_width * image_height],
79+
smooth_f16: vec![f16::ZERO; image_width * image_height],
80+
smooth_f32: Vec::new(),
6381
display_glitches,
6482
data_type
6583
}
@@ -102,6 +120,8 @@ impl DataExport {
102120
self.rgb[k + 1] = colour.1;
103121
self.rgb[k + 2] = colour.2;
104122
};
123+
124+
self.iterations[k / 3] = pixel.iteration as u32;
105125
}
106126
},
107127
DataType::RAW => {
@@ -117,7 +137,7 @@ impl DataExport {
117137
};
118138

119139
let z_norm = (reference.reference_data[pixel.iteration - reference.start_iteration].z_fixed + pixel.delta_current.mantissa).norm_sqr() as f32;
120-
self.smooth[k] = 1.0 - (z_norm.ln() / escape_radius_ln).log2();
140+
self.smooth_f16[k] = f16::from_f32(1.0 - (z_norm.ln() / escape_radius_ln).log2());
121141
}
122142
},
123143
DataType::KFB => {
@@ -133,7 +153,7 @@ impl DataExport {
133153
};
134154

135155
let z_norm = (reference.reference_data[pixel.iteration - reference.start_iteration].z_fixed + pixel.delta_current.mantissa).norm_sqr() as f32;
136-
self.smooth[k] = 1.0 - (z_norm.ln() / escape_radius_ln).log2();
156+
self.smooth_f32[k] = 1.0 - (z_norm.ln() / escape_radius_ln).log2();
137157
}
138158
},
139159
DataType::BOTH => {
@@ -168,7 +188,7 @@ impl DataExport {
168188
self.rgb[k + 1] = colour.1;
169189
self.rgb[k + 2] = colour.2;
170190
self.iterations[k / 3] = pixel.iteration as u32;
171-
self.smooth[k / 3] = smooth
191+
self.smooth_f16[k / 3] = f16::from_f32(smooth)
172192
};
173193
}
174194
}
@@ -204,7 +224,7 @@ impl DataExport {
204224

205225
fn save_raw(&mut self, filename: &str) {
206226
let iterations = simple_image::Channel::non_color_data(simple_image::Text::from("N").unwrap(), simple_image::Samples::U32(self.iterations.clone()));
207-
let smooth = simple_image::Channel::non_color_data(simple_image::Text::from("NF").unwrap(), simple_image::Samples::F32(self.smooth.clone()));
227+
let smooth = simple_image::Channel::non_color_data(simple_image::Text::from("NF").unwrap(), simple_image::Samples::F16(self.smooth_f16.clone()));
208228

209229
let layer = simple_image::Layer::new(simple_image::Text::from("fractal_data").unwrap(), (self.image_width, self.image_height), smallvec::smallvec![iterations, smooth])
210230
.with_compression(simple_image::Compression::PXR24)
@@ -252,7 +272,7 @@ impl DataExport {
252272
}).unwrap();
253273

254274
file.write_all(unsafe {
255-
slice::from_raw_parts(self.smooth.as_ptr() as *const u8, self.iterations.len() * 4)
275+
slice::from_raw_parts(self.smooth_f32.as_ptr() as *const u8, self.iterations.len() * 4)
256276
}).unwrap();
257277

258278
}
@@ -310,14 +330,18 @@ impl DataExport {
310330
DataType::COLOUR => {
311331
self.rgb = vec![0u8; self.image_width * self.image_height * 3];
312332
}
313-
DataType::RAW | DataType::KFB => {
333+
DataType::RAW => {
314334
self.iterations = vec![0xFFFFFFFF; self.image_width * self.image_height];
315-
self.smooth = vec![0.0f32; self.image_width * self.image_height];
316-
}
335+
self.smooth_f16 = vec![f16::ZERO; self.image_width * self.image_height];
336+
},
337+
DataType::KFB => {
338+
self.iterations = vec![0xFFFFFFFF; self.image_width * self.image_height];
339+
self.smooth_f32 = vec![0.0f32; self.image_width * self.image_height];
340+
},
317341
DataType::BOTH => {
318342
self.rgb = vec![0u8; self.image_width * self.image_height * 3];
319343
self.iterations = vec![0xFFFFFFFF; self.image_width * self.image_height];
320-
self.smooth = vec![0.0f32; self.image_width * self.image_height];
344+
self.smooth_f16 = vec![f16::ZERO; self.image_width * self.image_height];
321345
}
322346
}
323347
}

0 commit comments

Comments
 (0)