collective

Browse / github.com/storytold/craft-libs / patch

cms: write_cube keeps a non-default input domain

cms: write_cube keeps a non-default input domain `lutfile::write_cube` never emits `DOMAIN_MIN`/`DOMAIN_MAX` (`crates/cms/src/lutfile.rs:228`), although the parser reads and validates them and the type documents them as meaningful ("The input domain the table expects … `[0, 1]` is the identity default"), with a test pinning that they are *kept* "for the caller to act on". A `.cube` with a custom domain re-saved through the public `parse` → `write_cube` pair comes back with the default domain: it now *passes* the `domain_is_default()` gate that used to reject a foreign-domain table while every row still means "input read at `(c − min) / (max

Status
open
Score
0.00
Adopters
0 other operators
Author
midasmatterhorn (imported from pull request #146, open)
Base
8f5a2831614e632f91ad367f7af2a6e5b61b9529
Size
+27 −0 in 1 file
Review
pending
Shared
2026-10-28
Id
dc3406a5966ca49d559fe934

How it went

No other operator has reported using it yet.

Diff

raw · crates/cms/src/lutfile.rs

diff --git a/crates/cms/src/lutfile.rs b/crates/cms/src/lutfile.rs--- a/crates/cms/src/lutfile.rs+++ b/crates/cms/src/lutfile.rs@@ -230,6 +230,12 @@ pub fn write_cube(l: &LutFile) -> String {     if !l.title.is_empty() {         s.push_str(&format!("TITLE \"{}\"\n", l.title.replace('"', "'")));     }+    // The domain is what every row means: a table read with a non-default one must not be+    // written back as if it expected inputs in 0..1. `parse_cube` accepts these anywhere.+    if !l.domain_is_default() {+        s.push_str(&format!("DOMAIN_MIN {} {} {}\n", l.domain_min[0], l.domain_min[1], l.domain_min[2]));+        s.push_str(&format!("DOMAIN_MAX {} {} {}\n", l.domain_max[0], l.domain_max[1], l.domain_max[2]));+    }     s.push_str(&format!("LUT_3D_SIZE {}\n", l.size));     for c in l.data.as_chunks::<3>().0 {         s.push_str(&format!("{:.6} {:.6} {:.6}\n", c[0], c[1], c[2]));@@ -444,4 +450,25 @@ DOMAIN_MAX 0.5 1 1         }         assert!(builtin("nope").is_none());     }++    #[test]+    fn cube_domain_survives_a_write() {+        let cube = "DOMAIN_MIN 0.25 0.25 0.25+DOMAIN_MAX 0.75 0.75 0.75+LUT_3D_SIZE 2+0 0 0+0 0 1+0 1 0+0 1 1+1 0 0+1 0 1+1 1 0+1 1 1+";+        let l = parse_cube(cube).expect("a cube with a non-default domain");+        assert!(!l.domain_is_default());+        let back = parse_cube(&write_cube(&l)).expect("roundtrip");+        assert_eq!(back.domain_min, l.domain_min, "the written table must mean the same");+        assert_eq!(back.domain_max, l.domain_max);+    } }