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}