code wiki / (root) / nx_de_referee_lib.nx

nx_de_referee_lib.nx source

↩ module page · 128 lines · 5255 B

1// nx_de_referee_lib.nx -- THE PER-REGION CIEDE2000 REFEREE: rung ST1 of /compare/skintwin (2026-09-03) 2// 3// WHY THIS IS THE HIGHEST-VALUE RUNG ON THAT BOARD. nx_colorsci_lib has carried cs_de2000 -- the colour 4// difference the whole field states its errors in -- since 2026-08-24, and MEASURED with corpus_complete=1 5// it has ZERO adopters outside the garment-print lane. Until something in the render lane calls it, every 6// quality claim about a rendered human is an assertion about MECHANISM, not about appearance. The chromophore 7// stack can be perfectly derived and still look wrong, and nothing in the estate could say so in a number. 8// This file is the thing that can say so. 9// 10// IT COMPOSES, IT DOES NOT RE-RULE. The colour difference itself is cs_de2000, untouched: this file adds only 11// the AGGREGATION -- per region, worst region, mean, and a verdict against a declared tolerance. There is 12// exactly one CIEDE2000 in this estate and it is not here. 13// 14// THE THREE LAWS THIS FILE EXISTS TO ENFORCE, each of which the estate has been bitten by before: 15// 1. ABSTAIN, NEVER ACQUIT. A region with no samples is UNOBSERVED. It is not a pass. A referee that 16// silently counts an unmeasured region as agreement is worse than no referee, because its green is 17// indistinguishable from a real one. 18// 2. A TOOTH THAT PASSES ON THE EMPTY SET IS NOT A TOOTH. If nothing was measured, the verdict is ABSTAIN. 19// Zero regions must never return PASS, however tight the tolerance. 20// 3. THE DENOMINATOR TRAVELS WITH THE VERDICT. measured + unobserved always equals the declared region 21// count, and both halves are written to the output so a caller can reconcile them rather than trust a 22// bare number. 23// 24// The TOLERANCE is an ARGUMENT, not a constant. A bar for a print proof and a bar for a screen render are 25// different numbers with the same units, and a lib that picks one has decided something it has no standing 26// to decide. The caller declares it and the gate prints it. 27// license_tier: ORIGINAL No hw writes (Rule 26). LIB (no main). 28import "nx_syscalls.nx" 29import "nx_fixq30_lib.nx" 30import "nx_colorsci_lib.nx" 31 32const DR_REFUSED: i64 = 0 - 1 33// verdicts 34const DR_PASS: i64 = 0 35const DR_FAIL: i64 = 1 36const DR_ABSTAIN: i64 = 2 37// a region carrying no samples 38const DR_UNOBSERVED: i64 = 0 - 1 39 40// out slots 41const DR_O_VERDICT: i64 = 0 42const DR_O_WORST_IDX: i64 = 1 43const DR_O_WORST_DE: i64 = 2 44const DR_O_MEAN_DE: i64 = 3 45const DR_O_MEASURED: i64 = 4 46const DR_O_UNOBSERVED: i64 = 5 47const DR_O_DECLARED: i64 = 6 48const DR_O_SLOTS: i64 = 7 49const DR_SLOT: i64 = 8 50const DR_LAB: i64 = 3 51 52// The colour difference for ONE region, straight through the estate's single CIEDE2000. 53// ref3 and rnd3 are L*, a*, b* triples in Q30. 54func dr_region_de(cs: *i64, ref3: *i64, rnd3: *i64) -> i64 { 55 return cs_de2000(cs, ref3[0], ref3[1], ref3[2], rnd3[0], rnd3[1], rnd3[2]) 56} 57 58// Judge a whole set of regions. 59// refs, rnds : n contiguous Lab triples each (3 slots per region) 60// counts : n sample counts; a count of zero marks the region UNOBSERVED 61// tol : the declared tolerance in Q30 CIEDE2000 units 62// Returns the verdict, and writes the full picture to out so nothing has to be inferred from it. 63func dr_run(cs: *i64, refs: *i64, rnds: *i64, counts: *i64, n: i64, tol: i64, out: *i64) -> i64 { 64 var z: i64 = 0 65 while z < DR_O_SLOTS { 66 out[z] = 0 67 z = z + 1 68 } 69 out[DR_O_WORST_IDX] = DR_UNOBSERVED 70 out[DR_O_DECLARED] = n 71 if n < 0 { return DR_REFUSED } 72 if tol <= 0 { return DR_REFUSED } 73 74 var measured: i64 = 0 75 var unobserved: i64 = 0 76 var worst: i64 = 0 77 var worst_i: i64 = DR_UNOBSERVED 78 var sum: i64 = 0 79 var i: i64 = 0 80 while i < n { 81 if counts[i] <= 0 { 82 unobserved = unobserved + 1 83 } else { 84 let base: i64 = i * DR_LAB 85 let de: i64 = dr_region_de(cs, (refs as i64 + base * DR_SLOT) as *i64, 86 (rnds as i64 + base * DR_SLOT) as *i64) 87 sum = sum + de 88 if measured == 0 { 89 worst = de 90 worst_i = i 91 } else { 92 if de > worst { 93 worst = de 94 worst_i = i 95 } 96 } 97 measured = measured + 1 98 } 99 i = i + 1 100 } 101 102 out[DR_O_MEASURED] = measured 103 out[DR_O_UNOBSERVED] = unobserved 104 out[DR_O_WORST_IDX] = worst_i 105 out[DR_O_WORST_DE] = worst 106 if measured > 0 { out[DR_O_MEAN_DE] = sum / measured } 107 108 // LAW 2: nothing measured is never a pass, however tight the tolerance. 109 if measured == 0 { 110 out[DR_O_VERDICT] = DR_ABSTAIN 111 return DR_ABSTAIN 112 } 113 // LAW 1: only MEASURED regions can fail it, and only measured regions can pass it. An unobserved region 114 // rescues nothing and condemns nothing. 115 if worst > tol { 116 out[DR_O_VERDICT] = DR_FAIL 117 return DR_FAIL 118 } 119 out[DR_O_VERDICT] = DR_PASS 120 return DR_PASS 121} 122 123func dr_verdict_name(v: i64) -> *u8 { 124 if v == DR_PASS { return "PASS" as *u8 } 125 if v == DR_FAIL { return "FAIL" as *u8 } 126 if v == DR_ABSTAIN { return "ABSTAIN" as *u8 } 127 return "REFUSED" as *u8 128}