code wiki / _hdl_build / nx_jpeg_write_gate.nx

nx_jpeg_write_gate.nx source

↩ module page · 133 lines · 7834 B

1// nx_jpeg_write_gate.nx -- SOVEREIGN gate for J3 (baseline JFIF writer). Encodes a test image to a real 2// .jpg (written to /mnt/c/Users/elder/nishi_test.jpg so any real JPEG viewer can open it), then validates 3// WITHOUT python / 3rd party: (T1) SOI+EOI framing; (T2) marker walk reaches SOS + SOF0 carries the right 4// dims; (T3) DQT + both DHT tables present; (T4) entropy round-trip -- walk to the scan, un-stuff the 5// 0xFF00 bytes, decode every block with our own jbe_decode_block, dequant+IDCT, reconstruct, and the image 6// comes back faithfully; (T5) the .jpg compresses below raw; (T6) the file landed on disk. 7// GREEN iff 6/6. knowledge/status/jpeg_write_gate.log. license_tier: ORIGINAL 8import "nx_syscalls.nx" 9import "nx_gate_emit_lib.nx" 10import "nx_h264_bitwriter.nx" 11import "nx_dct8.nx" 12import "nx_quant_table.nx" 13import "nx_zigzag.nx" 14import "nx_jpeg_huff_enc.nx" 15import "nx_jpeg_block_enc.nx" 16import "nx_jpeg_write.nx" 17 18func 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 } 19func 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 } 20func g_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; 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 } 21func iabs(v: i64) -> i64 { if v<0 { return 0-v } return v } 22func u16(b: *u8, o: i64) -> i64 { return ((b[o] as i64)<<8) | (b[o+1] as i64) } 23 24func main() -> i64 { 25 g_puts("=== JPEG WRITE GATE: sovereign baseline JFIF writer -> real .jpg + round-trip ===\n" as *u8) 26 let W: i64=64; let H: i64=64; let npx: i64=W*H 27 28 let img: *i64=sys_mmap(npx*8) as *i64 29 var y: i64=0 30 while y<H { var x: i64=0; while x<W { var v: i64=(x+y)*2; if v>255 { v=255 } if x>=20 { if x<44 { if y>=20 { if y<44 { v=210 } } } } img[y*W+x]=v; x=x+1 } y=y+1 } 31 32 // tables / quant / zigzag / DCT 33 let dcB: *i64=sys_mmap(20*8) as *i64; let dcV: *i64=sys_mmap(20*8) as *i64 34 let acB: *i64=sys_mmap(20*8) as *i64; let acV: *i64=sys_mmap(200*8) as *i64 35 let ndc: i64=jhe_dc_bits(dcB); jhe_dc_val(dcV); let nac: i64=jhe_ac_bits(acB); jhe_ac_val(acV) 36 let dcCO: *i64=sys_mmap(256*8) as *i64; let dcSI: *i64=sys_mmap(256*8) as *i64 37 let acCO: *i64=sys_mmap(256*8) as *i64; let acSI: *i64=sys_mmap(256*8) as *i64 38 jhe_gen(dcB, dcV, ndc, dcCO, dcSI); jhe_gen(acB, acV, nac, acCO, acSI) 39 let qt: *i64=sys_mmap(64*8) as *i64; nx_qt_luma(qt, 50) 40 let to_zz: *i64=sys_mmap(64*8) as *i64; let from_zz: *i64=sys_mmap(64*8) as *i64; nx_zigzag_init(to_zz, from_zz) 41 let DM: *i64=sys_mmap(64*8) as *i64; nx_dct8_init(DM) 42 let scratch: *i64=sys_mmap(64*8) as *i64; let ti: *i64=sys_mmap(8*8) as *i64; let to: *i64=sys_mmap(8*8) as *i64 43 44 // write the JPEG 45 let out: *u8=sys_mmap(npx*2 + 4096) 46 let jlen: i64=jw_write_jpeg(out, W, H, qt, dcB, dcV, acB, acV, dcCO, dcSI, acCO, acSI, to_zz, from_zz, DM, scratch, ti, to, img) 47 48 // write to disk for real-viewer validation 49 let fd: i64=sys_openat_wr("/mnt/c/Users/elder/nishi_test.jpg" as *u8, 0x1a4) 50 var wrote: i64=0 51 if fd>=0 { wrote=sys_write(fd, out, jlen); sys_close(fd) } 52 53 // T1 SOI + EOI 54 var t1: i64=0 55 if out[0]==(0xFF as u8) { if out[1]==(0xD8 as u8) { if out[jlen-2]==(0xFF as u8) { if out[jlen-1]==(0xD9 as u8) { t1=1 } } } } 56 57 // marker walk: capture SOF dims, SOS scan start, and presence of DQT/DHT 58 var off: i64=2; var scan_start: i64=0; var sofW: i64=0; var sofH: i64=0 59 var have_dqt: i64=0; var have_dht_dc: i64=0; var have_dht_ac: i64=0 60 var walking: i64=1 61 while walking==1 { 62 if off+4 > jlen { walking=0 } else { 63 if out[off]!=(0xFF as u8) { walking=0 } else { 64 let m: i64=out[off+1] as i64 65 if m==0xDA { let len: i64=u16(out, off+2); scan_start=off+2+len; walking=0 } else { 66 let len: i64=u16(out, off+2) 67 if m==0xDB { have_dqt=1 } 68 if m==0xC0 { sofH=u16(out, off+5); sofW=u16(out, off+7) } 69 if m==0xC4 { if (out[off+4] as i64)==0x00 { have_dht_dc=1 } if (out[off+4] as i64)==0x10 { have_dht_ac=1 } } 70 off=off+2+len 71 } 72 } 73 } 74 } 75 var t2: i64=0; if scan_start>0 { if sofW==W { if sofH==H { t2=1 } } } 76 var t3: i64=0; if have_dqt==1 { if have_dht_dc==1 { if have_dht_ac==1 { t3=1 } } } 77 78 // un-stuff the entropy scan into ebuf 79 let ebuf: *u8=sys_mmap(npx*2 + 1024) 80 var ip: i64=scan_start; var ep: i64=0; var scanning: i64=1 81 while scanning==1 { 82 if ip>=jlen { scanning=0 } else { 83 let b: i64=out[ip] as i64 84 if b==0xFF { 85 let nb: i64=out[ip+1] as i64 86 if nb==0x00 { ebuf[ep]=0xFF as u8; ep=ep+1; ip=ip+2 } else { scanning=0 } 87 } else { ebuf[ep]=b as u8; ep=ep+1; ip=ip+1 } 88 } 89 } 90 91 // decode every block from ebuf, reconstruct the image 92 let recon: *i64=sys_mmap(npx*8) as *i64 93 let pos: *i64=sys_mmap(8) as *i64; pos[0]=0 94 let zz: *i64=sys_mmap(64*8) as *i64; let q: *i64=sys_mmap(64*8) as *i64 95 let co: *i64=sys_mmap(64*8) as *i64; let rsh: *i64=sys_mmap(64*8) as *i64 96 var prevdc: i64=0 97 var by: i64=0 98 while by < H/8 { 99 var bx: i64=0 100 while bx < W/8 { 101 prevdc=jbe_decode_block(ebuf, pos, dcCO, dcSI, acCO, acSI, prevdc, zz) 102 nx_zigzag_unscan(zz, from_zz, q) 103 var i: i64=0; while i<64 { co[i]=q[i]*qt[i]; i=i+1 } 104 nx_dct8_inverse_2d(DM, co, rsh, scratch, ti, to) 105 var r: i64=0 106 while r<8 { var c: i64=0; while c<8 { var p: i64=rsh[r*8+c]+128; if p<0 {p=0} if p>255 {p=255} recon[(by*8+r)*W+(bx*8+c)]=p; c=c+1 } r=r+1 } 107 bx=bx+1 108 } 109 by=by+1 110 } 111 var maxe: i64=0; var sume: i64=0 112 var j: i64=0; while j<npx { let e: i64=iabs(recon[j]-img[j]); if e>maxe { maxe=e } sume=sume+e; j=j+1 } 113 var t4: i64=0; if maxe <= 40 { t4=1 } 114 var t5: i64=0; if jlen < npx { t5=1 } 115 var t6: i64=0; if wrote==jlen { if jlen>0 { t6=1 } } 116 117 g_puts("-- .jpg " as *u8); g_num(W); g_puts("x" as *u8); g_num(H); g_puts(": " as *u8); g_num(jlen); g_puts("B vs raw " as *u8); g_num(npx) 118 g_puts("B maxErr=" as *u8); g_num(maxe); g_puts(" meanErr=" as *u8); g_num(sume/npx); g_puts(" -> /mnt/c/Users/elder/nishi_test.jpg\n" as *u8) 119 120 var pass: i64=0; let rows: i64=6 121 pass=pass+g_check(" T1 SOI + EOI framing" as *u8, t1) 122 pass=pass+g_check(" T2 marker walk -> SOS + SOF0 dims match" as *u8, t2) 123 pass=pass+g_check(" T3 DQT + DHT(DC) + DHT(AC) present" as *u8, t3) 124 pass=pass+g_check(" T4 entropy round-trip (un-stuff + own decode) faithful" as *u8, t4) 125 pass=pass+g_check(" T5 .jpg compresses below raw" as *u8, t5) 126 pass=pass+g_check(" T6 file written to disk" as *u8, t6) 127 128 g_puts("----\nJWRITE rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass); g_puts("\n" as *u8) 129 let lg: i64=sys_openat_append("knowledge/status/jpeg_write_gate.log" as *u8, 0x1a4) 130 if lg>=0 { g_w(lg, "JWRITE rows=" as *u8); g_wn(lg, rows); g_w(lg, " pass=" as *u8); g_wn(lg, pass); g_w(lg, " jpgbytes=" as *u8); g_wn(lg, jlen); g_w(lg, " maxErr=" as *u8); g_wn(lg, maxe); if pass==rows { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } sys_close(lg) } 131 if pass==rows { g_puts("JWRITE GREEN (sovereign JPEG file written + round-trip proven)\n" as *u8); sys_exit(0); return 0 } 132 g_puts("JWRITE RED\n" as *u8); sys_exit(1); return 1 133}