nx_jpeg_decode_test.nx source
↩ module page · 127 lines · 4586 B
1// nx_jpeg_decode_test.nx -- KAT for top-level baseline-JPEG decoder.
2//
3// Constructs a minimal grayscale 8x8 JPEG byte-by-byte (137 bytes)
4// then decodes it end-to-end via nx_jpeg_decode. Verifies the
5// output plane is all 128 (zero-coefficient block + level shift).
6//
7// JPEG byte layout:
8// FF D8 SOI
9// FF DB 00 43 00 + 64x01 DQT (Pq=0 Tq=0, all-ones identity quant)
10// FF C4 00 26 DHT (DC + AC stacked, 36-byte payload)
11// 00 01 00...00 00 DC: tc=0 th=0, BITS={1,0...0}, HUFFVAL={0}
12// 10 01 00...00 00 AC: tc=1 th=0, BITS={1,0...0}, HUFFVAL={0}
13// FF C0 00 0B SOF0 (1 comp, 8x8)
14// 08 00 08 00 08 01 01 11 00
15// FF DA 00 08 SOS (1 comp)
16// 01 01 00 00 3F 00
17// 00 entropy: DC cat 0 + AC EOB
18// FF D9 EOI
19//
20// expect_exit: 0
21// license_tier: ORIGINAL
22
23import "nx_syscalls.nx"
24import "nx_jpeg_decode.nx"
25
26func _fail(n: i64) -> i64 {
27 let b: *u8 = sys_mmap(16)
28 b[0]=0x46; b[1]=0x41; b[2]=0x49; b[3]=0x4C; b[4]=0x3D
29 sys_write(2, b, 5)
30 var x: i64 = n
31 if x < 0 { let m: *u8 = sys_mmap(4); m[0]=0x2D; sys_write(2, m, 1); x = 0 - x }
32 if x == 0 { let z: *u8 = sys_mmap(4); z[0]=0x30; sys_write(2, z, 1) }
33 else {
34 let buf: *u8 = sys_mmap(16)
35 var pos: i64 = 0
36 while x > 0 { buf[pos] = (0x30 + (x % 10)) as u8; x = x / 10; pos = pos + 1 }
37 let out: *u8 = sys_mmap(16)
38 var i: i64 = 0
39 while i < pos { out[i] = buf[pos - 1 - i]; i = i + 1 }
40 sys_write(2, out, pos)
41 }
42 let nl: *u8 = sys_mmap(4); nl[0]=0x0A; sys_write(2, nl, 1)
43 return 0
44}
45
46func main() -> i64 {
47 let jpeg: *u8 = sys_mmap(256)
48 var p: i64 = 0
49 // SOI
50 jpeg[p]=0xFF; p=p+1; jpeg[p]=0xD8; p=p+1
51 // DQT
52 jpeg[p]=0xFF; p=p+1; jpeg[p]=0xDB; p=p+1
53 jpeg[p]=0x00; p=p+1; jpeg[p]=0x43; p=p+1 // len 67
54 jpeg[p]=0x00; p=p+1 // Pq=0 Tq=0
55 var i: i64 = 0
56 while i < 64 { jpeg[p+i] = 1; i = i + 1 }
57 p = p + 64
58 // DHT (DC + AC stacked, 36 bytes)
59 jpeg[p]=0xFF; p=p+1; jpeg[p]=0xC4; p=p+1
60 jpeg[p]=0x00; p=p+1; jpeg[p]=0x26; p=p+1 // len 38
61 // DC tc=0 th=0, BITS={1,0..0}, HUFFVAL={0}
62 jpeg[p]=0x00; p=p+1
63 jpeg[p]=0x01; p=p+1
64 i = 0
65 while i < 15 { jpeg[p+i] = 0; i = i + 1 }
66 p = p + 15
67 jpeg[p]=0x00; p=p+1 // HUFFVAL[0] = 0
68 // AC tc=1 th=0
69 jpeg[p]=0x10; p=p+1
70 jpeg[p]=0x01; p=p+1
71 i = 0
72 while i < 15 { jpeg[p+i] = 0; i = i + 1 }
73 p = p + 15
74 jpeg[p]=0x00; p=p+1
75 // SOF0
76 jpeg[p]=0xFF; p=p+1; jpeg[p]=0xC0; p=p+1
77 jpeg[p]=0x00; p=p+1; jpeg[p]=0x0B; p=p+1 // len 11
78 jpeg[p]=0x08; p=p+1 // P=8
79 jpeg[p]=0x00; p=p+1; jpeg[p]=0x08; p=p+1 // Y=8
80 jpeg[p]=0x00; p=p+1; jpeg[p]=0x08; p=p+1 // X=8
81 jpeg[p]=0x01; p=p+1 // Nf=1
82 jpeg[p]=0x01; p=p+1 // Ci=1
83 jpeg[p]=0x11; p=p+1 // HiVi=0x11
84 jpeg[p]=0x00; p=p+1 // Tqi=0
85 // SOS
86 jpeg[p]=0xFF; p=p+1; jpeg[p]=0xDA; p=p+1
87 jpeg[p]=0x00; p=p+1; jpeg[p]=0x08; p=p+1 // len 8
88 jpeg[p]=0x01; p=p+1 // Ns=1
89 jpeg[p]=0x01; p=p+1 // Csj=1
90 jpeg[p]=0x00; p=p+1 // TdjTaj=0x00
91 jpeg[p]=0x00; p=p+1 // Ss=0
92 jpeg[p]=0x3F; p=p+1 // Se=63
93 jpeg[p]=0x00; p=p+1 // AhAl=0
94 // Entropy: 0x00 = DC cat 0 + AC EOB
95 jpeg[p]=0x00; p=p+1
96 // EOI
97 jpeg[p]=0xFF; p=p+1; jpeg[p]=0xD9; p=p+1
98 let jpeg_len: i64 = p // 137 expected
99
100 // ---- Output plane: 8x8 grayscale ----
101 let plane: *u8 = sys_mmap(64)
102 i = 0
103 while i < 64 { plane[i] = 0xFF; i = i + 1 }
104 let planes_arr: *i64 = sys_mmap(8) as *i64
105 planes_arr[0] = plane as i64
106 let strides: *i64 = sys_mmap(8) as *i64
107 strides[0] = 8
108
109 // ---- Decode context ----
110 let ctx: *NxJpegDecCtx = sys_mmap(NX_JPEG_DEC_CTX_BYTES) as *NxJpegDecCtx
111 nx_jpeg_dec_ctx_init(ctx)
112
113 let rc: i64 = nx_jpeg_decode(jpeg, jpeg_len, ctx, planes_arr as *u8, strides)
114 if rc != NX_JPEG_DEC_TOP_OK { _fail(10 + rc); return 10 }
115
116 // ---- Verify output: all 64 plane bytes equal 128 ----
117 i = 0
118 while i < 64 {
119 if plane[i] != 128 { _fail(30 + i); return 30 }
120 i = i + 1
121 }
122
123 let pass: *u8 = sys_mmap(16)
124 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A
125 sys_write(1, pass, 5)
126 return 0
127}