Util: Add 8-bit PNG write support

This commit is contained in:
Vicki Pfau 2017-02-02 16:33:27 -08:00
parent e4d3aefb4a
commit cea83a5444
3 changed files with 51 additions and 0 deletions

View File

@ -60,6 +60,7 @@ Misc:
- 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:

View File

@ -22,7 +22,10 @@ enum {
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);

View File

@ -51,6 +51,40 @@ png_infop PNGWriteHeader(png_structp png, unsigned width, unsigned height) {
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) {
@ -94,6 +128,19 @@ bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned s
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;
}
bool PNGWriteCustomChunk(png_structp png, const char* name, size_t size, void* data) {
char realName[5];
strncpy(realName, name, 4);