ColonelPanic

LoadPng

Mar 7th, 2013
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.83 KB | None | 0 0
  1. #include <png.h>
  2. #include <stdio.h>
  3.  
  4. typedef struct
  5. {
  6.    unsigned char* Data;
  7.    unsigned int Width, Height;
  8.    enum { RGB, RGBA } Type;
  9. } Image;
  10.  
  11. BOOL LoadPng(char const* fileName, Image* image)
  12. {
  13.    FILE *fp = fopen(fileName, "rb");
  14.  
  15.    unsigned char header[8];
  16.    if(fread(header, 1, 8, fp) != 8 || png_sig_cmp(header, 0, 8) != 0)
  17.    {
  18.       fclose(fp);
  19.       return FALSE;
  20.    }
  21.    
  22.    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  23.    if(!png == NULL)
  24.    {
  25.       fclose(fp);
  26.       return FALSE;
  27.    }
  28.    
  29.    png_infop info = png_create_info_struct(png);
  30.    if(info == NULL)
  31.    {
  32.       fclose(fp);
  33.       png_destroy_read_struct(&png, NULL, NULL);
  34.       return FALSE;
  35.    }
  36.    
  37.    if(setjmp(png_jmpbuf(png)))
  38.    {
  39.       if(image->Data != NULL);
  40.       {
  41.          free(image->Data);
  42.       }
  43.      
  44.       fclose(fp);
  45.       png_destroy_read_struct(&png, &info, NULL);
  46.       return FALSE;
  47.    }
  48.    
  49.    png_init_io(png, fp);
  50.    png_set_sig_bytes(png, 8); // Already read the first 8 bytes.
  51.    png_read_png(png, info, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);
  52.    image->Width = png_get_image_width(png, info);
  53.    image->Height = png_get_image_height(png, info);
  54.    image->Type = png_get_color_type(png, info) == PNG_COLOR_TYPE_RGB ? RGB : RGBA;
  55.    
  56.    png_size_t stride = png_get_rowbytes(png, info);
  57.    image->Data = malloc(stride * image->Height); // stride rather than width to take into account padding
  58.    
  59.    // Flipping the rows because OpenGL uses bottom left as origin
  60.    png_bytepp rows = png_get_rows(png, info);
  61.    for(unsigned int i = 0; i < image->Height; i++)
  62.    {
  63.       memcpy(image->Data + (stride * i), rows[image->Height - 1 - i], stride);
  64.    }
  65.  
  66.    png_destroy_read_struct(&png, &info, NULL);
  67.    fclose(fp);
  68.    return TRUE;
  69. }
Advertisement
Add Comment
Please, Sign In to add comment