nx_imgquery_e2e_gate.nx source
↩ module page · 236 lines · 13140 B
1// nx_imgquery_e2e_gate.nx -- END-TO-END referee for hybrid reverse-image query on REAL decoded PNGs.
2// Builds a real RGB PNG corpus, decodes every image through nx_img_to_rgb (and luma for dHash), computes
3// each item's dHash + 112-dim imgsig, then runs the hybrid query (nx_imgquery copy + similar tiers).
4// corpus: A=red V-stripes, B=green V-stripes (same structure as A, different color),
5// C=red checker, D=green checker. queries built as separate PNGs and decoded the same way.
6// row1 COPY exact -- Q1 (a re-encoded copy of A) is found in the COPY tier at Hamming 0.
7// row2 dHash COLORBLIND-- dHash(A) ~ dHash(B): a red and a green image of the SAME structure are
8// indistinguishable to dHash (Hamming <= copy_thresh) -- the gap color fills.
9// row3 COLOR disambiguates -- imgsig nearest to Q1 is A, and imgsig(Q1,A) < imgsig(Q1,B): the hybrid
10// tells the TRUE copy from its different-color structural twin.
11// row4 LOOK-ALIKE -- Q2 (a red V-stripes image of a DIFFERENT period) is NOT a dHash copy of A
12// (Hamming > copy_thresh) yet imgsig nearest = A: a match the copy tier misses.
13// row5 HYBRID ORDERING -- imgsig(Q2,A) < imgsig(Q2,B) and < imgsig(Q2,C): structure AND color jointly
14// correct, on REAL decoded pixels.
15// GREEN iff 5/5. Durable verdict -> knowledge/status/imgquery_e2e_gate.log. license_tier: ORIGINAL
16import "nx_imgquery.nx"
17import "nx_img_to_rgb.nx"
18import "nx_crc32.nx"
19import "nx_adler32.nx"
20
21func 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 }
22func 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 }
23func 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 }
24func 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 }
25func g_clamp255(v: i64) -> i64 { if v<0 { return 0 } if v>255 { return 255 } return v }
26func 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 }
27
28// fill an interleaved-RGB buffer with a structured color pattern.
29// structIdx 0=vertical stripes 1=checker; colorIdx 0=red 1=green.
30func g_synth_rgb_sc(rgb: *u8, w: i64, h: i64, structIdx: i64, colorIdx: i64, p: i64, phase: i64, dbright: i64) -> i64 {
31 var y: i64 = 0
32 while y < h {
33 var x: i64 = 0
34 while x < w {
35 var s: i64 = 0
36 if structIdx==0 { s = (((x+phase)/p) & 1) } else { s = ((((x+phase)/p) + (y/p)) & 1) }
37 var r: i64 = 0
38 var g: i64 = 0
39 var b: i64 = 0
40 if colorIdx==0 {
41 if s==1 { r=200; g=0; b=0 } else { r=40; g=0; b=0 }
42 } else {
43 if s==1 { r=0; g=160; b=0 } else { r=0; g=40; b=0 }
44 }
45 let nz: i64 = ((x*7 + y*13 + phase*5) & 3)
46 let idx: i64 = (y*w+x)*3
47 rgb[idx] = g_clamp255(r + dbright + nz) as u8
48 rgb[idx+1] = g_clamp255(g + dbright + nz) as u8
49 rgb[idx+2] = g_clamp255(b + dbright + nz) as u8
50 x = x + 1
51 }
52 y = y + 1
53 }
54 return 0
55}
56
57// encode an interleaved-RGB buffer as a stored-zlib 8-bit RGB PNG into out; returns byte length.
58func 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 }
59func gp_build_buf(out: *u8, rgb: *u8, w: i64, h: i64) -> i64 {
60 out[0]=137 as u8; out[1]=80 as u8; out[2]=78 as u8; out[3]=71 as u8
61 out[4]=13 as u8; out[5]=10 as u8; out[6]=26 as u8; out[7]=10 as u8
62 var pos: i64=8
63 gp_wbe(out,pos,13); pos=pos+4
64 let ihdr_t: i64=pos
65 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
66 gp_wbe(out,pos,w); pos=pos+4
67 gp_wbe(out,pos,h); pos=pos+4
68 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
69 gp_wbe(out,pos, nx_crc32(((out as i64)+ihdr_t) as *u8, 17)); pos=pos+4
70 let payload_len: i64=h*(1+w*3)
71 let zlib_len: i64=2+5+payload_len+4
72 gp_wbe(out,pos,zlib_len); pos=pos+4
73 let idat_t: i64=pos
74 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
75 out[pos]=0x78 as u8; out[pos+1]=0x01 as u8; pos=pos+2
76 out[pos]=0x01 as u8; pos=pos+1
77 out[pos]=(payload_len&255) as u8; out[pos+1]=((payload_len>>8)&255) as u8; pos=pos+2
78 let nlen: i64=(payload_len^0xFFFF)&0xFFFF
79 out[pos]=(nlen&255) as u8; out[pos+1]=((nlen>>8)&255) as u8; pos=pos+2
80 let payload_off: i64=pos
81 var y: i64=0
82 while y<h {
83 out[pos]=0 as u8; pos=pos+1
84 var x: i64=0
85 while x<w {
86 let i: i64=(y*w+x)*3
87 out[pos]=rgb[i] as u8; out[pos+1]=rgb[i+1] as u8; out[pos+2]=rgb[i+2] as u8; pos=pos+3
88 x=x+1
89 }
90 y=y+1
91 }
92 gp_wbe(out,pos, adler32(((out as i64)+payload_off) as *u8, payload_len)); pos=pos+4
93 gp_wbe(out,pos, nx_crc32(((out as i64)+idat_t) as *u8, 4+zlib_len)); pos=pos+4
94 gp_wbe(out,pos,0); pos=pos+4
95 let iend_t: i64=pos
96 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
97 gp_wbe(out,pos, nx_crc32(((out as i64)+iend_t) as *u8, 4)); pos=pos+4
98 return pos
99}
100
101func g_rgb_to_gray(rgb: *u8, gray: *u8, w: i64, h: i64) -> i64 {
102 var i: i64=0
103 let n: i64=w*h
104 while i<n {
105 let r: i64=rgb[i*3] as i64
106 let g: i64=rgb[i*3+1] as i64
107 let b: i64=rgb[i*3+2] as i64
108 gray[i]=g_clamp255((77*r + 150*g + 29*b) / 256) as u8
109 i=i+1
110 }
111 return 0
112}
113
114// build PNG of a pattern, write to `path`, decode via nx_img_to_rgb, return rgb (or 0). sets wh.
115func g_make_decode(path: *u8, pb: *u8, scratch: *u8, w: i64, h: i64, structIdx: i64, colorIdx: i64, p: i64, phase: i64, dbright: i64, wh: *i64) -> *u8 {
116 g_synth_rgb_sc(scratch, w, h, structIdx, colorIdx, p, phase, dbright)
117 let sz: i64 = gp_build_buf(pb, scratch, w, h)
118 g_write_bytes(path, pb, sz)
119 return nx_img_to_rgb(path, wh)
120}
121
122func main() -> i64 {
123 g_puts("=== IMGQUERY E2E GATE (hybrid: dHash copies + imgsig look-alikes, on REAL decoded PNGs) ===\n" as *u8)
124 let W: i64 = 16
125 let H: i64 = 16
126 let NIMG: i64 = 4
127 let CTHRESH: i64 = 10
128 let pb: *u8 = sys_mmap(8192)
129 let scratch: *u8 = sys_mmap(W*H*3)
130 let whk: *i64 = sys_mmap(16) as *i64
131
132 let dh: *i64 = sys_mmap(8*NIMG) as *i64
133 let sigs: *i64 = sys_mmap(8*NIMG) as *i64
134 let pays: *i64 = sys_mmap(8*NIMG) as *i64
135
136 // corpus: 0=red V-stripes p3, 1=green V-stripes p3, 2=red checker p3, 3=green checker p3
137 let sidx: *i64 = sys_mmap(8*NIMG) as *i64
138 let cidx: *i64 = sys_mmap(8*NIMG) as *i64
139 sidx[0]=0; cidx[0]=0
140 sidx[1]=0; cidx[1]=1
141 sidx[2]=1; cidx[2]=0
142 sidx[3]=1; cidx[3]=1
143
144 var built: i64 = 0
145 var k: i64 = 0
146 while k < NIMG {
147 let path: *u8 = sys_mmap(64)
148 path[0]=47 as u8; path[1]=116 as u8; path[2]=109 as u8; path[3]=112 as u8; path[4]=47 as u8 // "/tmp/"
149 path[5]=113 as u8; path[6]=(48+k) as u8; path[7]=46 as u8; path[8]=112 as u8; path[9]=110 as u8; path[10]=103 as u8; path[11]=0 as u8 // "q<k>.png"
150 let rgb: *u8 = g_make_decode(path, pb, scratch, W, H, sidx[k], cidx[k], 3, 0, 0, whk)
151 if rgb!=(0 as *u8) {
152 let gray: *u8 = sys_mmap(W*H)
153 g_rgb_to_gray(rgb, gray, W, H)
154 dh[k] = nx_phash_dhash(gray, W, H)
155 let sg: *i64 = sys_mmap(8*112) as *i64
156 nx_imgsig_extract(gray, rgb, W, H, sg)
157 sigs[k] = sg as i64
158 pays[k] = k
159 built = built + 1
160 }
161 k = k + 1
162 }
163
164 // Q1 = exact copy of A (same params, separate file). Q2 = look-alike of A (red V-stripes, period 6).
165 let whq: *i64 = sys_mmap(16) as *i64
166 let rgbQ1: *u8 = g_make_decode("/tmp/q_copy.png" as *u8, pb, scratch, W, H, 0, 0, 3, 0, 0, whq)
167 let grayQ1: *u8 = sys_mmap(W*H)
168 g_rgb_to_gray(rgbQ1, grayQ1, W, H)
169 let q1dh: i64 = nx_phash_dhash(grayQ1, W, H)
170 let q1sig: *i64 = sys_mmap(8*112) as *i64
171 nx_imgsig_extract(grayQ1, rgbQ1, W, H, q1sig)
172
173 let rgbQ2: *u8 = g_make_decode("/tmp/q_look.png" as *u8, pb, scratch, W, H, 0, 0, 6, 1, 10, whq)
174 let grayQ2: *u8 = sys_mmap(W*H)
175 g_rgb_to_gray(rgbQ2, grayQ2, W, H)
176 let q2dh: i64 = nx_phash_dhash(grayQ2, W, H)
177 let q2sig: *i64 = sys_mmap(8*112) as *i64
178 nx_imgsig_extract(grayQ2, rgbQ2, W, H, q2sig)
179
180 var pass: i64 = 0
181 let rows: i64 = 5
182
183 let outc: *i64 = sys_mmap(8*NIMG) as *i64
184 let outh: *i64 = sys_mmap(8*NIMG) as *i64
185 let outs: *i64 = sys_mmap(8*NIMG) as *i64
186 let outl: *i64 = sys_mmap(8*NIMG) as *i64
187 let taken: *i64 = sys_mmap(8*NIMG) as *i64
188
189 // ---- row1: COPY tier finds A at Hamming 0 ----
190 let mc: i64 = nx_imgquery_copies(q1dh, dh, pays, NIMG, CTHRESH, outc, outh)
191 var a_copy0: i64 = 0
192 var ci: i64 = 0
193 while ci < mc { if outc[ci]==0 { if outh[ci]==0 { a_copy0=1 } } ci=ci+1 }
194 g_puts(" row1 COPY tier: A found at ham0? " as *u8); g_num(a_copy0); g_puts(" (copies=" as *u8); g_num(mc); g_puts(") -> " as *u8)
195 if built==NIMG { if a_copy0==1 { pass=pass+1; g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL (corpus build)\n" as *u8) }
196
197 // ---- row2: dHash is colorblind -- A (red) vs B (green), same structure ----
198 let hamAB: i64 = nx_simhash_hamming(dh[0], dh[1])
199 g_puts(" row2 dHash colorblind: ham(A red, B green)=" as *u8); g_num(hamAB); g_puts(" (<=" as *u8); g_num(CTHRESH); g_puts(") -> " as *u8)
200 if hamAB <= CTHRESH { pass=pass+1; g_puts("PASS (red~green to dHash; needs color)\n" as *u8) } else { g_puts("FAIL\n" as *u8) }
201
202 // ---- row3: color disambiguates the true copy ----
203 let l1_q1a: i64 = nx_imgsig_l1(q1sig, sigs[0] as *i64)
204 let l1_q1b: i64 = nx_imgsig_l1(q1sig, sigs[1] as *i64)
205 let ms1: i64 = nx_imgquery_similar(q1sig, sigs, pays, NIMG, 1, outs, outl, taken)
206 var near_q1: i64 = 0-1
207 if ms1>0 { near_q1 = outs[0] }
208 g_puts(" row3 color disambiguates: imgsig nearest(Q1)=" as *u8); g_num(near_q1); g_puts(" l1(Q1,A)=" as *u8); g_num(l1_q1a); g_puts(" l1(Q1,B)=" as *u8); g_num(l1_q1b); g_puts(" -> " as *u8)
209 if near_q1==0 { if l1_q1a < l1_q1b { pass=pass+1; g_puts("PASS (true copy A beats its green twin B)\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) }
210
211 // ---- row4: look-alike Q2 -- NOT a dHash copy of A, but imgsig nearest = A ----
212 let hamQ2A: i64 = nx_simhash_hamming(q2dh, dh[0])
213 let ms2: i64 = nx_imgquery_similar(q2sig, sigs, pays, NIMG, 1, outs, outl, taken)
214 var near_q2: i64 = 0-1
215 if ms2>0 { near_q2 = outs[0] }
216 g_puts(" row4 look-alike: ham(Q2,A)=" as *u8); g_num(hamQ2A); g_puts(" (>" as *u8); g_num(CTHRESH); g_puts(" = not a copy), imgsig nearest=" as *u8); g_num(near_q2); g_puts(" -> " as *u8)
217 if hamQ2A > CTHRESH { if near_q2==0 { pass=pass+1; g_puts("PASS (found the look-alike the copy tier misses)\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) }
218
219 // ---- row5: hybrid ordering -- A (red V) < B (green V) and < C (red checker) ----
220 let l1_q2a: i64 = nx_imgsig_l1(q2sig, sigs[0] as *i64)
221 let l1_q2b: i64 = nx_imgsig_l1(q2sig, sigs[1] as *i64)
222 let l1_q2c: i64 = nx_imgsig_l1(q2sig, sigs[2] as *i64)
223 g_puts(" row5 ordering: l1(Q2,A)=" as *u8); g_num(l1_q2a); g_puts(" l1(Q2,B green)=" as *u8); g_num(l1_q2b); g_puts(" l1(Q2,C struct)=" as *u8); g_num(l1_q2c); g_puts(" -> " as *u8)
224 if l1_q2a < l1_q2b { if l1_q2a < l1_q2c { pass=pass+1; g_puts("PASS (structure AND color jointly right)\n" as *u8) } else { g_puts("FAIL\n" as *u8) } } else { g_puts("FAIL\n" as *u8) }
225
226 g_puts("----\nIMGQUERY-E2E-GATE rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass); g_puts("\n" as *u8)
227 let lg: i64 = sys_openat_append("knowledge/status/imgquery_e2e_gate.log" as *u8, 0x1a4)
228 if lg>=0 {
229 g_w(lg,"IMGQUERY-E2E-GATE rows=" as *u8); g_wn(lg,rows); g_w(lg," pass=" as *u8); g_wn(lg,pass)
230 g_w(lg," hamAB=" as *u8); g_wn(lg,hamAB); g_w(lg," hamQ2A=" as *u8); g_wn(lg,hamQ2A); g_w(lg," l1Q2A=" as *u8); g_wn(lg,l1_q2a); g_w(lg," l1Q2B=" as *u8); g_wn(lg,l1_q2b)
231 if pass==rows { g_w(lg," verdict=GREEN\n" as *u8) } else { g_w(lg," verdict=RED\n" as *u8) }
232 sys_close(lg)
233 }
234 if pass==rows { g_puts("IMGQUERY-E2E-GATE GREEN\n" as *u8); sys_exit(0); return 0 }
235 g_puts("IMGQUERY-E2E-GATE RED\n" as *u8); sys_exit(1); return 1
236}