nx_img_to_rgb_gate.nx source
↩ module page · 172 lines · 9476 B
1// nx_img_to_rgb_gate.nx -- referee for the RGB decode path (nx_img_to_rgb) AND the color descriptors
2// running on REAL decoded pixels (not just synthetic buffers). Builds genuine RGB PNGs at runtime
3// (stored-zlib, 8-bit RGB -- the same format the image-search e2e gate uses), decodes them through the
4// REAL nx_img_to_rgb, and checks:
5// row1 dims -- decoded width/height match.
6// row2 left=RED -- top-left pixel decodes to red (R high, G/B low).
7// row3 right=GREEN -- top-right pixel decodes to green (G high, R/B low).
8// row4 graceful -- a non-PNG file returns 0 (skip), never crashes.
9// row5 REAL-PIPE color -- a red PNG and a luma-matched green PNG, BOTH decoded via nx_img_to_rgb:
10// grayscale dHash Hamming == 0 (the gray engine collapses them) yet colordesc L1 is large
11// (color distinguishes) -- the colordesc headline reproduced end-to-end through the real decoder.
12// GREEN iff 5/5. Durable verdict -> knowledge/status/img_to_rgb_gate.log. license_tier: ORIGINAL
13import "nx_img_to_rgb.nx"
14import "nx_colordesc.nx"
15import "nx_phash.nx"
16import "nx_crc32.nx"
17import "nx_adler32.nx"
18
19func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
20func g_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; 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}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 }
21func g_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
22func g_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; 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}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 }
23
24func g_write_bytes(path: *u8, buf: *u8, n: i64) -> i64 { let fd: i64=sys_openat_wr(path, 0x1a4); if fd<0 { return 0-1 } sys_write(fd, buf, n); sys_close(fd); return 0 }
25
26// build a stored-zlib 8-bit RGB PNG: left half (r1,g1,b1), right half (r2,g2,b2). returns byte length.
27func gp_wbe(buf: *u8, off: i64, val: i64) -> i64 { buf[off]=((val>>24)&255) as u8; buf[off+1]=((val>>16)&255) as u8; buf[off+2]=((val>>8)&255) as u8; buf[off+3]=(val&255) as u8; return 0 }
28func gp_build_lr(out: *u8, w: i64, h: i64, r1: i64, g1: i64, b1: i64, r2: i64, g2: i64, b2: i64) -> i64 {
29 out[0]=137 as u8; out[1]=80 as u8; out[2]=78 as u8; out[3]=71 as u8
30 out[4]=13 as u8; out[5]=10 as u8; out[6]=26 as u8; out[7]=10 as u8
31 var pos: i64=8
32 gp_wbe(out,pos,13); pos=pos+4
33 let ihdr_t: i64=pos
34 out[pos]=73 as u8; out[pos+1]=72 as u8; out[pos+2]=68 as u8; out[pos+3]=82 as u8; pos=pos+4
35 gp_wbe(out,pos,w); pos=pos+4
36 gp_wbe(out,pos,h); pos=pos+4
37 out[pos]=8 as u8; out[pos+1]=2 as u8; out[pos+2]=0 as u8; out[pos+3]=0 as u8; out[pos+4]=0 as u8; pos=pos+5
38 gp_wbe(out,pos, nx_crc32(((out as i64)+ihdr_t) as *u8, 17)); pos=pos+4
39 let payload_len: i64=h*(1+w*3)
40 let zlib_len: i64=2+5+payload_len+4
41 gp_wbe(out,pos,zlib_len); pos=pos+4
42 let idat_t: i64=pos
43 out[pos]=73 as u8; out[pos+1]=68 as u8; out[pos+2]=65 as u8; out[pos+3]=84 as u8; pos=pos+4
44 out[pos]=0x78 as u8; out[pos+1]=0x01 as u8; pos=pos+2
45 out[pos]=0x01 as u8; pos=pos+1
46 out[pos]=(payload_len&255) as u8; out[pos+1]=((payload_len>>8)&255) as u8; pos=pos+2
47 let nlen: i64=(payload_len^0xFFFF)&0xFFFF
48 out[pos]=(nlen&255) as u8; out[pos+1]=((nlen>>8)&255) as u8; pos=pos+2
49 let payload_off: i64=pos
50 var y: i64=0
51 while y<h {
52 out[pos]=0 as u8; pos=pos+1
53 var x: i64=0
54 while x<w {
55 var r: i64=r1
56 var g: i64=g1
57 var b: i64=b1
58 if x>=w/2 { r=r2; g=g2; b=b2 }
59 out[pos]=r as u8; out[pos+1]=g as u8; out[pos+2]=b as u8; pos=pos+3
60 x=x+1
61 }
62 y=y+1
63 }
64 gp_wbe(out,pos, adler32(((out as i64)+payload_off) as *u8, payload_len)); pos=pos+4
65 gp_wbe(out,pos, nx_crc32(((out as i64)+idat_t) as *u8, 4+zlib_len)); pos=pos+4
66 gp_wbe(out,pos,0); pos=pos+4
67 let iend_t: i64=pos
68 out[pos]=73 as u8; out[pos+1]=69 as u8; out[pos+2]=78 as u8; out[pos+3]=68 as u8; pos=pos+4
69 gp_wbe(out,pos, nx_crc32(((out as i64)+iend_t) as *u8, 4)); pos=pos+4
70 return pos
71}
72
73func g_rgb_to_gray(rgb: *u8, gray: *u8, w: i64, h: i64) -> i64 {
74 var i: i64=0
75 let n: i64=w*h
76 while i<n {
77 let r: i64=rgb[i*3] as i64
78 let g: i64=rgb[i*3+1] as i64
79 let b: i64=rgb[i*3+2] as i64
80 var v: i64=(77*r + 150*g + 29*b) / 256
81 if v>255 { v=255 }
82 gray[i]=v as u8
83 i=i+1
84 }
85 return 0
86}
87
88func main() -> i64 {
89 g_puts("=== IMG-TO-RGB GATE (real PNG decode -> RGB; color descriptors on real decoded pixels) ===\n" as *u8)
90 let W: i64=16
91 let H: i64=16
92 let pb: *u8=sys_mmap(8192)
93
94 var pass: i64=0
95 let rows: i64=5
96
97 // build + decode the left-red / right-green PNG
98 let sz: i64=gp_build_lr(pb, W, H, 200,0,0, 0,200,0)
99 g_write_bytes("/tmp/nx_rgb_lr.png" as *u8, pb, sz)
100 let wh: *i64=sys_mmap(16) as *i64
101 let rgb: *u8=nx_img_to_rgb("/tmp/nx_rgb_lr.png" as *u8, wh)
102 var decoded: i64=0
103 if rgb!=(0 as *u8) { decoded=1 }
104
105 // row1: dims
106 g_puts(" row1 decode dims -> " as *u8)
107 if decoded==1 { g_num(wh[0]); g_puts("x" as *u8); g_num(wh[1]) }
108 g_puts(" -> " as *u8)
109 if decoded==1 { if wh[0]==W { if wh[1]==H { pass=pass+1; g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL (decode returned 0)\n" as *u8) }
110
111 // row2: top-left = red
112 var tlr: i64=0
113 var tlg: i64=0
114 var tlb: i64=0
115 if decoded==1 { tlr=rgb[0] as i64; tlg=rgb[1] as i64; tlb=rgb[2] as i64 }
116 g_puts(" row2 top-left RGB=(" as *u8); g_num(tlr); g_puts("," as *u8); g_num(tlg); g_puts("," as *u8); g_num(tlb); g_puts(") -> " as *u8)
117 if tlr>150 { if tlg<50 { if tlb<50 { pass=pass+1; g_puts("PASS (red)\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) }
118
119 // row3: top-right = green
120 var trr: i64=0
121 var trg: i64=0
122 var trb: i64=0
123 if decoded==1 { let o: i64=(W-1)*3; trr=rgb[o] as i64; trg=rgb[o+1] as i64; trb=rgb[o+2] as i64 }
124 g_puts(" row3 top-right RGB=(" as *u8); g_num(trr); g_puts("," as *u8); g_num(trg); g_puts("," as *u8); g_num(trb); g_puts(") -> " as *u8)
125 if trg>150 { if trr<50 { if trb<50 { pass=pass+1; g_puts("PASS (green)\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) }
126
127 // row4: graceful-degrade on a non-PNG file
128 g_write_bytes("/tmp/nx_notpng.bin" as *u8, "this is definitely not a png file" as *u8, 33)
129 let wh2: *i64=sys_mmap(16) as *i64
130 let bad: *u8=nx_img_to_rgb("/tmp/nx_notpng.bin" as *u8, wh2)
131 g_puts(" row4 non-PNG -> " as *u8)
132 if bad==(0 as *u8) { pass=pass+1; g_puts("returns 0 (skipped cleanly) PASS\n" as *u8) } else { g_puts("FAIL (should have refused)\n" as *u8) }
133
134 // row5: real-pipeline color proof -- red vs luma-matched green, both through nx_img_to_rgb
135 let szR: i64=gp_build_lr(pb, W, H, 204,0,0, 204,0,0); g_write_bytes("/tmp/nx_red.png" as *u8, pb, szR)
136 let whR: *i64=sys_mmap(16) as *i64
137 let rgbR: *u8=nx_img_to_rgb("/tmp/nx_red.png" as *u8, whR)
138 let szG: i64=gp_build_lr(pb, W, H, 0,105,0, 0,105,0); g_write_bytes("/tmp/nx_green.png" as *u8, pb, szG)
139 let whG: *i64=sys_mmap(16) as *i64
140 let rgbG: *u8=nx_img_to_rgb("/tmp/nx_green.png" as *u8, whG)
141 var ok5: i64=0
142 var color_l1: i64=0
143 var gray_ham: i64=0
144 if rgbR!=(0 as *u8) {
145 if rgbG!=(0 as *u8) {
146 let cdR: *i64=sys_mmap(8*32) as *i64
147 let cdG: *i64=sys_mmap(8*32) as *i64
148 nx_colordesc_extract(rgbR, W, H, cdR)
149 nx_colordesc_extract(rgbG, W, H, cdG)
150 color_l1=nx_colordesc_l1(cdR, cdG)
151 let gR: *u8=sys_mmap(W*H)
152 let gG: *u8=sys_mmap(W*H)
153 g_rgb_to_gray(rgbR, gR, W, H)
154 g_rgb_to_gray(rgbG, gG, W, H)
155 gray_ham=nx_simhash_hamming(nx_phash_dhash(gR, W, H), nx_phash_dhash(gG, W, H))
156 ok5=1
157 }
158 }
159 g_puts(" row5 real-decode color -> grayscale dHash ham=" as *u8); g_num(gray_ham); g_puts(", colordesc L1=" as *u8); g_num(color_l1); g_puts(" -> " as *u8)
160 if ok5==1 { if gray_ham<=2 { if color_l1>200 { pass=pass+1; g_puts("PASS (gray collapses, color separates -- on REAL pixels)\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL (decode)\n" as *u8) }
161
162 g_puts("----\nIMG-TO-RGB-GATE rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass); g_puts("\n" as *u8)
163 let lg: i64=sys_openat_append("knowledge/status/img_to_rgb_gate.log" as *u8, 0x1a4)
164 if lg>=0 {
165 g_w(lg,"IMG-TO-RGB-GATE rows=" as *u8); g_wn(lg,rows); g_w(lg," pass=" as *u8); g_wn(lg,pass)
166 g_w(lg," gray_ham=" as *u8); g_wn(lg,gray_ham); g_w(lg," color_l1=" as *u8); g_wn(lg,color_l1)
167 if pass==rows { g_w(lg," verdict=GREEN\n" as *u8) } else { g_w(lg," verdict=RED\n" as *u8) }
168 sys_close(lg)
169 }
170 if pass==rows { g_puts("IMG-TO-RGB-GATE GREEN\n" as *u8); sys_exit(0); return 0 }
171 g_puts("IMG-TO-RGB-GATE RED\n" as *u8); sys_exit(1); return 1
172}