code wiki / _hdl_build / nx_apng_write_gate.nx

nx_apng_write_gate.nx source

↩ module page · 144 lines · 8440 B

1// nx_apng_write_gate.nx -- gate for the sovereign APNG encoder. Writes a 4-frame moving-square clip, 2// reads the ON-DISK bytes back and verifies the structure a browser needs: PNG signature, acTL with the 3// right frame count, the fcTL/fdAT chain with the SPEC's shared sequence numbering (0,1,2,3,4,5 across 4// fcTL/IDAT/fcTL/fdAT...), CRC of the acTL chunk validates, and the frame PAYLOADS DIFFER (the square 5// really moves -- parsed out of the stored-zlib stream, not assumed). NEG: a plain nx_png_write PNG has 6// NO acTL (the animated check cannot false-fire on a still). expect_exit: 0 license_tier: ORIGINAL 7import "nx_apng_write.nx" 8import "nx_gate_verdict.nx" 9 10func ag_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func ag_num(v: i64) -> i64 { let b: *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{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 12func ag_rd32(b: *u8, o: i64) -> i64 { return ((b[o] as i64)<<24)|((b[o+1] as i64)<<16)|((b[o+2] as i64)<<8)|(b[o+3] as i64) } 13func ag_typ(b: *u8, o: i64, t0: i64, t1: i64, t2: i64, t3: i64) -> i64 { 14 if (b[o] as i64)==t0 { if (b[o+1] as i64)==t1 { if (b[o+2] as i64)==t2 { if (b[o+3] as i64)==t3 { return 1 } } } } 15 return 0 16} 17 18func main() -> i64 { 19 ag_puts("APNG-WRITE gate: sovereign animated-PNG clips (the test-evidence video container)\n" as *u8) 20 let W: i64 = 64 21 let H: i64 = 48 22 let st: *ApngState = sys_mmap(NX_APNG_STATE_BYTES) as *ApngState 23 if apng_open(st, "knowledge/status/apng_demo.png\x00" as *u8, W, H, 4, 1, 4) < 0 { ag_puts("open fail\n" as *u8); sys_exit(1); return 1 } 24 let rgb: *u8 = sys_mmap(W*H*3 + 16) 25 var f: i64 = 0 26 while f < 4 { 27 var i: i64 = 0 28 while i < W*H { rgb[i*3]=240 as u8; rgb[i*3+1]=244 as u8; rgb[i*3+2]=248 as u8; i=i+1 } 29 var y: i64 = 12 30 while y < 36 { var x: i64 = 4 + f*14; while x < 4 + f*14 + 14 { let o: i64=(y*W+x)*3; rgb[o]=30 as u8; rgb[o+1]=90 as u8; rgb[o+2]=200 as u8; x=x+1 } y=y+1 } 31 apng_frame(st, rgb) 32 f = f + 1 33 } 34 apng_close(st) 35 36 // read back + chunk-walk 37 let lp: *i64 = sys_mmap(16) as *i64 38 lp[0] = 0 - 1 39 let b: *u8 = sys_read_file("knowledge/status/apng_demo.png\x00" as *u8, lp) 40 let n: i64 = lp[0] 41 var pass: i64=0 42 var ttl: i64=0 43 ttl=ttl+1; ag_puts(" T1 file written + PNG signature: " as *u8) 44 var sig_ok: i64=0 45 if n > 100 { if (b[0] as i64)==137 { if (b[1] as i64)==80 { sig_ok=1 } } } 46 if sig_ok==1 { pass=pass+1; ag_puts("PASS (" as *u8); ag_num(n); ag_puts("B)\n" as *u8) } else { ag_puts("FAIL\n" as *u8) } 47 48 var p: i64 = 8 49 var actl_frames: i64 = 0 - 1 50 var n_fctl: i64 = 0 51 var n_fdat: i64 = 0 52 var n_idat: i64 = 0 53 var seq_ok: i64 = 1 54 var expect_seq: i64 = 0 55 var actl_crc_ok: i64 = 0 56 var frame0_off: i64 = 0 - 1 57 var frame1_off: i64 = 0 - 1 58 while p + 12 <= n { 59 let clen: i64 = ag_rd32(b, p) 60 let to: i64 = p + 4 61 if ag_typ(b,to, 97,99,84,76)==1 { // acTL 62 actl_frames = ag_rd32(b, p+8) 63 var crc: i64 = pw_crc_block(0xFFFFFFFF, ((b as i64)+to) as *u8, 0, 4) 64 crc = pw_crc_block(crc, ((b as i64)+p+8) as *u8, 0, clen) 65 if (crc ^ 0xFFFFFFFF) == ag_rd32(b, p+8+clen) { actl_crc_ok = 1 } 66 } 67 if ag_typ(b,to, 102,99,84,76)==1 { // fcTL 68 n_fctl = n_fctl + 1 69 if ag_rd32(b, p+8) != expect_seq { seq_ok = 0 } 70 expect_seq = expect_seq + 1 71 } 72 if ag_typ(b,to, 73,68,65,84)==1 { // IDAT 73 n_idat = n_idat + 1 74 frame0_off = p + 8 75 } 76 if ag_typ(b,to, 102,100,65,84)==1 { // fdAT 77 n_fdat = n_fdat + 1 78 if ag_rd32(b, p+8) != expect_seq { seq_ok = 0 } 79 expect_seq = expect_seq + 1 80 if frame1_off < 0 { frame1_off = p + 12 } // payload after the 4-byte seq 81 } 82 p = p + 8 + clen + 4 83 } 84 ttl=ttl+1; ag_puts(" T2 acTL frames==4 + CRC validates: " as *u8) 85 if actl_frames==4 { if actl_crc_ok==1 { pass=pass+1; ag_puts("PASS\n" as *u8) } else { ag_puts("FAIL\n" as *u8) } } else { ag_puts("FAIL\n" as *u8) } 86 ttl=ttl+1; ag_puts(" T3 chunk chain: fcTL=4, IDAT=1, fdAT=3: " as *u8) 87 if n_fctl==4 { if n_idat==1 { if n_fdat==3 { pass=pass+1; ag_puts("PASS\n" as *u8) } else { ag_puts("FAIL\n" as *u8) } } else { ag_puts("FAIL\n" as *u8) } } else { ag_puts("FAIL\n" as *u8) } 88 ttl=ttl+1; ag_puts(" T4 shared fcTL/fdAT sequence numbering exact (0..6): " as *u8) 89 if seq_ok==1 { if expect_seq==7 { pass=pass+1; ag_puts("PASS\n" as *u8) } else { ag_puts("FAIL\n" as *u8) } } else { ag_puts("FAIL\n" as *u8) } 90 // frames really differ: compare the two stored-zlib payloads' data regions (skip 2B zlib hdr + 5B block hdr) 91 ttl=ttl+1; ag_puts(" T5 frame payloads DIFFER (the square moved): " as *u8) 92 var differ: i64 = 0 93 if frame0_off > 0 { if frame1_off > 0 { 94 // scan past the all-background top rows: the moving square lives at y>=12 (~byte 12*(1+W*3)) 95 var k: i64 = 7 96 while k < 9000 { if b[frame0_off + k] != b[frame1_off + k] { differ = 1; k = 9000 } k = k + 1 } 97 } } 98 if differ==1 { pass=pass+1; ag_puts("PASS\n" as *u8) } else { ag_puts("FAIL\n" as *u8) } 99 // NEG: a still PNG has no acTL 100 nx_png_write_rgb("knowledge/status/apng_neg_still.png\x00" as *u8, rgb, W, H) 101 lp[0]=0-1 102 let s2: *u8 = sys_read_file("knowledge/status/apng_neg_still.png\x00" as *u8, lp) 103 let n2: i64 = lp[0] 104 var has_actl: i64 = 0 105 var q: i64 = 8 106 while q + 12 <= n2 { if ag_typ(s2,q+4, 97,99,84,76)==1 { has_actl=1 } q = q + 8 + ag_rd32(s2,q) + 4 } 107 ttl=ttl+1; ag_puts(" T6 NEG: a still PNG has NO acTL (animated check cannot false-fire): " as *u8) 108 if has_actl==0 { pass=pass+1; ag_puts("PASS\n" as *u8) } else { ag_puts("FAIL\n" as *u8) } 109 110 // ---- T7: STORED-DEFLATE LEN/NLEN COMPLEMENT (mutation-derived, debt 1785604588) ---- 111 // nx_gate_mutation_probe scored this pair 3/4 with a survivor at nx_apng_write.nx:76 -- the write of 112 // the NLEN field of a zlib STORED block. In a stored deflate block the layout is 113 // [BFINAL/BTYPE:1][LEN:2 LE][NLEN:2 LE][raw LEN bytes] 114 // and the format REQUIRES NLEN == ~LEN. A real decoder rejects the stream when it does not. 115 // It survived because every existing tooth reads PNG CHUNK structure -- signature, acTL, the 116 // fcTL/fdAT chain, sequence numbers, a chunk CRC -- and then compares frame payload BYTES. All of 117 // that stays valid when NLEN is wrong: the chunks are still well-formed and the payload region is 118 // still where the gate looks. Only an actual inflate would notice. 119 // LAW: VALIDATING THE CONTAINER IS NOT VALIDATING THE STREAM INSIDE IT. A chunk-level check can be 120 // perfect while the compressed payload is undecodable, and "a browser would render this" is a claim 121 // about the STREAM, which this gate had never tested. 122 ttl=ttl+1; ag_puts(" T7 stored-deflate LEN/NLEN are one's complements (a decoder would accept): " as *u8) 123 var nlen_ok: i64 = 0 124 if frame0_off > 0 { 125 let hb: i64 = frame0_off + 2 // skip the 2-byte zlib header -> block header byte 126 if hb + 5 <= n { 127 let dlen: i64 = (b[hb+1] as i64) | ((b[hb+2] as i64) << 8) 128 let dnl: i64 = (b[hb+3] as i64) | ((b[hb+4] as i64) << 8) 129 if dnl == ((dlen ^ 0xFFFF) & 0xFFFF) { nlen_ok = 1 } 130 } 131 } 132 if nlen_ok==1 { pass=pass+1; ag_puts("PASS\n" as *u8) } else { ag_puts("FAIL\n" as *u8) } 133 134 ag_puts("APNG-WRITE-GATE passed " as *u8); ag_num(pass); ag_puts("/" as *u8); ag_num(ttl) 135 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 136 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 137 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 138 let ctr__dry: *i64 = gv_ctr() 139 ctr__dry[0] = pass 140 ctr__dry[1] = ttl 141 let rc__dry: i64 = gv_verdict("APNG-WRITE-GATE" as *u8, ctr__dry, "open knowledge/status/apng_demo.png in a browser -- it MOVES)" as *u8) 142 sys_exit(rc__dry) 143 return rc__dry 144}