nx_view_transform_gate.nx source
↩ module page · 143 lines · 6643 B
1// nx_view_transform_gate.nx -- IS THE VIEW TRANSFORM DERIVED, OR JUST TYPED?
2// license_tier: ORIGINAL No hw writes (Rule 26).
3//
4// The claim under test is not "the curve looks nice". It is four mechanical properties, each of
5// which the shipped page FAILED on 2026-08-28 and each of which nx_view_transform is supposed to
6// make true BY CONSTRUCTION:
7// 1. the exponent is COMPUTED from declared measurements, not hand-typed (the page carried 1.45,
8// whose own comment claimed "half-way" while it moved the median 45.7%);
9// 2. the anchor is an exact FIXED POINT, so the white point cannot drift;
10// 3. the application PRESERVES HSV saturation exactly (the page raised S mean .313 -> .411, out
11// of the .27-.32 band the measurement said saturation already sat inside);
12// 4. the LUT size is SEARCHED against a declared tolerance, not chosen.
13//
14// THE NEG-CONTROL IS THE LOAD-BEARING TOOTH. T5 applies the OLD per-channel form to the same
15// triple and requires that it RAISES saturation. Without it, T4 could pass on a transform that
16// does nothing at all: a no-op preserves chroma perfectly. T5 is what proves this gate can tell
17// the fix from the defect rather than merely tell quiet from loud.
18import "nx_syscalls.nx"
19import "nx_gate_verdict.nx"
20import "nx_fixq30_lib.nx"
21import "nx_view_transform_lib.nx"
22
23const VG_SLOTS: i64 = 3
24const VG_SLOT_BYTES: i64 = 8
25const VG_EPS: i64 = 1024 // Q30 slack: 1024/2^30 = 9.5e-7, far below one 8-bit code
26const VG_NONGREY_R: i64 = 800000 // a strongly non-grey probe triple, in micro
27const VG_NONGREY_G: i64 = 400000
28const VG_NONGREY_B: i64 = 200000
29const VG_MIDGREY_MICRO: i64 = 500000
30const VG_HALF: i64 = 2
31
32func vg_near(a: i64, b: i64) -> i64 {
33 var d: i64 = a - b
34 if d < 0 { d = 0 - d }
35 if d <= VG_EPS { return 1 }
36 return 0
37}
38
39// the OLD, shipped application: the same curve applied per channel. Present ONLY as the control.
40func vg_perchannel(ctx: *i64, g: i64, rgb: *i64) -> i64 {
41 var i: i64 = 0
42 while i < VG_SLOTS { rgb[i] = vt_curve(ctx, g, rgb[i]); i = i + 1 }
43 return 0
44}
45
46func vg_fill(rgb: *i64) -> i64 {
47 rgb[0] = fq_from_micro(VG_NONGREY_R)
48 rgb[1] = fq_from_micro(VG_NONGREY_G)
49 rgb[2] = fq_from_micro(VG_NONGREY_B)
50 return 0
51}
52
53func main(argc: i64, argv: **u8) -> i64 {
54 let ctr: *i64 = gv_ctr()
55 gv_head("nx_view_transform -- the curve is DERIVED, anchored, chroma-safe, and its LUT is searched" as *u8)
56
57 let ctx: *i64 = fq_ctx()
58 let g: i64 = vt_exponent(ctx)
59 let k: i64 = fq_from_micro(VT_ANCHOR_MICRO)
60 let src: i64 = fq_from_micro(VT_SRC_MEDIAN_MICRO)
61
62 // T1 -- the exponent is DERIVED. Recomputed here independently from the same declared inputs;
63 // a hand-typed constant in the organ would not survive this.
64 let tgt: i64 = vt_target_median()
65 let want: i64 = fq_div(fq_ln(ctx, fq_div(tgt, k)), fq_ln(ctx, fq_div(src, k)))
66 gv_check("T1 exponent equals ln(m_tgt/k)/ln(m_src/k), computed not typed" as *u8, vg_near(g, want), ctr)
67
68 // T2 -- the anchor is an exact fixed point of the curve, whatever the exponent is
69 gv_check("T2 anchor k is a FIXED POINT of the curve (white point cannot drift)" as *u8,
70 vg_near(vt_curve(ctx, g, k), k), ctr)
71
72 // T3 -- the declared target median is reproduced by construction from the source median
73 gv_check("T3 curve(src_median) reproduces the declared target median" as *u8,
74 vg_near(vt_curve(ctx, g, src), tgt), ctr)
75
76 // T4 -- THE FIX: luminance-scaled application preserves the chroma ratio EXACTLY
77 let a: *i64 = sys_mmap(VG_SLOTS * VG_SLOT_BYTES) as *i64
78 vg_fill(a)
79 let ratio_before: i64 = fq_div(a[2], a[0])
80 vt_apply(ctx, g, a)
81 let ratio_after: i64 = fq_div(a[2], a[0])
82 gv_check("T4 vt_apply preserves HSV saturation exactly (min/max ratio unchanged)" as *u8,
83 vg_near(ratio_before, ratio_after), ctr)
84
85 // T4b -- and it actually DARKENS: preserving chroma must not mean doing nothing
86 let b: *i64 = sys_mmap(VG_SLOTS * VG_SLOT_BYTES) as *i64
87 vg_fill(b)
88 let lum_before: i64 = vt_luma(b[0], b[1], b[2])
89 vt_apply(ctx, g, b)
90 let lum_after: i64 = vt_luma(b[0], b[1], b[2])
91 gv_check("T4b vt_apply lowers luminance (a chroma-safe no-op would also pass T4)" as *u8,
92 (lum_after < lum_before) as i64, ctr)
93
94 // T5 -- NEG-CONTROL: the OLD per-channel form must RAISE saturation on the same triple.
95 // This is what makes T4 mean something: it proves the two applications are distinguishable.
96 let c: *i64 = sys_mmap(VG_SLOTS * VG_SLOT_BYTES) as *i64
97 vg_fill(c)
98 let pc_before: i64 = fq_div(c[2], c[0])
99 vg_perchannel(ctx, g, c)
100 let pc_after: i64 = fq_div(c[2], c[0])
101 // S = 1 - min/max, so S RISES exactly when the min/max ratio FALLS
102 gv_check("T5 neg-control-per-channel-application-RAISES-saturation (min/max ratio falls)" as *u8,
103 (pc_after < pc_before) as i64, ctr)
104
105 // T6 -- the LUT size is the SMALLEST that meets the declared tolerance, not merely one that does
106 let n: i64 = vt_lut_size(ctx, g)
107 let tol: i64 = FQ_ONE / (VT_CODE_LEVELS * FQ_TWO)
108 var t6: i64 = 0
109 if n > 0 {
110 if vt_lut_worst_err(ctx, g, n) < tol {
111 if n <= VT_LUT_MIN_N { t6 = 1 }
112 else { if vt_lut_worst_err(ctx, g, n / VG_HALF) >= tol { t6 = 1 } }
113 }
114 }
115 gv_check("T6 LUT size is the SMALLEST n meeting half-a-code (n passes, n/2 does not)" as *u8, t6, ctr)
116
117 // T7 -- the emitted table is a usable curve: monotone non-decreasing, and it starts at zero
118 var t7: i64 = 1
119 if n <= 0 { t7 = 0 }
120 else {
121 let lut: *i64 = sys_mmap((n + 1) * VG_SLOT_BYTES) as *i64
122 vt_lut_fill(ctx, g, lut, n)
123 if lut[0] != 0 { t7 = 0 }
124 var i: i64 = 1
125 while i <= n { if lut[i] < lut[i - 1] { t7 = 0 } i = i + 1 }
126 }
127 gv_check("T7 generated LUT is monotone non-decreasing and anchored at zero" as *u8, t7, ctr)
128
129 // T8 -- a grey pixel keeps its chroma ratio of unity: the scaling cannot invent colour
130 let d: *i64 = sys_mmap(VG_SLOTS * VG_SLOT_BYTES) as *i64
131 d[0] = fq_from_micro(VG_MIDGREY_MICRO)
132 d[1] = fq_from_micro(VG_MIDGREY_MICRO)
133 d[2] = fq_from_micro(VG_MIDGREY_MICRO)
134 vt_apply(ctx, g, d)
135 var t8: i64 = 0
136 if vg_near(d[0], d[1]) == 1 { if vg_near(d[1], d[2]) == 1 { t8 = 1 } }
137 gv_check("T8 a grey pixel stays grey (the scaling cannot invent chroma)" as *u8, t8, ctr)
138
139 let rc: i64 = gv_verdict("VIEW-TRANSFORM-GATE" as *u8, ctr,
140 "derived exponent, anchored white point, chroma-preserving application, searched LUT" as *u8)
141 sys_exit(rc)
142 return rc
143}