]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/libsdl-image/contrib/IMG_png.c
update
[l4.git] / l4 / pkg / libsdl-image / contrib / IMG_png.c
index f00af1ce49cc607391514a7cdc97c561e1448e1e..99d5b5718ab23724d28aea47e99f05930cdac358 100644 (file)
@@ -20,6 +20,8 @@
     slouken@libsdl.org
 */
 
+#if !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND)
+
 /* This is a PNG image file loading framework */
 
 #include <stdlib.h>
 #endif
 #include <png.h>
 
+/* Check for the older version of libpng */
+#if (PNG_LIBPNG_VER_MAJOR == 1) && (PNG_LIBPNG_VER_MINOR < 4)
+#define LIBPNG_VERSION_12
+#endif
 
 static struct {
        int loaded;
@@ -78,6 +84,8 @@ static struct {
        void (*png_destroy_read_struct) (png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr);
        png_uint_32 (*png_get_IHDR) (png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, int *interlace_method, int *compression_method, int *filter_method);
        png_voidp (*png_get_io_ptr) (png_structp png_ptr);
+       png_byte (*png_get_channels) (png_structp png_ptr, png_infop info_ptr);
+       png_uint_32 (*png_get_PLTE) (png_structp png_ptr, png_infop info_ptr, png_colorp *palette, int *num_palette);
        png_uint_32 (*png_get_tRNS) (png_structp png_ptr, png_infop info_ptr, png_bytep *trans, int *num_trans, png_color_16p *trans_values);
        png_uint_32 (*png_get_valid) (png_structp png_ptr, png_infop info_ptr, png_uint_32 flag);
        void (*png_read_image) (png_structp png_ptr, png_bytepp image);
@@ -89,6 +97,9 @@ static struct {
        void (*png_set_read_fn) (png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn);
        void (*png_set_strip_16) (png_structp png_ptr);
        int (*png_sig_cmp) (png_bytep sig, png_size_t start, png_size_t num_to_check);
+#ifndef LIBPNG_VERSION_12
+       jmp_buf* (*png_set_longjmp_fn) (png_structp, png_longjmp_ptr, size_t);
+#endif
 } lib;
 
 #ifdef LOAD_PNG_DYNAMIC
@@ -127,6 +138,13 @@ int IMG_InitPNG()
                        SDL_UnloadObject(lib.handle);
                        return -1;
                }
+               lib.png_get_channels =
+                       (png_byte (*) (png_structp, png_infop))
+                       SDL_LoadFunction(lib.handle, "png_get_channels");
+               if ( lib.png_get_channels == NULL ) {
+                       SDL_UnloadObject(lib.handle);
+                       return -1;
+               }
                lib.png_get_io_ptr =
                        (png_voidp (*) (png_structp))
                        SDL_LoadFunction(lib.handle, "png_get_io_ptr");
@@ -134,6 +152,13 @@ int IMG_InitPNG()
                        SDL_UnloadObject(lib.handle);
                        return -1;
                }
+               lib.png_get_PLTE =
+                       (png_uint_32 (*) (png_structp, png_infop, png_colorp *, int *))
+                       SDL_LoadFunction(lib.handle, "png_get_PLTE");
+               if ( lib.png_get_PLTE == NULL ) {
+                       SDL_UnloadObject(lib.handle);
+                       return -1;
+               }
                lib.png_get_tRNS =
                        (png_uint_32 (*) (png_structp, png_infop, png_bytep *, int *, png_color_16p *))
                        SDL_LoadFunction(lib.handle, "png_get_tRNS");
@@ -211,6 +236,15 @@ int IMG_InitPNG()
                        SDL_UnloadObject(lib.handle);
                        return -1;
                }
+#ifndef LIBPNG_VERSION_12
+               lib.png_set_longjmp_fn =
+                       (jmp_buf * (*) (png_structp, png_longjmp_ptr, size_t))
+                       SDL_LoadFunction(lib.handle, "png_set_longjmp_fn");
+               if ( lib.png_set_longjmp_fn == NULL ) {
+                       SDL_UnloadObject(lib.handle);
+                       return -1;
+               }
+#endif
        }
        ++lib.loaded;
 
@@ -234,7 +268,9 @@ int IMG_InitPNG()
                lib.png_create_read_struct = png_create_read_struct;
                lib.png_destroy_read_struct = png_destroy_read_struct;
                lib.png_get_IHDR = png_get_IHDR;
+               lib.png_get_channels = png_get_channels;
                lib.png_get_io_ptr = png_get_io_ptr;
+               lib.png_get_PLTE = png_get_PLTE;
                lib.png_get_tRNS = png_get_tRNS;
                lib.png_get_valid = png_get_valid;
                lib.png_read_image = png_read_image;
