diff options
Diffstat (limited to 'Build/source/libs/gd/gd_png.c')
-rw-r--r-- | Build/source/libs/gd/gd_png.c | 829 |
1 files changed, 0 insertions, 829 deletions
diff --git a/Build/source/libs/gd/gd_png.c b/Build/source/libs/gd/gd_png.c deleted file mode 100644 index 52218b706aa..00000000000 --- a/Build/source/libs/gd/gd_png.c +++ /dev/null @@ -1,829 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <math.h> -#include <string.h> -#include <stdlib.h> -#include "gd.h" - -/* JCE: Arrange HAVE_LIBPNG so that it can be set in gd.h */ -#ifdef HAVE_LIBPNG - -#include "gdhelpers.h" -#include "png.h" /* includes zlib.h and setjmp.h */ - -#define TRUE 1 -#define FALSE 0 - -/*--------------------------------------------------------------------------- - - gd_png.c Copyright 1999 Greg Roelofs and Thomas Boutell - - The routines in this file, gdImagePng*() and gdImageCreateFromPng*(), - are drop-in replacements for gdImageGif*() and gdImageCreateFromGif*(), - except that these functions are noisier in the case of errors (comment - out all fprintf() statements to disable that). - - GD 2.0 supports RGBA truecolor and will read and write truecolor PNGs. - GD 2.0 supports 8 bits of color resolution per channel and - 7 bits of alpha channel resolution. Images with more than 8 bits - per channel are reduced to 8 bits. Images with an alpha channel are - only able to resolve down to '1/128th opaque' instead of '1/256th', - and this conversion is also automatic. I very much doubt you can see it. - Both tRNS and true alpha are supported. - - Gamma is ignored, and there is no support for text annotations. - - Last updated: 9 February 2001 - - ---------------------------------------------------------------------------*/ - -#ifndef PNG_SETJMP_NOT_SUPPORTED -typedef struct _jmpbuf_wrapper -{ - jmp_buf jmpbuf; -} -jmpbuf_wrapper; - -static jmpbuf_wrapper gdPngJmpbufStruct; - -static void -gdPngErrorHandler (png_structp png_ptr, png_const_charp msg) -{ - jmpbuf_wrapper *jmpbuf_ptr; - - /* This function, aside from the extra step of retrieving the "error - * pointer" (below) and the fact that it exists within the application - * rather than within libpng, is essentially identical to libpng's - * default error handler. The second point is critical: since both - * setjmp() and longjmp() are called from the same code, they are - * guaranteed to have compatible notions of how big a jmp_buf is, - * regardless of whether _BSD_SOURCE or anything else has (or has not) - * been defined. */ - - fprintf (stderr, "gd-png: fatal libpng error: %s\n", 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"); - fflush (stderr); - exit (99); - } - - longjmp (jmpbuf_ptr->jmpbuf, 1); -} -#endif - -static void -gdPngReadData (png_structp png_ptr, png_bytep data, png_size_t length) -{ - gdGetBuf (data, length, (gdIOCtx *) png_get_io_ptr (png_ptr)); -} - -static void -gdPngWriteData (png_structp png_ptr, png_bytep data, png_size_t length) -{ - gdPutBuf (data, length, (gdIOCtx *) png_get_io_ptr (png_ptr)); -} - -static void -gdPngFlushData (png_structp png_ptr) -{ -} - -BGD_DECLARE(gdImagePtr) gdImageCreateFromPng (FILE * inFile) -{ - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx (inFile); - im = gdImageCreateFromPngCtx (in); - in->gd_free (in); - return im; -} - -BGD_DECLARE(gdImagePtr) gdImageCreateFromPngPtr (int size, void *data) -{ - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0); - im = gdImageCreateFromPngCtx (in); - in->gd_free (in); - return im; -} - -/* This routine is based in part on the Chapter 13 demo code in "PNG: The - * Definitive Guide" (http://www.cdrom.com/pub/png/pngbook.html). - */ -BGD_DECLARE(gdImagePtr) gdImageCreateFromPngCtx (gdIOCtx * infile) -{ - png_byte sig[8]; - png_structp png_ptr; - png_infop info_ptr; - png_uint_32 width, height, rowbytes; - int bit_depth, color_type, interlace_type; - int num_palette, num_trans; - png_colorp palette; - png_color_16p trans_gray_rgb; - png_color_16p trans_color_rgb; - png_bytep trans; - png_bytep image_data = NULL; - png_bytepp row_pointers = NULL; - gdImagePtr im = NULL; - int i, j, *open = NULL; - volatile int transparent = -1; - volatile int palette_allocated = FALSE; - - /* 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)); - - /* 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 */ - -#ifndef PNG_SETJMP_NOT_SUPPORTED - 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) - { - 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) - { - 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) */ - - /* 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"); - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - return NULL; - } -#endif - - png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */ - - 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)) - { - im = gdImageCreateTrueColor ((int) width, (int) height); - } - else - { - im = gdImageCreate ((int) width, (int) height); - } - 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) - png_set_strip_16 (png_ptr); - else if (bit_depth < 8) - png_set_packing (png_ptr); /* expand to 1 byte per pixel */ - 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); -#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. */ - int firstZero = 1; - png_get_tRNS (png_ptr, info_ptr, &trans, &num_trans, NULL); - for (i = 0; i < num_trans; ++i) - { - im->alpha[i] = gdAlphaMax - (trans[i] >> 1); - if ((trans[i] == 0) && (firstZero)) - { - /* 2.0.5: long-forgotten patch from Wez Furlong */ - transparent = i; - firstZero = 0; - } - } - } - break; - - 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) - { - 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) - { - num_palette = 1 << bit_depth; - for (i = 0; i < 256; ++i) - { - j = (255 * i) / (num_palette - 1); - palette[i].red = palette[i].green = palette[i].blue = j; - } - } - else - { - num_palette = 256; - 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)) - { - png_get_tRNS (png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb); - if (bit_depth == 16) /* png_set_strip_16() not yet in effect */ - transparent = trans_gray_rgb->gray >> 8; - 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 - * transparent pixels will be mapped into the transparent entry. - * There is no particularly good way around this in the case - * that all 256 8-bit shades are used, but one could write some - * custom 16-bit code to handle the case where there are gdFree - * palette entries. This error will be extremely rare in - * general, though. (Quite possibly there is only one such - * image in existence.) */ - } - break; - - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - /* 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)) - { - png_get_tRNS (png_ptr, info_ptr, NULL, NULL, &trans_color_rgb); - 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 - transparent = gdTrueColor (trans_color_rgb->red, - trans_color_rgb->green, - trans_color_rgb->blue); - } - break; - } - - png_read_update_info (png_ptr, info_ptr); - - /* allocate space for the PNG image data */ - rowbytes = png_get_rowbytes (png_ptr, info_ptr); - if (overflow2(rowbytes, height)) { - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - return NULL; - } - if ((image_data = (png_bytep) gdMalloc (rowbytes * height)) == NULL) - { - fprintf (stderr, "gd-png error: cannot allocate image data\n"); - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - return NULL; - } - if (overflow2(height, sizeof (png_bytep))) { - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - gdFree (image_data); - return NULL; - } - if ((row_pointers = - (png_bytepp) gdMalloc (height * sizeof (png_bytep))) == NULL) - { - fprintf (stderr, "gd-png error: cannot allocate row pointers\n"); - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - 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; - } - - png_read_image (png_ptr, row_pointers); /* read whole image... */ - png_read_end (png_ptr, NULL); /* ...done! */ - - 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) - { - 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) - { - open[i] = 1; - } - } - /* 2.0.12: Slaven Rezic: palette images are not the only images - with a simple transparent color setting */ - im->transparent = transparent; - im->interlace = (interlace_type == PNG_INTERLACE_ADAM7); - - /* can't nuke structs until done with palette */ - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - switch (color_type) - { - case PNG_COLOR_TYPE_RGB: - for (j = 0; j < height; j++) - { - 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); - } - } - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - for (j = 0; j < height; j++) - { - 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); - } - } - 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; - open[idx] = 0; - } - } - } -#ifdef DEBUG - 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); - } - } - } -#endif - - if (palette_allocated) - gdFree (palette); - gdFree (image_data); - gdFree (row_pointers); - - return im; -} - - -BGD_DECLARE(void) gdImagePngEx (gdImagePtr im, FILE * outFile, int level) -{ - gdIOCtx *out = gdNewFileCtx (outFile); - gdImagePngCtxEx (im, out, level); - out->gd_free (out); -} - -BGD_DECLARE(void) gdImagePng (gdImagePtr im, FILE * outFile) -{ - gdIOCtx *out = gdNewFileCtx (outFile); - gdImagePngCtxEx (im, out, -1); - out->gd_free (out); -} - -BGD_DECLARE(void *) gdImagePngPtr (gdImagePtr im, int *size) -{ - void *rv; - gdIOCtx *out = gdNewDynamicCtx (2048, NULL); - gdImagePngCtxEx (im, out, -1); - rv = gdDPExtractData (out, size); - out->gd_free (out); - return rv; -} - -BGD_DECLARE(void *) gdImagePngPtrEx (gdImagePtr im, int *size, int level) -{ - void *rv; - gdIOCtx *out = gdNewDynamicCtx (2048, NULL); - gdImagePngCtxEx (im, out, level); - rv = gdDPExtractData (out, size); - out->gd_free (out); - return rv; -} - -BGD_DECLARE(void) gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile) -{ - /* 2.0.13: 'return' here was an error, thanks to Kevin Smith */ - gdImagePngCtxEx (im, outfile, -1); -} - -/* This routine is based in part on code from Dale Lutz (Safe Software Inc.) - * and in part on demo code from Chapter 15 of "PNG: The Definitive Guide" - * (http://www.cdrom.com/pub/png/pngbook.html). - */ -BGD_DECLARE(void) gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level) -{ - int i, j, bit_depth = 0, interlace_type; - int width = im->sx; - int height = im->sy; - int colors = im->colorsTotal; - int *open = im->open; - int mapping[gdMaxColors]; /* mapping[gd_index] == png_index */ - png_byte trans_values[256]; - png_color_16 trans_rgb_value; - png_color palette[gdMaxColors]; - png_structp png_ptr; - png_infop info_ptr; - volatile int transparent = im->transparent; - volatile int remap = FALSE; - -#ifndef PNG_SETJMP_NOT_SUPPORTED - png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, - &gdPngJmpbufStruct, gdPngErrorHandler, - NULL); -#else - png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif - if (png_ptr == NULL) - { - fprintf (stderr, "gd-png error: cannot allocate libpng main struct\n"); - return; - } - - info_ptr = png_create_info_struct (png_ptr); - if (info_ptr == NULL) - { - fprintf (stderr, "gd-png error: cannot allocate libpng info struct\n"); - png_destroy_write_struct (&png_ptr, (png_infopp) NULL); - return; - } - -#ifndef PNG_SETJMP_NOT_SUPPORTED - if (setjmp (gdPngJmpbufStruct.jmpbuf)) - { - fprintf (stderr, "gd-png error: setjmp returns error condition\n"); - png_destroy_write_struct (&png_ptr, &info_ptr); - return; - } -#endif - - png_set_write_fn (png_ptr, (void *) outfile, gdPngWriteData, - gdPngFlushData); - - /* This is best for palette images, and libpng defaults to it for - palette images anyway, so we don't need to do it explicitly. - What to ideally do for truecolor images depends, alas, on the image. - gd is intentionally imperfect and doesn't spend a lot of time - fussing with such things. */ - - /* Faster if this is uncommented, but may produce larger truecolor files. - Wait for gdImagePngCtxEx. */ -#if 0 - png_set_filter (png_ptr, 0, PNG_FILTER_NONE); -#endif - - /* 2.0.12: this is finally a parameter */ - png_set_compression_level (png_ptr, level); - - /* can set this to a smaller value without compromising compression if all - * image data is 16K or less; will save some decoder memory [min == 8] */ -/* png_set_compression_window_bits(png_ptr, 15); */ - - if (!im->trueColor) - { - if (transparent >= im->colorsTotal || - (transparent >= 0 && open[transparent])) - transparent = -1; - } - if (!im->trueColor) - { - for (i = 0; i < gdMaxColors; ++i) - mapping[i] = -1; - } - if (!im->trueColor) - { - /* count actual number of colors used (colorsTotal == high-water mark) */ - colors = 0; - for (i = 0; i < im->colorsTotal; ++i) - { - if (!open[i]) - { - mapping[i] = colors; - ++colors; - } - } - if (colors < im->colorsTotal) - { - remap = TRUE; - } - if (colors <= 2) - bit_depth = 1; - else if (colors <= 4) - bit_depth = 2; - else if (colors <= 16) - bit_depth = 4; - else - bit_depth = 8; - } - interlace_type = im->interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; - - if (im->trueColor) - { - if (im->saveAlphaFlag) - { - png_set_IHDR (png_ptr, info_ptr, width, height, 8, - PNG_COLOR_TYPE_RGB_ALPHA, interlace_type, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - } - else - { - png_set_IHDR (png_ptr, info_ptr, width, height, 8, - PNG_COLOR_TYPE_RGB, interlace_type, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - } - } - else - { - png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, - PNG_COLOR_TYPE_PALETTE, interlace_type, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - } - if (im->trueColor && (!im->saveAlphaFlag) && (transparent >= 0)) - { - /* 2.0.9: fixed by Thomas Winzig */ - trans_rgb_value.red = gdTrueColorGetRed (im->transparent); - trans_rgb_value.green = gdTrueColorGetGreen (im->transparent); - trans_rgb_value.blue = gdTrueColorGetBlue (im->transparent); - png_set_tRNS (png_ptr, info_ptr, 0, 0, &trans_rgb_value); - } - if (!im->trueColor) - { - /* Oy veh. Remap the PNG palette to put the - entries with interesting alpha channel - values first. This minimizes the size - of the tRNS chunk and thus the size - of the PNG file as a whole. */ - int tc = 0; - int i; - int j; - int k; - for (i = 0; (i < im->colorsTotal); i++) - { - if ((!im->open[i]) && (im->alpha[i] != gdAlphaOpaque)) - { - tc++; - } - } - if (tc) - { -#if 0 - for (i = 0; (i < im->colorsTotal); i++) - { - trans_values[i] = 255 - - ((im->alpha[i] << 1) + (im->alpha[i] >> 6)); - } - png_set_tRNS (png_ptr, info_ptr, trans_values, 256, NULL); -#endif - if (!remap) - { - remap = TRUE; - } - /* (Semi-)transparent indexes come up from the bottom - of the list of real colors; opaque - indexes come down from the top */ - j = 0; - k = colors - 1; - for (i = 0; (i < im->colorsTotal); i++) - { - if (!im->open[i]) - { - if (im->alpha[i] != gdAlphaOpaque) - { - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ - trans_values[j] = 255 - - ((im->alpha[i] << 1) + (im->alpha[i] >> 6)); - mapping[i] = j++; - } - else - { - mapping[i] = k--; - } - } - } - png_set_tRNS (png_ptr, info_ptr, trans_values, tc, NULL); - } - } - - /* convert palette to libpng layout */ - if (!im->trueColor) - { - if (remap) - for (i = 0; i < im->colorsTotal; ++i) - { - if (mapping[i] < 0) - continue; - palette[mapping[i]].red = im->red[i]; - palette[mapping[i]].green = im->green[i]; - palette[mapping[i]].blue = im->blue[i]; - } - else - for (i = 0; i < colors; ++i) - { - palette[i].red = im->red[i]; - palette[i].green = im->green[i]; - palette[i].blue = im->blue[i]; - } - png_set_PLTE (png_ptr, info_ptr, palette, colors); - } - - /* write out the PNG header info (everything up to first IDAT) */ - png_write_info (png_ptr, info_ptr); - - /* make sure < 8-bit images are packed into pixels as tightly as possible */ - png_set_packing (png_ptr); - - /* This code allocates a set of row buffers and copies the gd image data - * into them only in the case that remapping is necessary; in gd 1.3 and - * later, the im->pixels array is laid out identically to libpng's row - * pointers and can be passed to png_write_image() function directly. - * The remapping case could be accomplished with less memory for non- - * interlaced images, but interlacing causes some serious complications. */ - if (im->trueColor) - { - /* performance optimizations by Phong Tran */ - int channels = im->saveAlphaFlag ? 4 : 3; - /* Our little 7-bit alpha channel trick costs us a bit here. */ - png_bytep *row_pointers; - unsigned char *pOutputRow; - int **ptpixels = im->tpixels; - int *pThisRow; - unsigned char a; - int thisPixel; - png_bytep *prow_pointers; - int saveAlphaFlag = im->saveAlphaFlag; - if (overflow2(sizeof (png_bytep), height)) { - return; - } - row_pointers = gdMalloc (sizeof (png_bytep) * height); - if (row_pointers == NULL) - { - fprintf (stderr, "gd-png error: unable to allocate row_pointers\n"); - /* 2.0.29: return was missing */ - return; - } - prow_pointers = row_pointers; - for (j = 0; j < height; ++j) - { - if (overflow2(width, channels) || ((*prow_pointers = - (png_bytep) gdMalloc (width * channels)) == NULL)) - { - fprintf (stderr, "gd-png error: unable to allocate rows\n"); - for (i = 0; i < j; ++i) - gdFree (row_pointers[i]); - /* 2.0.29: memory leak TBB */ - free(row_pointers); - return; - } - pOutputRow = *prow_pointers++; - pThisRow = *ptpixels++; - for (i = 0; i < width; ++i) - { - thisPixel = *pThisRow++; - *pOutputRow++ = gdTrueColorGetRed (thisPixel); - *pOutputRow++ = gdTrueColorGetGreen (thisPixel); - *pOutputRow++ = gdTrueColorGetBlue (thisPixel); - - if (saveAlphaFlag) - { - /* convert the 7-bit alpha channel to an 8-bit alpha channel. - We do a little bit-flipping magic, repeating the MSB - as the LSB, to ensure that 0 maps to 0 and - 127 maps to 255. We also have to invert to match - PNG's convention in which 255 is opaque. */ - a = gdTrueColorGetAlpha (thisPixel); - /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ - *pOutputRow++ = 255 - ((a << 1) + (a >> 6)); - } - } - } - - png_write_image (png_ptr, row_pointers); - png_write_end (png_ptr, info_ptr); - - for (j = 0; j < height; ++j) - gdFree (row_pointers[j]); - gdFree (row_pointers); - } - else - { - if (remap) - { - png_bytep *row_pointers; - if (overflow2(sizeof (png_bytep), height)) { - return; - } - row_pointers = gdMalloc (sizeof (png_bytep) * height); - if (row_pointers == NULL) - { - fprintf (stderr, - "gd-png error: unable to allocate row_pointers\n"); - /* TBB: return missing */ - return; - } - for (j = 0; j < height; ++j) - { - if ((row_pointers[j] = (png_bytep) gdMalloc (width)) == NULL) - { - fprintf (stderr, "gd-png error: unable to allocate rows\n"); - for (i = 0; i < j; ++i) - gdFree (row_pointers[i]); - /* TBB: memory leak */ - gdFree (row_pointers); - return; - } - for (i = 0; i < width; ++i) - row_pointers[j][i] = mapping[im->pixels[j][i]]; - } - - png_write_image (png_ptr, row_pointers); - png_write_end (png_ptr, info_ptr); - - for (j = 0; j < height; ++j) - gdFree (row_pointers[j]); - gdFree (row_pointers); - } - else - { - png_write_image (png_ptr, im->pixels); - png_write_end (png_ptr, info_ptr); - } - } - /* 1.6.3: maybe we should give that memory BACK! TBB */ - png_destroy_write_struct (&png_ptr, &info_ptr); -} - - -#endif /* HAVE_LIBPNG */ |