9. Writing a PNG file
PNG files are written to disk using the very portable lodepng library, included with monolith.
<<gfx_aux_includes>>=
#include "lodepng/lodepng.h"
A framebuffer is written to a PNG file using the function
monolith_framebuffer_write_png
.
<<gfx_function_declarations>>=
void monolith_framebuffer_write_png(monolith_framebuffer *fb,
const char *filename);
Pixels are copied to a an allocated "zoom buffer", which is then written to a PNG file via lodepng. This is done regardless of whether or not there a zoom because it also ensures proper byte order.
<<gfx_functions>>=
void monolith_framebuffer_write_png(monolith_framebuffer *fb,
const char *filename)
{
unsigned char *zbuf;
unsigned int x, y, xi, yi;
unsigned int pos;
unsigned int pos_zoom;
unsigned int zoom;
monolith_pixel *pix;
zbuf = NULL;
if(fb == NULL) return;
zoom = monolith_framebuffer_zoom_get(fb);
zbuf = calloc(1, 4 * monolith_gfx_width(fb) *
zoom * monolith_gfx_height(fb) * zoom);
pix = monolith_framebuffer_pix(fb);
for(y = 0; y < monolith_gfx_height(fb); y++) {
for(x = 0; x < monolith_gfx_width(fb); x++) {
pos = y * monolith_gfx_width(fb) + x;
for(yi = 0; yi < zoom; yi++) {
for(xi = 0; xi < zoom; xi++) {
pos_zoom =
y * zoom * monolith_gfx_width(fb) * zoom +
x * zoom +
yi * monolith_gfx_width(fb) * zoom +
xi;
pos_zoom *= 4;
zbuf[pos_zoom] = pix[pos].r;
zbuf[pos_zoom + 1] = pix[pos].g;
zbuf[pos_zoom + 2] = pix[pos].b;
zbuf[pos_zoom + 3] = pix[pos].a;
}
}
}
}
lodepng_encode32_file(filename,
zbuf,
monolith_gfx_width(fb) * zoom,
monolith_gfx_height(fb) * zoom);
if(zbuf != NULL) free(zbuf);
}
This function can be called using the function
monolith:gfx-write-png
. It will
use the global monolith framebuffer, if it exists.
<<gfx_scheme_entries>>=
{"monolith:gfx-write-png", pp_write_png, 1, 1, {STR,___,___}},
<<gfx_scheme_functions>>=
static cell pp_write_png(cell p)
{
monolith_d *m;
monolith_framebuffer *fb;
const char *filename;
m = monolith_data_get();
filename = string(car(p));
fb = monolith_fb_get(m);
monolith_framebuffer_write_png(fb, filename);
return UNSPECIFIC;
}
Similar functionality is done with Janet using the function
monolith/gfx-write-png
.
<<gfx_janet>>=
static Janet j_gfx_write_png(int32_t argc, Janet *argv)
{
monolith_framebuffer *fb;
monolith_d *m;
const char *filename;
janet_fixarity(argc, 1);
m = monolith_data_get();
fb = monolith_fb_get(m);
filename = (const char *)janet_unwrap_string(argv[0]);
if(fb != NULL) {
monolith_framebuffer_write_png(fb, filename);
}
return janet_wrap_nil();
}
<<gfx_janet_entries>>=
{
"monolith/gfx-write-png",
j_gfx_write_png,
"Writes framebuffer to disk."
},
prev | home | next