code wiki / (root) / nx_img_dims_gate.nx

nx_img_dims_gate.nx source

↩ module page · 66 lines · 4054 B

1// nx_img_dims_gate.nx -- KAT for the header dimension reader against hand-built PNG/GIF/JPEG headers with KNOWN 2// sizes + the KEEP-on-unknown invariant. Proves the importer's junk filter measures REAL pixels. GREEN iff 7/7. 3import "nx_syscalls.nx" 4import "nx_img_dims.nx" 5import "nx_gate_verdict.nx" 6 7func gw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 8func gn(v: i64) -> i64 { let b: *u8=sys_mmap(24); var m: i64=v; if m<0{gw("-" as *u8);m=0-m} let t: *u8=sys_mmap(24); 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{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 9func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("\n" as *u8); return ok } 10func hxn(c: i64) -> i64 { if c>=48 { if c<=57 { return c-48 } } if c>=97 { if c<=102 { return c-87 } } if c>=65 { if c<=70 { return c-55 } } return 0 } 11func h2b(s: *u8, out: *u8) -> i64 { var i: i64=0; var o: i64=0; while s[i]!=(0 as u8){ if s[i+1]==(0 as u8){i=i+1} else { out[o]=((hxn(s[i] as i64)<<4)|hxn(s[i+1] as i64)) as u8; o=o+1; i=i+2 } } return o } 12 13func main() -> i64 { 14 gw("nx_img_dims KAT gate (PNG/GIF/JPEG header sizes + keep-on-unknown)\n" as *u8) 15 var pass: i64 = 0 16 let wh: *i64 = sys_mmap(16) as *i64 17 let b: *u8 = sys_mmap(256) 18 19 // PNG 1200x800: sig + IHDR len(0d) + "IHDR" + W(000004b0) + H(00000320) + 08060000 00 20 let n1: i64 = h2b("89504e470d0a1a0a0000000d49484452000004b0000003200806000000" as *u8, b) 21 nx_img_dims(b, n1, wh) 22 pass = pass + grow("T1 PNG 1200x800 parsed\x00" as *u8, (wh[0]==1200) & (wh[1]==800)) 23 24 // PNG 40x42 (a nav icon) -> long edge 42 25 let n2: i64 = h2b("89504e470d0a1a0a0000000d49484452000000280000002a0806000000" as *u8, b) 26 let le2: i64 = nx_img_long_edge(b, n2) 27 gw(" icon long_edge=" as *u8); gn(le2); gw("\n" as *u8) 28 pass = pass + grow("T2 PNG 40x42 long_edge=42\x00" as *u8, le2==42) 29 30 // GIF 40x42 31 let n3: i64 = h2b("47494638396128002a00f0000000000000000021f9" as *u8, b) 32 nx_img_dims(b, n3, wh) 33 pass = pass + grow("T3 GIF 40x42 parsed\x00" as *u8, (wh[0]==40) & (wh[1]==42)) 34 35 // JPEG 1200x800: FFD8 FFC0 0011 08 0320(H) 04b0(W) 03... 36 let n4: i64 = h2b("ffd8ffc0001108032004b003011100021101031101" as *u8, b) 37 let le4: i64 = nx_img_long_edge(b, n4) 38 gw(" jpeg long_edge=" as *u8); gn(le4); gw("\n" as *u8) 39 pass = pass + grow("T4 JPEG 1200x800 long_edge=1200\x00" as *u8, le4==1200) 40 41 // JPEG with a leading APP0 segment before SOF (real-world) 1024x768 42 let n5: i64 = h2b("ffd8ffe000104a46494600010100000100010000ffc0001108030004000301110002110103110100" as *u8, b) 43 nx_img_dims(b, n5, wh) 44 gw(" jpeg2 w=" as *u8); gn(wh[0]); gw(" h=" as *u8); gn(wh[1]); gw("\n" as *u8) 45 pass = pass + grow("T5 JPEG w/ APP0 then SOF (0x0400 x 0x0300) parsed\x00" as *u8, (wh[0]==1024) & (wh[1]==768)) 46 47 // unknown bytes -> KEEP (long edge = INT_MAX) 48 let n6: i64 = h2b("00010203040506070809101112131415" as *u8, b) 49 let le6: i64 = nx_img_long_edge(b, n6) 50 pass = pass + grow("T6 unknown format -> KEEP (long_edge=INT_MAX)\x00" as *u8, le6==0x7fffffff) 51 52 // filter decision at threshold 100: icon(42) rejected, photo(1200) kept 53 var t7: i64 = 0; if le2 < 100 { if le4 >= 100 { t7 = 1 } } 54 pass = pass + grow("T7 threshold-100 filter: icon REJECT, photo KEEP\x00" as *u8, t7) 55 56 gw("pass=" as *u8); gn(pass); gw("/7\n" as *u8) 57 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 58 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 59 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 60 let ctr__dry: *i64 = gv_ctr() 61 ctr__dry[0] = pass 62 ctr__dry[1] = 7 63 let rc__dry: i64 = gv_verdict("IMG-DIMS-GATE" as *u8, ctr__dry, "header dimension reader correct; junk-filter measures real pixels)" as *u8) 64 sys_exit(rc__dry) 65 return rc__dry 66}