code wiki / (root) / nx_jpeg_dequant_test.nx

nx_jpeg_dequant_test.nx source

↩ module page · 122 lines · 4375 B

1// nx_jpeg_dequant_test.nx -- KAT for dequant + un-zigzag composer. 2// 3// Construction: 4// zz_coeffs[k] = k (0, 1, 2, ..., 63) 5// quant_zz[k] = k + 1 (1, 2, 3, ..., 64) 6// natural[un_zigzag[k]] = zz_coeffs[k] * quant_zz[k] = k * (k + 1) 7// 8// Cross-check against the published un_zigzag table for the first 9// few positions: 10// k=0 -> nat[0] = 0 * 1 = 0 11// k=1 -> nat[1] = 1 * 2 = 2 12// k=2 -> nat[8] = 2 * 3 = 6 13// k=3 -> nat[16] = 3 * 4 = 12 14// k=4 -> nat[9] = 4 * 5 = 20 15// k=5 -> nat[2] = 5 * 6 = 30 16// ... 17// 18// Also: end-to-end composition with the entropy decoder's output 19// shape (zero-padded zig-zag block) yields a sparse natural block 20// at the expected natural positions. 21// 22// expect_exit: 0 23// license_tier: ORIGINAL 24 25import "nx_syscalls.nx" 26import "nx_jpeg_zigzag.nx" 27import "nx_jpeg_dequant.nx" 28 29func _fail(n: i64) -> i64 { 30 let b: *u8 = sys_mmap(16) 31 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D 32 sys_write(2, b, 5) 33 var x: i64 = n 34 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x } 35 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) } 36 else { 37 let buf: *u8 = sys_mmap(16) 38 var pos: i64 = 0 39 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 } 40 let out: *u8 = sys_mmap(16) 41 var i: i64 = 0 42 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 } 43 sys_write(2, out, pos) 44 } 45 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1) 46 return 0 47} 48 49func main() -> i64 { 50 let table: *i64 = sys_mmap(64 * 8) as *i64 51 nx_jpeg_zigzag_inverse_table(table) 52 53 // ============================================================ 54 // Section A: full sweep. Each zig-zag position k holds k, each 55 // quantization value holds (k+1); product = k * (k+1) at natural 56 // position un_zigzag[k]. 57 // ============================================================ 58 let zz: *i64 = sys_mmap(64 * 8) as *i64 59 let quant: *i64 = sys_mmap(64 * 8) as *i64 60 let nat: *i64 = sys_mmap(64 * 8) as *i64 61 var k: i64 = 0 62 while k < 64 { 63 zz[k] = k 64 quant[k] = k + 1 65 nat[k] = 0 // zero-init so we can confirm WRITES happened 66 k = k + 1 67 } 68 nx_jpeg_dequant_un_zigzag(zz, quant, nat) 69 70 k = 0 71 while k < 64 { 72 let expected: i64 = k * (k + 1) 73 let got: i64 = nat[table[k]] 74 if got != expected { _fail(1 + k); return 1 } 75 k = k + 1 76 } 77 78 // ============================================================ 79 // Section B: DC-only block (typical from EOB-right-after-DC 80 // entropy output). zz[0] != 0, rest zero. natural should 81 // have natural[0] = zz[0] * quant[0], rest zero. 82 // ============================================================ 83 k = 0 84 while k < 64 { zz[k] = 0; quant[k] = 5; nat[k] = 0; k = k + 1 } 85 zz[0] = 7 86 nx_jpeg_dequant_un_zigzag(zz, quant, nat) 87 if nat[0] != 35 { _fail(70); return 70 } 88 k = 1 89 while k < 64 { 90 if nat[k] != 0 { _fail(71); return 71 } 91 k = k + 1 92 } 93 94 // ============================================================ 95 // Section C: AC-at-zz[1] block. zz[1] is the second zig-zag 96 // coefficient; un_zigzag[1] = 1 (i.e., natural-position 1, the 97 // "AC top-right of DC" in row-major). Quant[1] = 2. 98 // zz[1] = 9; natural[1] should be 18, all others 0. 99 // ============================================================ 100 k = 0 101 while k < 64 { zz[k] = 0; quant[k] = 2; nat[k] = 0; k = k + 1 } 102 zz[1] = 9 103 nx_jpeg_dequant_un_zigzag(zz, quant, nat) 104 if nat[1] != 18 { _fail(80); return 80 } 105 if nat[0] != 0 { _fail(81); return 81 } 106 107 // ============================================================ 108 // Section D: AC-at-zz[2] -> natural-position 8 (start of row 1). 109 // ============================================================ 110 k = 0 111 while k < 64 { zz[k] = 0; quant[k] = 3; nat[k] = 0; k = k + 1 } 112 zz[2] = 4 113 nx_jpeg_dequant_un_zigzag(zz, quant, nat) 114 if nat[8] != 12 { _fail(90); return 90 } 115 if nat[0] != 0 { _fail(91); return 91 } 116 if nat[1] != 0 { _fail(92); return 92 } 117 118 let pass: *u8 = sys_mmap(16) 119 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A 120 sys_write(1, pass, 5) 121 return 0 122}