code wiki / _hdl_build / nx_look_compose_gate.nx
nx_look_compose_gate.nx source
↩ module page · 191 lines · 8810 B
1// nx_look_compose_gate.nx -- pixel-truth gate for the sovereign LOOK composer (2026-07-29).
2// Builds three tiny synthetic panes IN MEMORY, writes them as BMPs, runs the real composer twice
3// (full strip + 2x crop), reads the composites back and asserts:
4// T1 full strip: pane0==src, pane1==a, pane2==b pixel-for-pixel; gutters + row-pad are WHITE
5// T2 crop+2x: every 2x2 output block == its source pixel (nearest, no resampling opinions)
6// T3 (negative) dim-mismatched inputs are REFUSED (nonzero rc), output absent
7// The composer is forked as a real process (the gate tests the SHIPPED path, not a code copy).
8// license: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_gate_verdict.nx"
11
12const GW2: i64 = 16
13const GH2: i64 = 8
14const GUT: i64 = 4
15const HDRB: i64 = 1078
16
17func gw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
18func gn(v: i64) -> i64 {
19 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m}
20 let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}
21 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
22func wr32le(b: *u8, off: i64, v: i64) -> i64 {
23 b[off]=(v&0xff) as u8; b[off+1]=((v>>8)&0xff) as u8
24 b[off+2]=((v>>16)&0xff) as u8; b[off+3]=((v>>24)&0xff) as u8; return 0 }
25func wr16le(b: *u8, off: i64, v: i64) -> i64 {
26 b[off]=(v&0xff) as u8; b[off+1]=((v>>8)&0xff) as u8; return 0 }
27func rd32le(b: *u8, off: i64) -> i64 {
28 return (b[off]&0xff) + ((b[off+1]&0xff)<<8) + ((b[off+2]&0xff)<<16) + ((b[off+3]&0xff)<<24) }
29
30func bmp_write(path: *u8, luma: *u8, w: i64, h: i64) -> i64 {
31 let isz: i64 = w*h
32 let fsz: i64 = HDRB + isz
33 let buf: *u8 = sys_mmap(fsz + 64)
34 buf[0]=66 as u8; buf[1]=77 as u8
35 wr32le(buf, 2, fsz); wr32le(buf, 6, 0); wr32le(buf, 10, HDRB)
36 wr32le(buf, 14, 40); wr32le(buf, 18, w); wr32le(buf, 22, h)
37 wr16le(buf, 26, 1); wr16le(buf, 28, 8)
38 wr32le(buf, 30, 0); wr32le(buf, 34, isz)
39 wr32le(buf, 38, 2835); wr32le(buf, 42, 2835)
40 wr32le(buf, 46, 256); wr32le(buf, 50, 0)
41 var c: i64=0
42 while c<256 { let o: i64=54+c*4
43 buf[o]=c as u8; buf[o+1]=c as u8; buf[o+2]=c as u8; buf[o+3]=0 as u8; c=c+1 }
44 var y: i64=0
45 while y<h { var x: i64=0
46 while x<w { buf[HDRB + (h-1-y)*w + x] = luma[y*w + x]; x=x+1 } y=y+1 }
47 let fd: i64 = sys_openat_wr(path, 0x1a4)
48 if fd < 0 { return 1 }
49 sys_write(fd, buf, fsz)
50 sys_close(fd)
51 return 0 }
52
53func bmp_read(path: *u8, wh: *i64) -> *u8 {
54 let box: *i64 = sys_mmap(16) as *i64
55 let d: *u8 = sys_read_file(path, box)
56 if (d as i64) == 0 { return 0 as *u8 }
57 let off: i64 = rd32le(d, 10)
58 let w: i64 = rd32le(d, 18)
59 let h: i64 = rd32le(d, 22)
60 let out: *u8 = sys_mmap(w*h + 64)
61 var y: i64 = 0
62 while y < h { var x: i64 = 0
63 while x < w { out[y*w + x] = d[off + (h-1-y)*w + x]; x = x + 1 } y = y + 1 }
64 wh[0] = w; wh[1] = h
65 return out }
66
67func run_composer(a1: *u8, a2: *u8, a3: *u8, a4: *u8, cx: i64, cy: i64, cw: i64, ch: i64) -> i64 {
68 let av: *i64 = sys_mmap(8*12) as *i64
69 let nb: *u8 = sys_mmap(256)
70 av[0] = "_offc/nx_look_compose.elf" as *u8 as i64
71 av[1] = a1 as i64; av[2] = a2 as i64; av[3] = a3 as i64; av[4] = a4 as i64
72 var na: i64 = 5
73 if cw > 0 {
74 // render the four ints as separate NUL strings inside nb
75 var off: i64 = 0
76 var vi: i64 = 0
77 while vi < 4 {
78 var v: i64 = cx
79 if vi == 1 { v = cy }
80 if vi == 2 { v = cw }
81 if vi == 3 { v = ch }
82 av[na] = ((nb as i64) + off) as i64
83 if v == 0 { nb[off] = 48 as u8; off = off + 1 }
84 let t: *u8 = sys_mmap(28)
85 var k: i64 = 0
86 while v > 0 { t[k] = (48 + (v % 10)) as u8; v = v / 10; k = k + 1 }
87 while k > 0 { k = k - 1; nb[off] = t[k]; off = off + 1 }
88 nb[off] = 0 as u8; off = off + 1
89 na = na + 1; vi = vi + 1
90 }
91 }
92 av[na] = 0
93 let envp: *i64 = sys_mmap(16) as *i64
94 envp[0] = 0
95 let pid: i64 = sys_fork()
96 if pid == 0 { sys_execve("_offc/nx_look_compose.elf" as *u8, av, envp); sys_exit(127) }
97 let st: *i64 = sys_mmap(16) as *i64
98 sys_wait4(pid, st, 0)
99 return (st[0] >> 8) & 0xff }
100
101func main() -> i64 {
102 gw("=== nx_look_compose_gate: pixel-truth teeth for the sovereign LOOK composer ===\n" as *u8)
103 var pass: i64 = 0
104 var fail: i64 = 0
105 // synthetic panes: src = gradient, a = inverted, b = checker
106 let ps: *u8 = sys_mmap(GW2*GH2 + 16)
107 let pa: *u8 = sys_mmap(GW2*GH2 + 16)
108 let pb: *u8 = sys_mmap(GW2*GH2 + 16)
109 var y: i64 = 0
110 while y < GH2 { var x: i64 = 0
111 while x < GW2 {
112 ps[y*GW2+x] = ((x*16 + y*2) % 256) as u8
113 pa[y*GW2+x] = (255 - ((x*16 + y*2) % 256)) as u8
114 var v: i64 = 0
115 if ((x+y) % 2) == 1 { v = 200 }
116 pb[y*GW2+x] = v as u8
117 x = x + 1 } y = y + 1 }
118 bmp_write("_build/_lcg_s.bmp" as *u8, ps, GW2, GH2)
119 bmp_write("_build/_lcg_a.bmp" as *u8, pa, GW2, GH2)
120 bmp_write("_build/_lcg_b.bmp" as *u8, pb, GW2, GH2)
121 // T1: full strip
122 let rc1: i64 = run_composer("_build/_lcg_s.bmp" as *u8, "_build/_lcg_a.bmp" as *u8, "_build/_lcg_b.bmp" as *u8, "_build/_lcg_full.bmp" as *u8, 0, 0, 0, 0)
123 let wh: *i64 = sys_mmap(32) as *i64
124 var t1: i64 = 0
125 if rc1 == 0 {
126 let cm: *u8 = bmp_read("_build/_lcg_full.bmp" as *u8, wh)
127 let ow: i64 = wh[0]
128 let exw: i64 = (((GW2*3 + GUT*2) + 3) / 4) * 4
129 if ow == exw { if wh[1] == GH2 {
130 t1 = 1
131 var p: i64 = 0
132 while p < 3 {
133 var ref: *u8 = ps
134 if p == 1 { ref = pa }
135 if p == 2 { ref = pb }
136 let ox: i64 = p * (GW2 + GUT)
137 y = 0
138 while y < GH2 { var x: i64 = 0
139 while x < GW2 { if cm[y*ow + ox + x] != ref[y*GW2 + x] { t1 = 0 } x = x + 1 } y = y + 1 }
140 // gutter after panes 0,1 must be white
141 if p < 2 { y = 0
142 while y < GH2 { var g: i64 = 0
143 while g < GUT { if cm[y*ow + ox + GW2 + g] != (255 as u8) { t1 = 0 } g = g + 1 } y = y + 1 } }
144 p = p + 1 }
145 } }
146 }
147 if t1 == 1 { pass = pass + 1; gw(" T1 full strip pane+gutter pixel-truth: PASS\n" as *u8) }
148 else { fail = fail + 1; gw(" T1 full strip pane+gutter pixel-truth: FAIL\n" as *u8) }
149 // T2: crop 2x (crop 4,2 8x4)
150 let rc2: i64 = run_composer("_build/_lcg_s.bmp" as *u8, "_build/_lcg_a.bmp" as *u8, "_build/_lcg_b.bmp" as *u8, "_build/_lcg_crop.bmp" as *u8, 4, 2, 8, 4)
151 var t2: i64 = 0
152 if rc2 == 0 {
153 let cm2: *u8 = bmp_read("_build/_lcg_crop.bmp" as *u8, wh)
154 let ow2: i64 = wh[0]
155 if wh[1] == 8 {
156 t2 = 1
157 var p2: i64 = 0
158 while p2 < 3 {
159 var ref2: *u8 = ps
160 if p2 == 1 { ref2 = pa }
161 if p2 == 2 { ref2 = pb }
162 let ox2: i64 = p2 * (16 + GUT)
163 y = 0
164 while y < 8 { var x: i64 = 0
165 while x < 16 {
166 if cm2[y*ow2 + ox2 + x] != ref2[(2 + y/2)*GW2 + 4 + x/2] { t2 = 0 }
167 x = x + 1 } y = y + 1 }
168 p2 = p2 + 1 }
169 }
170 }
171 if t2 == 1 { pass = pass + 1; gw(" T2 crop+2x nearest pixel-truth: PASS\n" as *u8) }
172 else { fail = fail + 1; gw(" T2 crop+2x nearest pixel-truth: FAIL\n" as *u8) }
173 // T3 negative: mismatched dims REFUSED (a 8x8 pane vs 16x8 others)
174 let pm: *u8 = sys_mmap(64 + 16)
175 var i3: i64 = 0
176 while i3 < 64 { pm[i3] = 7 as u8; i3 = i3 + 1 }
177 bmp_write("_build/_lcg_m.bmp" as *u8, pm, 8, 8)
178 let rc3: i64 = run_composer("_build/_lcg_s.bmp" as *u8, "_build/_lcg_m.bmp" as *u8, "_build/_lcg_b.bmp" as *u8, "_build/_lcg_bad.bmp" as *u8, 0, 0, 0, 0)
179 if rc3 != 0 { pass = pass + 1; gw(" T3 dim-mismatch REFUSED (negative): PASS\n" as *u8) }
180 else { fail = fail + 1; gw(" T3 dim-mismatch REFUSED (negative): FAIL (rc=0!)\n" as *u8) }
181 gw("NX-LOOK-COMPOSE-GATE passed " as *u8); gn(pass); gw("/" as *u8); gn(pass+fail)
182 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
183 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
184 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
185 let ctr__dry: *i64 = gv_ctr()
186 ctr__dry[0] = pass
187 ctr__dry[1] = pass + fail
188 let rc__dry: i64 = gv_verdict("LOOK-COMPOSE-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
189 sys_exit(rc__dry)
190 return rc__dry
191}