Description: Add support for libpng 1.5 (based on DirectFB 1.4.16 source code)
Author: Fathi Boudra <fabo@debian.org>
---
 interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c |  128 ++++++++++
 tools/directfb-csource.c                                       |   25 +
 tools/mkdfiff.c                                                |    4 
 3 files changed, 157 insertions(+)

--- a/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c
+++ b/interfaces/IDirectFBImageProvider/idirectfbimageprovider_png.c
@@ -204,7 +204,11 @@ Construct( IDirectFBImageProvider *thiz,
      if (!data->png_ptr)
           goto error;
 
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+     if (setjmp( png_jmpbuf( data->png_ptr ))) {
+#else
      if (setjmp( data->png_ptr->jmpbuf )) {
+#endif
           D_ERROR( "ImageProvider/PNG: Error reading header!\n" );
           goto error;
      }
@@ -331,7 +335,11 @@ IDirectFBImageProvider_PNG_RenderTo( IDi
           rect = dst_data->area.wanted;
      }
 
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+     if (setjmp( png_jmpbuf( data->png_ptr ))) {
+#else
      if (setjmp( data->png_ptr->jmpbuf )) {
+#endif
           D_ERROR( "ImageProvider/PNG: Error during decoding!\n" );
 
           if (data->stage < STAGE_IMAGE)
@@ -351,13 +359,21 @@ IDirectFBImageProvider_PNG_RenderTo( IDi
      if (dfb_rectangle_region_intersects( &rect, &clip )) {
           CoreSurfaceBufferLock lock;
 
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+          int bit_depth = png_get_bit_depth(data->png_ptr,data->info_ptr);
+#endif
+
           ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAF_CPU_WRITE, &lock );
           if (ret)
                return ret;
 
           switch (data->color_type) {
                case PNG_COLOR_TYPE_PALETTE:
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+                    if (dst_surface->config.format == DSPF_LUT8 && bit_depth == 8) {
+#else
                     if (dst_surface->config.format == DSPF_LUT8 && data->info_ptr->bit_depth == 8) {
+#endif
                          /*
                           * Special indexed PNG to LUT8 loading.
                           */
@@ -400,7 +416,11 @@ IDirectFBImageProvider_PNG_RenderTo( IDi
                     }
                     else {
                          if (data->color_type == PNG_COLOR_TYPE_GRAY) {
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+                              int num = 1 << bit_depth;
+#else
                               int num = 1 << data->info_ptr->bit_depth;
+#endif
 
                               for (x=0; x<num; x++) {
                                    int value = x * 255 / (num - 1);
@@ -409,7 +429,11 @@ IDirectFBImageProvider_PNG_RenderTo( IDi
                               }
                          }
 
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+                         switch (bit_depth) {
+#else
                          switch (data->info_ptr->bit_depth) {
+#endif
                               case 8:
                                    for (y=0; y<data->height; y++) {
                                         u8  *S = data->image + data->pitch * y;
@@ -464,7 +488,11 @@ IDirectFBImageProvider_PNG_RenderTo( IDi
 
                               default:
                                    D_ERROR( "ImageProvider/PNG: Unsupported indexed bit depth %d!\n",
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+                                            bit_depth );
+#else
                                             data->info_ptr->bit_depth );
+#endif
                          }
 
                          dfb_scale_linear_32( image_argb, data->width, data->height,
@@ -616,6 +644,12 @@ png_info_callback( png_structp png_read_
      int                              i;
      IDirectFBImageProvider_PNG_data *data;
 
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+     u32 bpp1[2] = {0, 0xff};
+     u32 bpp2[4] = {0, 0x55, 0xaa, 0xff};
+     u32 bpp4[16] = {0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
+#endif
+
      data = png_get_progressive_ptr( png_read_ptr );
 
      /* error stage? */
@@ -635,6 +669,41 @@ png_info_callback( png_structp png_read_
           /* generate color key based on palette... */
           if (data->color_type == PNG_COLOR_TYPE_PALETTE) {
                u32        key;
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+               png_colorp     palette;
+               png_bytep      trans_alpha;
+               png_color_16p  trans_color;
+               u8             cmap[3][MAXCOLORMAPSIZE];
+               int            num_palette = 0, num_colors = 0, num_trans = 0;
+
+               D_DEBUG_AT(imageProviderPNG,"%s(%d) - num_trans %d \n",__FUNCTION__,__LINE__, num_trans);
+
+               if (png_get_PLTE(data->png_ptr,data->info_ptr,&palette,&num_palette)) {
+
+                   if (png_get_tRNS(data->png_ptr,data->info_ptr,
+                                     &trans_alpha,&num_trans,&trans_color)) {
+                       num_colors = MIN( MAXCOLORMAPSIZE,num_palette );
+
+                       for (i=0; i<num_colors; i++) {
+                         cmap[0][i] = palette[i].red;
+                         cmap[1][i] = palette[i].green;
+                         cmap[2][i] = palette[i].blue;
+                       }
+
+                       key = FindColorKey( num_colors, &cmap[0][0] );
+
+                       for (i=0; i< num_trans; i++) {
+                           if (!trans_alpha[i]) {
+                               palette[i].red   = (key & 0xff0000) >> 16;
+                               palette[i].green = (key & 0x00ff00) >>  8;
+                               palette[i].blue  = (key & 0x0000ff);
+                           }
+                       }
+
+                       data->color_key = key;
+                   }
+               }
+#else
                png_colorp palette    = data->info_ptr->palette;
                png_bytep  trans      = data->info_ptr->trans;
                int        num_colors = MIN( MAXCOLORMAPSIZE,
@@ -658,19 +727,77 @@ png_info_callback( png_structp png_read_
                }
 
                data->color_key = key;
+#endif
           }
           else {
                /* ...or based on trans rgb value */
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+               png_bytep     trans_alpha;
+               png_color_16p trans_color;
+               int            num_trans = 0;
+
+               D_DEBUG_AT(imageProviderPNG,"%s(%d)\n",__FUNCTION__,__LINE__);
+
+               if (png_get_tRNS(data->png_ptr,data->info_ptr,
+                                &trans_alpha,&num_trans,&trans_color)) {
+                   switch(data->bpp) {
+                       case 1:
+                           data->color_key = (((bpp1[trans_color[0].red]) << 16) |
+                                              ((bpp1[trans_color[0].green]) << 8) |
+                                              ((bpp1[trans_color[0].blue])));
+                           break;
+                       case 2:
+                           data->color_key = (((bpp2[trans_color[0].red]) << 16) |
+                                              ((bpp2[trans_color[0].green]) << 8) |
+                                              ((bpp2[trans_color[0].blue])));
+                           break;
+                       case 4:
+                           data->color_key = (((bpp4[trans_color[0].red]) << 16) |
+                                              ((bpp4[trans_color[0].green]) << 8) |
+                                              ((bpp4[trans_color[0].blue])));
+                           break;
+                       case 8:
+                           data->color_key = (((trans_color[0].red & 0x00ff) << 16) |
+                                              ((trans_color[0].green & 0x00ff) << 8) |
+                                              ((trans_color[0].blue & 0x00ff)));
+                           break;
+                       case 16:
+                       default:
+                           data->color_key = (((trans_color[0].red & 0xff00) << 8) |
+                                              ((trans_color[0].green & 0xff00)) |
+                                              ((trans_color[0].blue & 0xff00) >> 8));
+                           break;
+                   }
+               }
+#else
                png_color_16p trans = &data->info_ptr->trans_values;
 
                data->color_key = (((trans->red & 0xff00) << 8) |
                                   ((trans->green & 0xff00)) |
                                   ((trans->blue & 0xff00) >> 8));
+#endif
           }
      }
 
      switch (data->color_type) {
           case PNG_COLOR_TYPE_PALETTE: {
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+               png_colorp     palette;
+               png_bytep      trans_alpha;
+               png_color_16p  trans_color;
+               int            num_palette = 0, num_colors = 0, num_trans = 0;
+
+
+               png_get_PLTE(data->png_ptr,data->info_ptr,&palette,&num_palette);
+
+               png_get_tRNS(data->png_ptr,data->info_ptr,
+                            &trans_alpha,&num_trans,&trans_color);
+
+               num_colors = MIN( MAXCOLORMAPSIZE, num_palette );
+
+               for (i=0; i < num_colors; i++) {
+                    data->colors[i].a = (i < num_trans) ? trans_alpha[i] : 0xff;
+#else
                png_colorp palette    = data->info_ptr->palette;
                png_bytep  trans      = data->info_ptr->trans;
                int        num_trans  = data->info_ptr->num_trans;
@@ -678,6 +805,7 @@ png_info_callback( png_structp png_read_
 
                for (i=0; i<num_colors; i++) {
                     data->colors[i].a = (i < num_trans) ? trans[i] : 0xff;
+#endif
                     data->colors[i].r = palette[i].red;
                     data->colors[i].g = palette[i].green;
                     data->colors[i].b = palette[i].blue;
--- a/tools/directfb-csource.c
+++ b/tools/directfb-csource.c
@@ -300,7 +300,11 @@ static DFBResult load_image (const char
      if (!png_ptr)
           goto cleanup;
 
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+     if (setjmp (png_jmpbuf(png_ptr))) {
+#else
      if (setjmp (png_ptr->jmpbuf)) {
+#endif
           if (desc->preallocated[0].data) {
                free (desc->preallocated[0].data);
                desc->preallocated[0].data = NULL;
@@ -368,6 +372,25 @@ static DFBResult load_image (const char
 
      switch (src_format) {
           case DSPF_LUT8:
+          {
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+               png_colorp *info_palette;
+               int num_palette;
+
+               png_get_PLTE(png_ptr,info_ptr,info_palette,&num_palette);
+
+               if (num_palette) {
+                    png_byte *alpha;
+                    int       i, num;
+
+                    *palette_size = MIN (num_palette, 256);
+                    for (i = 0; i < *palette_size; i++) {
+                         palette[i].a = 0xFF;
+                         palette[i].r = info_palette[i]->red;
+                         palette[i].g = info_palette[i]->green;
+                         palette[i].b = info_palette[i]->blue;
+                    }
+#else
                if (info_ptr->num_palette) {
                     png_byte *alpha;
                     int       i, num;
@@ -379,6 +402,7 @@ static DFBResult load_image (const char
                          palette[i].g = info_ptr->palette[i].green;
                          palette[i].b = info_ptr->palette[i].blue;
                     }
+#endif
                     if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
                          png_get_tRNS (png_ptr, info_ptr, &alpha, &num, NULL);
                          for (i = 0; i < MIN (num, *palette_size); i++)
@@ -386,6 +410,7 @@ static DFBResult load_image (const char
                     }
                }
                break;
+          }
           case DSPF_RGB32:
                 png_set_filler (png_ptr, 0xFF,
 #ifdef WORDS_BIGENDIAN
--- a/tools/mkdfiff.c
+++ b/tools/mkdfiff.c
@@ -97,7 +97,11 @@ load_image (const char            *filen
      if (!png_ptr)
           goto cleanup;
 
+#if PNG_LIBPNG_VER_MAJOR >= 1 && PNG_LIBPNG_VER_MINOR >= 4
+     if (setjmp (png_jmpbuf(png_ptr))) {
+#else
      if (setjmp (png_ptr->jmpbuf)) {
+#endif
           if (desc->preallocated[0].data) {
                free (desc->preallocated[0].data);
                desc->preallocated[0].data = NULL;
