nx_jpeg_pgm_dump_test.nx source
↩ module page · 99 lines · 3465 B
1// nx_jpeg_pgm_dump_test.nx -- PROOF dumper for the bits-up JPEG
2// decoder. Reads the real source.jpg staged in the proof folder,
3// decodes it through nx_jpeg_decode_luma (the SAME decode path the
4// ASCII renderer uses), and writes the full-resolution luma (Y)
5// plane as a binary PGM (P5) so an INDEPENDENT decoder (Windows
6// GDI+ via PowerShell) can be diffed against it pixel-for-pixel.
7//
8// This exists because "assertions PASS" is not proof. The PGM this
9// writes is compared, off-box, to a third-party decode of the same
10// bytes; the MAE / PSNR is the proof.
11//
12// Asserts the decoded dimensions equal the known 239x178 (so a
13// silent SOF mis-parse can't pass), then emits the PGM.
14//
15// expect_exit: 0
16// license_tier: ORIGINAL
17
18import "nx_syscalls.nx"
19import "nx_jpeg_ascii.nx"
20
21func _put_dec(buf: *u8, pos: i64, v: i64) -> i64 {
22 if v == 0 { buf[pos] = 0x30 as u8; return pos + 1 }
23 var x: i64 = v
24 let tmp: *u8 = sys_mmap(24)
25 var n: i64 = 0
26 while x > 0 { tmp[n] = (0x30 + (x % 10)) as u8; x = x / 10; n = n + 1 }
27 var i: i64 = 0
28 var p: i64 = pos
29 while i < n { buf[p] = tmp[n - 1 - i]; p = p + 1; i = i + 1 }
30 return p
31}
32
33func main() -> i64 {
34 // ---- Read the staged real JPEG ----
35 let in_path: *u8 = "/mnt/c/Users/elder/nishi-browser-proofs/source.jpg\x00"
36 let len_p: *i64 = sys_mmap(8) as *i64
37 let jpeg: *u8 = sys_read_file(in_path, len_p)
38 let jpeg_len: i64 = len_p[0]
39 if (jpeg as i64) == 0 { return 10 }
40 if jpeg_len < 100 { return 11 }
41
42 // ---- Decode to full-res luma ----
43 let pp_plane: *i64 = sys_mmap(8) as *i64
44 let pp_w: *i64 = sys_mmap(8) as *i64
45 let pp_h: *i64 = sys_mmap(8) as *i64
46 let pp_s: *i64 = sys_mmap(8) as *i64
47 let dl: i64 = nx_jpeg_decode_luma(jpeg, jpeg_len, pp_plane, pp_w, pp_h, pp_s)
48 if dl != NX_JPEG_ASCII_OK { return 20 + dl }
49 let luma: *u8 = pp_plane[0] as *u8
50 let w: i64 = pp_w[0]
51 let h: i64 = pp_h[0]
52 let stride: i64 = pp_s[0]
53
54 // ---- Guard: real SOF parse must yield the known dimensions ----
55 if w != 239 { return 41 }
56 if h != 178 { return 42 }
57
58 // ---- Build PGM header: "P5\n<w> <h>\n255\n" ----
59 let hdr: *u8 = sys_mmap(32)
60 var hp: i64 = 0
61 hdr[hp]=0x50 as u8; hp=hp+1 // 'P'
62 hdr[hp]=0x35 as u8; hp=hp+1 // '5'
63 hdr[hp]=0x0A as u8; hp=hp+1 // '\n'
64 hp = _put_dec(hdr, hp, w)
65 hdr[hp]=0x20 as u8; hp=hp+1 // ' '
66 hp = _put_dec(hdr, hp, h)
67 hdr[hp]=0x0A as u8; hp=hp+1 // '\n'
68 hdr[hp]=0x32 as u8; hp=hp+1 // '2'
69 hdr[hp]=0x35 as u8; hp=hp+1 // '5'
70 hdr[hp]=0x35 as u8; hp=hp+1 // '5'
71 hdr[hp]=0x0A as u8; hp=hp+1 // '\n'
72
73 // ---- Pack the luma plane row-major (drop MCU stride padding) ----
74 let body: *u8 = sys_mmap(w * h + 16)
75 var bp: i64 = 0
76 var y: i64 = 0
77 while y < h {
78 var x: i64 = 0
79 while x < w {
80 body[bp] = luma[y * stride + x]
81 bp = bp + 1
82 x = x + 1
83 }
84 y = y + 1
85 }
86
87 // ---- Write the PGM ----
88 let out_path: *u8 = "/mnt/c/Users/elder/nishi-browser-proofs/nishi_luma.pgm\x00"
89 let ofd: i64 = sys_openat_wr(out_path, 0x1A4) // 0644
90 if ofd <= 0 { return 70 }
91 sys_write(ofd, hdr, hp)
92 sys_write(ofd, body, bp)
93 sys_close(ofd)
94
95 let pass: *u8 = sys_mmap(16)
96 pass[0]=0x50; pass[1]=0x41; pass[2]=0x53; pass[3]=0x53; pass[4]=0x0A
97 sys_write(1, pass, 5)
98 return 0
99}