aboutsummaryrefslogtreecommitdiff
path: root/vendor/exr/examples/5b_extract_exr_layers_as_pngs.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
committerValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
commita990de90fe41456a23e58bd087d2f107d321f3a1 (patch)
tree15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/exr/examples/5b_extract_exr_layers_as_pngs.rs
parent3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff)
downloadfparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz
fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip
Deleted vendor folder
Diffstat (limited to 'vendor/exr/examples/5b_extract_exr_layers_as_pngs.rs')
-rw-r--r--vendor/exr/examples/5b_extract_exr_layers_as_pngs.rs74
1 files changed, 0 insertions, 74 deletions
diff --git a/vendor/exr/examples/5b_extract_exr_layers_as_pngs.rs b/vendor/exr/examples/5b_extract_exr_layers_as_pngs.rs
deleted file mode 100644
index 1f14ea7..0000000
--- a/vendor/exr/examples/5b_extract_exr_layers_as_pngs.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-extern crate image as png;
-use std::cmp::Ordering;
-
-extern crate exr;
-
-/// For each layer in the exr file,
-/// extract each channel as grayscale png,
-/// including all multi-resolution levels.
-//
-// FIXME throws "access denied" sometimes, simply trying again usually works.
-//
-pub fn main() {
- use exr::prelude::*;
-
- let path = "layers.exr";
- let now = ::std::time::Instant::now();
-
- // load the exr file from disk with multi-core decompression
- let image = read()
- .no_deep_data().largest_resolution_level().all_channels().all_layers().all_attributes()
- .from_file(path).expect("run example `5a_write_multiple_layers` to generate this image file");
-
- // warning: highly unscientific benchmarks ahead!
- println!("\nloaded file in {:?}s", now.elapsed().as_secs_f32());
- let _ = std::fs::create_dir_all("pngs/");
- println!("writing images...");
-
- for (layer_index, layer) in image.layer_data.iter().enumerate() {
- let layer_name = layer.attributes.layer_name.as_ref()
- .map_or(String::from("main_layer"), Text::to_string);
-
- for channel in &layer.channel_data.list {
- let data : Vec<f32> = channel.sample_data.values_as_f32().collect();
- save_f32_image_as_png(&data, layer.size, format!(
- "pngs/{} ({}) {}_{}x{}.png",
- layer_index, layer_name, channel.name,
- layer.size.width(), layer.size.height(),
- ))
- }
- }
-
- /// Save raw float data to a PNG file, doing automatic brightness adjustments per channel
- fn save_f32_image_as_png(data: &[f32], size: Vec2<usize>, name: String) {
- let mut png_buffer = png::GrayImage::new(size.width() as u32, size.height() as u32);
- let mut sorted = Vec::from(data);
- sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Less));
-
- // percentile normalization
- let max = sorted[7 * sorted.len() / 8];
- let min = sorted[1 * sorted.len() / 8];
-
- // primitive tone mapping
- let tone = |v: f32| (v - 0.5).tanh() * 0.5 + 0.5;
- let max_toned = tone(*sorted.last().unwrap());
- let min_toned = tone(*sorted.first().unwrap());
-
- // for each pixel, tone map the value
- for (x, y, pixel) in png_buffer.enumerate_pixels_mut() {
- let v = data[y as usize * size.0 + x as usize];
- let v = (v - min) / (max - min);
- let v = tone(v);
-
- let v = (v - min_toned) / (max_toned - min_toned);
-
- // TODO does the `image` crate expect gamma corrected data?
- *pixel = png::Luma([(v.max(0.0).min(1.0) * 255.0) as u8]);
- }
-
- png_buffer.save(&name).unwrap();
- }
-
- println!("extracted all layers to folder `./pngs/*.png`");
-}
-