code wiki / _hdl_build / nx_ppm_to_png.nx
nx_ppm_to_png.nx source
↩ module page · 64 lines · 2874 B
1// nx_ppm_to_png.nx -- sovereign P6 PPM -> PNG converter (viewing/interop tool for framebuffer dumps that Nishi
2// Windows surfaces write via win_writefile). Parses the P6 header (magic, w, h, maxval) then encodes RGB via
3// nx_png_write. usage: nx_ppm_to_png <in.ppm> <out.png>. license_tier: ORIGINAL
4import "nx_syscalls.nx"
5import "nx_png_write.nx"
6
7func hw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
8
9func skipws(buf: *u8, n: i64, p: i64) -> i64 {
10 var i: i64 = p
11 var go: i64 = 1
12 while go == 1 {
13 go = 0
14 if i < n {
15 let c: i64 = buf[i] as i64
16 if c == 32 { i = i + 1; go = 1 }
17 if c == 10 { i = i + 1; go = 1 }
18 if c == 9 { i = i + 1; go = 1 }
19 if c == 13 { i = i + 1; go = 1 }
20 }
21 }
22 return i
23}
24func rdint(buf: *u8, n: i64, p: *i64) -> i64 {
25 var i: i64 = skipws(buf, n, p[0])
26 var v: i64 = 0
27 var go: i64 = 1
28 while go == 1 {
29 go = 0
30 if i < n {
31 let c: i64 = buf[i] as i64
32 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); i = i + 1; go = 1 } }
33 }
34 }
35 p[0] = i
36 return v
37}
38
39func main(argc: i64, argv: *i64) -> i64 {
40 if argc < 3 { hw("usage: nx_ppm_to_png <in.ppm> <out.png>\n" as *u8); sys_exit(2); return 2 }
41 let inp: *u8 = argv[1] as *u8
42 let outp: *u8 = argv[2] as *u8
43 let lb: *i64 = sys_mmap(16) as *i64
44 let buf: *u8 = sys_read_file(inp, lb)
45 if (buf as i64) == 0 { hw("cannot read input\n" as *u8); sys_exit(3); return 3 }
46 let n: i64 = lb[0]
47 if n < 10 { hw("too small\n" as *u8); sys_exit(4); return 4 }
48 if buf[0] != (80 as u8) { hw("not P6 (no P)\n" as *u8); sys_exit(5); return 5 } // 'P'
49 let p: *i64 = sys_mmap(16) as *i64
50 p[0] = 2 // after "P6"
51 let w: i64 = rdint(buf, n, p)
52 let h: i64 = rdint(buf, n, p)
53 let mx: i64 = rdint(buf, n, p)
54 let doff: i64 = p[0] + 1 // exactly one whitespace after maxval, then binary RGB
55 hw("ppm w=" as *u8); let t: *u8=sys_mmap(24); var m: i64=w; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var j: i64=0; while j<k{sys_write(1,(t as i64+k-1-j) as *u8,1);j=j+1}
56 hw(" h=" as *u8); m=h; k=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} j=0; while j<k{sys_write(1,(t as i64+k-1-j) as *u8,1);j=j+1}
57 hw(" dataoff=" as *u8); m=doff; k=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} j=0; while j<k{sys_write(1,(t as i64+k-1-j) as *u8,1);j=j+1}
58 hw("\n" as *u8)
59 if doff + w * h * 3 > n { hw("truncated (need more bytes than the file has)\n" as *u8); sys_exit(6); return 6 }
60 nx_png_write_rgb(outp, (buf as i64 + doff) as *u8, w, h)
61 hw("wrote PNG\n" as *u8)
62 sys_exit(0)
63 return 0
64}