Last active
June 18, 2018 13:01
-
-
Save devinacker/bd02c7276845d66bf9cd46616d43be2d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Quick SDL2 wrapper for uPNG | |
[email protected] | |
This code is public domain. | |
*/ | |
// https://github.com/elanthis/upng | |
#include "upng/upng.h" | |
#include <SDL2/SDL.h> | |
SDL_Surface* PNG_Load(const char *file); | |
SDL_Surface* PNG_LoadMem(const unsigned char *data, unsigned size); | |
static const char *PNG_error[] = { | |
"no error", | |
"out of memory", | |
"file not found", | |
"not a PNG file", | |
"invalid PNG image", | |
"unsupported PNG chunk", | |
"image interlacing not supported", | |
"unsupported color format", | |
"invalid parameter", | |
}; | |
static SDL_Surface* PNG_Decode(upng_t *png) { | |
SDL_Surface *s = 0; | |
uint8_t *out, *in; | |
unsigned inpitch, format; | |
if (!png || upng_decode(png) != UPNG_EOK) goto end; | |
// get format of decoded PNG | |
switch (upng_get_format(png)) { | |
case UPNG_RGB8: | |
format = SDL_PIXELFORMAT_RGB24; | |
break; | |
case UPNG_RGBA8: | |
format = SDL_PIXELFORMAT_RGBA32; | |
break; | |
default: | |
// unsupported | |
SDL_SetError("SDL_upng: only RGB24 and RGBA32 are supported"); | |
goto end; | |
} | |
s = SDL_CreateRGBSurfaceWithFormat(0, | |
upng_get_width(png), upng_get_height(png), | |
upng_get_bpp(png), format); | |
if (!s) goto end; | |
// copy decoded image | |
SDL_LockSurface(s); | |
out = (uint8_t*)s->pixels; | |
in = (uint8_t*)upng_get_buffer(png); | |
/* | |
upng_get_pixelsize is supposed to return bytes, but returns bits instead... | |
Just use upng_get_bpp in case that gets fixed later | |
(https://github.com/elanthis/upng/pull/6) | |
*/ | |
inpitch = s->w * ((upng_get_bpp(png)+7) / 8); | |
for (int i = 0; i < s->h; i++) { | |
memcpy(out, in, inpitch); | |
out += s->pitch; | |
in += inpitch; | |
} | |
SDL_UnlockSurface(s); | |
end: | |
if (png) { | |
if (upng_get_error(png)) { | |
SDL_SetError("uPNG: %s", PNG_error[upng_get_error(png)]); | |
} | |
upng_free(png); | |
} else { | |
SDL_SetError("SDL_upng: couldn't allocate PNG info"); | |
} | |
return s; | |
} | |
SDL_Surface* PNG_Load(const char *file) { | |
upng_t *png = upng_new_from_file(file); | |
return PNG_Decode(png); | |
} | |
SDL_Surface* PNG_LoadMem(const unsigned char *data, unsigned size) { | |
upng_t *png = upng_new_from_bytes(data, size); | |
return PNG_Decode(png); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment