summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libpng/pngrutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libpng/pngrutil.c')
-rw-r--r--src/3rdparty/libpng/pngrutil.c250
1 files changed, 150 insertions, 100 deletions
diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c
index 4c3cd53..07e46e2 100644
--- a/src/3rdparty/libpng/pngrutil.c
+++ b/src/3rdparty/libpng/pngrutil.c
@@ -1,7 +1,7 @@
/* pngrutil.c - utilities to read a PNG file
*
- * Last changed in libpng 1.5.1 [February 3, 2011]
+ * Last changed in libpng 1.5.4 [July 7, 2011]
* Copyright (c) 1998-2011 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.)
@@ -278,8 +278,7 @@ png_crc_error(png_structp png_ptr)
return (0);
}
-#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
- defined(PNG_READ_iCCP_SUPPORTED)
+#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
static png_size_t
png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
png_bytep output, png_size_t output_size)
@@ -370,41 +369,31 @@ png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
* and the error message is dumped into the uncompressed
* buffer if available.
*/
+# ifdef PNG_WARNINGS_SUPPORTED
{
- PNG_CONST char *msg;
-#ifdef PNG_CONSOLE_IO_SUPPORTED
- char umsg[52];
-#endif
+ png_const_charp msg;
+
if (png_ptr->zstream.msg != 0)
msg = png_ptr->zstream.msg;
- else
+ else switch (ret)
{
-#ifdef PNG_CONSOLE_IO_SUPPORTED
- switch (ret)
- {
- case Z_BUF_ERROR:
- msg = "Buffer error in compressed datastream in %s chunk";
- break;
+ case Z_BUF_ERROR:
+ msg = "Buffer error in compressed datastream";
+ break;
- case Z_DATA_ERROR:
- msg = "Data error in compressed datastream in %s chunk";
- break;
+ case Z_DATA_ERROR:
+ msg = "Data error in compressed datastream";
+ break;
- default:
- msg = "Incomplete compressed datastream in %s chunk";
- break;
- }
-
- png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
- msg = umsg;
-#else
- msg = "Damaged compressed datastream in chunk other than IDAT";
-#endif
+ default:
+ msg = "Incomplete compressed datastream";
+ break;
}
- png_warning(png_ptr, msg);
+ png_chunk_warning(png_ptr, msg);
}
+# endif
/* 0 means an error - notice that this code simply ignores
* zero length compressed chunks as a result.
@@ -438,8 +427,8 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
png_size_t expanded_size = png_inflate(png_ptr,
(png_bytep)(png_ptr->chunkdata + prefix_size),
chunklength - prefix_size,
- 0, /*output*/
- 0); /*output size*/
+ 0, /* output */
+ 0); /* output size */
/* Now check the limits on this chunk - if the limit fails the
* compressed data will be removed, the prefix will remain.
@@ -500,15 +489,9 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
{
-#ifdef PNG_STDIO_SUPPORTED
- char umsg[50];
-
- png_snprintf(umsg, sizeof umsg,
- "Unknown zTXt compression type %d", comp_type);
- png_warning(png_ptr, umsg);
-#else
- png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
+ PNG_WARNING_PARAMETERS(p)
+ png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type);
+ png_formatted_warning(png_ptr, p, "Unknown zTXt compression type @1");
/* The recovery is to simply drop the data. */
}
@@ -536,7 +519,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
*newlength = prefix_size;
}
-#endif
+#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
/* Read and check the IDHR chunk */
void /* PRIVATE */
@@ -846,12 +829,10 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
{
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
-
-# ifdef PNG_CONSOLE_IO_SUPPORTED
- fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
-# endif
+ PNG_WARNING_PARAMETERS(p)
+ png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
+ png_formatted_warning(png_ptr, p,
+ "Ignoring incorrect gAMA value @1 when sRGB is also present");
return;
}
}
@@ -1020,21 +1001,52 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
PNG_OUT_OF_RANGE(x_blue, 15000, 1000) ||
PNG_OUT_OF_RANGE(y_blue, 6000, 1000))
{
- png_warning(png_ptr,
- "Ignoring incorrect cHRM value when sRGB is also present");
-
-#ifdef PNG_CONSOLE_IO_SUPPORTED
- fprintf(stderr, "wx=%d, wy=%d, rx=%d, ry=%d\n",
- x_white, y_white, x_red, y_red);
-
- fprintf(stderr, "gx=%d, gy=%d, bx=%d, by=%d\n",
- x_green, y_green, x_blue, y_blue);
-#endif /* PNG_CONSOLE_IO_SUPPORTED */
+ PNG_WARNING_PARAMETERS(p)
+
+ png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white);
+ png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white);
+ png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red);
+ png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red);
+ png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green);
+ png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green);
+ png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue);
+ png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue);
+
+ png_formatted_warning(png_ptr, p,
+ "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) "
+ "when sRGB is also present");
}
return;
}
#endif /* PNG_READ_sRGB_SUPPORTED */
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* Store the _white values as default coefficients for the rgb to gray
+ * operation if it is supported.
+ */
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
+ {
+ /* png_set_background has not been called, the coefficients must be in
+ * range for the following to work without overflow.
+ */
+ if (y_red <= (1<<17) && y_green <= (1<<17) && y_blue <= (1<<17))
+ {
+ /* The y values are chromaticities: Y/X+Y+Z, the weights for the gray
+ * transformation are simply the normalized Y values for red, green and
+ * blue scaled by 32768.
+ */
+ png_uint_32 w = y_red + y_green + y_blue;
+
+ png_ptr->rgb_to_gray_red_coeff = (png_uint_16)(((png_uint_32)y_red *
+ 32768)/w);
+ png_ptr->rgb_to_gray_green_coeff = (png_uint_16)(((png_uint_32)y_green
+ * 32768)/w);
+ png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(((png_uint_32)y_blue *
+ 32768)/w);
+ }
+ }
+#endif
+
png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
x_green, y_green, x_blue, y_blue);
}
@@ -1096,11 +1108,13 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500))
{
- png_warning(png_ptr,
- "Ignoring incorrect gAMA value when sRGB is also present");
-#ifdef PNG_CONSOLE_IO_SUPPORTED
- fprintf(stderr, "incorrect gamma=(%d/100000)\n", info_ptr->gamma);
-#endif
+ PNG_WARNING_PARAMETERS(p)
+
+ png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed,
+ info_ptr->gamma);
+
+ png_formatted_warning(png_ptr, p,
+ "Ignoring incorrect gAMA value @1 when sRGB is also present");
}
}
#endif /* PNG_READ_gAMA_SUPPORTED */
@@ -1240,23 +1254,15 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* And the following guarantees that profile_size == profile_length. */
if (profile_size > profile_length)
{
+ PNG_WARNING_PARAMETERS(p)
+
png_free(png_ptr, png_ptr->chunkdata);
png_ptr->chunkdata = NULL;
-#ifdef PNG_STDIO_SUPPORTED
- {
- char umsg[80];
-
- png_snprintf2(umsg, 80,
- "Ignoring iCCP chunk with declared size = %u "
- "and actual length = %u",
- (unsigned int) profile_size,
- (unsigned int) profile_length);
- png_warning(png_ptr, umsg);
- }
-#else
- png_warning(png_ptr,
- "Ignoring iCCP chunk with uncompressed size mismatch");
-#endif
+
+ png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size);
+ png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length);
+ png_formatted_warning(png_ptr, p,
+ "Ignoring iCCP chunk with declared size = @1 and actual length = @2");
return;
}
@@ -1275,9 +1281,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_bytep entry_start;
png_sPLT_t new_palette;
-#ifdef PNG_POINTER_INDEXING_SUPPORTED
png_sPLT_entryp pp;
-#endif
png_uint_32 data_length;
int entry_size, i;
png_uint_32 skip = 0;
@@ -1442,7 +1446,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
}
- pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
}
#endif
@@ -1567,6 +1571,7 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
png_size_t truelen;
png_byte buf[6];
+ png_color_16 background;
png_debug(1, "in png_handle_bKGD");
@@ -1623,7 +1628,7 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
*/
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
- png_ptr->background.index = buf[0];
+ background.index = buf[0];
if (info_ptr && info_ptr->num_palette)
{
@@ -1633,33 +1638,36 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
return;
}
- png_ptr->background.red =
- (png_uint_16)png_ptr->palette[buf[0]].red;
+ background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
+ background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
+ background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
+ }
- png_ptr->background.green =
- (png_uint_16)png_ptr->palette[buf[0]].green;
+ else
+ background.red = background.green = background.blue = 0;
- png_ptr->background.blue =
- (png_uint_16)png_ptr->palette[buf[0]].blue;
- }
+ background.gray = 0;
}
else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
{
- png_ptr->background.red =
- png_ptr->background.green =
- png_ptr->background.blue =
- png_ptr->background.gray = png_get_uint_16(buf);
+ background.index = 0;
+ background.red =
+ background.green =
+ background.blue =
+ background.gray = png_get_uint_16(buf);
}
else
{
- png_ptr->background.red = png_get_uint_16(buf);
- png_ptr->background.green = png_get_uint_16(buf + 2);
- png_ptr->background.blue = png_get_uint_16(buf + 4);
+ background.index = 0;
+ background.red = png_get_uint_16(buf);
+ background.green = png_get_uint_16(buf + 2);
+ background.blue = png_get_uint_16(buf + 4);
+ background.gray = 0;
}
- png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
+ png_set_bKGD(png_ptr, info_ptr, &background);
}
#endif
@@ -1984,6 +1992,14 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
return;
}
+ /* Need unit type, width, \0, height: minimum 4 bytes */
+ else if (length < 4)
+ {
+ png_warning(png_ptr, "sCAL chunk too short");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
length + 1);
@@ -2019,23 +2035,29 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
/* Validate the ASCII numbers, need two ASCII numbers separated by
* a '\0' and they need to fit exactly in the chunk data.
*/
- i = 0;
+ i = 1;
state = 0;
- if (png_ptr->chunkdata[1] == 45 /* negative width */ ||
- !png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
+ if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
i >= slength || png_ptr->chunkdata[i++] != 0)
png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format");
+ else if (!PNG_FP_IS_POSITIVE(state))
+ png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width");
+
else
{
png_size_t heighti = i;
- if (png_ptr->chunkdata[i] == 45 /* negative height */ ||
- !png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
+ state = 0;
+ if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
i != slength)
png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format");
+ else if (!PNG_FP_IS_POSITIVE(state))
+ png_warning(png_ptr,
+ "Invalid sCAL chunk ignored: non-positive height");
+
else
/* This is the (only) success case. */
png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0],
@@ -2662,6 +2684,14 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask)
{
png_debug(1, "in png_combine_row");
+ /* Added in 1.5.4: the row_info should match the information returned by any
+ * call to png_read_update_info at this point. Do not continue if we got
+ * this wrong.
+ */
+ if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
+ PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width))
+ png_error(png_ptr, "internal row size calculation error");
+
if (mask == 0xff)
{
png_memcpy(row, png_ptr->row_buf + 1,
@@ -3400,7 +3430,9 @@ png_read_start_row(png_structp png_ptr)
png_debug(1, "in png_read_start_row");
png_ptr->zstream.avail_in = 0;
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
png_init_read_transformations(png_ptr);
+#endif
#ifdef PNG_READ_INTERLACING_SUPPORTED
if (png_ptr->interlaced)
{
@@ -3463,6 +3495,24 @@ png_read_start_row(png_structp png_ptr)
}
#endif
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND_16)
+ {
+# ifdef PNG_READ_EXPAND_SUPPORTED
+ /* In fact it is an error if it isn't supported, but checking is
+ * the safe way.
+ */
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->bit_depth < 16)
+ max_pixel_depth *= 2;
+ }
+ else
+# endif
+ png_ptr->transformations &= ~PNG_EXPAND_16;
+ }
+#endif
+
#ifdef PNG_READ_FILLER_SUPPORTED
if (png_ptr->transformations & (PNG_FILLER))
{