Skip to content

Instantly share code, notes, and snippets.

@devinacker
Last active June 18, 2018 13:01
Show Gist options
  • Save devinacker/bd02c7276845d66bf9cd46616d43be2d to your computer and use it in GitHub Desktop.
Save devinacker/bd02c7276845d66bf9cd46616d43be2d to your computer and use it in GitHub Desktop.

Revisions

  1. devinacker revised this gist Jun 17, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion SDL_upng.c
    Original file line number Diff line number Diff line change
    @@ -63,7 +63,7 @@ static SDL_Surface* PNG_Decode(upng_t *png) {
    Just use upng_get_bpp in case that gets fixed later
    (https://github.com/elanthis/upng/pull/6)
    */
    inpitch = upng_get_width(png) * ((upng_get_bpp(png)+7) / 8);
    inpitch = s->w * ((upng_get_bpp(png)+7) / 8);

    for (int i = 0; i < s->h; i++) {
    memcpy(out, in, inpitch);
  2. devinacker created this gist Jun 17, 2018.
    95 changes: 95 additions & 0 deletions SDL_upng.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,95 @@
    /*
    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 = upng_get_width(png) * ((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);
    }