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;