code wiki / (root) / nx_jpeg_idct_test.nx

nx_jpeg_idct_test.nx source

↩ module page · 98 lines · 3797 B

1// nx_jpeg_idct_test.nx -- KAT for 8x8 inverse DCT. 2// 3// Test cases: 4// A. DC-only block: F[0,0]=N, all other coeffs 0 -> flat output N/8. 5// B. Single high-frequency coeff via dc_only_block helper sanity. 6// C. cosine table bijection-ish spot checks. 7// 8// Substrate-honesty: this KAT does NOT yet do a 64-coefficient 9// IEEE-1180 conformance test; that requires comparison against a 10// reference implementation per sec 4.1 of IEEE 1180 and is queued 11// once the full decode pipeline can ingest a JPEG and we have 12// libjpeg reference output to diff against. 13// 14// expect_exit: 0 15// license_tier: ORIGINAL 16 17import "nx_syscalls.nx" 18import "nx_jpeg_idct.nx" 19 20func _fail(n: i64) -> i64 { 21 let b: *u8 = sys_mmap(16) 22 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D 23 sys_write(2, b, 5) 24 var x: i64 = n 25 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x } 26 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) } 27 else { 28 let buf: *u8 = sys_mmap(16) 29 var pos: i64 = 0 30 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 } 31 let out: *u8 = sys_mmap(16) 32 var i: i64 = 0 33 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 } 34 sys_write(2, out, pos) 35 } 36 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1) 37 return 0 38} 39 40func main() -> i64 { 41 let cos_tbl: *i64 = sys_mmap(64 * 8) as *i64 42 nx_jpeg_idct_init_cos_table(cos_tbl) 43 44 // ============================================================ 45 // Section A: cosine-table spot checks. 46 // ============================================================ 47 if cos_tbl[0] != 4096 { _fail(1); return 1 } // (x=0,u=0) = cos(0) = 1 48 if cos_tbl[1] != 4017 { _fail(2); return 2 } // cos(pi/16) 49 if cos_tbl[4] != 2896 { _fail(3); return 3 } // cos(4pi/16) = cos(pi/4) 50 if cos_tbl[7] != 799 { _fail(4); return 4 } // cos(7pi/16) 51 // Row 7 col 0: cos((15)*0*pi/16) = cos(0) = 1 -> 4096 52 if cos_tbl[7*8+0] != 4096 { _fail(5); return 5 } 53 // Row 7 col 1: cos(15 pi / 16) = -cos(pi/16) = -4017 54 if cos_tbl[7*8+1] != (0 - 4017) { _fail(6); return 6 } 55 56 // ============================================================ 57 // Section B: dc_only_block helper sanity. 58 // F[0,0]=80 -> samples all equal 10. 59 // ============================================================ 60 let samples: *i64 = sys_mmap(64 * 8) as *i64 61 nx_jpeg_idct_dc_only_block(80, samples) 62 var k: i64 = 0 63 while k < 64 { 64 if samples[k] != 10 { _fail(10 + k); return 10 } 65 k = k + 1 66 } 67 68 // ============================================================ 69 // Section C: DC-only block via full IDCT (should match helper). 70 // coeffs = [80, 0, 0, ..., 0] 71 // ============================================================ 72 let coeffs: *i64 = sys_mmap(64 * 8) as *i64 73 k = 0 74 while k < 64 { coeffs[k] = 0; k = k + 1 } 75 coeffs[0] = 80 76 77 let out: *i64 = sys_mmap(64 * 8) as *i64 78 nx_jpeg_idct_8x8(coeffs, out, cos_tbl) 79 80 // All samples should be approximately 10. Allow off-by-1 due to 81 // fixed-point rounding (cosine table is rounded to 12 fractional 82 // bits; 2896/4096 ~= 0.70703 vs true 1/sqrt(2) = 0.70711). 83 k = 0 84 while k < 64 { 85 let v: i64 = out[k] 86 var ok: i64 = 0 87 if v == 9 { ok = 1 } 88 if v == 10 { ok = 1 } 89 if v == 11 { ok = 1 } 90 if ok != 1 { _fail(80 + k); return 80 } 91 k = k + 1 92 } 93 94 let pass: *u8 = sys_mmap(16) 95 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A 96 sys_write(1, pass, 5) 97 return 0 98}