+
/* pngrutil.c - utilities to read a PNG file
*
- * libpng version 1.2.7 - September 12, 2004
+ * Last changed in libpng 1.2.34 [December 18, 2008]
* For conditions of distribution and use, see copyright notice in png.h
- * Copyright (c) 1998-2004 Glenn Randers-Pehrson
+ * Copyright (c) 1998-2008 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
#define PNG_INTERNAL
#include "png.h"
+#if defined(PNG_READ_SUPPORTED)
+
+#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
+# define WIN32_WCE_OLD
+#endif
-#if defined(_WIN32_WCE)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+# if defined(WIN32_WCE_OLD)
/* strtod() function is not supported on WindowsCE */
-# ifdef PNG_FLOATING_POINT_SUPPORTED
-__inline double strtod(const char *nptr, char **endptr)
+__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
{
double result = 0;
int len;
wchar_t *str, *end;
len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
- str = (wchar_t *)malloc(len * sizeof(wchar_t));
+ str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
if ( NULL != str )
{
MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
result = wcstod(str, &end);
len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
*endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
- free(str);
+ png_free(png_ptr, str);
}
return result;
}
+# else
+# define png_strtod(p,a,b) strtod(a,b)
# endif
#endif
-png_uint_32 /* PRIVATE */
+png_uint_32 PNGAPI
png_get_uint_31(png_structp png_ptr, png_bytep buf)
{
+#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
png_uint_32 i = png_get_uint_32(buf);
+#else
+ /* Avoid an extra function call by inlining the result. */
+ png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+ ((png_uint_32)(*(buf + 1)) << 16) +
+ ((png_uint_32)(*(buf + 2)) << 8) +
+ (png_uint_32)(*(buf + 3));
+#endif
if (i > PNG_UINT_31_MAX)
- png_error(png_ptr, "PNG unsigned integer out of range.\n");
+ png_error(png_ptr, "PNG unsigned integer out of range.");
return (i);
}
#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
-png_uint_32 /* PRIVATE */
+png_uint_32 PNGAPI
png_get_uint_32(png_bytep buf)
{
png_uint_32 i = ((png_uint_32)(*buf) << 24) +
return (i);
}
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
/* Grab a signed 32-bit integer from a buffer in big-endian format. The
* data is stored in the PNG file in two's complement format, and it is
* assumed that the machine format for signed integers is the same. */
-png_int_32 /* PRIVATE */
+png_int_32 PNGAPI
png_get_int_32(png_bytep buf)
{
png_int_32 i = ((png_int_32)(*buf) << 24) +
return (i);
}
-#endif /* PNG_READ_pCAL_SUPPORTED */
/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
-png_uint_16 /* PRIVATE */
+png_uint_16 PNGAPI
png_get_uint_16(png_bytep buf)
{
png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
}
#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+/* Read the chunk header (length + type name).
+ * Put the type name into png_ptr->chunk_name, and return the length.
+ */
+png_uint_32 /* PRIVATE */
+png_read_chunk_header(png_structp png_ptr)
+{
+ png_byte buf[8];
+ png_uint_32 length;
+
+ /* read the length and the chunk name */
+ png_read_data(png_ptr, buf, 8);
+ length = png_get_uint_31(png_ptr, buf);
+
+ /* put the chunk name into png_ptr->chunk_name */
+ png_memcpy(png_ptr->chunk_name, buf + 4, 4);
+
+ png_debug2(0, "Reading %s chunk, length = %lu",
+ png_ptr->chunk_name, length);
+
+ /* reset the crc and run it over the chunk name */
+ png_reset_crc(png_ptr);
+ png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
+
+ /* check to see if chunk name is valid */
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+ return length;
+}
+
/* Read data, and (optionally) run it through the CRC. */
void /* PRIVATE */
png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
{
+ if (png_ptr == NULL) return;
png_read_data(png_ptr, buf, length);
png_calculate_crc(png_ptr, buf, length);
}
* holding the original prefix part and an uncompressed version of the
* trailing part (the malloc area passed in is freed).
*/
-png_charp /* PRIVATE */
+void /* PRIVATE */
png_decompress_chunk(png_structp png_ptr, int comp_type,
- png_charp chunkdata, png_size_t chunklength,
+ png_size_t chunklength,
png_size_t prefix_size, png_size_t *newlength)
{
- static char msg[] = "Error decoding compressed text";
+ static PNG_CONST char msg[] = "Error decoding compressed text";
png_charp text;
png_size_t text_size;
if (comp_type == PNG_COMPRESSION_TYPE_BASE)
{
int ret = Z_OK;
- png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
+ png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size);
png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
text = (png_charp)png_malloc_warn(png_ptr, text_size);
if (text == NULL)
{
- png_free(png_ptr,chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_error(png_ptr, "Not enough memory to decompress chunk");
}
- png_memcpy(text, chunkdata, prefix_size);
+ png_memcpy(text, png_ptr->chunkdata, prefix_size);
}
text[text_size - 1] = 0x00;
/* Copy what we can of the error message into the text chunk */
- text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
- text_size = png_sizeof(msg) > text_size ? text_size :
- png_sizeof(msg);
- png_memcpy(text + prefix_size, msg, text_size + 1);
+ text_size = (png_size_t)(chunklength -
+ (text - png_ptr->chunkdata) - 1);
+ if (text_size > png_sizeof(msg))
+ text_size = png_sizeof(msg);
+ png_memcpy(text + prefix_size, msg, text_size);
break;
}
if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
png_ptr->zbuf_size - png_ptr->zstream.avail_out;
text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
if (text == NULL)
- {
- png_free(png_ptr,chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk.");
- }
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_error(png_ptr,
+ "Not enough memory to decompress chunk.");
+ }
png_memcpy(text + prefix_size, png_ptr->zbuf,
text_size - prefix_size);
- png_memcpy(text, chunkdata, prefix_size);
+ png_memcpy(text, png_ptr->chunkdata, prefix_size);
*(text + text_size) = 0x00;
}
else
if (text == NULL)
{
png_free(png_ptr, tmp);
- png_free(png_ptr, chunkdata);
- png_error(png_ptr,"Not enough memory to decompress chunk..");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_error(png_ptr,
+ "Not enough memory to decompress chunk..");
}
png_memcpy(text, tmp, text_size);
png_free(png_ptr, tmp);
if (ret != Z_STREAM_END)
{
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
- char umsg[50];
+ char umsg[52];
if (ret == Z_BUF_ERROR)
- sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
- (char *)png_ptr->chunk_name);
+ png_snprintf(umsg, 52,
+ "Buffer error in compressed datastream in %s chunk",
+ png_ptr->chunk_name);
else if (ret == Z_DATA_ERROR)
- sprintf(umsg,"Data error in compressed datastream in %s chunk",
- (char *)png_ptr->chunk_name);
+ png_snprintf(umsg, 52,
+ "Data error in compressed datastream in %s chunk",
+ png_ptr->chunk_name);
else
- sprintf(umsg,"Incomplete compressed datastream in %s chunk",
- (char *)png_ptr->chunk_name);
+ png_snprintf(umsg, 52,
+ "Incomplete compressed datastream in %s chunk",
+ png_ptr->chunk_name);
png_warning(png_ptr, umsg);
#else
png_warning(png_ptr,
"Incomplete compressed datastream in chunk other than IDAT");
#endif
- text_size=prefix_size;
+ text_size = prefix_size;
if (text == NULL)
{
text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
if (text == NULL)
{
- png_free(png_ptr, chunkdata);
- png_error(png_ptr,"Not enough memory for text.");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_error(png_ptr, "Not enough memory for text.");
}
- png_memcpy(text, chunkdata, prefix_size);
+ png_memcpy(text, png_ptr->chunkdata, prefix_size);
}
*(text + text_size) = 0x00;
}
inflateReset(&png_ptr->zstream);
png_ptr->zstream.avail_in = 0;
- png_free(png_ptr, chunkdata);
- chunkdata = text;
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = text;
*newlength=text_size;
}
else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
char umsg[50];
- sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
+ png_snprintf(umsg, 50, "Unknown zTXt compression type %d", comp_type);
png_warning(png_ptr, umsg);
#else
png_warning(png_ptr, "Unknown zTXt compression type");
#endif
- *(chunkdata + prefix_size) = 0x00;
- *newlength=prefix_size;
+ *(png_ptr->chunkdata + prefix_size) = 0x00;
+ *newlength = prefix_size;
}
-
- return chunkdata;
}
#endif
int bit_depth, color_type, compression_type, filter_type;
int interlace_type;
- png_debug(1, "in png_handle_IHDR\n");
+ png_debug(1, "in png_handle_IHDR");
if (png_ptr->mode & PNG_HAVE_IHDR)
png_error(png_ptr, "Out of place IHDR");
/* set up other useful info */
png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
png_ptr->channels);
- png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
- png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
- png_debug1(3,"channels = %d\n", png_ptr->channels);
- png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
+ png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
+ png_debug1(3, "channels = %d", png_ptr->channels);
+ png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
color_type, interlace_type, compression_type, filter_type);
}
png_colorp pal_ptr;
#endif
- png_debug(1, "in png_handle_PLTE\n");
+ png_debug(1, "in png_handle_PLTE");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before PLTE");
void /* PRIVATE */
png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
- png_debug(1, "in png_handle_IEND\n");
+ png_debug(1, "in png_handle_IEND");
if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
{
}
png_crc_finish(png_ptr, length);
- if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
- return;
+ info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
}
#if defined(PNG_READ_gAMA_SUPPORTED)
#endif
png_byte buf[4];
- png_debug(1, "in png_handle_gAMA\n");
+ png_debug(1, "in png_handle_gAMA");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before gAMA");
}
#if defined(PNG_READ_sRGB_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sRGB)
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
{
png_warning(png_ptr,
"Ignoring incorrect gAMA value when sRGB is also present");
#ifndef PNG_NO_CONSOLE_IO
- fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
+ fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
#endif
return;
}
png_size_t truelen;
png_byte buf[4];
- png_debug(1, "in png_handle_sBIT\n");
+ png_debug(1, "in png_handle_sBIT");
buf[0] = buf[1] = buf[2] = buf[3] = 0;
void /* PRIVATE */
png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
- png_byte buf[4];
+ png_byte buf[32];
#ifdef PNG_FLOATING_POINT_SUPPORTED
float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
#endif
png_uint_32 uint_x, uint_y;
- png_debug(1, "in png_handle_cHRM\n");
+ png_debug(1, "in png_handle_cHRM");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before cHRM");
return;
}
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x > 80000L || uint_y > 80000L ||
- uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM white point");
- png_crc_finish(png_ptr, 24);
+ png_crc_read(png_ptr, buf, 32);
+ if (png_crc_finish(png_ptr, 0))
return;
- }
- int_x_white = (png_fixed_point)uint_x;
- int_y_white = (png_fixed_point)uint_y;
- png_crc_read(png_ptr, buf, 4);
uint_x = png_get_uint_32(buf);
+ uint_y = png_get_uint_32(buf + 4);
+ int_x_white = (png_fixed_point)uint_x;
+ int_y_white = (png_fixed_point)uint_y;
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x > 80000L || uint_y > 80000L ||
- uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM red point");
- png_crc_finish(png_ptr, 16);
- return;
- }
+ uint_x = png_get_uint_32(buf + 8);
+ uint_y = png_get_uint_32(buf + 12);
int_x_red = (png_fixed_point)uint_x;
int_y_red = (png_fixed_point)uint_y;
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x > 80000L || uint_y > 80000L ||
- uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM green point");
- png_crc_finish(png_ptr, 8);
- return;
- }
+ uint_x = png_get_uint_32(buf + 16);
+ uint_y = png_get_uint_32(buf + 20);
int_x_green = (png_fixed_point)uint_x;
int_y_green = (png_fixed_point)uint_y;
- png_crc_read(png_ptr, buf, 4);
- uint_x = png_get_uint_32(buf);
-
- png_crc_read(png_ptr, buf, 4);
- uint_y = png_get_uint_32(buf);
-
- if (uint_x > 80000L || uint_y > 80000L ||
- uint_x + uint_y > 100000L)
- {
- png_warning(png_ptr, "Invalid cHRM blue point");
- png_crc_finish(png_ptr, 0);
- return;
- }
+ uint_x = png_get_uint_32(buf + 24);
+ uint_y = png_get_uint_32(buf + 28);
int_x_blue = (png_fixed_point)uint_x;
int_y_blue = (png_fixed_point)uint_y;
#endif
#if defined(PNG_READ_sRGB_SUPPORTED)
- if (info_ptr->valid & PNG_INFO_sRGB)
+ if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
{
if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
{
-
png_warning(png_ptr,
"Ignoring incorrect cHRM value when sRGB is also present");
#ifndef PNG_NO_CONSOLE_IO
#ifdef PNG_FLOATING_POINT_SUPPORTED
- fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
+ fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
white_x, white_y, red_x, red_y);
- fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
+ fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
green_x, green_y, blue_x, blue_y);
#else
- fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
+ fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
int_x_white, int_y_white, int_x_red, int_y_red);
- fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
+ fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
int_x_green, int_y_green, int_x_blue, int_y_blue);
#endif
#endif /* PNG_NO_CONSOLE_IO */
}
- png_crc_finish(png_ptr, 0);
return;
}
#endif /* PNG_READ_sRGB_SUPPORTED */
int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
int_y_green, int_x_blue, int_y_blue);
#endif
- if (png_crc_finish(png_ptr, 0))
- return;
}
#endif
int intent;
png_byte buf[1];
- png_debug(1, "in png_handle_sRGB\n");
+ png_debug(1, "in png_handle_sRGB");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before sRGB");
}
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
- if ((info_ptr->valid & PNG_INFO_gAMA))
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
{
png_fixed_point igamma;
#ifdef PNG_FIXED_POINT_SUPPORTED
"Ignoring incorrect gAMA value when sRGB is also present");
#ifndef PNG_NO_CONSOLE_IO
# ifdef PNG_FIXED_POINT_SUPPORTED
- fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
+ fprintf(stderr, "incorrect gamma=(%d/100000)\n",
+ (int)png_ptr->int_gamma);
# else
# ifdef PNG_FLOATING_POINT_SUPPORTED
- fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
+ fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
# endif
# endif
#endif
#ifdef PNG_READ_cHRM_SUPPORTED
#ifdef PNG_FIXED_POINT_SUPPORTED
- if (info_ptr->valid & PNG_INFO_cHRM)
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
- png_charp chunkdata;
png_byte compression_type;
png_bytep pC;
png_charp profile;
png_uint_32 profile_size, profile_length;
png_size_t slength, prefix_length, data_length;
- png_debug(1, "in png_handle_iCCP\n");
+ png_debug(1, "in png_handle_iCCP");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before iCCP");
}
#endif
- chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
if (png_crc_finish(png_ptr, skip))
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
- chunkdata[slength] = 0x00;
+ png_ptr->chunkdata[slength] = 0x00;
- for (profile = chunkdata; *profile; profile++)
+ for (profile = png_ptr->chunkdata; *profile; profile++)
/* empty loop to find end of name */ ;
++profile;
/* there should be at least one zero (the compression type byte)
following the separator, and we should be on it */
- if ( profile >= chunkdata + slength)
+ if ( profile >= png_ptr->chunkdata + slength - 1)
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_warning(png_ptr, "Malformed iCCP chunk");
return;
}
if (compression_type)
{
png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
- compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
+ compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
wrote nonzero) */
}
- prefix_length = profile - chunkdata;
- chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
- slength, prefix_length, &data_length);
+ prefix_length = profile - png_ptr->chunkdata;
+ png_decompress_chunk(png_ptr, compression_type,
+ slength, prefix_length, &data_length);
profile_length = data_length - prefix_length;
if ( prefix_length > data_length || profile_length < 4)
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_warning(png_ptr, "Profile size field missing from iCCP chunk");
return;
}
/* Check the profile_size recorded in the first 32 bits of the ICC profile */
- pC = (png_bytep)(chunkdata+prefix_length);
- profile_size = ((*(pC ))<<24) |
- ((*(pC+1))<<16) |
- ((*(pC+2))<< 8) |
- ((*(pC+3)) );
+ pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
+ profile_size = ((*(pC ))<<24) |
+ ((*(pC + 1))<<16) |
+ ((*(pC + 2))<< 8) |
+ ((*(pC + 3)) );
- if(profile_size < profile_length)
+ if (profile_size < profile_length)
profile_length = profile_size;
- if(profile_size > profile_length)
+ if (profile_size > profile_length)
{
- png_free(png_ptr, chunkdata);
- png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_warning(png_ptr, "Ignoring truncated iCCP profile.");
return;
}
- png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
- chunkdata + prefix_length, profile_length);
- png_free(png_ptr, chunkdata);
+ png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
+ compression_type, png_ptr->chunkdata + prefix_length, profile_length);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
}
#endif /* PNG_READ_iCCP_SUPPORTED */
png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Note: this does not properly handle chunks that are > 64K under DOS */
{
- png_bytep chunkdata;
png_bytep entry_start;
png_sPLT_t new_palette;
#ifdef PNG_NO_POINTER_INDEXING
png_uint_32 skip = 0;
png_size_t slength;
- png_debug(1, "in png_handle_sPLT\n");
+ png_debug(1, "in png_handle_sPLT");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before sPLT");
}
#endif
- chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
if (png_crc_finish(png_ptr, skip))
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
- chunkdata[slength] = 0x00;
+ png_ptr->chunkdata[slength] = 0x00;
- for (entry_start = chunkdata; *entry_start; entry_start++)
+ for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; entry_start++)
/* empty loop to find end of name */ ;
++entry_start;
/* a sample depth should follow the separator, and we should be on it */
- if (entry_start > chunkdata + slength)
+ if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_warning(png_ptr, "malformed sPLT chunk");
return;
}
new_palette.depth = *entry_start++;
entry_size = (new_palette.depth == 8 ? 6 : 10);
- data_length = (slength - (entry_start - chunkdata));
+ data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
/* integrity-check the data length */
if (data_length % entry_size)
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_warning(png_ptr, "sPLT chunk has bad length");
return;
}
- new_palette.nentries = (png_uint_32) (data_length / entry_size);
- if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
- png_sizeof(png_sPLT_entry)))
+ new_palette.nentries = (png_int_32) ( data_length / entry_size);
+ if ((png_uint_32) new_palette.nentries >
+ (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
{
png_warning(png_ptr, "sPLT chunk too long");
return;
#endif
/* discard all chunk data except the name and stash that */
- new_palette.name = (png_charp)chunkdata;
+ new_palette.name = png_ptr->chunkdata;
png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_free(png_ptr, new_palette.entries);
}
#endif /* PNG_READ_sPLT_SUPPORTED */
{
png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
- png_debug(1, "in png_handle_tRNS\n");
+ png_debug(1, "in png_handle_tRNS");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before tRNS");
}
if (png_crc_finish(png_ptr, 0))
+ {
+ png_ptr->num_trans = 0;
return;
+ }
png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
&(png_ptr->trans_values));
png_size_t truelen;
png_byte buf[6];
- png_debug(1, "in png_handle_bKGD\n");
+ png_debug(1, "in png_handle_bKGD");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before bKGD");
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
png_ptr->background.index = buf[0];
- if(info_ptr->num_palette)
+ if (info_ptr && info_ptr->num_palette)
{
- if(buf[0] > info_ptr->num_palette)
+ if (buf[0] >= info_ptr->num_palette)
{
png_warning(png_ptr, "Incorrect bKGD chunk index value");
return;
unsigned int num, i;
png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
- png_debug(1, "in png_handle_hIST\n");
+ png_debug(1, "in png_handle_hIST");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before hIST");
png_uint_32 res_x, res_y;
int unit_type;
- png_debug(1, "in png_handle_pHYs\n");
+ png_debug(1, "in png_handle_pHYs");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before pHYs");
png_int_32 offset_x, offset_y;
int unit_type;
- png_debug(1, "in png_handle_oFFs\n");
+ png_debug(1, "in png_handle_oFFs");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before oFFs");
void /* PRIVATE */
png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
- png_charp purpose;
png_int_32 X0, X1;
png_byte type, nparams;
png_charp buf, units, endptr;
png_size_t slength;
int i;
- png_debug(1, "in png_handle_pCAL\n");
+ png_debug(1, "in png_handle_pCAL");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before pCAL");
return;
}
- png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
+ png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
length + 1);
- purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (purpose == NULL)
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
{
png_warning(png_ptr, "No memory for pCAL purpose.");
return;
}
slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)purpose, slength);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
if (png_crc_finish(png_ptr, 0))
{
- png_free(png_ptr, purpose);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
- purpose[slength] = 0x00; /* null terminate the last string */
+ png_ptr->chunkdata[slength] = 0x00; /* null terminate the last string */
- png_debug(3, "Finding end of pCAL purpose string\n");
- for (buf = purpose; *buf; buf++)
+ png_debug(3, "Finding end of pCAL purpose string");
+ for (buf = png_ptr->chunkdata; *buf; buf++)
/* empty loop */ ;
- endptr = purpose + slength;
+ endptr = png_ptr->chunkdata + slength;
/* We need to have at least 12 bytes after the purpose string
in order to get the parameter information. */
if (endptr <= buf + 12)
{
png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
- png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
+ png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
X0 = png_get_int_32((png_bytep)buf+1);
X1 = png_get_int_32((png_bytep)buf+5);
type = buf[9];
nparams = buf[10];
units = buf + 11;
- png_debug(3, "Checking pCAL equation type and number of parameters\n");
+ png_debug(3, "Checking pCAL equation type and number of parameters");
/* Check that we have the right number of parameters for known
equation types. */
if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
(type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
{
png_warning(png_ptr, "Invalid pCAL parameters for equation type");
- png_free(png_ptr, purpose);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
else if (type >= PNG_EQUATION_LAST)
for (buf = units; *buf; buf++)
/* Empty loop to move past the units string. */ ;
- png_debug(3, "Allocating pCAL parameters array\n");
- params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
- *png_sizeof(png_charp))) ;
+ png_debug(3, "Allocating pCAL parameters array");
+ params = (png_charpp)png_malloc_warn(png_ptr,
+ (png_uint_32)(nparams * png_sizeof(png_charp))) ;
if (params == NULL)
{
- png_free(png_ptr, purpose);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_warning(png_ptr, "No memory for pCAL params.");
return;
}
{
buf++; /* Skip the null string terminator from previous parameter. */
- png_debug1(3, "Reading pCAL parameter %d\n", i);
- for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
+ png_debug1(3, "Reading pCAL parameter %d", i);
+ for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
/* Empty loop to move past each parameter string */ ;
/* Make sure we haven't run out of data yet */
if (buf > endptr)
{
png_warning(png_ptr, "Invalid pCAL data");
- png_free(png_ptr, purpose);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_free(png_ptr, params);
return;
}
}
- png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
+ png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
units, params);
- png_free(png_ptr, purpose);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_free(png_ptr, params);
}
#endif
void /* PRIVATE */
png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
- png_charp buffer, ep;
+ png_charp ep;
#ifdef PNG_FLOATING_POINT_SUPPORTED
double width, height;
png_charp vp;
#endif
png_size_t slength;
- png_debug(1, "in png_handle_sCAL\n");
+ png_debug(1, "in png_handle_sCAL");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before sCAL");
return;
}
- png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
+ png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
length + 1);
- buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (buffer == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk");
- return;
- }
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk");
+ return;
+ }
slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)buffer, slength);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
if (png_crc_finish(png_ptr, 0))
{
- png_free(png_ptr, buffer);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
- buffer[slength] = 0x00; /* null terminate the last string */
+ png_ptr->chunkdata[slength] = 0x00; /* null terminate the last string */
- ep = buffer + 1; /* skip unit byte */
+ ep = png_ptr->chunkdata + 1; /* skip unit byte */
#ifdef PNG_FLOATING_POINT_SUPPORTED
- width = strtod(ep, &vp);
+ width = png_strtod(png_ptr, ep, &vp);
if (*vp)
{
- png_warning(png_ptr, "malformed width string in sCAL chunk");
- return;
+ png_warning(png_ptr, "malformed width string in sCAL chunk");
+ return;
}
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
if (swidth == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
- return;
- }
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
+ return;
+ }
png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
#endif
#endif
- for (ep = buffer; *ep; ep++)
+ for (ep = png_ptr->chunkdata; *ep; ep++)
/* empty loop */ ;
ep++;
+ if (png_ptr->chunkdata + slength < ep)
+ {
+ png_warning(png_ptr, "Truncated sCAL chunk");
+#if defined(PNG_FIXED_POINT_SUPPORTED) && \
+ !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+#endif
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
#ifdef PNG_FLOATING_POINT_SUPPORTED
- height = strtod(ep, &vp);
+ height = png_strtod(png_ptr, ep, &vp);
if (*vp)
{
- png_warning(png_ptr, "malformed height string in sCAL chunk");
- return;
+ png_warning(png_ptr, "malformed height string in sCAL chunk");
+ return;
}
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
- if (swidth == NULL)
- {
- png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
- return;
- }
+ if (sheight == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
+ return;
+ }
png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
#endif
#endif
- if (buffer + slength < ep
+ if (png_ptr->chunkdata + slength < ep
#ifdef PNG_FLOATING_POINT_SUPPORTED
|| width <= 0. || height <= 0.
#endif
)
{
png_warning(png_ptr, "Invalid sCAL data");
- png_free(png_ptr, buffer);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
png_free(png_ptr, swidth);
png_free(png_ptr, sheight);
#ifdef PNG_FLOATING_POINT_SUPPORTED
- png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
+ png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
#else
#ifdef PNG_FIXED_POINT_SUPPORTED
- png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
+ png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
#endif
#endif
- png_free(png_ptr, buffer);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
png_free(png_ptr, swidth);
png_free(png_ptr, sheight);
png_byte buf[7];
png_time mod_time;
- png_debug(1, "in png_handle_tIME\n");
+ png_debug(1, "in png_handle_tIME");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Out of place tIME chunk");
png_size_t slength;
int ret;
- png_debug(1, "in png_handle_tEXt\n");
+ png_debug(1, "in png_handle_tEXt");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before tEXt");
}
#endif
- key = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (key == NULL)
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
{
png_warning(png_ptr, "No memory to process text chunk.");
return;
}
slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)key, slength);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
if (png_crc_finish(png_ptr, skip))
{
- png_free(png_ptr, key);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
+ key = png_ptr->chunkdata;
key[slength] = 0x00;
for (text = key; *text; text++)
if (text_ptr == NULL)
{
png_warning(png_ptr, "Not enough memory to process text chunk.");
- png_free(png_ptr, key);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr->text = text;
text_ptr->text_length = png_strlen(text);
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
- png_free(png_ptr, key);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
png_free(png_ptr, text_ptr);
if (ret)
png_warning(png_ptr, "Insufficient memory to process text chunk.");
png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_textp text_ptr;
- png_charp chunkdata;
png_charp text;
int comp_type;
int ret;
png_size_t slength, prefix_len, data_len;
- png_debug(1, "in png_handle_zTXt\n");
+ png_debug(1, "in png_handle_zTXt");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before zTXt");
there is no hard and fast rule to tell us where to stop. */
if (length > (png_uint_32)65535L)
{
- png_warning(png_ptr,"zTXt chunk too large to fit in memory");
+ png_warning(png_ptr, "zTXt chunk too large to fit in memory");
png_crc_finish(png_ptr, length);
return;
}
#endif
- chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (chunkdata == NULL)
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
{
- png_warning(png_ptr,"Out of memory processing zTXt chunk.");
+ png_warning(png_ptr, "Out of memory processing zTXt chunk.");
return;
}
slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
if (png_crc_finish(png_ptr, 0))
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
- chunkdata[slength] = 0x00;
+ png_ptr->chunkdata[slength] = 0x00;
- for (text = chunkdata; *text; text++)
+ for (text = png_ptr->chunkdata; *text; text++)
/* empty loop */ ;
/* zTXt must have some text after the chunkdataword */
- if (text == chunkdata + slength)
+ if (text >= png_ptr->chunkdata + slength - 2)
{
- comp_type = PNG_TEXT_COMPRESSION_NONE;
- png_warning(png_ptr, "Zero length zTXt chunk");
+ png_warning(png_ptr, "Truncated zTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
}
else
{
}
text++; /* skip the compression_method byte */
}
- prefix_len = text - chunkdata;
+ prefix_len = text - png_ptr->chunkdata;
- chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
- (png_size_t)length, prefix_len, &data_len);
+ png_decompress_chunk(png_ptr, comp_type,
+ (png_size_t)length, prefix_len, &data_len);
text_ptr = (png_textp)png_malloc_warn(png_ptr,
- (png_uint_32)png_sizeof(png_text));
+ (png_uint_32)png_sizeof(png_text));
if (text_ptr == NULL)
{
- png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
- png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
text_ptr->compression = comp_type;
- text_ptr->key = chunkdata;
+ text_ptr->key = png_ptr->chunkdata;
#ifdef PNG_iTXt_SUPPORTED
text_ptr->lang = NULL;
text_ptr->lang_key = NULL;
text_ptr->itxt_length = 0;
#endif
- text_ptr->text = chunkdata + prefix_len;
+ text_ptr->text = png_ptr->chunkdata + prefix_len;
text_ptr->text_length = data_len;
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
png_free(png_ptr, text_ptr);
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
if (ret)
png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
}
png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_textp text_ptr;
- png_charp chunkdata;
png_charp key, lang, text, lang_key;
int comp_flag;
int comp_type = 0;
int ret;
png_size_t slength, prefix_len, data_len;
- png_debug(1, "in png_handle_iTXt\n");
+ png_debug(1, "in png_handle_iTXt");
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before iTXt");
there is no hard and fast rule to tell us where to stop. */
if (length > (png_uint_32)65535L)
{
- png_warning(png_ptr,"iTXt chunk too large to fit in memory");
+ png_warning(png_ptr, "iTXt chunk too large to fit in memory");
png_crc_finish(png_ptr, length);
return;
}
#endif
- chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
- if (chunkdata == NULL)
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (png_ptr->chunkdata == NULL)
{
png_warning(png_ptr, "No memory to process iTXt chunk.");
return;
}
slength = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
if (png_crc_finish(png_ptr, 0))
{
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
- chunkdata[slength] = 0x00;
+ png_ptr->chunkdata[slength] = 0x00;
- for (lang = chunkdata; *lang; lang++)
+ for (lang = png_ptr->chunkdata; *lang; lang++)
/* empty loop */ ;
lang++; /* skip NUL separator */
translated keyword (possibly empty), and possibly some text after the
keyword */
- if (lang >= chunkdata + slength)
+ if (lang >= png_ptr->chunkdata + slength - 3)
{
- comp_flag = PNG_TEXT_COMPRESSION_NONE;
- png_warning(png_ptr, "Zero length iTXt chunk");
+ png_warning(png_ptr, "Truncated iTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
}
else
{
/* empty loop */ ;
lang_key++; /* skip NUL separator */
+ if (lang_key >= png_ptr->chunkdata + slength)
+ {
+ png_warning(png_ptr, "Truncated iTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
+
for (text = lang_key; *text; text++)
/* empty loop */ ;
text++; /* skip NUL separator */
+ if (text >= png_ptr->chunkdata + slength)
+ {
+ png_warning(png_ptr, "Malformed iTXt chunk");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ return;
+ }
- prefix_len = text - chunkdata;
+ prefix_len = text - png_ptr->chunkdata;
- key=chunkdata;
+ key=png_ptr->chunkdata;
if (comp_flag)
- chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
- (size_t)length, prefix_len, &data_len);
+ png_decompress_chunk(png_ptr, comp_type,
+ (size_t)length, prefix_len, &data_len);
else
- data_len=png_strlen(chunkdata + prefix_len);
+ data_len = png_strlen(png_ptr->chunkdata + prefix_len);
text_ptr = (png_textp)png_malloc_warn(png_ptr,
(png_uint_32)png_sizeof(png_text));
if (text_ptr == NULL)
{
- png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
- png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
return;
}
text_ptr->compression = (int)comp_flag + 1;
- text_ptr->lang_key = chunkdata+(lang_key-key);
- text_ptr->lang = chunkdata+(lang-key);
+ text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
+ text_ptr->lang = png_ptr->chunkdata + (lang - key);
text_ptr->itxt_length = data_len;
text_ptr->text_length = 0;
- text_ptr->key = chunkdata;
- text_ptr->text = chunkdata + prefix_len;
+ text_ptr->key = png_ptr->chunkdata;
+ text_ptr->text = png_ptr->chunkdata + prefix_len;
- ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
png_free(png_ptr, text_ptr);
- png_free(png_ptr, chunkdata);
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
if (ret)
png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
}
{
png_uint_32 skip = 0;
- png_debug(1, "in png_handle_unknown\n");
+ png_debug(1, "in png_handle_unknown");
if (png_ptr->mode & PNG_HAVE_IDAT)
{
#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IDAT;
+ PNG_CONST PNG_IDAT;
#endif
if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
png_ptr->mode |= PNG_AFTER_IDAT;
}
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
-
if (!(png_ptr->chunk_name[0] & 0x20))
{
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
PNG_HANDLE_CHUNK_ALWAYS
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
&& png_ptr->read_user_chunk_fn == NULL
}
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
- if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+ if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
+ (png_ptr->read_user_chunk_fn != NULL))
{
- png_unknown_chunk chunk;
-
#ifdef PNG_MAX_MALLOC_64K
if (length > (png_uint_32)65535L)
{
length = (png_uint_32)65535L;
}
#endif
- png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
- chunk.data = (png_bytep)png_malloc(png_ptr, length);
- chunk.size = (png_size_t)length;
- png_crc_read(png_ptr, (png_bytep)chunk.data, length);
+ png_memcpy((png_charp)png_ptr->unknown_chunk.name,
+ (png_charp)png_ptr->chunk_name,
+ png_sizeof(png_ptr->unknown_chunk.name));
+ png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] = '\0';
+ png_ptr->unknown_chunk.size = (png_size_t)length;
+ if (length == 0)
+ png_ptr->unknown_chunk.data = NULL;
+ else
+ {
+ png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
+ png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
+ }
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- if(png_ptr->read_user_chunk_fn != NULL)
+ if (png_ptr->read_user_chunk_fn != NULL)
{
/* callback to user unknown chunk handler */
- if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
+ int ret;
+ ret = (*(png_ptr->read_user_chunk_fn))
+ (png_ptr, &png_ptr->unknown_chunk);
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+ if (ret == 0)
{
if (!(png_ptr->chunk_name[0] & 0x20))
- if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
PNG_HANDLE_CHUNK_ALWAYS)
- {
- png_free(png_ptr, chunk.data);
png_chunk_error(png_ptr, "unknown critical chunk");
- }
- png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
}
}
else
#endif
- png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
- png_free(png_ptr, chunk.data);
+ png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
}
else
#endif
png_crc_finish(png_ptr, skip);
#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
- if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */
- return;
+ info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
#endif
}
void /* PRIVATE */
png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
{
- png_debug(1, "in png_check_chunk_name\n");
+ png_debug(1, "in png_check_chunk_name");
if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
{
a zero indicates the pixel is to be skipped. This is in addition
to any alpha or transparency value associated with the pixel. If
you want all pixels to be combined, pass 0xff (255) in mask. */
-#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+
void /* PRIVATE */
png_combine_row(png_structp png_ptr, png_bytep row, int mask)
{
- png_debug(1,"in png_combine_row\n");
+ png_debug(1, "in png_combine_row");
if (mask == 0xff)
{
png_memcpy(row, png_ptr->row_buf + 1,
}
}
}
-#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
#ifdef PNG_READ_INTERLACING_SUPPORTED
-#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
/* OLD pre-1.0.9 interface:
void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
png_uint_32 transformations)
#ifdef PNG_USE_LOCAL_ARRAYS
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* offset to next interlace block */
- const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
#endif
- png_debug(1,"in png_do_read_interlace (stock C version)\n");
+ png_debug(1, "in png_do_read_interlace");
if (row != NULL && row_info != NULL)
{
png_uint_32 final_width;
}
}
row_info->width = final_width;
- row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
}
#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
- if (&transformations == NULL) /* silence compiler warning */
- return;
+ transformations = transformations; /* silence compiler warning */
#endif
}
-#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
#endif /* PNG_READ_INTERLACING_SUPPORTED */
-#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
void /* PRIVATE */
png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
png_bytep prev_row, int filter)
{
- png_debug(1, "in png_read_filter_row\n");
- png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
+ png_debug(1, "in png_read_filter_row");
+ png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
switch (filter)
{
case PNG_FILTER_VALUE_NONE:
p = c;
*/
- p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+ p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
*rp = (png_byte)(((int)(*rp) + p) & 0xff);
rp++;
}
default:
png_warning(png_ptr, "Ignoring bad adaptive filter type");
- *row=0;
+ *row = 0;
break;
}
}
-#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
void /* PRIVATE */
png_read_finish_row(png_structp png_ptr)
{
#ifdef PNG_USE_LOCAL_ARRAYS
+#ifdef PNG_READ_INTERLACING_SUPPORTED
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* start of interlace block */
- const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+ PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* offset to next interlace block */
- const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
/* start of interlace block in the y direction */
- const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+ PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
/* offset to next interlace block in the y direction */
- const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
#endif
- png_debug(1, "in png_read_finish_row\n");
+ png_debug(1, "in png_read_finish_row");
png_ptr->row_number++;
if (png_ptr->row_number < png_ptr->num_rows)
return;
+#ifdef PNG_READ_INTERLACING_SUPPORTED
if (png_ptr->interlaced)
{
png_ptr->row_number = 0;
- png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+ png_memset_check(png_ptr, png_ptr->prev_row, 0,
+ png_ptr->rowbytes + 1);
do
{
png_ptr->pass++;
if (png_ptr->pass < 7)
return;
}
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
{
#ifdef PNG_USE_LOCAL_ARRAYS
- PNG_IDAT;
+ PNG_CONST PNG_IDAT;
#endif
char extra;
int ret;
png_ptr->zstream.next_out = (Byte *)&extra;
png_ptr->zstream.avail_out = (uInt)1;
- for(;;)
+ for (;;)
{
if (!(png_ptr->zstream.avail_in))
{
png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4);
- if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
png_error(png_ptr, "Not enough image data");
}
png_read_start_row(png_structp png_ptr)
{
#ifdef PNG_USE_LOCAL_ARRAYS
+#ifdef PNG_READ_INTERLACING_SUPPORTED
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* start of interlace block */
- const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+ PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* offset to next interlace block */
- const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
/* start of interlace block in the y direction */
- const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+ PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
/* offset to next interlace block in the y direction */
- const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
#endif
int max_pixel_depth;
- png_uint_32 row_bytes;
+ png_size_t row_bytes;
- png_debug(1, "in png_read_start_row\n");
+ png_debug(1, "in png_read_start_row");
png_ptr->zstream.avail_in = 0;
png_init_read_transformations(png_ptr);
+#ifdef PNG_READ_INTERLACING_SUPPORTED
if (png_ptr->interlaced)
{
if (!(png_ptr->transformations & PNG_INTERLACE))
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
- row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
-
- png_ptr->irowbytes = (png_size_t)row_bytes;
- if((png_uint_32)png_ptr->irowbytes != row_bytes)
- png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
+ png_ptr->irowbytes =
+ PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1;
}
else
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
{
png_ptr->num_rows = png_ptr->height;
png_ptr->iwidth = png_ptr->width;
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
- if(png_ptr->transformations & PNG_USER_TRANSFORM)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
{
- int user_pixel_depth=png_ptr->user_transform_depth*
+ int user_pixel_depth = png_ptr->user_transform_depth*
png_ptr->user_transform_channels;
- if(user_pixel_depth > max_pixel_depth)
+ if (user_pixel_depth > max_pixel_depth)
max_pixel_depth=user_pixel_depth;
}
#endif
row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
/* calculate the maximum bytes needed, adding a byte and a pixel
for safety's sake */
- row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
+ row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
1 + ((max_pixel_depth + 7) >> 3);
#ifdef PNG_MAX_MALLOC_64K
if (row_bytes > (png_uint_32)65536L)
png_error(png_ptr, "This image requires a row greater than 64KB");
#endif
- png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
- png_ptr->row_buf = png_ptr->big_row_buf+32;
-#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
- png_ptr->row_buf_size = row_bytes;
-#endif
+
+ if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
+ {
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
+ png_ptr->row_buf = png_ptr->big_row_buf+32;
+ png_ptr->old_big_row_buf_size = row_bytes+64;
+ }
#ifdef PNG_MAX_MALLOC_64K
if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
png_error(png_ptr, "This image requires a row greater than 64KB");
#endif
- if ((png_uint_32)png_ptr->rowbytes + 1 > PNG_SIZE_MAX)
+ if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
png_error(png_ptr, "Row has too many bytes to allocate in memory.");
- png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
- png_ptr->rowbytes + 1));
+
+ if (png_ptr->rowbytes+1 > png_ptr->old_prev_row_size)
+ {
+ png_free(png_ptr, png_ptr->prev_row);
+ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
+ png_ptr->rowbytes + 1));
+ png_ptr->old_prev_row_size = png_ptr->rowbytes+1;
+ }
png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
- png_debug1(3, "width = %lu,\n", png_ptr->width);
- png_debug1(3, "height = %lu,\n", png_ptr->height);
- png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
- png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
- png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
- png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
+ png_debug1(3, "width = %lu,", png_ptr->width);
+ png_debug1(3, "height = %lu,", png_ptr->height);
+ png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
+ png_debug1(3, "num_rows = %lu", png_ptr->num_rows);
+ png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
+ png_debug1(3, "irowbytes = %lu,", png_ptr->irowbytes);
png_ptr->flags |= PNG_FLAG_ROW_INIT;
}
+#endif /* PNG_READ_SUPPORTED */