code wiki / (root) / nx_jpeg_decode_image_test.nx

nx_jpeg_decode_image_test.nx source

↩ module page · 162 lines · 6755 B

1// nx_jpeg_decode_image_test.nx -- KAT for the top-level image 2// decoder. Minimal 8x8 grayscale: 1 component, 1 MCU, 1 block. 3// 4// Bitstream: DC category 0 + AC EOB = "0 0" packed MSB-first = 0x00. 5// All coefficients zero -> IDCT all zeros -> level shift -> 128. 6// Expected output plane: 8x8 of 128. 7// 8// expect_exit: 0 9// license_tier: ORIGINAL 10 11import "nx_syscalls.nx" 12import "nx_jpeg_sof.nx" 13import "nx_jpeg_sos.nx" 14import "nx_jpeg_dqt.nx" 15import "nx_jpeg_dht.nx" 16import "nx_jpeg_mcu.nx" 17import "nx_jpeg_decode_image.nx" 18 19func _fail(n: i64) -> i64 { 20 let b: *u8 = sys_mmap(16) 21 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D 22 sys_write(2, b, 5) 23 var x: i64 = n 24 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x } 25 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) } 26 else { 27 let buf: *u8 = sys_mmap(16) 28 var pos: i64 = 0 29 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 } 30 let out: *u8 = sys_mmap(16) 31 var i: i64 = 0 32 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 } 33 sys_write(2, out, pos) 34 } 35 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1) 36 return 0 37} 38 39func main() -> i64 { 40 // ============================================================ 41 // Build SOF: 1 component, 8x8, P=8, Y=8, X=8, comp{id=1, H=V=1, Tq=0} 42 // ============================================================ 43 let sof_payload: *u8 = sys_mmap(16) 44 sof_payload[0] = 8 45 sof_payload[1] = 0; sof_payload[2] = 8 // Y=8 46 sof_payload[3] = 0; sof_payload[4] = 8 // X=8 47 sof_payload[5] = 1 // Nf=1 48 sof_payload[6] = 1; sof_payload[7] = 0x11; sof_payload[8] = 0 49 50 let frame: *NxJpegFrame = sys_mmap(NX_JPEG_FRAME_BYTES) as *NxJpegFrame 51 let sof_comps: *NxJpegSofComponent = sys_mmap(NX_JPEG_SOF_COMP_BYTES * 4) as *NxJpegSofComponent 52 frame.components = sof_comps 53 if nx_jpeg_sof_parse(sof_payload, 9, frame) != NX_JPEG_SOF_OK { _fail(1); return 1 } 54 55 // ============================================================ 56 // Build SOS: 1 component, Cs=1, Td=0 Ta=0, Ss=0 Se=63 AhAl=0 57 // ============================================================ 58 let sos_payload: *u8 = sys_mmap(16) 59 sos_payload[0] = 1 60 sos_payload[1] = 1; sos_payload[2] = 0x00 61 sos_payload[3] = 0; sos_payload[4] = 63; sos_payload[5] = 0 62 63 let scan: *NxJpegScan = sys_mmap(NX_JPEG_SCAN_BYTES) as *NxJpegScan 64 let sos_comps: *NxJpegSosComponent = sys_mmap(NX_JPEG_SOS_COMP_BYTES * 4) as *NxJpegSosComponent 65 scan.components = sos_comps 66 if nx_jpeg_sos_parse(sos_payload, 6, scan) != NX_JPEG_SOS_OK { _fail(2); return 2 } 67 68 // ============================================================ 69 // Build DQT: 1 table, Tq=0 Pq=0, all 64 values = 1 (identity) 70 // ============================================================ 71 let dqt_payload: *u8 = sys_mmap(128) 72 dqt_payload[0] = 0 73 var i: i64 = 0 74 while i < 64 { dqt_payload[1 + i] = 1; i = i + 1 } 75 76 let qtables: *NxJpegQTable = sys_mmap(NX_JPEG_QTABLE_BYTES * 4) as *NxJpegQTable 77 let qvalue_bufs: *i64 = sys_mmap(4 * 64 * 8) as *i64 78 let qcount_p: *i64 = sys_mmap(8) as *i64 79 if nx_jpeg_dqt_parse(dqt_payload, 65, qtables, qvalue_bufs, qcount_p) != NX_JPEG_DQT_OK { _fail(3); return 3 } 80 if qcount_p[0] != 1 { _fail(4); return 4 } 81 82 // ============================================================ 83 // Build DHT: 2 tables stacked (DC tc=0/th=0, AC tc=1/th=0) 84 // DC BITS={1,0...}, HUFFVAL={0} -> sym 0 = "0" 85 // AC BITS={1,0...}, HUFFVAL={0x00} -> sym 0 = "0" EOB 86 // ============================================================ 87 let dht_payload: *u8 = sys_mmap(128) 88 dht_payload[0] = 0x00 // DC tc=0 th=0 89 dht_payload[1] = 1 90 i = 2 91 while i <= 16 { dht_payload[i] = 0; i = i + 1 } 92 dht_payload[17] = 0 93 dht_payload[18] = 0x10 // AC tc=1 th=0 94 dht_payload[19] = 1 95 i = 20 96 while i <= 34 { dht_payload[i] = 0; i = i + 1 } 97 dht_payload[35] = 0x00 98 99 let htables: *NxJpegHTable = sys_mmap(NX_JPEG_HTABLE_BYTES * 4) as *NxJpegHTable 100 let hbits: *i64 = sys_mmap(4 * 17 * 8) as *i64 101 let hhv: *i64 = sys_mmap(4 * 256 * 8) as *i64 102 let hmc: *i64 = sys_mmap(4 * 17 * 8) as *i64 103 let hxc: *i64 = sys_mmap(4 * 17 * 8) as *i64 104 let hvp: *i64 = sys_mmap(4 * 17 * 8) as *i64 105 let hcount_p: *i64 = sys_mmap(8) as *i64 106 if nx_jpeg_dht_parse(dht_payload, 36, htables, hbits, hhv, hmc, hxc, hvp, hcount_p) != NX_JPEG_DHT_OK { _fail(5); return 5 } 107 if hcount_p[0] != 2 { _fail(6); return 6 } 108 109 // ============================================================ 110 // Entropy bytes: 0x00 = "0 0" = DC cat 0 + AC EOB 111 // ============================================================ 112 let ent: *u8 = sys_mmap(8) 113 ent[0] = 0x00 114 ent[1] = 0x00 115 116 let bs: *NxJpegBitStream = sys_mmap(NX_JPEG_BITSTREAM_BYTES) as *NxJpegBitStream 117 bs.src = ent 118 bs.src_end = 2 119 bs.byte_idx = 0 120 bs.bit_off = 0 121 122 // ============================================================ 123 // Output planes: 1 plane (8x8 grayscale), init to 0xFF. 124 // The decoder expects a `planes` packed array of *u8. 125 // ============================================================ 126 let plane: *u8 = sys_mmap(64) 127 i = 0 128 while i < 64 { plane[i] = 0xFF; i = i + 1 } 129 let planes_arr: *i64 = sys_mmap(8) as *i64 130 planes_arr[0] = plane as i64 131 let strides: *i64 = sys_mmap(8) as *i64 132 strides[0] = 8 133 134 // Scratch + state. 135 let sc: *NxJpegMcuScratch = sys_mmap(NX_JPEG_MCU_SCRATCH_BYTES) as *NxJpegMcuScratch 136 nx_jpeg_mcu_scratch_init(sc) 137 let cstates: *NxJpegDecCompState = sys_mmap(NX_JPEG_DEC_COMPSTATE_BYTES * 4) as *NxJpegDecCompState 138 139 // Resolve per-component tables/planes. 140 let rc_res: i64 = nx_jpeg_decode_image_resolve(frame, scan, 141 qtables, 1, 142 htables, 2, 143 planes_arr as *u8, strides, 144 cstates) 145 if rc_res != NX_JPEG_DEC_OK { _fail(10 + rc_res); return 10 } 146 147 // Walk MCUs. 148 let rc_walk: i64 = nx_jpeg_decode_image_walk_mcus(frame, scan, cstates, bs, sc) 149 if rc_walk != NX_JPEG_DEC_OK { _fail(20 + rc_walk); return 20 } 150 151 // Verify plane is all 128. 152 i = 0 153 while i < 64 { 154 if plane[i] != 128 { _fail(30 + i); return 30 } 155 i = i + 1 156 } 157 158 let pass: *u8 = sys_mmap(16) 159 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A 160 sys_write(1, pass, 5) 161 return 0 162}