Util: Add 8-bit PNG write support
Vicki Pfau vi@endrift.com
Thu, 02 Feb 2017 16:33:27 -0800
3 files changed,
51 insertions(+),
0 deletions(-)
M
CHANGES
→
CHANGES
@@ -60,6 +60,7 @@ - SDL: Automatically map controllers when plugged in
- Qt: Automatically load controller profile when plugged in - OpenGL: Add xBR-lv2 shader - GBA, GB: ROM is now unloaded if a patch is applied + - Util: Add 8-bit PNG write support 0.5.2: (2016-12-31) Bugfixes:
M
include/mgba-util/png-io.h
→
include/mgba-util/png-io.h
@@ -22,7 +22,10 @@ };
png_structp PNGWriteOpen(struct VFile* source); png_infop PNGWriteHeader(png_structp png, unsigned width, unsigned height); +png_infop PNGWriteHeader8(png_structp png, unsigned width, unsigned height); +bool PNGWritePalette(png_structp png, png_infop info, const uint32_t* palette, unsigned entries); bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels); +bool PNGWritePixels8(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels); bool PNGWriteCustomChunk(png_structp png, const char* name, size_t size, void* data); void PNGWriteClose(png_structp png, png_infop info);
M
src/util/png-io.c
→
src/util/png-io.c
@@ -51,6 +51,40 @@ png_write_info(png, info);
return info; } +png_infop PNGWriteHeader8(png_structp png, unsigned width, unsigned height) { + png_infop info = png_create_info_struct(png); + if (!info) { + return 0; + } + if (setjmp(png_jmpbuf(png))) { + return 0; + } + png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + return info; +} + +bool PNGWritePalette(png_structp png, png_infop info, const uint32_t* palette, unsigned entries) { + if (!palette || !entries) { + return false; + } + if (setjmp(png_jmpbuf(png))) { + return false; + } + png_color colors[256]; + png_byte trans[256]; + unsigned i; + for (i = 0; i < entries && i < 256; ++i) { + colors[i].red = palette[i]; + colors[i].green = palette[i] >> 8; + colors[i].blue = palette[i] >> 16; + trans[i] = palette[i] >> 24; + } + png_set_PLTE(png, info, colors, entries); + png_set_tRNS(png, info, trans, entries, NULL); + png_write_info(png, info); + return true; +} + bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels) { png_bytep row = malloc(sizeof(png_byte) * width * 3); if (!row) {@@ -91,6 +125,19 @@ }
png_write_row(png, row); } free(row); + return true; +} + +bool PNGWritePixels8(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels) { + UNUSED(width); + const png_byte* pixelData = pixels; + if (setjmp(png_jmpbuf(png))) { + return false; + } + unsigned i; + for (i = 0; i < height; ++i) { + png_write_row(png, &pixelData[stride * i]); + } return true; }