From f741efe09a624271c72d14e170f6ce7e5d295a92 Mon Sep 17 00:00:00 2001 From: ellson Date: Thu, 26 Jul 2007 18:21:54 +0000 Subject: [PATCH] upgrade mylibgd tree to gd-2.0.35 use system gd-2.0.34 or later on fc7 or later distros --- lib/gd/gd_png.c | 248 +++++++++++++++++++++++++----------------------- 1 file changed, 127 insertions(+), 121 deletions(-) diff --git a/lib/gd/gd_png.c b/lib/gd/gd_png.c index 52218b706..135cc02ee 100644 --- a/lib/gd/gd_png.c +++ b/lib/gd/gd_png.c @@ -1,3 +1,4 @@ +/* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -67,10 +68,8 @@ gdPngErrorHandler (png_structp png_ptr, png_const_charp msg) fflush (stderr); jmpbuf_ptr = png_get_error_ptr (png_ptr); - if (jmpbuf_ptr == NULL) - { /* we are completely hosed now */ - fprintf (stderr, - "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n"); + if (jmpbuf_ptr == NULL) { /* we are completely hosed now */ + fprintf (stderr, "gd-png: EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n"); fflush (stderr); exit (99); } @@ -82,7 +81,11 @@ gdPngErrorHandler (png_structp png_ptr, png_const_charp msg) static void gdPngReadData (png_structp png_ptr, png_bytep data, png_size_t length) { - gdGetBuf (data, length, (gdIOCtx *) png_get_io_ptr (png_ptr)); + int check; + check = gdGetBuf (data, length, (gdIOCtx *) png_get_io_ptr (png_ptr)); + if (check != length) { + png_error(png_ptr, "Read Error: truncated data"); + } } static void @@ -122,7 +125,7 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) png_byte sig[8]; png_structp png_ptr; png_infop info_ptr; - png_uint_32 width, height, rowbytes; + png_uint_32 width, height, rowbytes, w, h; int bit_depth, color_type, interlace_type; int num_palette, num_trans; png_colorp palette; @@ -138,45 +141,48 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) /* Make sure the signature can't match by dumb luck -- TBB */ /* GRR: isn't sizeof(infile) equal to the size of the pointer? */ - memset (infile, 0, sizeof (infile)); + memset (sig, 0, sizeof (sig)); /* first do a quick check that the file really is a PNG image; could * have used slightly more general png_sig_cmp() function instead */ - gdGetBuf (sig, 8, infile); - if (!png_check_sig (sig, 8)) - return NULL; /* bad signature */ + if (gdGetBuf (sig, 8, infile) < 8) { + return NULL; + } + + if (!png_check_sig (sig, 8)) { /* bad signature */ + return NULL; /* bad signature */ + } #ifndef PNG_SETJMP_NOT_SUPPORTED - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, &gdPngJmpbufStruct, - gdPngErrorHandler, NULL); + png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, &gdPngJmpbufStruct, gdPngErrorHandler, NULL); #else png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); #endif - if (png_ptr == NULL) - { + if (png_ptr == NULL) { fprintf (stderr, "gd-png error: cannot allocate libpng main struct\n"); return NULL; } info_ptr = png_create_info_struct (png_ptr); - if (info_ptr == NULL) - { + if (info_ptr == NULL) { fprintf (stderr, "gd-png error: cannot allocate libpng info struct\n"); png_destroy_read_struct (&png_ptr, NULL, NULL); + return NULL; } /* we could create a second info struct here (end_info), but it's only * useful if we want to keep pre- and post-IDAT chunk info separated - * (mainly for PNG-aware image editors and converters) */ + * (mainly for PNG-aware image editors and converters) + */ /* setjmp() must be called in every non-callback function that calls a * PNG-reading libpng function */ #ifndef PNG_SETJMP_NOT_SUPPORTED - if (setjmp (gdPngJmpbufStruct.jmpbuf)) - { - fprintf (stderr, "gd-png error: setjmp returns error condition\n"); + if (setjmp (gdPngJmpbufStruct.jmpbuf)) { + fprintf (stderr, "gd-png error: setjmp returns error condition 1\n"); png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return NULL; } #endif @@ -186,52 +192,61 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) png_set_read_fn (png_ptr, (void *) infile, gdPngReadData); png_read_info (png_ptr, info_ptr); /* read all PNG info up to image data */ - png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - &interlace_type, NULL, NULL); - if ((color_type == PNG_COLOR_TYPE_RGB) || - (color_type == PNG_COLOR_TYPE_RGB_ALPHA)) - { + png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); + if ((color_type == PNG_COLOR_TYPE_RGB) || (color_type == PNG_COLOR_TYPE_RGB_ALPHA)) { im = gdImageCreateTrueColor ((int) width, (int) height); - } - else - { + } else { im = gdImageCreate ((int) width, (int) height); } - if (im == NULL) - { + if (im == NULL) { fprintf (stderr, "gd-png error: cannot allocate gdImage struct\n"); png_destroy_read_struct (&png_ptr, &info_ptr, NULL); gdFree (image_data); gdFree (row_pointers); + return NULL; } - if (bit_depth == 16) + if (bit_depth == 16) { png_set_strip_16 (png_ptr); - else if (bit_depth < 8) + } else if (bit_depth < 8) { png_set_packing (png_ptr); /* expand to 1 byte per pixel */ - switch (color_type) - { + } + + /* setjmp() must be called in every non-callback function that calls a + * PNG-reading libpng function + */ +#ifndef PNG_SETJMP_NOT_SUPPORTED + if (setjmp(gdPngJmpbufStruct.jmpbuf)) { + fprintf(stderr, "gd-png error: setjmp returns error condition 2"); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + gdFree(image_data); + gdFree(row_pointers); + if (im) { + gdImageDestroy(im); + } + return NULL; + } +#endif + + switch (color_type) { case PNG_COLOR_TYPE_PALETTE: png_get_PLTE (png_ptr, info_ptr, &palette, &num_palette); #ifdef DEBUG - fprintf (stderr, "gd-png color_type is palette, colors: %d\n", - num_palette); + fprintf (stderr, "gd-png color_type is palette, colors: %d\n", num_palette); #endif /* DEBUG */ - if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) - { - /* gd 2.0: we support this rather thoroughly now. Grab the - first fully transparent entry, if any, as the value of - the simple-transparency index, mostly for backwards - binary compatibility. The alpha channel is where it's - really at these days. */ + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) { + /* gd 2.0: we support this rather thoroughly now. Grab the + * first fully transparent entry, if any, as the value of + * the simple-transparency index, mostly for backwards + * binary compatibility. The alpha channel is where it's + * really at these days. + */ int firstZero = 1; png_get_tRNS (png_ptr, info_ptr, &trans, &num_trans, NULL); - for (i = 0; i < num_trans; ++i) - { + for (i = 0; i < num_trans; ++i) { im->alpha[i] = gdAlphaMax - (trans[i] >> 1); - if ((trans[i] == 0) && (firstZero)) - { + if ((trans[i] == 0) && (firstZero)) { /* 2.0.5: long-forgotten patch from Wez Furlong */ transparent = i; firstZero = 0; @@ -243,38 +258,31 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_GRAY_ALPHA: /* create a fake palette and check for single-shade transparency */ - if ((palette = - (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) - { + if ((palette = (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) { fprintf (stderr, "gd-png error: cannot allocate gray palette\n"); png_destroy_read_struct (&png_ptr, &info_ptr, NULL); return NULL; } palette_allocated = TRUE; - if (bit_depth < 8) - { + if (bit_depth < 8) { num_palette = 1 << bit_depth; - for (i = 0; i < 256; ++i) - { + for (i = 0; i < 256; ++i) { j = (255 * i) / (num_palette - 1); palette[i].red = palette[i].green = palette[i].blue = j; } - } - else - { + } else { num_palette = 256; - for (i = 0; i < 256; ++i) - { + for (i = 0; i < 256; ++i) { palette[i].red = palette[i].green = palette[i].blue = i; } } - if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) - { + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) { png_get_tRNS (png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb); - if (bit_depth == 16) /* png_set_strip_16() not yet in effect */ + if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */ transparent = trans_gray_rgb->gray >> 8; - else + } else { transparent = trans_gray_rgb->gray; + } /* Note slight error in 16-bit case: up to 256 16-bit shades * may get mapped to a single 8-bit shade, and only one of them * is supposed to be transparent. IOW, both opaque pixels and @@ -293,18 +301,18 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) /* gd 2.0: we now support truecolor. See the comment above for a rare situation in which the transparent pixel may not work properly with 16-bit channels. */ - if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) - { + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) { png_get_tRNS (png_ptr, info_ptr, NULL, NULL, &trans_color_rgb); - if (bit_depth == 16) /* png_set_strip_16() not yet in effect */ + if (bit_depth == 16) { /* png_set_strip_16() not yet in effect */ transparent = gdTrueColor (trans_color_rgb->red >> 8, trans_color_rgb->green >> 8, trans_color_rgb->blue >> 8); - else + } else { transparent = gdTrueColor (trans_color_rgb->red, trans_color_rgb->green, trans_color_rgb->blue); } + } break; } @@ -315,52 +323,57 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) if (overflow2(rowbytes, height)) { png_destroy_read_struct (&png_ptr, &info_ptr, NULL); return NULL; - } - if ((image_data = (png_bytep) gdMalloc (rowbytes * height)) == NULL) - { + } + image_data = (png_bytep) gdMalloc (rowbytes * height); + if (!image_data) { fprintf (stderr, "gd-png error: cannot allocate image data\n"); png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + if (im) { + gdImageDestroy(im); + } return NULL; } if (overflow2(height, sizeof (png_bytep))) { png_destroy_read_struct (&png_ptr, &info_ptr, NULL); gdFree (image_data); + if (im) { + gdImageDestroy(im); + } return NULL; - } - if ((row_pointers = - (png_bytepp) gdMalloc (height * sizeof (png_bytep))) == NULL) - { + } + + row_pointers = (png_bytepp) gdMalloc (height * sizeof (png_bytep)); + if (!row_pointers) { fprintf (stderr, "gd-png error: cannot allocate row pointers\n"); png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + if (im) { + gdImageDestroy(im); + } gdFree (image_data); return NULL; } /* set the individual row_pointers to point at the correct offsets */ - for (j = 0; j < height; ++j) - { - row_pointers[j] = image_data + j * rowbytes; + for (h = 0; h < height; ++h) { + row_pointers[h] = image_data + h * rowbytes; } png_read_image (png_ptr, row_pointers); /* read whole image... */ png_read_end (png_ptr, NULL); /* ...done! */ - if (!im->trueColor) - { + if (!im->trueColor) { im->colorsTotal = num_palette; /* load the palette and mark all entries "open" (unused) for now */ open = im->open; - for (i = 0; i < num_palette; ++i) - { + for (i = 0; i < num_palette; ++i) { im->red[i] = palette[i].red; im->green[i] = palette[i].green; im->blue[i] = palette[i].blue; open[i] = 1; } - for (i = num_palette; i < gdMaxColors; ++i) - { + for (i = num_palette; i < gdMaxColors; ++i) { open[i] = 1; - } + } } /* 2.0.12: Slaven Rezic: palette images are not the only images with a simple transparent color setting */ @@ -369,58 +382,50 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) /* can't nuke structs until done with palette */ png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - switch (color_type) - { + switch (color_type) { case PNG_COLOR_TYPE_RGB: - for (j = 0; j < height; j++) - { + for (h = 0; h < height; h++) { int boffset = 0; - for (i = 0; i < width; i++) - { - register png_byte r = row_pointers[j][boffset++]; - register png_byte g = row_pointers[j][boffset++]; - register png_byte b = row_pointers[j][boffset++]; - im->tpixels[j][i] = gdTrueColor (r, g, b); + for (w = 0; w < width; w++) { + register png_byte r = row_pointers[h][boffset++]; + register png_byte g = row_pointers[h][boffset++]; + register png_byte b = row_pointers[h][boffset++]; + im->tpixels[h][w] = gdTrueColor (r, g, b); } } break; case PNG_COLOR_TYPE_RGB_ALPHA: - for (j = 0; j < height; j++) - { + for (h = 0; h < height; h++) { int boffset = 0; - for (i = 0; i < width; i++) - { - register png_byte r = row_pointers[j][boffset++]; - register png_byte g = row_pointers[j][boffset++]; - register png_byte b = row_pointers[j][boffset++]; - /* gd has only 7 bits of alpha channel resolution, and - 127 is transparent, 0 opaque. A moment of convenience, - a lifetime of compatibility. */ - register png_byte a = gdAlphaMax - - (row_pointers[j][boffset++] >> 1); - im->tpixels[j][i] = gdTrueColorAlpha (r, g, b, a); + for (w = 0; w < width; w++) { + register png_byte r = row_pointers[h][boffset++]; + register png_byte g = row_pointers[h][boffset++]; + register png_byte b = row_pointers[h][boffset++]; + + /* gd has only 7 bits of alpha channel resolution, and + * 127 is transparent, 0 opaque. A moment of convenience, + * a lifetime of compatibility. + */ + + register png_byte a = gdAlphaMax - (row_pointers[h][boffset++] >> 1); + im->tpixels[h][w] = gdTrueColorAlpha(r, g, b, a); } } break; default: /* Palette image, or something coerced to be one */ - for (j = 0; j < height; ++j) - { - for (i = 0; i < width; ++i) - { - register png_byte idx = row_pointers[j][i]; - im->pixels[j][i] = idx; + for (h = 0; h < height; ++h) { + for (w = 0; w < width; ++w) { + register png_byte idx = row_pointers[h][w]; + im->pixels[h][w] = idx; open[idx] = 0; } } } #ifdef DEBUG - if (!im->trueColor) - { - for (i = num_palette; i < gdMaxColors; ++i) - { - if (!open[i]) - { + if (!im->trueColor) { + for (i = num_palette; i < gdMaxColors; ++i) { + if (!open[i]) { fprintf (stderr, "gd-png warning: image data references out-of-range" " color index (%d)\n", i); @@ -429,8 +434,9 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) } #endif - if (palette_allocated) + if (palette_allocated) { gdFree (palette); + } gdFree (image_data); gdFree (row_pointers); @@ -744,7 +750,7 @@ BGD_DECLARE(void) gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level) for (i = 0; i < j; ++i) gdFree (row_pointers[i]); /* 2.0.29: memory leak TBB */ - free(row_pointers); + gdFree(row_pointers); return; } pOutputRow = *prow_pointers++; -- 2.40.0