code wiki / (root) / nx_jpeg_entropy_test.nx

nx_jpeg_entropy_test.nx source

↩ module page · 154 lines · 5976 B

1// nx_jpeg_entropy_test.nx -- KAT for baseline JPEG entropy decoder. 2// 3// Designs hand-built Huffman tables + a known bitstream that should 4// decode to a specific 64-entry zig-zag-ordered block, then verifies. 5// 6// Tables: 7// DC: BITS={1,1,1,0,...}, HUFFVAL={0,1,2} 8// symbol 0 = code "0" (1 bit) 9// symbol 1 = code "10" (2 bits) 10// symbol 2 = code "110" (3 bits) 11// AC: BITS={2,0,...}, HUFFVAL={0x00, 0x01} 12// symbol 0x00 = code "0" (EOB) 13// symbol 0x01 = code "1" (run=0 size=1) 14// 15// Block 1: DC=+1, AC[1]=+1, EOB. 16// DC stream: symbol 1 "10" + 1 mag bit "1" = "101" 17// AC stream: symbol 0x01 "1" + 1 mag bit "1" = "11" 18// EOB: symbol 0x00 "0" = "0" 19// total: "101110" = 6 bits 20// 21// Block 2: DC delta=+3 (prev_dc was 1, want 4), then EOB. 22// DC stream: symbol 2 "110" + 2 mag bits "11" = "11011" 23// EOB: symbol 0x00 "0" = "0" 24// total: "110110" = 6 bits 25// 26// Combined 12 bits, packed MSB-first: 27// byte 0 = 0b10111011 = 0xBB 28// byte 1 = 0b01100000 = 0x60 29// 30// expect_exit: 0 31// license_tier: ORIGINAL 32 33import "nx_syscalls.nx" 34import "nx_jpeg_dht.nx" 35import "nx_jpeg_entropy.nx" 36 37func _fail(n: i64) -> i64 { 38 let b: *u8 = sys_mmap(16) 39 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D 40 sys_write(2, b, 5) 41 var x: i64 = n 42 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x } 43 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) } 44 else { 45 let buf: *u8 = sys_mmap(16) 46 var pos: i64 = 0 47 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 } 48 let out: *u8 = sys_mmap(16) 49 var i: i64 = 0 50 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 } 51 sys_write(2, out, pos) 52 } 53 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1) 54 return 0 55} 56 57func main() -> i64 { 58 // ============================================================ 59 // Section A: EXTEND() spot checks per T.81 Fig F.12 60 // ============================================================ 61 // EXTEND(0b00, t=1): raw 0 < 2^0=1 ? yes -> 0 - (2-1) = -1 62 if nx_jpeg_ent_extend(0, 1) != (0 - 1) { _fail(1); return 1 } 63 // EXTEND(1, t=1): 1 < 1 ? no -> 1 64 if nx_jpeg_ent_extend(1, 1) != 1 { _fail(2); return 2 } 65 // EXTEND(0, t=2): 0 < 2 ? yes -> 0 - 3 = -3 66 if nx_jpeg_ent_extend(0, 2) != (0 - 3) { _fail(3); return 3 } 67 // EXTEND(2, t=2): 2 < 2 ? no -> 2 68 if nx_jpeg_ent_extend(2, 2) != 2 { _fail(4); return 4 } 69 // EXTEND(3, t=2): 3 < 2 ? no -> 3 70 if nx_jpeg_ent_extend(3, 2) != 3 { _fail(5); return 5 } 71 // EXTEND(0, t=0) = 0 72 if nx_jpeg_ent_extend(0, 0) != 0 { _fail(6); return 6 } 73 74 // ============================================================ 75 // Section B: build DC + AC Huffman tables via nx_jpeg_dht_parse 76 // ============================================================ 77 let tables: *NxJpegHTable = sys_mmap(NX_JPEG_HTABLE_BYTES * 4) as *NxJpegHTable 78 let bits_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 79 let hv_pool: *i64 = sys_mmap(4 * 256 * 8) as *i64 80 let mc_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 81 let xc_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 82 let vp_pool: *i64 = sys_mmap(4 * 17 * 8) as *i64 83 let count_p: *i64 = sys_mmap(8) as *i64 84 85 // DHT payload: DC table + AC table stacked. 86 let pld: *u8 = sys_mmap(128) 87 // DC: tc=0, th=0, BITS={1,1,1,0,...}, HUFFVAL={0,1,2} 88 pld[0] = 0x00 89 pld[1] = 1; pld[2] = 1; pld[3] = 1 90 var i: i64 = 4 91 while i <= 16 { pld[i] = 0; i = i + 1 } 92 pld[17] = 0; pld[18] = 1; pld[19] = 2 93 // AC: tc=1, th=0, BITS={2,0,...}, HUFFVAL={0x00, 0x01} 94 pld[20] = 0x10 95 pld[21] = 2 96 i = 22 97 while i <= 36 { pld[i] = 0; i = i + 1 } 98 pld[37] = 0x00 99 pld[38] = 0x01 100 101 let rc_p: i64 = nx_jpeg_dht_parse(pld, 39, tables, bits_pool, hv_pool, mc_pool, xc_pool, vp_pool, count_p) 102 if rc_p != NX_JPEG_DHT_OK { _fail(10); return 10 } 103 if count_p[0] != 2 { _fail(11); return 11 } 104 105 let dc_table: *NxJpegHTable = tables 106 let ac_table: *NxJpegHTable = (tables as i64 + NX_JPEG_HTABLE_BYTES) as *NxJpegHTable 107 108 // ============================================================ 109 // Section C: decode 2 blocks from a hand-packed bitstream. 110 // ============================================================ 111 let stream: *u8 = sys_mmap(8) 112 stream[0] = 0xBB 113 stream[1] = 0x60 114 115 let bit_off_p: *i64 = sys_mmap(8) as *i64 116 let byte_idx_p: *i64 = sys_mmap(8) as *i64 117 bit_off_p[0] = 0 118 byte_idx_p[0] = 0 119 120 let prev_dc_p: *i64 = sys_mmap(8) as *i64 121 prev_dc_p[0] = 0 122 123 let block: *i64 = sys_mmap(64 * 8) as *i64 124 125 // Block 1: expect DC=+1, AC[1]=+1, rest=0. 126 let rc1: i64 = nx_jpeg_ent_decode_block(dc_table, ac_table, prev_dc_p, 127 block, stream, bit_off_p, byte_idx_p, 2) 128 if rc1 != NX_JPEG_ENT_OK { _fail(20); return 20 } 129 if block[0] != 1 { _fail(21); return 21 } 130 if block[1] != 1 { _fail(22); return 22 } 131 var k: i64 = 2 132 while k < 64 { 133 if block[k] != 0 { _fail(23 + k); return 23 } 134 k = k + 1 135 } 136 if prev_dc_p[0] != 1 { _fail(100); return 100 } 137 138 // Block 2: expect DC=+4 (delta=+3 from prev=1), rest=0. 139 let rc2: i64 = nx_jpeg_ent_decode_block(dc_table, ac_table, prev_dc_p, 140 block, stream, bit_off_p, byte_idx_p, 2) 141 if rc2 != NX_JPEG_ENT_OK { _fail(110); return 110 } 142 if block[0] != 4 { _fail(111); return 111 } 143 k = 1 144 while k < 64 { 145 if block[k] != 0 { _fail(112 + k); return 112 } 146 k = k + 1 147 } 148 if prev_dc_p[0] != 4 { _fail(200); return 200 } 149 150 let pass: *u8 = sys_mmap(16) 151 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A 152 sys_write(1, pass, 5) 153 return 0 154}