code wiki / (root) / nx_imgquery_e2e_gate.nx

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}