all repos — mgba @ 4f312a099848ccc657fdf0cb39efbf710895039e

mGBA Game Boy Advance Emulator

Util: Add missing PNG read functions
Vicki Pfau vi@endrift.com
Wed, 12 Sep 2018 19:27:23 -0700
commit

4f312a099848ccc657fdf0cb39efbf710895039e

parent

cc2362aea9c63bf914972bbeda8b2bae114da4f9

2 files changed, 77 insertions(+), 0 deletions(-)

jump to
M include/mgba-util/png-io.hinclude/mgba-util/png-io.h

@@ -42,6 +42,8 @@ png_structp PNGReadOpen(struct VFile* source, unsigned offset);

bool PNGInstallChunkHandler(png_structp png, void* context, ChunkHandler handler, const char* chunkName); bool PNGReadHeader(png_structp png, png_infop info); bool PNGReadPixels(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride); +bool PNGReadPixelsA(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride); +bool PNGReadPixels8(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride); bool PNGIgnorePixels(png_structp png, png_infop info); bool PNGReadFooter(png_structp png, png_infop end); void PNGReadClose(png_structp png, png_infop info, png_infop end);
M src/util/png-io.csrc/util/png-io.c

@@ -323,6 +323,81 @@ free(row);

return true; } +bool PNGReadPixelsA(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride) { + if (setjmp(png_jmpbuf(png))) { + return false; + } + + uint8_t* pixelData = pixels; + unsigned pngHeight = png_get_image_height(png, info); + if (height < pngHeight) { + pngHeight = height; + } + + unsigned pngWidth = png_get_image_width(png, info); + if (width < pngWidth) { + pngWidth = width; + } + + unsigned i; + png_bytep row = malloc(png_get_rowbytes(png, info)); + for (i = 0; i < pngHeight; ++i) { + png_read_row(png, row, 0); + unsigned x; + for (x = 0; x < pngWidth; ++x) { +#ifdef COLOR_16_BIT + uint16_t c = row[x * 4 + 2] >> 3; +#ifdef COLOR_5_6_5 + c |= (row[x * 4 + 1] << 3) & 0x7E0; + c |= (row[x * 4] << 8) & 0xF800; +#else + c |= (row[x * 4 + 1] << 2) & 0x3E0; + c |= (row[x * 4] << 7) & 0x7C00; +#endif + ((uint16_t*) pixelData)[stride * i + x] = c; +#else +#if __BIG_ENDIAN__ + pixelData[stride * i * 4 + x * 4 + 3] = row[x * 4]; + pixelData[stride * i * 4 + x * 4 + 2] = row[x * 4 + 1]; + pixelData[stride * i * 4 + x * 4 + 1] = row[x * 4 + 2]; + pixelData[stride * i * 4 + x * 4] = row[x * 4 + 3]; +#else + pixelData[stride * i * 4 + x * 4] = row[x * 4]; + pixelData[stride * i * 4 + x * 4 + 1] = row[x * 4 + 1]; + pixelData[stride * i * 4 + x * 4 + 2] = row[x * 4 + 2]; + pixelData[stride * i * 4 + x * 4 + 3] = row[x * 4 + 3]; +#endif +#endif + } + } + free(row); + return true; +} + +bool PNGReadPixels8(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride) { + if (setjmp(png_jmpbuf(png))) { + return false; + } + + uint8_t* pixelData = pixels; + unsigned pngHeight = png_get_image_height(png, info); + if (height < pngHeight) { + pngHeight = height; + } + + unsigned pngWidth = png_get_image_width(png, info); + if (width < pngWidth) { + pngWidth = width; + } + + unsigned i; + for (i = 0; i < pngHeight; ++i) { + png_read_row(png, &pixelData[stride * i], 0); + } + return true; +} + + bool PNGReadFooter(png_structp png, png_infop end) { if (setjmp(png_jmpbuf(png))) { return false;