Compare commits

...

2 Commits

2 changed files with 90 additions and 51 deletions

View File

@ -5,9 +5,8 @@ mod test_image;
use std::{fs::File, io::BufWriter, path::Path}; use std::{fs::File, io::BufWriter, path::Path};
use clap::{Arg, Command}; use clap::{Arg, Command};
// use colorbox::transfer_functions::srgb;
use test_image::{GRADIENT_LEN, RES_X, RES_Y}; use test_image::{rgb_idx, GRADIENT_LEN, RES_X, RES_Y, TABLE_SIZE};
const VERSION: &str = env!("CARGO_PKG_VERSION"); const VERSION: &str = env!("CARGO_PKG_VERSION");
const LUT_LEN: usize = 1 << 12; const LUT_LEN: usize = 1 << 12;
@ -31,6 +30,12 @@ fn main() {
.long("test_image") .long("test_image")
.help("Generates the test EXR file."), .help("Generates the test EXR file."),
) )
.arg(
Arg::new("chromaticities")
.short('c')
.long("chroma")
.help("Extract chromaticities instead of a transfer function"),
)
.get_matches(); .get_matches();
if args.is_present("test_image") { if args.is_present("test_image") {
@ -62,8 +67,34 @@ fn main() {
image image
}; };
if args.is_present("chromaticities") {
// Get the "pure" red, green, blue, and white pixels.
// These should have been transformed into XYZ space.
let idx = TABLE_SIZE / 2;
let r = input_image[rgb_idx(idx, 0, 0)];
let g = input_image[rgb_idx(0, idx, 0)];
let b = input_image[rgb_idx(0, 0, idx)];
let w = input_image[rgb_idx(idx, idx, idx)];
let xy_chroma = |xyz: [f32; 3]| {
let sum = xyz[0] + xyz[1] + xyz[2];
(xyz[0] / sum, xyz[1] / sum)
};
let r_xy = xy_chroma(r);
let g_xy = xy_chroma(g);
let b_xy = xy_chroma(b);
let w_xy = xy_chroma(w);
println!("Chromaticities (assuming XYZ input):");
println!("R: ({}, {})", r_xy.0, r_xy.1);
println!("G: ({}, {})", g_xy.0, g_xy.1);
println!("B: ({}, {})", b_xy.0, b_xy.1);
println!("W: ({}, {})", w_xy.0, w_xy.1);
} else {
// Fetch the transfer function LUT. // Fetch the transfer function LUT.
let gray = &mut input_image[test_image::gray_idx(0)..test_image::gray_idx(GRADIENT_LEN)]; let gray =
&mut input_image[test_image::gray_idx(0)..test_image::gray_idx(GRADIENT_LEN)];
// Attempt to find an analytic log-linear function that matches // Attempt to find an analytic log-linear function that matches
// the transfer function. // the transfer function.
@ -103,13 +134,17 @@ fn main() {
// Write the LUT files. // Write the LUT files.
colorbox::formats::cube::write_1d( colorbox::formats::cube::write_1d(
BufWriter::new(File::create(&Path::new(input_path).with_extension("cube")).unwrap()), BufWriter::new(
File::create(&Path::new(input_path).with_extension("cube")).unwrap(),
),
[(0.0, 1.0); 3], [(0.0, 1.0); 3],
[&gray_r, &gray_g, &gray_b], [&gray_r, &gray_g, &gray_b],
) )
.unwrap(); .unwrap();
colorbox::formats::spi1d::write( colorbox::formats::spi1d::write(
BufWriter::new(File::create(&Path::new(input_path).with_extension("spi1d")).unwrap()), BufWriter::new(
File::create(&Path::new(input_path).with_extension("spi1d")).unwrap(),
),
0.0, 0.0,
1.0, 1.0,
&[&gray_avg], &[&gray_avg],
@ -117,6 +152,7 @@ fn main() {
.unwrap(); .unwrap();
} }
} }
}
fn lerp_slice_3(slice: &[[f32; 3]], t: f32) -> [f32; 3] { fn lerp_slice_3(slice: &[[f32; 3]], t: f32) -> [f32; 3] {
assert!(!slice.is_empty()); assert!(!slice.is_empty());

View File

@ -8,7 +8,10 @@ pub fn find_parameters(lut: &[f32]) {
let end = lut[lut.len() - 1] as f64; let end = lut[lut.len() - 1] as f64;
let slope = { let slope = {
// We take the difference of points near zero for increased accuracy. // We take the difference of points near zero for increased accuracy.
let (i, _) = lut.iter().enumerate().find(|(_, y)| **y > 0.0).unwrap(); let (mut i, _) = lut.iter().enumerate().find(|(_, y)| **y > 0.0).unwrap();
if i == 0 {
i += 1;
}
lin_norm / (lut[i] as f64 - lut[i - 1] as f64) lin_norm / (lut[i] as f64 - lut[i - 1] as f64)
}; };