"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/gd_png.c" between
libgd-2.2.4.tar.gz and libgd-2.2.5.tar.gz

About: LibGD is a library for the dynamic creation of images by programmers (PNG, JPEG, GIF, WebP, XPM, BMP support).

gd_png.c  (libgd-2.2.4):gd_png.c  (libgd-2.2.5)
skipping to change at line 71 skipping to change at line 71
/* This function, aside from the extra step of retrieving the "error /* This function, aside from the extra step of retrieving the "error
* pointer" (below) and the fact that it exists within the application * pointer" (below) and the fact that it exists within the application
* rather than within libpng, is essentially identical to libpng's * rather than within libpng, is essentially identical to libpng's
* default error handler. The second point is critical: since both * default error handler. The second point is critical: since both
* setjmp() and longjmp() are called from the same code, they are * setjmp() and longjmp() are called from the same code, they are
* guaranteed to have compatible notions of how big a jmp_buf is, * guaranteed to have compatible notions of how big a jmp_buf is,
* regardless of whether _BSD_SOURCE or anything else has (or has not) * regardless of whether _BSD_SOURCE or anything else has (or has not)
* been defined. */ * been defined. */
gd_error_ex(GD_ERROR, "gd-png: fatal libpng error: %s\n", msg); gd_error_ex(GD_WARNING, "gd-png: fatal libpng error: %s\n", msg);
jmpbuf_ptr = png_get_error_ptr (png_ptr); jmpbuf_ptr = png_get_error_ptr (png_ptr);
if (jmpbuf_ptr == NULL) { /* we are complet ely hosed now */ if (jmpbuf_ptr == NULL) { /* we are complet ely hosed now */
gd_error_ex(GD_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unre coverable; terminating.\n"); gd_error_ex(GD_ERROR, "gd-png: EXTREMELY fatal error: jmpbuf unre coverable; terminating.\n");
exit (99); exit (99);
} }
longjmp (jmpbuf_ptr->jmpbuf, 1); longjmp (jmpbuf_ptr->jmpbuf, 1);
} }
#endif #endif
skipping to change at line 634 skipping to change at line 634
Nothing. Nothing.
*/ */
BGD_DECLARE(void) gdImagePng (gdImagePtr im, FILE * outFile) BGD_DECLARE(void) gdImagePng (gdImagePtr im, FILE * outFile)
{ {
gdIOCtx *out = gdNewFileCtx (outFile); gdIOCtx *out = gdNewFileCtx (outFile);
if (out == NULL) return; if (out == NULL) return;
gdImagePngCtxEx (im, out, -1); gdImagePngCtxEx (im, out, -1);
out->gd_free (out); out->gd_free (out);
} }
static int _gdImagePngCtxEx(gdImagePtr im, gdIOCtx * outfile, int level);
/* /*
Function: gdImagePngPtr Function: gdImagePngPtr
Equivalent to calling <gdImagePngPtrEx> with compression of -1. Equivalent to calling <gdImagePngPtrEx> with compression of -1.
See <gdImagePngEx> for more information. See <gdImagePngEx> for more information.
Parameters: Parameters:
im - the image to save. im - the image to save.
skipping to change at line 656 skipping to change at line 658
Returns: Returns:
A pointer to memory containing the image data or NULL on error. A pointer to memory containing the image data or NULL on error.
*/ */
BGD_DECLARE(void *) gdImagePngPtr (gdImagePtr im, int *size) BGD_DECLARE(void *) gdImagePngPtr (gdImagePtr im, int *size)
{ {
void *rv; void *rv;
gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
if (out == NULL) return NULL; if (out == NULL) return NULL;
gdImagePngCtxEx (im, out, -1); if (!_gdImagePngCtxEx (im, out, -1)) {
rv = gdDPExtractData (out, size); rv = gdDPExtractData (out, size);
} else {
rv = NULL;
}
out->gd_free (out); out->gd_free (out);
return rv; return rv;
} }
/* /*
Function: gdImagePngPtrEx Function: gdImagePngPtrEx
Identical to <gdImagePngEx> except that it returns a pointer to a Identical to <gdImagePngEx> except that it returns a pointer to a
memory area with the PNG data. This memory must be freed by the memory area with the PNG data. This memory must be freed by the
caller when it is no longer needed. **The caller must invoke caller when it is no longer needed. **The caller must invoke
skipping to change at line 691 skipping to change at line 696
Returns: Returns:
A pointer to memory containing the image data or NULL on error. A pointer to memory containing the image data or NULL on error.
*/ */
BGD_DECLARE(void *) gdImagePngPtrEx (gdImagePtr im, int *size, int level) BGD_DECLARE(void *) gdImagePngPtrEx (gdImagePtr im, int *size, int level)
{ {
void *rv; void *rv;
gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
if (out == NULL) return NULL; if (out == NULL) return NULL;
gdImagePngCtxEx (im, out, level); if (!_gdImagePngCtxEx (im, out, level)) {
rv = gdDPExtractData (out, size); rv = gdDPExtractData (out, size);
} else {
rv = NULL;
}
out->gd_free (out); out->gd_free (out);
return rv; return rv;
} }
/* /*
Function: gdImagePngCtx Function: gdImagePngCtx
Equivalent to calling <gdImagePngCtxEx> with compression of -1. Equivalent to calling <gdImagePngCtxEx> with compression of -1.
See <gdImagePngEx> for more information. See <gdImagePngEx> for more information.
skipping to change at line 736 skipping to change at line 744
im - the image to save. im - the image to save.
outfile - the <gdIOCtx> to write to. outfile - the <gdIOCtx> to write to.
level - compression level: 0 -> none, 1-9 -> level, -1 -> default level - compression level: 0 -> none, 1-9 -> level, -1 -> default
Returns: Returns:
Nothing. Nothing.
*/ */
BGD_DECLARE(void) gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level)
{
_gdImagePngCtxEx(im, outfile, level);
}
/* This routine is based in part on code from Dale Lutz (Safe Software Inc.) /* 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" * and in part on demo code from Chapter 15 of "PNG: The Definitive Guide"
* (http://www.libpng.org/pub/png/book/). * (http://www.libpng.org/pub/png/book/).
*/ */
BGD_DECLARE(void) gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level) /* returns 0 on success, 1 on failure */
static int _gdImagePngCtxEx(gdImagePtr im, gdIOCtx * outfile, int level)
{ {
int i, j, bit_depth = 0, interlace_type; int i, j, bit_depth = 0, interlace_type;
int width = im->sx; int width = im->sx;
int height = im->sy; int height = im->sy;
int colors = im->colorsTotal; int colors = im->colorsTotal;
int *open = im->open; int *open = im->open;
int mapping[gdMaxColors]; /* mapping[gd_index] == png_index */ int mapping[gdMaxColors]; /* mapping[gd_index] == png_index */
png_byte trans_values[256]; png_byte trans_values[256];
png_color_16 trans_rgb_value; png_color_16 trans_rgb_value;
png_color palette[gdMaxColors]; png_color palette[gdMaxColors];
png_structp png_ptr; png_structp png_ptr;
png_infop info_ptr; png_infop info_ptr;
volatile int transparent = im->transparent; volatile int transparent = im->transparent;
volatile int remap = FALSE; volatile int remap = FALSE;
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
jmpbuf_wrapper jbw; jmpbuf_wrapper jbw;
#endif #endif
int ret = 0;
/* width or height of value 0 is invalid in IHDR; /* width or height of value 0 is invalid in IHDR;
see http://www.w3.org/TR/PNG-Chunks.html */ see http://www.w3.org/TR/PNG-Chunks.html */
if (width == 0 || height ==0) return; if (width == 0 || height ==0) return 1;
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,
&jbw, gdPngErrorHandler, &jbw, gdPngErrorHandler,
NULL); NULL);
#else #else
png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NUL L); png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NUL L);
#endif #endif
if (png_ptr == NULL) { if (png_ptr == NULL) {
gd_error("gd-png error: cannot allocate libpng main struct\n"); gd_error("gd-png error: cannot allocate libpng main struct\n");
return; return 1;
} }
info_ptr = png_create_info_struct (png_ptr); info_ptr = png_create_info_struct (png_ptr);
if (info_ptr == NULL) { if (info_ptr == NULL) {
gd_error("gd-png error: cannot allocate libpng info struct\n"); gd_error("gd-png error: cannot allocate libpng info struct\n");
png_destroy_write_struct (&png_ptr, (png_infopp) NULL); png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
return; return 1;
} }
#ifdef PNG_SETJMP_SUPPORTED #ifdef PNG_SETJMP_SUPPORTED
if (setjmp(jbw.jmpbuf)) { if (setjmp(jbw.jmpbuf)) {
gd_error("gd-png error: setjmp returns error condition\n"); gd_error("gd-png error: setjmp returns error condition\n");
png_destroy_write_struct (&png_ptr, &info_ptr); png_destroy_write_struct (&png_ptr, &info_ptr);
return; return 1;
} }
#endif #endif
png_set_write_fn (png_ptr, (void *) outfile, gdPngWriteData, png_set_write_fn (png_ptr, (void *) outfile, gdPngWriteData,
gdPngFlushData); gdPngFlushData);
/* This is best for palette images, and libpng defaults to it for /* This is best for palette images, and libpng defaults to it for
palette images anyway, so we don't need to do it explicitly. palette images anyway, so we don't need to do it explicitly.
What to ideally do for truecolor images depends, alas, on the image. What to ideally do for truecolor images depends, alas, on the image.
gd is intentionally imperfect and doesn't spend a lot of time gd is intentionally imperfect and doesn't spend a lot of time
skipping to change at line 839 skipping to change at line 853
/* count actual number of colors used (colorsTotal == high-water mark) */ /* count actual number of colors used (colorsTotal == high-water mark) */
colors = 0; colors = 0;
for (i = 0; i < im->colorsTotal; ++i) { for (i = 0; i < im->colorsTotal; ++i) {
if (!open[i]) { if (!open[i]) {
mapping[i] = colors; mapping[i] = colors;
++colors; ++colors;
} }
} }
if (colors == 0) { if (colors == 0) {
gd_error("gd-png error: no colors in palette\n"); gd_error("gd-png error: no colors in palette\n");
ret = 1;
goto bail; goto bail;
} }
if (colors < im->colorsTotal) { if (colors < im->colorsTotal) {
remap = TRUE; remap = TRUE;
} }
if (colors <= 2) if (colors <= 2)
bit_depth = 1; bit_depth = 1;
else if (colors <= 4) else if (colors <= 4)
bit_depth = 2; bit_depth = 2;
else if (colors <= 16) else if (colors <= 16)
skipping to change at line 970 skipping to change at line 985
/* Our little 7-bit alpha channel trick costs us a bit here. */ /* Our little 7-bit alpha channel trick costs us a bit here. */
png_bytep *row_pointers; png_bytep *row_pointers;
unsigned char *pOutputRow; unsigned char *pOutputRow;
int **ptpixels = im->tpixels; int **ptpixels = im->tpixels;
int *pThisRow; int *pThisRow;
unsigned char a; unsigned char a;
int thisPixel; int thisPixel;
png_bytep *prow_pointers; png_bytep *prow_pointers;
int saveAlphaFlag = im->saveAlphaFlag; int saveAlphaFlag = im->saveAlphaFlag;
if (overflow2(sizeof (png_bytep), height)) { if (overflow2(sizeof (png_bytep), height)) {
ret = 1;
goto bail; goto bail;
} }
row_pointers = gdMalloc (sizeof (png_bytep) * height); row_pointers = gdMalloc (sizeof (png_bytep) * height);
if (row_pointers == NULL) { if (row_pointers == NULL) {
gd_error("gd-png error: unable to allocate row_pointers\n "); gd_error("gd-png error: unable to allocate row_pointers\n ");
ret = 1;
goto bail; goto bail;
} }
prow_pointers = row_pointers; prow_pointers = row_pointers;
for (j = 0; j < height; ++j) { for (j = 0; j < height; ++j) {
if (overflow2(width, channels) || ((*prow_pointers = if (overflow2(width, channels) || ((*prow_pointers =
(png_bytep) gdMal loc (width * channels)) == NULL)) { (png_bytep) gdMal loc (width * channels)) == NULL)) {
gd_error("gd-png error: unable to allocate rows\n "); gd_error("gd-png error: unable to allocate rows\n ");
for (i = 0; i < j; ++i) for (i = 0; i < j; ++i)
gdFree (row_pointers[i]); gdFree (row_pointers[i]);
/* 2.0.29: memory leak TBB */ /* 2.0.29: memory leak TBB */
gdFree(row_pointers); gdFree(row_pointers);
ret = 1;
goto bail; goto bail;
} }
pOutputRow = *prow_pointers++; pOutputRow = *prow_pointers++;
pThisRow = *ptpixels++; pThisRow = *ptpixels++;
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
thisPixel = *pThisRow++; thisPixel = *pThisRow++;
*pOutputRow++ = gdTrueColorGetRed (thisPixel); *pOutputRow++ = gdTrueColorGetRed (thisPixel);
*pOutputRow++ = gdTrueColorGetGreen (thisPixel); *pOutputRow++ = gdTrueColorGetGreen (thisPixel);
*pOutputRow++ = gdTrueColorGetBlue (thisPixel); *pOutputRow++ = gdTrueColorGetBlue (thisPixel);
skipping to change at line 1019 skipping to change at line 1037
png_write_image (png_ptr, row_pointers); png_write_image (png_ptr, row_pointers);
png_write_end (png_ptr, info_ptr); png_write_end (png_ptr, info_ptr);
for (j = 0; j < height; ++j) for (j = 0; j < height; ++j)
gdFree (row_pointers[j]); gdFree (row_pointers[j]);
gdFree (row_pointers); gdFree (row_pointers);
} else { } else {
if (remap) { if (remap) {
png_bytep *row_pointers; png_bytep *row_pointers;
if (overflow2(sizeof (png_bytep), height)) { if (overflow2(sizeof (png_bytep), height)) {
ret = 1;
goto bail; goto bail;
} }
row_pointers = gdMalloc (sizeof (png_bytep) * height); row_pointers = gdMalloc (sizeof (png_bytep) * height);
if (row_pointers == NULL) { if (row_pointers == NULL) {
gd_error("gd-png error: unable to allocate row_po inters\n"); gd_error("gd-png error: unable to allocate row_po inters\n");
ret = 1;
goto bail; goto bail;
} }
for (j = 0; j < height; ++j) { for (j = 0; j < height; ++j) {
if ((row_pointers[j] = (png_bytep) gdMalloc (widt h)) == NULL) { if ((row_pointers[j] = (png_bytep) gdMalloc (widt h)) == NULL) {
gd_error("gd-png error: unable to allocat e rows\n"); gd_error("gd-png error: unable to allocat e rows\n");
for (i = 0; i < j; ++i) for (i = 0; i < j; ++i)
gdFree (row_pointers[i]); gdFree (row_pointers[i]);
/* TBB: memory leak */ /* TBB: memory leak */
gdFree (row_pointers); gdFree (row_pointers);
ret = 1;
goto bail; goto bail;
} }
for (i = 0; i < width; ++i) for (i = 0; i < width; ++i)
row_pointers[j][i] = mapping[im->pixels[j ][i]]; row_pointers[j][i] = mapping[im->pixels[j ][i]];
} }
png_write_image (png_ptr, row_pointers); png_write_image (png_ptr, row_pointers);
png_write_end (png_ptr, info_ptr); png_write_end (png_ptr, info_ptr);
for (j = 0; j < height; ++j) for (j = 0; j < height; ++j)
gdFree (row_pointers[j]); gdFree (row_pointers[j]);
gdFree (row_pointers); gdFree (row_pointers);
} else { } else {
png_write_image (png_ptr, im->pixels); png_write_image (png_ptr, im->pixels);
png_write_end (png_ptr, info_ptr); png_write_end (png_ptr, info_ptr);
} }
} }
/* 1.6.3: maybe we should give that memory BACK! TBB */ /* 1.6.3: maybe we should give that memory BACK! TBB */
bail: bail:
png_destroy_write_struct (&png_ptr, &info_ptr); png_destroy_write_struct (&png_ptr, &info_ptr);
return ret;
} }
#endif /* HAVE_LIBPNG */ #endif /* HAVE_LIBPNG */
 End of changes. 19 change blocks. 
10 lines changed or deleted 32 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)