use std::{env, fs::File, io::Write, path::Path}; use colorbox::{ chroma::{self, Chromaticities}, matrix::{invert, rgb_to_xyz_matrix, xyz_chromatic_adaptation_matrix, AdaptationMethod}, matrix_compose, }; fn main() { let out_dir = env::var("OUT_DIR").unwrap(); // Rec709 { let dest_path = Path::new(&out_dir).join("rec709_inc.rs"); let mut f = File::create(&dest_path).unwrap(); write_conversion_functions("rec709", chroma::REC709, &mut f); } // Rec2020 { let dest_path = Path::new(&out_dir).join("rec2020_inc.rs"); let mut f = File::create(&dest_path).unwrap(); write_conversion_functions("rec2020", chroma::REC2020, &mut f); } // ACES AP0 { let dest_path = Path::new(&out_dir).join("aces_ap0_inc.rs"); let mut f = File::create(&dest_path).unwrap(); write_conversion_functions("aces_ap0", chroma::ACES_AP0, &mut f); } // ACES AP1 { let dest_path = Path::new(&out_dir).join("aces_ap1_inc.rs"); let mut f = File::create(&dest_path).unwrap(); write_conversion_functions("aces_ap1", chroma::ACES_AP1, &mut f); } } /// Generates conversion functions for the given rgb to xyz transform matrix. fn write_conversion_functions(space_name: &str, chroma: Chromaticities, f: &mut File) { let to_xyz = rgb_to_xyz_matrix(chroma); f.write_all( format!( r#" #[inline] pub fn {}_to_xyz(rgb: (f32, f32, f32)) -> (f32, f32, f32) {{ ( (rgb.0 * {:.10}) + (rgb.1 * {:.10}) + (rgb.2 * {:.10}), (rgb.0 * {:.10}) + (rgb.1 * {:.10}) + (rgb.2 * {:.10}), (rgb.0 * {:.10}) + (rgb.1 * {:.10}) + (rgb.2 * {:.10}), ) }} "#, space_name, to_xyz[0][0], to_xyz[0][1], to_xyz[0][2], to_xyz[1][0], to_xyz[1][1], to_xyz[1][2], to_xyz[2][0], to_xyz[2][1], to_xyz[2][2] ) .as_bytes(), ) .unwrap(); let inv = invert(to_xyz).unwrap(); f.write_all( format!( r#" #[inline] pub fn xyz_to_{}(xyz: (f32, f32, f32)) -> (f32, f32, f32) {{ ( (xyz.0 * {:.10}) + (xyz.1 * {:.10}) + (xyz.2 * {:.10}), (xyz.0 * {:.10}) + (xyz.1 * {:.10}) + (xyz.2 * {:.10}), (xyz.0 * {:.10}) + (xyz.1 * {:.10}) + (xyz.2 * {:.10}), ) }} "#, space_name, inv[0][0], inv[0][1], inv[0][2], inv[1][0], inv[1][1], inv[1][2], inv[2][0], inv[2][1], inv[2][2] ) .as_bytes(), ) .unwrap(); let e_to_xyz = matrix_compose!( rgb_to_xyz_matrix(chroma), xyz_chromatic_adaptation_matrix( chroma.w, (1.0 / 3.0, 1.0 / 3.0), AdaptationMethod::Bradford, ), ); f.write_all( format!( r#" #[inline] pub fn {}_e_to_xyz(rgb: (f32, f32, f32)) -> (f32, f32, f32) {{ ( (rgb.0 * {:.10}) + (rgb.1 * {:.10}) + (rgb.2 * {:.10}), (rgb.0 * {:.10}) + (rgb.1 * {:.10}) + (rgb.2 * {:.10}), (rgb.0 * {:.10}) + (rgb.1 * {:.10}) + (rgb.2 * {:.10}), ) }} "#, space_name, e_to_xyz[0][0], e_to_xyz[0][1], e_to_xyz[0][2], e_to_xyz[1][0], e_to_xyz[1][1], e_to_xyz[1][2], e_to_xyz[2][0], e_to_xyz[2][1], e_to_xyz[2][2] ) .as_bytes(), ) .unwrap(); let inv_e = invert(e_to_xyz).unwrap(); f.write_all( format!( r#" #[inline] pub fn xyz_to_{}_e(xyz: (f32, f32, f32)) -> (f32, f32, f32) {{ ( (xyz.0 * {:.10}) + (xyz.1 * {:.10}) + (xyz.2 * {:.10}), (xyz.0 * {:.10}) + (xyz.1 * {:.10}) + (xyz.2 * {:.10}), (xyz.0 * {:.10}) + (xyz.1 * {:.10}) + (xyz.2 * {:.10}), ) }} "#, space_name, inv_e[0][0], inv_e[0][1], inv_e[0][2], inv_e[1][0], inv_e[1][1], inv_e[1][2], inv_e[2][0], inv_e[2][1], inv_e[2][2] ) .as_bytes(), ) .unwrap(); }