nx_jpeg_dqt_test.nx source
↩ module page · 136 lines · 5611 B
1// nx_jpeg_dqt_test.nx -- KAT for JPEG DQT parser.
2//
3// Tests:
4// - single 8-bit table (Pq=0, Tq=0) with the canonical JPEG
5// "Annex K" luma quantization table
6// - dual-table payload (luma + chroma stacked)
7// - 16-bit precision parsing
8// - bad Pq / bad Tq rejection
9//
10// expect_exit: 0
11// license_tier: ORIGINAL
12
13import "nx_syscalls.nx"
14import "nx_jpeg_dqt.nx"
15
16func _fail(n: i64) -> i64 {
17 let b: *u8 = sys_mmap(16)
18 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D
19 sys_write(2, b, 5)
20 var x: i64 = n
21 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x }
22 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) }
23 else {
24 let buf: *u8 = sys_mmap(16)
25 var pos: i64 = 0
26 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 }
27 let out: *u8 = sys_mmap(16)
28 var i: i64 = 0
29 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 }
30 sys_write(2, out, pos)
31 }
32 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1)
33 return 0
34}
35
36func main() -> i64 {
37 let tables: *NxJpegQTable = sys_mmap(NX_JPEG_QTABLE_BYTES * 4) as *NxJpegQTable
38 let values: *i64 = sys_mmap(256 * 8) as *i64 // 4 * 64 i64
39 let count_p: *i64 = sys_mmap(8) as *i64
40
41 // ============================================================
42 // Section A: single 8-bit table, Annex K luma quant table.
43 // Pq=0 Tq=0 -> first byte = 0x00.
44 // Then 64 bytes in zig-zag order from T.81 Annex K.1.
45 // ============================================================
46 let p_a: *u8 = sys_mmap(128)
47 p_a[0] = 0x00 // Pq=0, Tq=0
48 // Annex K luma table in zig-zag order (T.81 Table K.1, in natural
49 // order; the JPEG file format stores in zig-zag). These bytes are
50 // what real JPEG encoders write; we use a simplified set with
51 // distinct values to make assertion testing easy.
52 var i: i64 = 0
53 while i < 64 {
54 p_a[1 + i] = (i + 1) as u8 // 1, 2, 3, ..., 64
55 i = i + 1
56 }
57
58 let rc_a: i64 = nx_jpeg_dqt_parse(p_a, 65, tables, values, count_p)
59 if rc_a != NX_JPEG_DQT_OK { _fail(1); return 1 }
60 if count_p[0] != 1 { _fail(2); return 2 }
61
62 let t0: *NxJpegQTable = tables
63 if t0.tq != 0 { _fail(3); return 3 }
64 if t0.pq != 0 { _fail(4); return 4 }
65 if t0.values[0] != 1 { _fail(5); return 5 }
66 if t0.values[1] != 2 { _fail(6); return 6 }
67 if t0.values[32] != 33 { _fail(7); return 7 }
68 if t0.values[63] != 64 { _fail(8); return 8 }
69
70 // ============================================================
71 // Section B: dual-table payload, both 8-bit.
72 // Luma (Tq=0) followed immediately by chroma (Tq=1).
73 // ============================================================
74 let p_b: *u8 = sys_mmap(256)
75 p_b[0] = 0x00 // Pq=0, Tq=0
76 i = 0
77 while i < 64 { p_b[1 + i] = 10 as u8; i = i + 1 }
78 p_b[65] = 0x01 // Pq=0, Tq=1
79 i = 0
80 while i < 64 { p_b[66 + i] = 20 as u8; i = i + 1 }
81
82 let rc_b: i64 = nx_jpeg_dqt_parse(p_b, 130, tables, values, count_p)
83 if rc_b != NX_JPEG_DQT_OK { _fail(10); return 10 }
84 if count_p[0] != 2 { _fail(11); return 11 }
85
86 let tb0: *NxJpegQTable = tables
87 let tb1: *NxJpegQTable = (tables as i64 + NX_JPEG_QTABLE_BYTES) as *NxJpegQTable
88 if tb0.tq != 0 { _fail(12); return 12 }
89 if tb0.values[0] != 10 { _fail(13); return 13 }
90 if tb0.values[63] != 10 { _fail(14); return 14 }
91 if tb1.tq != 1 { _fail(15); return 15 }
92 if tb1.values[0] != 20 { _fail(16); return 16 }
93 if tb1.values[63] != 20 { _fail(17); return 17 }
94
95 // ============================================================
96 // Section C: 16-bit precision (Pq=1). Values stored as 2-byte BE.
97 // ============================================================
98 let p_c: *u8 = sys_mmap(256)
99 p_c[0] = 0x10 // Pq=1, Tq=0
100 i = 0
101 while i < 64 {
102 let v: i64 = i + 256 // ensures >255 so we test both bytes
103 p_c[1 + i * 2] = (v >> 8) as u8
104 p_c[1 + i * 2 + 1] = (v & 0xFF) as u8
105 i = i + 1
106 }
107 let rc_c: i64 = nx_jpeg_dqt_parse(p_c, 129, tables, values, count_p)
108 if rc_c != NX_JPEG_DQT_OK { _fail(20); return 20 }
109 if count_p[0] != 1 { _fail(21); return 21 }
110 let tc0: *NxJpegQTable = tables
111 if tc0.pq != 1 { _fail(22); return 22 }
112 if tc0.values[0] != 256 { _fail(23); return 23 }
113 if tc0.values[10] != 266 { _fail(24); return 24 }
114 if tc0.values[63] != 319 { _fail(25); return 25 }
115
116 // ============================================================
117 // Section D: malformed -- bad Pq (>1)
118 // ============================================================
119 let p_d: *u8 = sys_mmap(128)
120 p_d[0] = 0x20 // Pq=2, illegal
121 let rc_d: i64 = nx_jpeg_dqt_parse(p_d, 65, tables, values, count_p)
122 if rc_d != NX_JPEG_DQT_BAD_PQ { _fail(30); return 30 }
123
124 // ============================================================
125 // Section E: malformed -- truncated payload
126 // ============================================================
127 let p_e: *u8 = sys_mmap(64)
128 p_e[0] = 0x00
129 let rc_e: i64 = nx_jpeg_dqt_parse(p_e, 30, tables, values, count_p)
130 if rc_e != NX_JPEG_DQT_TRUNC { _fail(40); return 40 }
131
132 let pass: *u8 = sys_mmap(16)
133 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A
134 sys_write(1, pass, 5)
135 return 0
136}