diff --git a/crates/color/src/lut.rs b/crates/color/src/lut.rs index 67590eb12..73879a5b0 100644 --- a/crates/color/src/lut.rs +++ b/crates/color/src/lut.rs @@ -308,7 +308,11 @@ impl Lut { if let Some(sh) = &self.shaper { let _ = writeln!(s, "LUT_1D_SIZE {}", sh.size()); if both { - if sh.domain_min != [0.0; 3] || sh.domain_max != [1.0; 3] { + let uniform = sh.domain_min.iter().all(|v| *v == sh.domain_min[0]) && sh.domain_max.iter().all(|v| *v == sh.domain_max[0]); + if !uniform { + // with both tables, DOMAIN_MIN/DOMAIN_MAX belong to the shaper + write_domain(&mut s, sh.domain_min, sh.domain_max); + } else if sh.domain_min != [0.0; 3] || sh.domain_max != [1.0; 3] { let _ = writeln!(s, "LUT_1D_INPUT_RANGE {} {}", sh.domain_min[0], sh.domain_max[0]); } } else { @@ -650,4 +654,16 @@ mod tests { let mesh257 = (0..257).map(|i| i.to_string()).collect::>().join(" ") + "\n"; assert!(Lut::parse_3dl(&mesh257).is_err()); } + + #[test] + fn cube_shaper_per_channel_domain_round_trips() { + let mut text = String::from("LUT_1D_SIZE 2\nLUT_3D_SIZE 2\nDOMAIN_MAX 1 2 3\n"); + for _ in 0..10 { + text.push_str("0 0 0\n"); + } + let a = Lut::parse_cube(&text).unwrap(); + assert_eq!(a.shaper.as_ref().unwrap().domain_max, [1.0, 2.0, 3.0]); + let b = Lut::parse_cube(&a.to_cube()).unwrap(); + assert_eq!(b.shaper.unwrap().domain_max, [1.0, 2.0, 3.0]); + } }