code wiki / (root) / nx_jpeg_tables_gate.nx

nx_jpeg_tables_gate.nx source

↩ module page · 191 lines · 11493 B

1// nx_jpeg_tables_gate.nx -- the referee for the decoder's table slots (debt 1789603770, 2026-09-16). T.81 B.2.4.2 names every 2// DHT and DQT table and a later definition REPLACES it. The decoders appended tables by order of appearance into four slots, 3// so a progressive file (one DHT per scan: ri_diora_baird_1 carries 7 tables over 6 scans, ri_diora_baird_4 ten over ten) 4// wrote past the array (ARENA-OVERRUN prev_alloc_size=256 on every real decode) and a redefined table lost to its stale first 5// definition. In-process teeth on hand-built payloads: slots are keyed by name, a redefinition wins, twelve definitions leave 6// the slot count at eight, an undefined name reads absent, a class the standard lacks is refused by name and places nothing. 7// End-to-end teeth on two mirrored progressive stills: the decode agrees with an OUTSIDE decoder (libjpeg-turbo through 8// OpenCV 5.0.0 on the laptop, 2026-09-16) on the channel means -- the liar-killer no in-process tooth can supply; that 9// decoder never enters a build or run path, only its numbers do. Values are printed with gv_kv. 10// license_tier: ORIGINAL No hw writes (Rule 26). 11import "nx_syscalls.nx" 12import "nx_gate_verdict.nx" 13import "nx_jpeg_ascii.nx" 14 15const JT_I64: i64 = 8 16const JT_BYTE: i64 = 255 17const JT_BPP: i64 = 3 18const JT_DHT_HDR: i64 = 17 19const JT_BITS_N: i64 = 16 20const JT_DQT_VALUES: i64 = 64 21const JT_PAYLOAD_B: i64 = 128 22const JT_MEANS_N: i64 = 5 23const JT_ROUNDS: i64 = 3 24const JT_TOL_MEAN: i64 = 4 25const JT_FIX1: *u8 = "knowledge/fetched/ri_diora_baird_1.jpg" 26const JT_FIX1_W: i64 = 405 27const JT_FIX1_H: i64 = 500 28const JT_FIX1_R: i64 = 171 29const JT_FIX1_G: i64 = 156 30const JT_FIX1_B: i64 = 146 31const JT_FIX2: *u8 = "knowledge/fetched/ri_diora_baird_4.jpg" 32const JT_FIX2_W: i64 = 831 33const JT_FIX2_H: i64 = 1200 34const JT_FIX2_R: i64 = 119 35const JT_FIX2_G: i64 = 117 36const JT_FIX2_B: i64 = 80 37const JT_TC_DC: i64 = 0 38const JT_TC_AC: i64 = 1 39const JT_TC_BAD: i64 = 2 40const JT_TH_NEVER: i64 = 2 41const JT_TQ_A: i64 = 1 42const JT_TQ_NEVER: i64 = 0 43const JT_VAL_A: i64 = 7 44const JT_VAL_B: i64 = 9 45const JT_SYM_A: i64 = 0 46const JT_SYM_B: i64 = 5 47const JT_SYM_B2: i64 = 7 48const JT_SYM_C: i64 = 8 49const JT_E_UNREADABLE: i64 = 0 - 1 50 51func jt_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 52func jt_near(a: i64, b: i64, tol: i64) -> i64 { if jt_abs(a - b) <= tol { return 1 } return 0 } 53// one DHT table at buf+o: class/id byte, BITS with n1 codes of length 1 and n2 of length 2, then the symbols sym0.. ; returns its byte length 54func jt_dht_table(buf: *u8, o: i64, tc: i64, th: i64, n1: i64, n2: i64, sym0: i64) -> i64 { 55 buf[o] = (tc * 16 + th) as u8 56 var i: i64 = 1 57 while i <= JT_BITS_N { buf[o + i] = 0 as u8; i = i + 1 } 58 buf[o + 1] = n1 as u8 59 buf[o + 2] = n2 as u8 60 var k: i64 = 0 61 while k < n1 + n2 { buf[o + JT_DHT_HDR + k] = (sym0 + k) as u8; k = k + 1 } 62 return JT_DHT_HDR + n1 + n2 63} 64// one 8-bit DQT table at buf+o with every value equal; returns its byte length 65func jt_dqt_table(buf: *u8, o: i64, tq: i64, value: i64) -> i64 { 66 buf[o] = tq as u8 67 var k: i64 = 0 68 while k < JT_DQT_VALUES { buf[o + 1 + k] = value as u8; k = k + 1 } 69 return 1 + JT_DQT_VALUES 70} 71// decode a mirrored still: out = w, h, mean R, mean G, mean B; returns the decoder's verdict, or JT_E_UNREADABLE 72func jt_decode_means(path: *u8, out: *i64) -> i64 { 73 let fl: *i64 = sys_mmap(16) as *i64 74 fl[0] = 0 75 let jpeg: *u8 = sys_read_file(path, fl) 76 if (jpeg as i64) == 0 { return JT_E_UNREADABLE } 77 if fl[0] <= 0 { return JT_E_UNREADABLE } 78 let orgb: *i64 = sys_mmap(JT_I64) as *i64 79 let ow: *i64 = sys_mmap(JT_I64) as *i64 80 let oh: *i64 = sys_mmap(JT_I64) as *i64 81 let rc: i64 = nx_jpeg_decode_rgb(jpeg, fl[0], orgb, ow, oh) 82 if rc != NX_JPEG_ASCII_OK { return rc } 83 let rgb: *u8 = orgb[0] as *u8 84 let n: i64 = ow[0] * oh[0] 85 var sr: i64 = 0 86 var sg: i64 = 0 87 var sb: i64 = 0 88 var i: i64 = 0 89 while i < n { 90 let o: i64 = i * JT_BPP 91 sr = sr + ((rgb[o] as i64) & JT_BYTE) 92 sg = sg + ((rgb[o + 1] as i64) & JT_BYTE) 93 sb = sb + ((rgb[o + 2] as i64) & JT_BYTE) 94 i = i + 1 95 } 96 out[0] = ow[0] 97 out[1] = oh[0] 98 out[2] = sr / n 99 out[3] = sg / n 100 out[4] = sb / n 101 return rc 102} 103func main() -> i64 { 104 let ctr: *i64 = gv_ctr() 105 let ctx: *NxJpegDecCtx = sys_mmap(NX_JPEG_DEC_CTX_BYTES) as *NxJpegDecCtx 106 nx_jpeg_dec_ctx_init(ctx) 107 gv_check("fresh-context-eight-keyed-huffman-slots" as *u8, (ctx.n_htables == NX_JPEG_HSLOTS) as i64, ctr) 108 gv_check("fresh-context-four-keyed-quant-slots" as *u8, (ctx.n_qtables == NX_JPEG_QSLOTS) as i64, ctr) 109 gv_check("undefined-name-reads-absent" as *u8, ((nx_jpeg_ctx_htable(ctx, JT_TC_DC, 0) as i64) == 0) as i64, ctr) 110 // payload A: DC0 with three codes; payload B: DC0 redefined with two codes plus AC1 with one; payload C: AC0 with two 111 let pa: *u8 = sys_mmap(JT_PAYLOAD_B) 112 let la: i64 = jt_dht_table(pa, 0, JT_TC_DC, 0, 1, 2, JT_SYM_A) 113 let pb: *u8 = sys_mmap(JT_PAYLOAD_B) 114 var lb: i64 = jt_dht_table(pb, 0, JT_TC_DC, 0, 2, 0, JT_SYM_B) 115 lb = lb + jt_dht_table(pb, lb, JT_TC_AC, 1, 1, 0, JT_SYM_B2) 116 let pc: *u8 = sys_mmap(JT_PAYLOAD_B) 117 let lc: i64 = jt_dht_table(pc, 0, JT_TC_AC, 0, 1, 1, JT_SYM_C) 118 gv_check("payload-a-parses" as *u8, (nx_jpeg_ctx_parse_dht(ctx, pa, la) == NX_JPEG_DHT_OK) as i64, ctr) 119 let t0: *NxJpegHTable = nx_jpeg_ctx_htable(ctx, JT_TC_DC, 0) 120 gv_check("dc0-defined-by-payload-a" as *u8, ((t0 as i64) != 0) as i64, ctr) 121 gv_check("dc0-three-symbols-after-a" as *u8, (t0.n_symbols == 3) as i64, ctr) 122 gv_check("payload-b-parses" as *u8, (nx_jpeg_ctx_parse_dht(ctx, pb, lb) == NX_JPEG_DHT_OK) as i64, ctr) 123 let t0b: *NxJpegHTable = nx_jpeg_ctx_htable(ctx, JT_TC_DC, 0) 124 gv_check("redefinition-wins-dc0-two-symbols-after-b" as *u8, (t0b.n_symbols == 2) as i64, ctr) 125 gv_check("redefinition-wins-dc0-first-symbol-is-b" as *u8, (t0b.huffval[0] == JT_SYM_B) as i64, ctr) 126 gv_check("redefinition-lands-in-the-same-slot" as *u8, ((t0b as i64) == (t0 as i64)) as i64, ctr) 127 let t11: *NxJpegHTable = nx_jpeg_ctx_htable(ctx, JT_TC_AC, 1) 128 gv_check("ac1-defined-by-payload-b" as *u8, ((t11 as i64) != 0) as i64, ctr) 129 gv_check("payload-c-parses" as *u8, (nx_jpeg_ctx_parse_dht(ctx, pc, lc) == NX_JPEG_DHT_OK) as i64, ctr) 130 let t10: *NxJpegHTable = nx_jpeg_ctx_htable(ctx, JT_TC_AC, 0) 131 gv_check("ac0-two-symbols-after-c" as *u8, (t10.n_symbols == 2) as i64, ctr) 132 // twelve definitions in all: the old append ran eight tables past a four-slot array; the keyed area does not move 133 var rounds: i64 = 0 134 var okall: i64 = 1 135 while rounds < JT_ROUNDS { 136 if nx_jpeg_ctx_parse_dht(ctx, pa, la) != NX_JPEG_DHT_OK { okall = 0 } 137 if nx_jpeg_ctx_parse_dht(ctx, pb, lb) != NX_JPEG_DHT_OK { okall = 0 } 138 if nx_jpeg_ctx_parse_dht(ctx, pc, lc) != NX_JPEG_DHT_OK { okall = 0 } 139 rounds = rounds + 1 140 } 141 gv_check("twelve-definitions-all-parse" as *u8, okall, ctr) 142 gv_check("slot-count-unchanged-after-twelve-definitions" as *u8, (ctx.n_htables == NX_JPEG_HSLOTS) as i64, ctr) 143 let t0c: *NxJpegHTable = nx_jpeg_ctx_htable(ctx, JT_TC_DC, 0) 144 gv_check("dc0-still-the-latest-definition" as *u8, (t0c.n_symbols == 2) as i64, ctr) 145 gv_check("never-defined-dc2-stays-absent" as *u8, ((nx_jpeg_ctx_htable(ctx, JT_TC_DC, JT_TH_NEVER) as i64) == 0) as i64, ctr) 146 // neg-control: a class the standard does not have is refused by name and changes no slot 147 let pbad: *u8 = sys_mmap(JT_PAYLOAD_B) 148 let lbad: i64 = jt_dht_table(pbad, 0, JT_TC_BAD, 0, 1, 0, 1) 149 gv_check("neg-control-bad-class-refused-by-name" as *u8, (nx_jpeg_ctx_parse_dht(ctx, pbad, lbad) == NX_JPEG_DHT_BAD_TC) as i64, ctr) 150 let t0d: *NxJpegHTable = nx_jpeg_ctx_htable(ctx, JT_TC_DC, 0) 151 gv_check("neg-control-refusal-changes-no-slot" as *u8, (t0d.n_symbols == 2) as i64, ctr) 152 // quantisation tables: keyed by Tq, a redefinition wins, the count is fixed 153 let qa: *u8 = sys_mmap(JT_PAYLOAD_B) 154 let lqa: i64 = jt_dqt_table(qa, 0, JT_TQ_A, JT_VAL_A) 155 let qb: *u8 = sys_mmap(JT_PAYLOAD_B) 156 let lqb: i64 = jt_dqt_table(qb, 0, JT_TQ_A, JT_VAL_B) 157 gv_check("dqt-a-parses" as *u8, (nx_jpeg_ctx_parse_dqt(ctx, qa, lqa) == NX_JPEG_DQT_OK) as i64, ctr) 158 let q1: *NxJpegQTable = nx_jpeg_ctx_qtable(ctx, JT_TQ_A) 159 gv_check("tq1-defined-by-dqt-a" as *u8, ((q1 as i64) != 0) as i64, ctr) 160 gv_check("tq1-first-value-after-a" as *u8, (q1.values[0] == JT_VAL_A) as i64, ctr) 161 gv_check("dqt-b-parses" as *u8, (nx_jpeg_ctx_parse_dqt(ctx, qb, lqb) == NX_JPEG_DQT_OK) as i64, ctr) 162 let q1b: *NxJpegQTable = nx_jpeg_ctx_qtable(ctx, JT_TQ_A) 163 gv_check("redefinition-wins-tq1-first-value-after-b" as *u8, (q1b.values[0] == JT_VAL_B) as i64, ctr) 164 gv_check("never-defined-tq0-stays-absent" as *u8, ((nx_jpeg_ctx_qtable(ctx, JT_TQ_NEVER) as i64) == 0) as i64, ctr) 165 gv_check("quant-slot-count-unchanged" as *u8, (ctx.n_qtables == NX_JPEG_QSLOTS) as i64, ctr) 166 // end to end on the mirrored stills, against the outside decoder's channel means 167 let m1: *i64 = sys_mmap(JT_MEANS_N * JT_I64) as *i64 168 let rc1: i64 = jt_decode_means(JT_FIX1, m1) 169 gv_check("fixture-ri-1-readable" as *u8, (rc1 != JT_E_UNREADABLE) as i64, ctr) 170 gv_check("ri-1-progressive-seven-tables-decodes" as *u8, (rc1 == NX_JPEG_ASCII_OK) as i64, ctr) 171 gv_check("ri-1-width" as *u8, (m1[0] == JT_FIX1_W) as i64, ctr) 172 gv_check("ri-1-height" as *u8, (m1[1] == JT_FIX1_H) as i64, ctr) 173 gv_check("ri-1-mean-red-agrees-with-outside-decoder" as *u8, jt_near(m1[2], JT_FIX1_R, JT_TOL_MEAN), ctr) 174 gv_check("ri-1-mean-green-agrees-with-outside-decoder" as *u8, jt_near(m1[3], JT_FIX1_G, JT_TOL_MEAN), ctr) 175 gv_check("ri-1-mean-blue-agrees-with-outside-decoder" as *u8, jt_near(m1[4], JT_FIX1_B, JT_TOL_MEAN), ctr) 176 let m2: *i64 = sys_mmap(JT_MEANS_N * JT_I64) as *i64 177 let rc2: i64 = jt_decode_means(JT_FIX2, m2) 178 gv_check("fixture-ri-4-readable" as *u8, (rc2 != JT_E_UNREADABLE) as i64, ctr) 179 gv_check("ri-4-progressive-ten-tables-decodes" as *u8, (rc2 == NX_JPEG_ASCII_OK) as i64, ctr) 180 gv_check("ri-4-width" as *u8, (m2[0] == JT_FIX2_W) as i64, ctr) 181 gv_check("ri-4-height" as *u8, (m2[1] == JT_FIX2_H) as i64, ctr) 182 gv_check("ri-4-mean-red-agrees-with-outside-decoder" as *u8, jt_near(m2[2], JT_FIX2_R, JT_TOL_MEAN), ctr) 183 gv_check("ri-4-mean-green-agrees-with-outside-decoder" as *u8, jt_near(m2[3], JT_FIX2_G, JT_TOL_MEAN), ctr) 184 gv_check("ri-4-mean-blue-agrees-with-outside-decoder" as *u8, jt_near(m2[4], JT_FIX2_B, JT_TOL_MEAN), ctr) 185 gv_values_head() 186 gv_kv("huffman_slots" as *u8, ctx.n_htables) 187 gv_kv("quant_slots" as *u8, ctx.n_qtables) 188 gv_kv("ri1_rc" as *u8, rc1); gv_kv("ri1_w" as *u8, m1[0]); gv_kv("ri1_h" as *u8, m1[1]); gv_kv("ri1_mean_r" as *u8, m1[2]); gv_kv("ri1_mean_g" as *u8, m1[3]); gv_kv("ri1_mean_b" as *u8, m1[4]) 189 gv_kv("ri4_rc" as *u8, rc2); gv_kv("ri4_w" as *u8, m2[0]); gv_kv("ri4_h" as *u8, m2[1]); gv_kv("ri4_mean_r" as *u8, m2[2]); gv_kv("ri4_mean_g" as *u8, m2[3]); gv_kv("ri4_mean_b" as *u8, m2[4]) 190 return gv_verdict("nx_jpeg_tables_gate" as *u8, ctr, "decoder table slots keyed by the name T.81 gives them: a redefinition replaces, twelve definitions leave eight slots, an undefined name reads absent, a class the standard lacks is refused, and two progressive stills with seven and ten tables decode to the outside decoder's channel means" as *u8) 191}