@@ -246,6 +282,9 @@ int IMG_InitPNG()
                lib.png_set_read_fn = png_set_read_fn;
                lib.png_set_strip_16 = png_set_strip_16;
                lib.png_sig_cmp = png_sig_cmp;
+#ifndef LIBPNG_VERSION_12
+               lib.png_set_longjmp_fn = png_set_longjmp_fn;
+#endif
        }
        ++lib.loaded;
 
@@ -281,7 +320,7 @@ int IMG_isPNG(SDL_RWops *src)
                        is_PNG = 1;
                }
        }
-       SDL_RWseek(src, start, SEEK_SET);
+       SDL_RWseek(src, start, RW_SEEK_SET);
        return(is_PNG);
 }
 
@@ -318,7 +357,7 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
        }
        start = SDL_RWtell(src);
 
-       if ( IMG_Init(IMG_INIT_PNG) < 0 ) {
+       if ( !IMG_Init(IMG_INIT_PNG) ) {
                return NULL;
        }
 
@@ -345,7 +384,12 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
         * the normal method of doing things with libpng).  REQUIRED unless you
         * set up your own error handlers in png_create_read_struct() earlier.
         */
-       if ( setjmp(png_ptr->jmpbuf) ) {
+#ifndef LIBPNG_VERSION_12
+       if ( setjmp(*lib.png_set_longjmp_fn(png_ptr, longjmp, sizeof (jmp_buf))) )
+#else
+       if ( setjmp(png_ptr->jmpbuf) )
+#endif
+       {
                error = "Error reading the PNG file.";
                goto done;
        }
@@ -414,9 +458,9 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
                        Rmask = 0x000000FF;
                        Gmask = 0x0000FF00;
                        Bmask = 0x00FF0000;
-                       Amask = (info_ptr->channels == 4) ? 0xFF000000 : 0;
+                       Amask = (lib.png_get_channels(png_ptr, info_ptr) == 4) ? 0xFF000000 : 0;
                } else {
-                       int s = (info_ptr->channels == 4) ? 0 : 8;
+                       int s = (lib.png_get_channels(png_ptr, info_ptr) == 4) ? 0 : 8;
                        Rmask = 0xFF000000 >> s;
                        Gmask = 0x00FF0000 >> s;
                        Bmask = 0x0000FF00 >> s;
@@ -424,7 +468,7 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
                }
        }
        surface = SDL_AllocSurface(SDL_SWSURFACE, width, height,
-                       bit_depth*info_ptr->channels, Rmask,Gmask,Bmask,Amask);
+                       bit_depth*lib.png_get_channels(png_ptr, info_ptr), Rmask,Gmask,Bmask,Amask);
        if ( surface == NULL ) {
                error = "Out of memory";
                goto done;
@@ -465,6 +509,9 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
        /* Load the palette, if any */
        palette = surface->format->palette;
        if ( palette ) {
+           int png_num_palette;
+           png_colorp png_palette;
+           lib.png_get_PLTE(png_ptr, info_ptr, &png_palette, &png_num_palette);
            if(color_type == PNG_COLOR_TYPE_GRAY) {
                palette->ncolors = 256;
                for(i = 0; i < 256; i++) {
@@ -472,12 +519,12 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
                    palette->colors[i].g = i;
                    palette->colors[i].b = i;
                }
-           } else if (info_ptr->num_palette > 0 ) {
-               palette->ncolors = info_ptr->num_palette; 
-               for( i=0; i<info_ptr->num_palette; ++i ) {
-                   palette->colors[i].b = info_ptr->palette[i].blue;
-                   palette->colors[i].g = info_ptr->palette[i].green;
-                   palette->colors[i].r = info_ptr->palette[i].red;
+           } else if (png_num_palette > 0 ) {
+               palette->ncolors = png_num_palette; 
+               for( i=0; i<png_num_palette; ++i ) {
+                   palette->colors[i].b = png_palette[i].blue;
+                   palette->colors[i].g = png_palette[i].green;
+                   palette->colors[i].r = png_palette[i].red;
                }
            }
        }
@@ -492,7 +539,7 @@ done:       /* Clean up and return */
                free(row_pointers);
        }
        if ( error ) {
-               SDL_RWseek(src, start, SEEK_SET);
+               SDL_RWseek(src, start, RW_SEEK_SET);
                if ( surface ) {
                        SDL_FreeSurface(surface);
                        surface = NULL;
@@ -527,3 +574,5 @@ SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src)
 }
 
 #endif /* LOAD_PNG */
+
+#endif /* !defined(__APPLE__) || defined(SDL_IMAGE_USE_COMMON_BACKEND) */