# png.ludic - the renderer writes a frame as a PPM; the lab keeps it as a PNG, stored rather than # compressed (png_write.ludic: a PNG anything opens, with no zlib here). # a PPM's header: "P6", width, height, maxval, each after white space; returns the pixel offset function lp_ppm_header(lab_st: mut LabState, d: []byte) -> int { var i = 2 var got = 0 var vals = new []int while got < 3 and i < len(d) { while i < len(d) and (d[i] == 32 or d[i] == 10 or d[i] == 13 or d[i] == 9) { i += 1 } var v = 0 while i < len(d) and d[i] >= 48 and d[i] <= 57 { v = v * 10 + (d[i] - 48) i += 1 } push(vals, v) got += 1 } lab_st.lp_w = vals[0] lab_st.lp_h = vals[1] return i + 1 } # the PPM at `ppm` as a PNG at `png`; the PPM is removed export function lab_ppm_to_png(lab_st: mut LabState, ppm: string, png: string) -> bool { let d = Fs.read_bytes(ppm) if d == null or len(d) < 8 { return false } let px = lp_ppm_header(lab_st, d) let w = lab_st.lp_w let h = lab_st.lp_h if px + w * h * 3 > len(d) { return false } let out = buffer(lp_png_size(w, h, 3)) let n = lp_encode(lab_st.lp_table, w, h, 3, d, px, out) if not Fs.write_bytes(png, out, n) { return false } Fs.remove(ppm) return true }