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}