code wiki / (root) / nx_jpeg_mcu_test.nx

nx_jpeg_mcu_test.nx source

↩ module page · 127 lines · 4306 B

1// nx_jpeg_mcu_test.nx -- KAT for the MCU walker. 2// 3// Strategy: minimal grayscale 8x8 image (1 MCU, 1 block, 1 component). 4// 5// Bitstream design: DC category 0 -> "0" + no magnitude bits. Then 6// AC EOB -> "0". Total 2 bits: 0b00000000 = 0x00. 7// 8// Expected output: all 64 IDCT samples are 0 (since all coefficients 9// are 0), then level-shift +128 -> all samples = 128. Plane should 10// have all 128s in the 8x8 region. 11// 12// Huffman tables: 13// DC: BITS={1,0,...}, HUFFVAL={0}. symbol 0 = code "0" (1 bit) 14// AC: BITS={1,0,...}, HUFFVAL={0x00}. symbol 0x00 = code "0" (1 bit) EOB 15// 16// expect_exit: 0 17// license_tier: ORIGINAL 18 19import "nx_syscalls.nx" 20import "nx_jpeg_dht.nx" 21import "nx_jpeg_mcu.nx" 22import "nx_jpeg_idct.nx" 23import "nx_jpeg_sof.nx" 24 25func _fail(n: i64) -> i64 { 26 let b: *u8 = sys_mmap(16) 27 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D 28 sys_write(2, b, 5) 29 var x: i64 = n 30 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x } 31 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) } 32 else { 33 let buf: *u8 = sys_mmap(16) 34 var pos: i64 = 0 35 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 } 36 let out: *u8 = sys_mmap(16) 37 var i: i64 = 0 38 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 } 39 sys_write(2, out, pos) 40 } 41 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1) 42 return 0 43} 44 45func main() -> i64 { 46 // ---- Build DC + AC Huffman tables ---- 47 let tables: *NxJpegHTable = sys_mmap(NX_JPEG_HTABLE_BYTES * 4) as *NxJpegHTable 48 let bits_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 49 let hv_pool: *i64 = sys_mmap(4 * 256 * 8) as *i64 50 let mc_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 51 let xc_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 52 let vp_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 53 let count_p: *i64 = sys_mmap(8) as *i64 54 55 let pld: *u8 = sys_mmap(128) 56 // DC: Tc=0 Th=0, BITS={1, 0...}, HUFFVAL={0} 57 pld[0] = 0x00 58 pld[1] = 1 59 var i: i64 = 2 60 while i <= 16 { pld[i] = 0; i = i + 1 } 61 pld[17] = 0 62 // AC: Tc=1 Th=0, BITS={1, 0...}, HUFFVAL={0x00} 63 pld[18] = 0x10 64 pld[19] = 1 65 i = 20 66 while i <= 34 { pld[i] = 0; i = i + 1 } 67 pld[35] = 0x00 68 69 let rc_p: i64 = nx_jpeg_dht_parse(pld, 36, tables, bits_pool, hv_pool, mc_pool, xc_pool, vp_pool, count_p) 70 if rc_p != NX_JPEG_DHT_OK { _fail(1); return 1 } 71 if count_p[0] != 2 { _fail(2); return 2 } 72 73 let dc_table: *NxJpegHTable = tables 74 let ac_table: *NxJpegHTable = (tables as i64 + NX_JPEG_HTABLE_BYTES) as *NxJpegHTable 75 76 // ---- Quantization table: identity (all 1s) ---- 77 let qt: *i64 = sys_mmap(64 * 8) as *i64 78 i = 0 79 while i < 64 { qt[i] = 1; i = i + 1 } 80 81 // ---- Bitstream: 0x00 = "0 0" = DC sym 0 (cat 0) + AC EOB ---- 82 let stream: *u8 = sys_mmap(8) 83 stream[0] = 0x00 84 stream[1] = 0x00 85 86 // ---- Bitstream cursor (struct API) ---- 87 let bs: *NxJpegBitStream = sys_mmap(NX_JPEG_BITSTREAM_BYTES) as *NxJpegBitStream 88 bs.src = stream 89 bs.src_end = 2 90 bs.byte_idx = 0 91 bs.bit_off = 0 92 93 let prev_dc_p: *i64 = sys_mmap(8) as *i64 94 prev_dc_p[0] = 0 95 96 // ---- Output plane: 8x8 u8, init to 0xFF to verify writes ---- 97 let plane: *u8 = sys_mmap(64) 98 i = 0 99 while i < 64 { plane[i] = 0xFF; i = i + 1 } 100 101 // ---- Scratch context (cosine table + 3 i64 64-entry buffers) ---- 102 let sc: *NxJpegMcuScratch = sys_mmap(NX_JPEG_MCU_SCRATCH_BYTES) as *NxJpegMcuScratch 103 nx_jpeg_mcu_scratch_init(sc) 104 105 // ---- Decode one block at (0, 0) ---- 106 let rc: i64 = nx_jpeg_mcu_decode_one_block( 107 dc_table, ac_table, qt, prev_dc_p, 108 bs, plane, 8, 0, 0, sc) 109 if rc != NX_JPEG_MCU_OK { _fail(10 + rc); return 10 } 110 111 // ---- Verify: all 64 plane bytes are 128 (level-shift of zero block) ---- 112 var k: i64 = 0 113 while k < 64 { 114 if plane[k] != 128 { 115 _fail(20 + k); return 20 116 } 117 k = k + 1 118 } 119 120 // ---- Verify prev_dc was updated to 0 (DC delta was 0) ---- 121 if prev_dc_p[0] != 0 { _fail(100); return 100 } 122 123 let pass: *u8 = sys_mmap(16) 124 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A 125 sys_write(1, pass, 5) 126 return 0 127}