code wiki / _hdl_build / nx_gif_color_gate.nx

nx_gif_color_gate.nx source

↩ module page · 181 lines · 7748 B

1// nx_gif_color_gate.nx -- gate for C2 of the codec-chokepoint program (debt 1785903075): GIF palette 2// COLOR decode + DE-INTERLACE, at the decoder (gif_decode_rgb) AND through the shared chokepoint 3// (nx_img_bytes_to_rgb). Fixtures are hand-built byte-exact GIF89a files: a 4x4 4-colour palette image 4// stored non-interlaced (rows 0,1,2,3) and interlaced (pass order 0,2,1,3 + descriptor bit 6), whose 5// DECODED images must be identical. The synthetic LZW uses CLEAR-before-every-literal (no dictionary 6// growth), so T6 decodes a REAL gathered web GIF (third-party encoder, real dictionary growth) as the 7// independent witness. Inherits nx_gate_verdict. license_tier: ORIGINAL expect_exit: 0 8import "nx_syscalls.nx" 9import "nx_gate_verdict.nx" 10import "nx_gif_decode.nx" 11import "nx_img_bytes_to_rgb.nx" 12 13// append one 3-bit LZW code, LSB-first (GIF bit order); buf must be zeroed (OR-only) 14func gg_putcode(buf: *u8, bitpos: *i64, code: i64) -> i64 { 15 var i: i64=0 16 while i<3 { 17 let bit: i64=(code>>i)&1 18 let bp: i64=bitpos[0] 19 if bit==1 { let by: i64=bp/8; let bo: i64=bp%8; buf[by]=((buf[by] as i64)|(1<<bo)) as u8 } 20 bitpos[0]=bitpos[0]+1 21 i=i+1 22 } 23 return 0 24} 25 26// build a 4x4 GIF89a with a 4-entry GCT (red,green,blue,white) whose pixel-index 27// STORAGE sequence is pixseq[16]; interlaced sets descriptor bit 6. returns length. 28func gg_build_gif(out: *u8, pixseq: *u8, interlaced: i64) -> i64 { 29 out[0]=0x47 as u8; out[1]=0x49 as u8; out[2]=0x46 as u8 30 out[3]=0x38 as u8; out[4]=0x39 as u8; out[5]=0x61 as u8 31 out[6]=4 as u8; out[7]=0 as u8; out[8]=4 as u8; out[9]=0 as u8 32 out[10]=0x81 as u8; out[11]=0 as u8; out[12]=0 as u8 33 out[13]=255 as u8; out[14]=0 as u8; out[15]=0 as u8 34 out[16]=0 as u8; out[17]=255 as u8; out[18]=0 as u8 35 out[19]=0 as u8; out[20]=0 as u8; out[21]=255 as u8 36 out[22]=255 as u8; out[23]=255 as u8; out[24]=255 as u8 37 var o: i64=25 38 out[o]=0x2C as u8 39 out[o+1]=0 as u8; out[o+2]=0 as u8; out[o+3]=0 as u8; out[o+4]=0 as u8 40 out[o+5]=4 as u8; out[o+6]=0 as u8; out[o+7]=4 as u8; out[o+8]=0 as u8 41 if interlaced==1 { out[o+9]=0x40 as u8 } else { out[o+9]=0 as u8 } 42 o=o+10 43 out[o]=2 as u8; o=o+1 44 let lzbuf: *u8=sys_mmap(256) 45 let bitpos: *i64=sys_mmap(8) as *i64 46 bitpos[0]=0 47 var p: i64=0 48 while p<16 { gg_putcode(lzbuf,bitpos,4); gg_putcode(lzbuf,bitpos,pixseq[p] as i64); p=p+1 } 49 gg_putcode(lzbuf,bitpos,5) 50 let nbytes: i64=(bitpos[0]+7)/8 51 out[o]=nbytes as u8; o=o+1 52 var q: i64=0 53 while q<nbytes { out[o]=lzbuf[q]; o=o+1; q=q+1 } 54 out[o]=0 as u8; o=o+1 55 out[o]=0x3B as u8; o=o+1 56 return o 57} 58 59func main() -> i64 { 60 let ctr: *i64 = gv_ctr() 61 gv_head("nx_gif_color_gate -- GIF palette colour + de-interlace, decoder and chokepoint" as *u8) 62 63 // display image: row y = colour y. non-interlaced storage = rows 0,1,2,3; 64 // interlaced storage = pass order rows 0,2,1,3. 65 let seq_n: *u8=sys_mmap(32) 66 let seq_i: *u8=sys_mmap(32) 67 var r: i64=0 68 while r<4 { var c: i64=0; while c<4 { seq_n[r*4+c]=r as u8; c=c+1 } r=r+1 } 69 var c2: i64=0 70 while c2<4 { seq_i[c2]=0 as u8; seq_i[4+c2]=2 as u8; seq_i[8+c2]=1 as u8; seq_i[12+c2]=3 as u8; c2=c2+1 } 71 72 let gif_n: *u8=sys_mmap(512) 73 let gif_i: *u8=sys_mmap(512) 74 let len_n: i64=gg_build_gif(gif_n, seq_n, 0) 75 let len_i: i64=gg_build_gif(gif_i, seq_i, 1) 76 77 // the two files must genuinely DIFFER on the wire (vacuity guard for T2) 78 var files_differ: i64=0 79 if len_n==len_i { var di: i64=0; while di<len_n { if gif_n[di]!=gif_i[di] { files_differ=1; di=len_n } else { di=di+1 } } } else { files_differ=1 } 80 81 // T1 palette colour KAT on the non-interlaced file 82 let wh1: *i64=sys_mmap(32) as *i64 83 let rgb1: *u8=gif_decode_rgb(gif_n, len_n, wh1) 84 var t1: i64=0 85 if rgb1!=(0 as *u8) { if wh1[0]==4 { if wh1[1]==4 { 86 var ok1: i64=1 87 var y1: i64=0 88 while y1<4 { 89 var x1: i64=0 90 while x1<4 { 91 let o1: i64=(y1*4+x1)*3 92 var er: i64=0 93 var eg: i64=0 94 var eb: i64=0 95 if y1==0 { er=255 } 96 if y1==1 { eg=255 } 97 if y1==2 { eb=255 } 98 if y1==3 { er=255; eg=255; eb=255 } 99 if (rgb1[o1] as i64)!=er { ok1=0 } 100 if (rgb1[o1+1] as i64)!=eg { ok1=0 } 101 if (rgb1[o1+2] as i64)!=eb { ok1=0 } 102 x1=x1+1 103 } 104 y1=y1+1 105 } 106 t1=ok1 107 } } } 108 gv_check("T1 gif_decode_rgb exact palette colours (4x4 KAT)" as *u8, t1, ctr) 109 110 // T2 interlaced file decodes to the IDENTICAL display image 111 let wh2: *i64=sys_mmap(32) as *i64 112 let rgb2: *u8=gif_decode_rgb(gif_i, len_i, wh2) 113 var t2: i64=0 114 if rgb2!=(0 as *u8) { if files_differ==1 { 115 var same2: i64=1 116 var p2: i64=0 117 while p2<48 { if rgb1[p2]!=rgb2[p2] { same2=0; p2=48 } else { p2=p2+1 } } 118 t2=same2 119 } } 120 gv_check("T2 interlaced storage decodes IDENTICAL to non-interlaced (files differ on wire)" as *u8, t2, ctr) 121 122 // T3 historic gray contract: Rec.709 of the palette rows = 53,182,18,255 123 let wh3: *i64=sys_mmap(32) as *i64 124 let gray3: *u8=gif_decode(gif_n, len_n, wh3) 125 var t3: i64=0 126 if gray3!=(0 as *u8) { 127 var ok3: i64=1 128 if (gray3[0] as i64)!=53 { ok3=0 } 129 if (gray3[5] as i64)!=182 { ok3=0 } 130 if (gray3[10] as i64)!=18 { ok3=0 } 131 if (gray3[15] as i64)!=255 { ok3=0 } 132 t3=ok3 133 } 134 gv_check("T3 gif_decode gray contract: Rec.709 rows 53/182/18/255" as *u8, t3, ctr) 135 136 // T4 BITE: a truncated GIF must be refused; the full file must decode 137 var bite_bad: i64=0 138 let wh4: *i64=sys_mmap(32) as *i64 139 let bad4: *u8=gif_decode_rgb(gif_n, 10, wh4) 140 if bad4==(0 as *u8) { bite_bad=1 } 141 var bite_good: i64=0 142 if rgb1==(0 as *u8) { bite_good=1 } 143 gv_bite("T4 truncated-GIF refusal" as *u8, bite_bad, bite_good, ctr) 144 145 // T5 the CHOKEPOINT delivers colour: before this rung it expanded gray R=G=B 146 let wh5: *i64=sys_mmap(32) as *i64 147 let ck5: *u8=nx_img_bytes_to_rgb(gif_n, len_n, wh5) 148 var t5: i64=0 149 if ck5!=(0 as *u8) { if wh5[0]==4 { if wh5[1]==4 { 150 if (ck5[0] as i64)==255 { if (ck5[1] as i64)==0 { if (ck5[2] as i64)==0 { t5=1 } } } 151 } } } 152 gv_check("T5 chokepoint nx_img_bytes_to_rgb returns COLOUR (R=255,G=0,B=0)" as *u8, t5, ctr) 153 154 // T6 INDEPENDENT WITNESS: a real gathered web GIF (third-party encoder, real 155 // LZW dictionary growth -- the synthetic CLEAR-spam stream never grows). 156 var t6: i64=0 157 var w6: i64=0 158 var h6: i64=0 159 let wbox: *i64=sys_mmap(16) as *i64 160 let wraw: *u8=sys_read_file("knowledge/media/barack_obama/1ec1849912da1655c037f34873dd363f848a2db9651624fd2098ef02c2c07a3c.gif" as *u8, wbox) 161 if wraw!=(0 as *u8) { 162 let wh6: *i64=sys_mmap(32) as *i64 163 let rgb6: *u8=gif_decode_rgb(wraw, wbox[0], wh6) 164 if rgb6!=(0 as *u8) { 165 w6=wh6[0]; h6=wh6[1] 166 if w6>0 { if h6>0 { 167 var vmin: i64=255 168 var vmax: i64=0 169 var s6: i64=0 170 while s6<w6*h6*3 { let pv: i64=rgb6[s6] as i64; if pv<vmin { vmin=pv } if pv>vmax { vmax=pv } s6=s6+37 } 171 if vmax-vmin>10 { t6=1 } 172 } } 173 } 174 } 175 gv_puts(" [witness gif w=" as *u8); gv_num(w6); gv_puts(" h=" as *u8); gv_num(h6); gv_puts("]\n" as *u8) 176 gv_check("T6 real gathered web GIF decodes with structure (independent LZW witness)" as *u8, t6, ctr) 177 178 let rc: i64 = gv_verdict("GIF-COLOR-GATE" as *u8, ctr, "palette colour + de-interlace at decoder and chokepoint" as *u8) 179 sys_exit(rc) 180 return rc 181}