[CHG] libpng updated to version 1.5.6

This commit is contained in:
Crayon2000 2011-11-07 16:43:36 +00:00
parent bfa2636b23
commit 54ded632b6
15 changed files with 1484 additions and 1085 deletions

View file

@ -1,7 +1,7 @@
/* png.c - location for general purpose libpng functions /* png.c - location for general purpose libpng functions
* *
* Last changed in libpng 1.5.5 [September 22, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -14,7 +14,7 @@
#include "pngpriv.h" #include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */ /* Generate a compiler error if there is an old png.h in the search path. */
typedef png_libpng_version_1_5_5 Your_png_h_is_not_version_1_5_5; typedef png_libpng_version_1_5_6 Your_png_h_is_not_version_1_5_6;
/* Tells libpng that we have already handled the first "num_bytes" bytes /* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another * of the PNG file signature. If the PNG data is embedded into another
@ -121,14 +121,14 @@ png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length)
{ {
int need_crc = 1; int need_crc = 1;
if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
{ {
if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
need_crc = 0; need_crc = 0;
} }
else /* critical */ else /* critical */
{ {
if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
need_crc = 0; need_crc = 0;
@ -645,13 +645,13 @@ png_get_copyright(png_const_structp png_ptr)
#else #else
# ifdef __STDC__ # ifdef __STDC__
return PNG_STRING_NEWLINE \ return PNG_STRING_NEWLINE \
"libpng version 1.5.5 - September 22, 2011" PNG_STRING_NEWLINE \ "libpng version 1.5.6 - November 3, 2011" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE; PNG_STRING_NEWLINE;
# else # else
return "libpng version 1.5.5 - September 22, 2011\ return "libpng version 1.5.6 - November 3, 2011\
Copyright (c) 1998-2011 Glenn Randers-Pehrson\ Copyright (c) 1998-2011 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@ -698,25 +698,43 @@ png_get_header_version(png_const_structp png_ptr)
#endif #endif
} }
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
int PNGAPI int PNGAPI
png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name)
{ {
/* Check chunk_name and return "keep" value if it's on the list, else 0 */ /* Check chunk_name and return "keep" value if it's on the list, else 0 */
int i; png_const_bytep p, p_end;
png_bytep p;
if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
return 0;
p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5; if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list <= 0)
for (i = png_ptr->num_chunk_list; i; i--, p -= 5) return PNG_HANDLE_CHUNK_AS_DEFAULT;
p_end = png_ptr->chunk_list;
p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
/* The code is the fifth byte after each four byte string. Historically this
* code was always searched from the end of the list, so it should continue
* to do so in case there are duplicated entries.
*/
do /* num_chunk_list > 0, so at least one */
{
p -= 5;
if (!png_memcmp(chunk_name, p, 4)) if (!png_memcmp(chunk_name, p, 4))
return ((int)*(p + 4)); return p[4];
return 0; }
while (p > p_end);
return PNG_HANDLE_CHUNK_AS_DEFAULT;
} }
# endif
#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ int /* PRIVATE */
png_chunk_unknown_handling(png_structp png_ptr, png_uint_32 chunk_name)
{
png_byte chunk_string[5];
PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
return png_handle_as_unknown(png_ptr, chunk_string);
}
#endif
#ifdef PNG_READ_SUPPORTED #ifdef PNG_READ_SUPPORTED
/* This function, added to libpng-1.0.6g, is untested. */ /* This function, added to libpng-1.0.6g, is untested. */
@ -2645,6 +2663,60 @@ png_build_8bit_table(png_structp png_ptr, png_bytepp ptable,
table[i] = (png_byte)i; table[i] = (png_byte)i;
} }
/* Used from png_read_destroy and below to release the memory used by the gamma
* tables.
*/
void /* PRIVATE */
png_destroy_gamma_table(png_structp png_ptr)
{
png_free(png_ptr, png_ptr->gamma_table);
png_ptr->gamma_table = NULL;
if (png_ptr->gamma_16_table != NULL)
{
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_table[i]);
}
png_free(png_ptr, png_ptr->gamma_16_table);
png_ptr->gamma_16_table = NULL;
}
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
png_free(png_ptr, png_ptr->gamma_from_1);
png_ptr->gamma_from_1 = NULL;
png_free(png_ptr, png_ptr->gamma_to_1);
png_ptr->gamma_to_1 = NULL;
if (png_ptr->gamma_16_from_1 != NULL)
{
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
}
png_free(png_ptr, png_ptr->gamma_16_from_1);
png_ptr->gamma_16_from_1 = NULL;
}
if (png_ptr->gamma_16_to_1 != NULL)
{
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
}
png_free(png_ptr, png_ptr->gamma_16_to_1);
png_ptr->gamma_16_to_1 = NULL;
}
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
}
/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit /* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
* tables, we don't make a full table if we are reducing to 8-bit in * tables, we don't make a full table if we are reducing to 8-bit in
* the future. Note also how the gamma_16 tables are segmented so that * the future. Note also how the gamma_16 tables are segmented so that
@ -2655,6 +2727,18 @@ png_build_gamma_table(png_structp png_ptr, int bit_depth)
{ {
png_debug(1, "in png_build_gamma_table"); png_debug(1, "in png_build_gamma_table");
/* Remove any existing table; this copes with multiple calls to
* png_read_update_info. The warning is because building the gamma tables
* multiple times is a performance hit - it's harmless but the ability to call
* png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
* to warn if the app introduces such a hit.
*/
if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
{
png_warning(png_ptr, "gamma table being rebuilt");
png_destroy_gamma_table(png_ptr);
}
if (bit_depth <= 8) if (bit_depth <= 8)
{ {
png_build_8bit_table(png_ptr, &png_ptr->gamma_table, png_build_8bit_table(png_ptr, &png_ptr->gamma_table,

View file

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library /* png.h - header file for PNG reference library
* *
* libpng version 1.5.5 - September 22, 2011 * libpng version 1.5.6 - November 3, 2011
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -11,7 +11,7 @@
* Authors and maintainers: * Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.5.5 - September 22, 2011: Glenn * libpng versions 0.97, January 1998, through 1.5.6 - November 3, 2011: Glenn
* See also "Contributing Authors", below. * See also "Contributing Authors", below.
* *
* Note about libpng version numbers: * Note about libpng version numbers:
@ -160,6 +160,9 @@
* 1.5.5beta01-08 15 10505 15.so.15.5[.0] * 1.5.5beta01-08 15 10505 15.so.15.5[.0]
* 1.5.5rc01 15 10505 15.so.15.5[.0] * 1.5.5rc01 15 10505 15.so.15.5[.0]
* 1.5.5 15 10505 15.so.15.5[.0] * 1.5.5 15 10505 15.so.15.5[.0]
* 1.5.6beta01-07 15 10506 15.so.15.6[.0]
* 1.5.6rc01-03 15 10506 15.so.15.6[.0]
* 1.5.6 15 10506 15.so.15.6[.0]
* *
* Henceforth the source version will match the shared-library major * Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be * and minor numbers; the shared-library major version number will be
@ -191,7 +194,7 @@
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* *
* libpng versions 1.2.6, August 15, 2004, through 1.5.5, September 22, 2011, are * libpng versions 1.2.6, August 15, 2004, through 1.5.6, November 3, 2011, are
* Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are * Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5 * distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors: * with the following individual added to the list of Contributing Authors:
@ -303,13 +306,13 @@
* Y2K compliance in libpng: * Y2K compliance in libpng:
* ========================= * =========================
* *
* September 22, 2011 * November 3, 2011
* *
* Since the PNG Development group is an ad-hoc body, we can't make * Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration. * an official declaration.
* *
* This is your unofficial assurance that libpng from version 0.71 and * This is your unofficial assurance that libpng from version 0.71 and
* upward through 1.5.5 are Y2K compliant. It is my belief that * upward through 1.5.6 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant. * earlier versions were also Y2K compliant.
* *
* Libpng only has two year fields. One is a 2-byte unsigned integer * Libpng only has two year fields. One is a 2-byte unsigned integer
@ -364,9 +367,9 @@
*/ */
/* Version information for png.h - this should match the version in png.c */ /* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.5.5" #define PNG_LIBPNG_VER_STRING "1.5.6"
#define PNG_HEADER_VERSION_STRING \ #define PNG_HEADER_VERSION_STRING \
" libpng version 1.5.5 - September 22, 2011\n" " libpng version 1.5.6 - November 3, 2011\n"
#define PNG_LIBPNG_VER_SONUM 15 #define PNG_LIBPNG_VER_SONUM 15
#define PNG_LIBPNG_VER_DLLNUM 15 #define PNG_LIBPNG_VER_DLLNUM 15
@ -374,7 +377,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 5 #define PNG_LIBPNG_VER_MINOR 5
#define PNG_LIBPNG_VER_RELEASE 5 #define PNG_LIBPNG_VER_RELEASE 6
/* This should match the numeric part of the final component of /* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero: * PNG_LIBPNG_VER_STRING, omitting any leading zero:
*/ */
@ -404,7 +407,7 @@
* version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/ */
#define PNG_LIBPNG_VER 10505 /* 1.5.5 */ #define PNG_LIBPNG_VER 10506 /* 1.5.6 */
/* Library configuration: these options cannot be changed after /* Library configuration: these options cannot be changed after
* the library has been built. * the library has been built.
@ -526,7 +529,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h /* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number. * do not agree upon the version number.
*/ */
typedef char* png_libpng_version_1_5_5; typedef char* png_libpng_version_1_5_6;
/* Three color definitions. The order of the red, green, and blue, (and the /* Three color definitions. The order of the red, green, and blue, (and the
* exact size) is not important, although the size of the fields need to * exact size) is not important, although the size of the fields need to
@ -1830,6 +1833,7 @@ PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structp, int save));
*/ */
PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp)); PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp));
#ifdef PNG_READ_INTERLACING_SUPPORTED
/* Function that combines rows. 'new_row' is a flag that should come from /* Function that combines rows. 'new_row' is a flag that should come from
* the callback and be non-NULL if anything needs to be done; the library * the callback and be non-NULL if anything needs to be done; the library
* stores its own version of the new data internally and ignores the passed * stores its own version of the new data internally and ignores the passed
@ -1837,6 +1841,7 @@ PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structp));
*/ */
PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr, PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr,
png_bytep old_row, png_const_bytep new_row)); png_bytep old_row, png_const_bytep new_row));
#endif /* PNG_READ_INTERLACING_SUPPORTED */
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
PNG_EXPORTA(94, png_voidp, png_malloc, PNG_EXPORTA(94, png_voidp, png_malloc,
@ -2305,15 +2310,21 @@ PNG_EXPORT(171, void, png_set_sCAL_s,
/* Provide a list of chunks and how they are to be handled, if the built-in /* Provide a list of chunks and how they are to be handled, if the built-in
handling or default unknown chunk handling is not desired. Any chunks not handling or default unknown chunk handling is not desired. Any chunks not
listed will be handled in the default manner. The IHDR and IEND chunks listed will be handled in the default manner. The IHDR and IEND chunks
must not be listed. must not be listed. Because this turns off the default handling for chunks
keep = 0: follow default behavior that would otherwise be recognized the behavior of libpng transformations may
= 1: do not keep well become incorrect!
= 2: keep only if safe-to-copy keep = 0: PNG_HANDLE_CHUNK_AS_DEFAULT: follow default behavior
= 3: keep even if unsafe-to-copy = 1: PNG_HANDLE_CHUNK_NEVER: do not keep
= 2: PNG_HANDLE_CHUNK_IF_SAFE: keep only if safe-to-copy
= 3: PNG_HANDLE_CHUNK_ALWAYS: keep even if unsafe-to-copy
*/ */
PNG_EXPORT(172, void, png_set_keep_unknown_chunks, PNG_EXPORT(172, void, png_set_keep_unknown_chunks,
(png_structp png_ptr, int keep, (png_structp png_ptr, int keep,
png_const_bytep chunk_list, int num_chunks)); png_const_bytep chunk_list, int num_chunks));
/* The handling code is returned; the result is therefore true (non-zero) if
* special handling is required, false for the default handling.
*/
PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr,
png_const_bytep chunk_name)); png_const_bytep chunk_name));
#endif #endif
@ -2453,8 +2464,16 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
* full, image which appears in a given pass. 'pass' is in the range 0 * full, image which appears in a given pass. 'pass' is in the range 0
* to 6 and the result is in the range 0 to 7. * to 6 and the result is in the range 0 to 7.
*/ */
#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) #define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)
#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) #define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)
/* A macro to return the offset between pixels in the output row for a pair of
* pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that
* follows. Note that ROW_OFFSET is the offset from one row to the next whereas
* COL_OFFSET is from one column to the next, within a row.
*/
#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)
#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))
/* Two macros to help evaluate the number of rows or columns in each /* Two macros to help evaluate the number of rows or columns in each
* pass. This is expressed as a shift - effectively log2 of the number or * pass. This is expressed as a shift - effectively log2 of the number or
@ -2489,8 +2508,8 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
* the tile. * the tile.
*/ */
#define PNG_PASS_MASK(pass,off) ( \ #define PNG_PASS_MASK(pass,off) ( \
((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \ ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \
((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))
#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)

View file

@ -1,7 +1,7 @@
/* pngconf.h - machine configurable file for libpng /* pngconf.h - machine configurable file for libpng
* *
* libpng version 1.5.5 - September 22, 2011 * libpng version 1.5.6 - November 3, 2011
* *
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)

View file

@ -1,7 +1,7 @@
/* pngerror.c - stub functions for i/o and memory allocation /* pngerror.c - stub functions for i/o and memory allocation
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -374,11 +374,14 @@ static void /* PRIVATE */
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
error_message) error_message)
{ {
int iout = 0, iin = 0; png_uint_32 chunk_name = png_ptr->chunk_name;
int iout = 0, ishift = 24;
while (iin < 4) while (ishift >= 0)
{ {
int c = png_ptr->chunk_name[iin++]; int c = (int)(chunk_name >> ishift) & 0xff;
ishift -= 8;
if (isnonalpha(c)) if (isnonalpha(c))
{ {
buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
@ -389,7 +392,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
else else
{ {
buffer[iout++] = (png_byte)c; buffer[iout++] = (char)c;
} }
} }
@ -398,10 +401,11 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
else else
{ {
int iin = 0;
buffer[iout++] = ':'; buffer[iout++] = ':';
buffer[iout++] = ' '; buffer[iout++] = ' ';
iin = 0;
while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
buffer[iout++] = error_message[iin++]; buffer[iout++] = error_message[iin++];

View file

@ -1,7 +1,7 @@
/* pngget.c - retrieval of values from info struct /* pngget.c - retrieval of values from info struct
* *
* Last changed in libpng 1.5.5 [September 22, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -950,9 +950,8 @@ png_get_text(png_const_structp png_ptr, png_const_infop info_ptr,
{ {
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
{ {
png_debug1(1, "in %s retrieval function", png_debug1(1, "in 0x%lx retrieval function",
(png_ptr->chunk_name[0] == '\0' ? "text" : (unsigned long)png_ptr->chunk_name);
(png_const_charp)png_ptr->chunk_name));
if (text_ptr != NULL) if (text_ptr != NULL)
*text_ptr = info_ptr->text; *text_ptr = info_ptr->text;
@ -1069,7 +1068,6 @@ png_get_compression_buffer_size(png_const_structp png_ptr)
return (png_ptr ? png_ptr->zbuf_size : 0); return (png_ptr ? png_ptr->zbuf_size : 0);
} }
#ifdef PNG_SET_USER_LIMITS_SUPPORTED #ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* These functions were added to libpng 1.2.6 and were enabled /* These functions were added to libpng 1.2.6 and were enabled
* by default in libpng-1.4.0 */ * by default in libpng-1.4.0 */
@ -1111,16 +1109,14 @@ png_get_io_state (png_structp png_ptr)
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_io_chunk_type (png_const_structp png_ptr) png_get_io_chunk_type (png_const_structp png_ptr)
{ {
return ((png_ptr->chunk_name[0] << 24) + return png_ptr->chunk_name;
(png_ptr->chunk_name[1] << 16) +
(png_ptr->chunk_name[2] << 8) +
(png_ptr->chunk_name[3]));
} }
png_const_bytep PNGAPI png_const_bytep PNGAPI
png_get_io_chunk_name (png_structp png_ptr) png_get_io_chunk_name (png_structp png_ptr)
{ {
return png_ptr->chunk_name; PNG_CSTRING_FROM_CHUNK(png_ptr->io_chunk_string, png_ptr->chunk_name);
return png_ptr->io_chunk_string;
} }
#endif /* ?PNG_IO_STATE_SUPPORTED */ #endif /* ?PNG_IO_STATE_SUPPORTED */

View file

@ -1,7 +1,7 @@
/* pngpread.c - read a png file in push mode /* pngpread.c - read a png file in push mode
* *
* Last changed in libpng 1.5.2 [March 31, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -208,61 +208,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
{ {
PNG_IHDR; png_uint_32 chunk_name;
PNG_IDAT;
PNG_IEND;
PNG_PLTE;
#ifdef PNG_READ_bKGD_SUPPORTED
PNG_bKGD;
#endif
#ifdef PNG_READ_cHRM_SUPPORTED
PNG_cHRM;
#endif
#ifdef PNG_READ_gAMA_SUPPORTED
PNG_gAMA;
#endif
#ifdef PNG_READ_hIST_SUPPORTED
PNG_hIST;
#endif
#ifdef PNG_READ_iCCP_SUPPORTED
PNG_iCCP;
#endif
#ifdef PNG_READ_iTXt_SUPPORTED
PNG_iTXt;
#endif
#ifdef PNG_READ_oFFs_SUPPORTED
PNG_oFFs;
#endif
#ifdef PNG_READ_pCAL_SUPPORTED
PNG_pCAL;
#endif
#ifdef PNG_READ_pHYs_SUPPORTED
PNG_pHYs;
#endif
#ifdef PNG_READ_sBIT_SUPPORTED
PNG_sBIT;
#endif
#ifdef PNG_READ_sCAL_SUPPORTED
PNG_sCAL;
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
PNG_sRGB;
#endif
#ifdef PNG_READ_sPLT_SUPPORTED
PNG_sPLT;
#endif
#ifdef PNG_READ_tEXt_SUPPORTED
PNG_tEXt;
#endif
#ifdef PNG_READ_tIME_SUPPORTED
PNG_tIME;
#endif
#ifdef PNG_READ_tRNS_SUPPORTED
PNG_tRNS;
#endif
#ifdef PNG_READ_zTXt_SUPPORTED
PNG_zTXt;
#endif
/* First we make sure we have enough data for the 4 byte chunk name /* First we make sure we have enough data for the 4 byte chunk name
* and the 4 byte chunk length before proceeding with decoding the * and the 4 byte chunk length before proceeding with decoding the
@ -273,6 +219,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
{ {
png_byte chunk_length[4]; png_byte chunk_length[4];
png_byte chunk_tag[4];
if (png_ptr->buffer_size < 8) if (png_ptr->buffer_size < 8)
{ {
@ -283,16 +230,27 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_push_fill_buffer(png_ptr, chunk_length, 4); png_push_fill_buffer(png_ptr, chunk_length, 4);
png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, chunk_tag, 4);
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
png_check_chunk_name(png_ptr, png_ptr->chunk_name); png_check_chunk_name(png_ptr, png_ptr->chunk_name);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
} }
if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) chunk_name = png_ptr->chunk_name;
if (chunk_name == png_IDAT)
{
/* This is here above the if/else case statement below because if the
* unknown handling marks 'IDAT' as unknown then the IDAT handling case is
* completely skipped.
*
* TODO: there must be a better way of doing this.
*/
if (png_ptr->mode & PNG_AFTER_IDAT) if (png_ptr->mode & PNG_AFTER_IDAT)
png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
}
if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) if (chunk_name == png_IHDR)
{ {
if (png_ptr->push_length != 13) if (png_ptr->push_length != 13)
png_error(png_ptr, "Invalid IHDR length"); png_error(png_ptr, "Invalid IHDR length");
@ -306,7 +264,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
} }
else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) else if (chunk_name == png_IEND)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -321,7 +279,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
} }
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) else if (png_chunk_unknown_handling(png_ptr, chunk_name))
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -329,15 +287,15 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
return; return;
} }
if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) if (chunk_name == png_IDAT)
png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->mode |= PNG_HAVE_IDAT;
png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) if (chunk_name == png_PLTE)
png_ptr->mode |= PNG_HAVE_PLTE; png_ptr->mode |= PNG_HAVE_PLTE;
else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) else if (chunk_name == png_IDAT)
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR)) if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before IDAT"); png_error(png_ptr, "Missing IHDR before IDAT");
@ -349,7 +307,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
} }
#endif #endif
else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) else if (chunk_name == png_PLTE)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -359,7 +317,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
} }
else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) else if (chunk_name == png_IDAT)
{ {
/* If we reach an IDAT chunk, this means we have read all of the /* If we reach an IDAT chunk, this means we have read all of the
* header chunks, and we can start reading the image (or if this * header chunks, and we can start reading the image (or if this
@ -395,7 +353,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
} }
#ifdef PNG_READ_gAMA_SUPPORTED #ifdef PNG_READ_gAMA_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) else if (png_ptr->chunk_name == png_gAMA)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -408,7 +366,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_sBIT_SUPPORTED #ifdef PNG_READ_sBIT_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) else if (png_ptr->chunk_name == png_sBIT)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -421,7 +379,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_READ_cHRM_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) else if (png_ptr->chunk_name == png_cHRM)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -434,7 +392,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_sRGB_SUPPORTED #ifdef PNG_READ_sRGB_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) else if (chunk_name == png_sRGB)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -447,7 +405,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_iCCP_SUPPORTED #ifdef PNG_READ_iCCP_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) else if (png_ptr->chunk_name == png_iCCP)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -460,7 +418,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_sPLT_SUPPORTED #ifdef PNG_READ_sPLT_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) else if (chunk_name == png_sPLT)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -473,7 +431,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_tRNS_SUPPORTED #ifdef PNG_READ_tRNS_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) else if (chunk_name == png_tRNS)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -486,7 +444,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_bKGD_SUPPORTED #ifdef PNG_READ_bKGD_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) else if (chunk_name == png_bKGD)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -499,7 +457,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_hIST_SUPPORTED #ifdef PNG_READ_hIST_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) else if (chunk_name == png_hIST)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -512,7 +470,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_pHYs_SUPPORTED #ifdef PNG_READ_pHYs_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) else if (chunk_name == png_pHYs)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -525,7 +483,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_oFFs_SUPPORTED #ifdef PNG_READ_oFFs_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) else if (chunk_name == png_oFFs)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -538,7 +496,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_pCAL_SUPPORTED #ifdef PNG_READ_pCAL_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) else if (chunk_name == png_pCAL)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -551,7 +509,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_sCAL_SUPPORTED #ifdef PNG_READ_sCAL_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) else if (chunk_name == png_sCAL)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -564,7 +522,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_tIME_SUPPORTED #ifdef PNG_READ_tIME_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) else if (chunk_name == png_tIME)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -577,7 +535,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_tEXt_SUPPORTED #ifdef PNG_READ_tEXt_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) else if (chunk_name == png_tEXt)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -590,7 +548,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_zTXt_SUPPORTED #ifdef PNG_READ_zTXt_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) else if (chunk_name == png_zTXt)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -603,7 +561,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif #endif
#ifdef PNG_READ_iTXt_SUPPORTED #ifdef PNG_READ_iTXt_SUPPORTED
else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) else if (chunk_name == png_iTXt)
{ {
if (png_ptr->push_length + 4 > png_ptr->buffer_size) if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{ {
@ -809,11 +767,12 @@ png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
void /* PRIVATE */ void /* PRIVATE */
png_push_read_IDAT(png_structp png_ptr) png_push_read_IDAT(png_structp png_ptr)
{ {
PNG_IDAT;
if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
{ {
png_byte chunk_length[4]; png_byte chunk_length[4];
png_byte chunk_tag[4];
/* TODO: this code can be commoned up with the same code in push_read */
if (png_ptr->buffer_size < 8) if (png_ptr->buffer_size < 8)
{ {
png_push_save_buffer(png_ptr); png_push_save_buffer(png_ptr);
@ -823,10 +782,11 @@ png_push_read_IDAT(png_structp png_ptr)
png_push_fill_buffer(png_ptr, chunk_length, 4); png_push_fill_buffer(png_ptr, chunk_length, 4);
png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_crc_read(png_ptr, chunk_tag, 4);
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) if (png_ptr->chunk_name != png_IDAT)
{ {
png_ptr->process_mode = PNG_READ_CHUNK_MODE; png_ptr->process_mode = PNG_READ_CHUNK_MODE;
@ -838,6 +798,7 @@ png_push_read_IDAT(png_structp png_ptr)
png_ptr->idat_size = png_ptr->push_length; png_ptr->idat_size = png_ptr->push_length;
} }
if (png_ptr->idat_size && png_ptr->save_buffer_size) if (png_ptr->idat_size && png_ptr->save_buffer_size)
{ {
png_size_t save_size = png_ptr->save_buffer_size; png_size_t save_size = png_ptr->save_buffer_size;
@ -1011,36 +972,56 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
void /* PRIVATE */ void /* PRIVATE */
png_push_process_row(png_structp png_ptr) png_push_process_row(png_structp png_ptr)
{ {
png_ptr->row_info.color_type = png_ptr->color_type; /* 1.5.6: row_info moved out of png_struct to a local here. */
png_ptr->row_info.width = png_ptr->iwidth; png_row_info row_info;
png_ptr->row_info.channels = png_ptr->channels;
png_ptr->row_info.bit_depth = png_ptr->bit_depth;
png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
png_ptr->row_info.width); row_info.color_type = png_ptr->color_type;
row_info.bit_depth = png_ptr->bit_depth;
row_info.channels = png_ptr->channels;
row_info.pixel_depth = png_ptr->pixel_depth;
row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
png_read_filter_row(png_ptr, &(png_ptr->row_info), if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
png_ptr->row_buf + 1, png_ptr->prev_row + 1, {
(int)(png_ptr->row_buf[0])); if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
png_read_filter_row(&row_info, png_ptr->row_buf + 1,
png_ptr->prev_row + 1, png_ptr->row_buf[0]);
else
png_error(png_ptr, "bad adaptive filter value");
}
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
* 1.5.6, while the buffer really is this big in current versions of libpng
* it may not be in the future, so this was changed just to copy the
* interlaced row count:
*/
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
if (png_ptr->transformations) if (png_ptr->transformations)
png_do_read_transformations(png_ptr); png_do_read_transformations(png_ptr, &row_info);
#endif #endif
/* The transformed pixel depth should match the depth now in row_info. */
if (png_ptr->transformed_pixel_depth == 0)
{
png_ptr->transformed_pixel_depth = row_info.pixel_depth;
if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
png_error(png_ptr, "progressive row overflow");
}
else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
png_error(png_ptr, "internal progressive row size calculation error");
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
/* Blow up interlaced rows to full size */ /* Blow up interlaced rows to full size */
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
{ {
if (png_ptr->pass < 6) if (png_ptr->pass < 6)
/* old interface (pre-1.0.9): png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
png_do_read_interlace(&(png_ptr->row_info), png_ptr->transformations);
png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
*/
png_do_read_interlace(png_ptr);
switch (png_ptr->pass) switch (png_ptr->pass)
{ {
@ -1223,20 +1204,20 @@ png_read_push_finish_row(png_structp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
/* Start of interlace block in the y direction */ /* Start of interlace block in the y direction */
PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
/* Offset to next interlace block in the y direction */ /* Offset to next interlace block in the y direction */
PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
/* Height of interlace block. This is not currently used - if you need /* Height of interlace block. This is not currently used - if you need
* it, uncomment it here and in png.h * it, uncomment it here and in png.h
PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
*/ */
png_ptr->row_number++; png_ptr->row_number++;
@ -1714,11 +1695,12 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
length) length)
{ {
png_uint_32 skip = 0; png_uint_32 skip = 0;
png_uint_32 chunk_name = png_ptr->chunk_name;
if (!(png_ptr->chunk_name[0] & 0x20)) if (PNG_CHUNK_CRITICAL(chunk_name))
{ {
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
PNG_HANDLE_CHUNK_ALWAYS PNG_HANDLE_CHUNK_ALWAYS
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
&& png_ptr->read_user_chunk_fn == NULL && png_ptr->read_user_chunk_fn == NULL
@ -1731,22 +1713,26 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
} }
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
/* TODO: the code below is apparently just using the
* png_struct::unknown_chunk member as a temporarily variable, it should be
* possible to eliminate both it and the temporary buffer.
*/
if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
{ {
#ifdef PNG_MAX_MALLOC_64K #ifdef PNG_MAX_MALLOC_64K
if (length > (png_uint_32)65535L) if (length > 65535)
{ {
png_warning(png_ptr, "unknown chunk too large to fit in memory"); png_warning(png_ptr, "unknown chunk too large to fit in memory");
skip = length - (png_uint_32)65535L; skip = length - 65535;
length = (png_uint_32)65535L; length = 65535;
} }
#endif #endif
png_memcpy((png_charp)png_ptr->unknown_chunk.name, /* This is just a record for the user; libpng doesn't use the character
(png_charp)png_ptr->chunk_name, * form of the name.
png_sizeof(png_ptr->unknown_chunk.name)); */
png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
= '\0';
/* The following cast should be safe because of the check above. */
png_ptr->unknown_chunk.size = (png_size_t)length; png_ptr->unknown_chunk.size = (png_size_t)length;
if (length == 0) if (length == 0)
@ -1755,8 +1741,9 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
else else
{ {
png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
(png_size_t)length); png_ptr->unknown_chunk.size);
png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data,
png_ptr->unknown_chunk.size);
} }
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
@ -1772,8 +1759,8 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
if (ret == 0) if (ret == 0)
{ {
if (!(png_ptr->chunk_name[0] & 0x20)) if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
PNG_HANDLE_CHUNK_ALWAYS) PNG_HANDLE_CHUNK_ALWAYS)
png_chunk_error(png_ptr, "unknown critical chunk"); png_chunk_error(png_ptr, "unknown critical chunk");
png_set_unknown_chunks(png_ptr, info_ptr, png_set_unknown_chunks(png_ptr, info_ptr,
@ -1816,19 +1803,22 @@ png_push_have_row(png_structp png_ptr, png_bytep row)
(int)png_ptr->pass); (int)png_ptr->pass);
} }
#ifdef PNG_READ_INTERLACING_SUPPORTED
void PNGAPI void PNGAPI
png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
png_const_bytep new_row) png_const_bytep new_row)
{ {
PNG_CONST int FARDATA png_pass_dsp_mask[7] =
{0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ /* new_row is a flag here - if it is NULL then the app callback was called
png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); * from an empty row (see the calls to png_struct::row_fn below), otherwise
* it must be png_ptr->row_buf+1
*/
if (new_row != NULL)
png_combine_row(png_ptr, old_row, 1/*display*/);
} }
#endif /* PNG_READ_INTERLACING_SUPPORTED */
void PNGAPI void PNGAPI
png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,

View file

@ -6,7 +6,7 @@
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
* Last changed in libpng 1.5.5 [September 22, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -44,6 +44,9 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
/* This is used to find 'offsetof', used below for alignment tests. */
#include <stddef.h>
#define PNGLIB_BUILD /*libpng is being built, not used*/ #define PNGLIB_BUILD /*libpng is being built, not used*/
#ifdef PNG_USER_CONFIG #ifdef PNG_USER_CONFIG
@ -321,6 +324,52 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
# define png_memset memset # define png_memset memset
# endif # endif
#endif #endif
/* These macros may need to be architecture dependent. */
#define PNG_ALIGN_NONE 0 /* do not use data alignment */
#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
#ifdef offsetof
# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
#else
# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
#endif
#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */
#ifndef PNG_ALIGN_TYPE
/* Default to using aligned access optimizations and requiring alignment to a
* multiple of the data type size. Override in a compiler specific fashion
* if necessary by inserting tests here:
*/
# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE
#endif
#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE
/* This is used because in some compiler implementations non-aligned
* structure members are supported, so the offsetof approach below fails.
* Set PNG_ALIGN_TO_SIZE=0 for compiler combinations where unaligned access
* is good for performance. Do not do this unless you have tested the result
* and understand it.
*/
# define png_alignof(type) (sizeof (type))
#else
# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
# define png_alignof(type) offsetof(struct{char c; type t;}, t)
# else
# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
# define png_alignof(type) (1)
# endif
/* Else leave png_alignof undefined to prevent use thereof */
# endif
#endif
/* This implicitly assumes alignment is always to a power of 2. */
#ifdef png_alignof
# define png_isaligned(ptr, type)\
((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
#else
# define png_isaligned(ptr, type) 0
#endif
/* End of memory model/platform independent support */ /* End of memory model/platform independent support */
/* End of 1.5.0beta36 move from pngconf.h */ /* End of 1.5.0beta36 move from pngconf.h */
@ -502,32 +551,70 @@ PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp,
#endif #endif
#endif #endif
/* Constant strings for known chunk types. If you need to add a chunk, /* Constants for known chunk types. If you need to add a chunk, define the name
* define the name here, and add an invocation of the macro wherever it's * here. For historical reasons these constants have the form png_<name>; i.e.
* needed. * the prefix is lower case. Please use decimal values as the parameters to
* match the ISO PNG specification and to avoid relying on the C locale
* interpretation of character values.
*
* Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values
* are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string
* to be generated if required.
*
* PNG_32b correctly produces a value shifted by up to 24 bits, even on
* architectures where (int) is only 16 bits.
*/ */
#define PNG_IHDR PNG_CONST png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} #define PNG_32b(b,s) ((png_uint_32)(b) << (s))
#define PNG_IDAT PNG_CONST png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} #define PNG_CHUNK(b1,b2,b3,b4) \
#define PNG_IEND PNG_CONST png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
#define PNG_PLTE PNG_CONST png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
#define PNG_bKGD PNG_CONST png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} #define png_IHDR PNG_CHUNK( 73, 72, 68, 82)
#define PNG_cHRM PNG_CONST png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} #define png_IDAT PNG_CHUNK( 73, 68, 65, 84)
#define PNG_gAMA PNG_CONST png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} #define png_IEND PNG_CHUNK( 73, 69, 78, 68)
#define PNG_hIST PNG_CONST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} #define png_PLTE PNG_CHUNK( 80, 76, 84, 69)
#define PNG_iCCP PNG_CONST png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} #define png_bKGD PNG_CHUNK( 98, 75, 71, 68)
#define PNG_iTXt PNG_CONST png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} #define png_cHRM PNG_CHUNK( 99, 72, 82, 77)
#define PNG_oFFs PNG_CONST png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} #define png_gAMA PNG_CHUNK(103, 65, 77, 65)
#define PNG_pCAL PNG_CONST png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} #define png_hIST PNG_CHUNK(104, 73, 83, 84)
#define PNG_sCAL PNG_CONST png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} #define png_iCCP PNG_CHUNK(105, 67, 67, 80)
#define PNG_pHYs PNG_CONST png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} #define png_iTXt PNG_CHUNK(105, 84, 88, 116)
#define PNG_sBIT PNG_CONST png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} #define png_oFFs PNG_CHUNK(111, 70, 70, 115)
#define PNG_sPLT PNG_CONST png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} #define png_pCAL PNG_CHUNK(112, 67, 65, 76)
#define PNG_sRGB PNG_CONST png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} #define png_sCAL PNG_CHUNK(115, 67, 65, 76)
#define PNG_sTER PNG_CONST png_byte png_sTER[5] = {115, 84, 69, 82, '\0'} #define png_pHYs PNG_CHUNK(112, 72, 89, 115)
#define PNG_tEXt PNG_CONST png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} #define png_sBIT PNG_CHUNK(115, 66, 73, 84)
#define PNG_tIME PNG_CONST png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} #define png_sPLT PNG_CHUNK(115, 80, 76, 84)
#define PNG_tRNS PNG_CONST png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} #define png_sRGB PNG_CHUNK(115, 82, 71, 66)
#define PNG_zTXt PNG_CONST png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} #define png_sTER PNG_CHUNK(115, 84, 69, 82)
#define png_tEXt PNG_CHUNK(116, 69, 88, 116)
#define png_tIME PNG_CHUNK(116, 73, 77, 69)
#define png_tRNS PNG_CHUNK(116, 82, 78, 83)
#define png_zTXt PNG_CHUNK(122, 84, 88, 116)
/* The following will work on (signed char*) strings, whereas the get_uint_32
* macro will fail on top-bit-set values because of the sign extension.
*/
#define PNG_CHUNK_FROM_STRING(s)\
PNG_CHUNK(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
* signed and the argument is a (char[]) This macro will fail miserably on
* systems where (char) is more than 8 bits.
*/
#define PNG_STRING_FROM_CHUNK(s,c)\
(void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\
((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c)))
/* Do the same but terminate with a null character. */
#define PNG_CSTRING_FROM_CHUNK(s,c)\
(void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0)
/* Test on flag values as defined in the spec (section 5.4): */
#define PNG_CHUNK_ANCILLIARY(c) (1 & ((c) >> 29))
#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLIARY(c))
#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21))
#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13))
#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5))
/* Gamma values (new at libpng-1.5.4): */ /* Gamma values (new at libpng-1.5.4): */
#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ #define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */
@ -784,17 +871,44 @@ PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
/* Internal use only. Called before first row of data */ /* Internal use only. Called before first row of data */
PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
/* Combine a row of data, dealing with alpha, etc. if requested */ /* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an
* array of png_ptr->width pixels. If the image is not interlaced or this
* is the final pass this just does a png_memcpy, otherwise the "display" flag
* is used to determine whether to copy pixels that are not in the current pass.
*
* Because 'png_do_read_interlace' (below) replicates pixels this allows this
* function to achieve the documented 'blocky' appearance during interlaced read
* if display is 1 and the 'sparkle' appearance, where existing pixels in 'row'
* are not changed if they are not in the current pass, when display is 0.
*
* 'display' must be 0 or 1, otherwise the memcpy will be done regardless.
*
* The API always reads from the png_struct row buffer and always assumes that
* it is full width (png_do_read_interlace has already been called.)
*
* This function is only ever used to write to row buffers provided by the
* caller of the relevant libpng API and the row must have already been
* transformed by the read transformations.
*
* The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed
* bitmasks for use within the code, otherwise runtime generated masks are used.
* The default is compile time masks.
*/
#ifndef PNG_USE_COMPILE_TIME_MASKS
# define PNG_USE_COMPILE_TIME_MASKS 1
#endif
PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
int mask)); int display));
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
/* Expand an interlaced row */ /* Expand an interlaced row: the 'row_info' describes the pass data that has
/* OLD pre-1.0.9 interface: * been read in and must correspond to the pixels in 'row', the pixels are
* expanded (moved apart) in 'row' to match the final layout, when doing this
* the pixels are *replicated* to the intervening space. This is essential for
* the correct operation of png_combine_row, above.
*/
PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
png_bytep row, int pass, png_uint_32 transformations)); png_bytep row, int pass, png_uint_32 transformations));
*/
PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
#endif #endif
/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ /* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
@ -805,10 +919,11 @@ PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
png_bytep row, int pass)); png_bytep row, int pass));
#endif #endif
/* Unfilter a row */ /* Unfilter a row: check the filter value before calling this, there is no point
PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, * calling it for PNG_FILTER_VALUE_NONE.
png_row_infop row_info, png_bytep row, png_const_bytep prev_row, */
int filter)); PNG_EXTERN void png_read_filter_row PNGARG((png_row_infop row_info,
png_bytep row, png_const_bytep prev_row, int filter));
/* Choose the best filter to use and filter the row data */ /* Choose the best filter to use and filter the row data */
PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
@ -1058,18 +1173,30 @@ PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length)); png_uint_32 length));
#endif #endif
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 length)); png_infop info_ptr, png_uint_32 length));
#endif
PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
png_const_bytep chunk_name)); png_uint_32 chunk_name));
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
/* Exactly as png_handle_as_unknown() except that the argument is a 32-bit chunk
* name, not a string.
*/
PNG_EXTERN int png_chunk_unknown_handling PNGARG((png_structp png_ptr,
png_uint_32 chunk_name));
#endif
/* Handle the transformations for reading and writing */ /* Handle the transformations for reading and writing */
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr,
png_row_infop row_info));
#endif #endif
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr,
png_row_infop row_info));
#endif #endif
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
@ -1441,6 +1568,7 @@ PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value,
png_fixed_point gamma_value)); png_fixed_point gamma_value));
PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value,
png_fixed_point gamma_value)); png_fixed_point gamma_value));
PNG_EXTERN void png_destroy_gamma_table(png_structp png_ptr);
PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr,
int bit_depth)); int bit_depth));
#endif #endif

View file

@ -1,7 +1,7 @@
/* pngread.c - read a PNG file /* pngread.c - read a PNG file
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -190,89 +190,35 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
for (;;) for (;;)
{ {
PNG_IHDR;
PNG_IDAT;
PNG_IEND;
PNG_PLTE;
#ifdef PNG_READ_bKGD_SUPPORTED
PNG_bKGD;
#endif
#ifdef PNG_READ_cHRM_SUPPORTED
PNG_cHRM;
#endif
#ifdef PNG_READ_gAMA_SUPPORTED
PNG_gAMA;
#endif
#ifdef PNG_READ_hIST_SUPPORTED
PNG_hIST;
#endif
#ifdef PNG_READ_iCCP_SUPPORTED
PNG_iCCP;
#endif
#ifdef PNG_READ_iTXt_SUPPORTED
PNG_iTXt;
#endif
#ifdef PNG_READ_oFFs_SUPPORTED
PNG_oFFs;
#endif
#ifdef PNG_READ_pCAL_SUPPORTED
PNG_pCAL;
#endif
#ifdef PNG_READ_pHYs_SUPPORTED
PNG_pHYs;
#endif
#ifdef PNG_READ_sBIT_SUPPORTED
PNG_sBIT;
#endif
#ifdef PNG_READ_sCAL_SUPPORTED
PNG_sCAL;
#endif
#ifdef PNG_READ_sPLT_SUPPORTED
PNG_sPLT;
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
PNG_sRGB;
#endif
#ifdef PNG_READ_tEXt_SUPPORTED
PNG_tEXt;
#endif
#ifdef PNG_READ_tIME_SUPPORTED
PNG_tIME;
#endif
#ifdef PNG_READ_tRNS_SUPPORTED
PNG_tRNS;
#endif
#ifdef PNG_READ_zTXt_SUPPORTED
PNG_zTXt;
#endif
png_uint_32 length = png_read_chunk_header(png_ptr); png_uint_32 length = png_read_chunk_header(png_ptr);
PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; png_uint_32 chunk_name = png_ptr->chunk_name;
/* This should be a binary subdivision search or a hash for /* This should be a binary subdivision search or a hash for
* matching the chunk name rather than a linear search. * matching the chunk name rather than a linear search.
*/ */
if (!png_memcmp(chunk_name, png_IDAT, 4)) if (chunk_name == png_IDAT)
if (png_ptr->mode & PNG_AFTER_IDAT) if (png_ptr->mode & PNG_AFTER_IDAT)
png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
if (!png_memcmp(chunk_name, png_IHDR, 4)) if (chunk_name == png_IHDR)
png_handle_IHDR(png_ptr, info_ptr, length); png_handle_IHDR(png_ptr, info_ptr, length);
else if (!png_memcmp(chunk_name, png_IEND, 4)) else if (chunk_name == png_IEND)
png_handle_IEND(png_ptr, info_ptr, length); png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if (png_handle_as_unknown(png_ptr, chunk_name)) else if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
PNG_HANDLE_CHUNK_AS_DEFAULT)
{ {
if (!png_memcmp(chunk_name, png_IDAT, 4)) if (chunk_name == png_IDAT)
png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->mode |= PNG_HAVE_IDAT;
png_handle_unknown(png_ptr, info_ptr, length); png_handle_unknown(png_ptr, info_ptr, length);
if (!png_memcmp(chunk_name, png_PLTE, 4)) if (chunk_name == png_PLTE)
png_ptr->mode |= PNG_HAVE_PLTE; png_ptr->mode |= PNG_HAVE_PLTE;
else if (!png_memcmp(chunk_name, png_IDAT, 4)) else if (chunk_name == png_IDAT)
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR)) if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before IDAT"); png_error(png_ptr, "Missing IHDR before IDAT");
@ -285,10 +231,10 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
} }
} }
#endif #endif
else if (!png_memcmp(chunk_name, png_PLTE, 4)) else if (chunk_name == png_PLTE)
png_handle_PLTE(png_ptr, info_ptr, length); png_handle_PLTE(png_ptr, info_ptr, length);
else if (!png_memcmp(chunk_name, png_IDAT, 4)) else if (chunk_name == png_IDAT)
{ {
if (!(png_ptr->mode & PNG_HAVE_IHDR)) if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before IDAT"); png_error(png_ptr, "Missing IHDR before IDAT");
@ -303,87 +249,87 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
} }
#ifdef PNG_READ_bKGD_SUPPORTED #ifdef PNG_READ_bKGD_SUPPORTED
else if (!png_memcmp(chunk_name, png_bKGD, 4)) else if (chunk_name == png_bKGD)
png_handle_bKGD(png_ptr, info_ptr, length); png_handle_bKGD(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_READ_cHRM_SUPPORTED
else if (!png_memcmp(chunk_name, png_cHRM, 4)) else if (chunk_name == png_cHRM)
png_handle_cHRM(png_ptr, info_ptr, length); png_handle_cHRM(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_gAMA_SUPPORTED #ifdef PNG_READ_gAMA_SUPPORTED
else if (!png_memcmp(chunk_name, png_gAMA, 4)) else if (chunk_name == png_gAMA)
png_handle_gAMA(png_ptr, info_ptr, length); png_handle_gAMA(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_hIST_SUPPORTED #ifdef PNG_READ_hIST_SUPPORTED
else if (!png_memcmp(chunk_name, png_hIST, 4)) else if (chunk_name == png_hIST)
png_handle_hIST(png_ptr, info_ptr, length); png_handle_hIST(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_oFFs_SUPPORTED #ifdef PNG_READ_oFFs_SUPPORTED
else if (!png_memcmp(chunk_name, png_oFFs, 4)) else if (chunk_name == png_oFFs)
png_handle_oFFs(png_ptr, info_ptr, length); png_handle_oFFs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pCAL_SUPPORTED #ifdef PNG_READ_pCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_pCAL, 4)) else if (chunk_name == png_pCAL)
png_handle_pCAL(png_ptr, info_ptr, length); png_handle_pCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sCAL_SUPPORTED #ifdef PNG_READ_sCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_sCAL, 4)) else if (chunk_name == png_sCAL)
png_handle_sCAL(png_ptr, info_ptr, length); png_handle_sCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pHYs_SUPPORTED #ifdef PNG_READ_pHYs_SUPPORTED
else if (!png_memcmp(chunk_name, png_pHYs, 4)) else if (chunk_name == png_pHYs)
png_handle_pHYs(png_ptr, info_ptr, length); png_handle_pHYs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sBIT_SUPPORTED #ifdef PNG_READ_sBIT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sBIT, 4)) else if (chunk_name == png_sBIT)
png_handle_sBIT(png_ptr, info_ptr, length); png_handle_sBIT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sRGB_SUPPORTED #ifdef PNG_READ_sRGB_SUPPORTED
else if (!png_memcmp(chunk_name, png_sRGB, 4)) else if (chunk_name == png_sRGB)
png_handle_sRGB(png_ptr, info_ptr, length); png_handle_sRGB(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iCCP_SUPPORTED #ifdef PNG_READ_iCCP_SUPPORTED
else if (!png_memcmp(chunk_name, png_iCCP, 4)) else if (chunk_name == png_iCCP)
png_handle_iCCP(png_ptr, info_ptr, length); png_handle_iCCP(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sPLT_SUPPORTED #ifdef PNG_READ_sPLT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sPLT, 4)) else if (chunk_name == png_sPLT)
png_handle_sPLT(png_ptr, info_ptr, length); png_handle_sPLT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tEXt_SUPPORTED #ifdef PNG_READ_tEXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_tEXt, 4)) else if (chunk_name == png_tEXt)
png_handle_tEXt(png_ptr, info_ptr, length); png_handle_tEXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tIME_SUPPORTED #ifdef PNG_READ_tIME_SUPPORTED
else if (!png_memcmp(chunk_name, png_tIME, 4)) else if (chunk_name == png_tIME)
png_handle_tIME(png_ptr, info_ptr, length); png_handle_tIME(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tRNS_SUPPORTED #ifdef PNG_READ_tRNS_SUPPORTED
else if (!png_memcmp(chunk_name, png_tRNS, 4)) else if (chunk_name == png_tRNS)
png_handle_tRNS(png_ptr, info_ptr, length); png_handle_tRNS(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_zTXt_SUPPORTED #ifdef PNG_READ_zTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_zTXt, 4)) else if (chunk_name == png_zTXt)
png_handle_zTXt(png_ptr, info_ptr, length); png_handle_zTXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iTXt_SUPPORTED #ifdef PNG_READ_iTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_iTXt, 4)) else if (chunk_name == png_iTXt)
png_handle_iTXt(png_ptr, info_ptr, length); png_handle_iTXt(png_ptr, info_ptr, length);
#endif #endif
@ -402,13 +348,7 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr);
png_read_start_row(png_ptr);
else
png_warning(png_ptr,
"Ignoring extra png_read_update_info() call;"
" row buffer not reallocated");
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
png_read_transform_info(png_ptr, info_ptr); png_read_transform_info(png_ptr, info_ptr);
@ -428,15 +368,8 @@ png_start_read_image(png_structp png_ptr)
{ {
png_debug(1, "in png_start_read_image"); png_debug(1, "in png_start_read_image");
if (png_ptr == NULL) if (png_ptr != NULL)
return; png_read_start_row(png_ptr);
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr);
else
png_warning(png_ptr,
"Ignoring extra png_start_read_image() call;"
" row buffer not reallocated");
} }
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
@ -444,23 +377,30 @@ png_start_read_image(png_structp png_ptr)
void PNGAPI void PNGAPI
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
{ {
PNG_IDAT;
#ifdef PNG_READ_INTERLACING_SUPPORTED
PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
0xff};
PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
#endif
int ret; int ret;
png_row_info row_info;
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
png_debug2(1, "in png_read_row (row %lu, pass %d)", png_debug2(1, "in png_read_row (row %lu, pass %d)",
(unsigned long)png_ptr->row_number, png_ptr->pass); (unsigned long)png_ptr->row_number, png_ptr->pass);
/* png_read_start_row sets the information (in particular iwidth) for this
* interlace pass.
*/
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr); png_read_start_row(png_ptr);
/* 1.5.6: row_info moved out of png_struct to a local here. */
row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
row_info.color_type = png_ptr->color_type;
row_info.bit_depth = png_ptr->bit_depth;
row_info.channels = png_ptr->channels;
row_info.pixel_depth = png_ptr->pixel_depth;
row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
if (png_ptr->row_number == 0 && png_ptr->pass == 0) if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{ {
/* Check for transforms that have been set but were defined out */ /* Check for transforms that have been set but were defined out */
@ -502,7 +442,12 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
} }
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
/* If interlaced and we do not need a new row, combine row and return */ /* If interlaced and we do not need a new row, combine row and return.
* Notice that the pixels we have from previous rows have been transformed
* already; we can only combine like with like (transformed or
* untransformed) and, because of the libpng API for interlaced images, this
* means we must transform before de-interlacing.
*/
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
{ {
switch (png_ptr->pass) switch (png_ptr->pass)
@ -511,8 +456,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if (png_ptr->row_number & 0x07) if (png_ptr->row_number & 0x07)
{ {
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
} }
@ -522,8 +466,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
{ {
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
@ -534,8 +477,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if ((png_ptr->row_number & 0x07) != 4) if ((png_ptr->row_number & 0x07) != 4)
{ {
if (dsp_row != NULL && (png_ptr->row_number & 4)) if (dsp_row != NULL && (png_ptr->row_number & 4))
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
@ -546,8 +488,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if ((png_ptr->row_number & 3) || png_ptr->width < 3) if ((png_ptr->row_number & 3) || png_ptr->width < 3)
{ {
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
@ -558,8 +499,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if ((png_ptr->row_number & 3) != 2) if ((png_ptr->row_number & 3) != 2)
{ {
if (dsp_row != NULL && (png_ptr->row_number & 2)) if (dsp_row != NULL && (png_ptr->row_number & 2))
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
@ -569,8 +509,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
if ((png_ptr->row_number & 1) || png_ptr->width < 2) if ((png_ptr->row_number & 1) || png_ptr->width < 2)
{ {
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
return; return;
@ -606,7 +545,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_crc_finish(png_ptr, 0); png_crc_finish(png_ptr, 0);
png_ptr->idat_size = png_read_chunk_header(png_ptr); png_ptr->idat_size = png_read_chunk_header(png_ptr);
if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) if (png_ptr->chunk_name != png_IDAT)
png_error(png_ptr, "Not enough image data"); png_error(png_ptr, "Not enough image data");
} }
png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
@ -636,63 +575,72 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
} while (png_ptr->zstream.avail_out); } while (png_ptr->zstream.avail_out);
png_ptr->row_info.color_type = png_ptr->color_type; if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
png_ptr->row_info.width = png_ptr->iwidth; {
png_ptr->row_info.channels = png_ptr->channels; if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
png_ptr->row_info.bit_depth = png_ptr->bit_depth; png_read_filter_row(&row_info, png_ptr->row_buf + 1,
png_ptr->row_info.pixel_depth = png_ptr->pixel_depth; png_ptr->prev_row + 1, png_ptr->row_buf[0]);
png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, else
png_ptr->row_info.width); png_error(png_ptr, "bad adaptive filter value");
}
if (png_ptr->row_buf[0]) /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
png_read_filter_row(png_ptr, &(png_ptr->row_info), * 1.5.6, while the buffer really is this big in current versions of libpng
png_ptr->row_buf + 1, png_ptr->prev_row + 1, * it may not be in the future, so this was changed just to copy the
(int)(png_ptr->row_buf[0])); * interlaced count:
*/
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
#ifdef PNG_MNG_FEATURES_SUPPORTED #ifdef PNG_MNG_FEATURES_SUPPORTED
if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
{ {
/* Intrapixel differencing */ /* Intrapixel differencing */
png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
} }
#endif #endif
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
if (png_ptr->transformations) if (png_ptr->transformations)
png_do_read_transformations(png_ptr); png_do_read_transformations(png_ptr, &row_info);
#endif #endif
/* The transformed pixel depth should match the depth now in row_info. */
if (png_ptr->transformed_pixel_depth == 0)
{
png_ptr->transformed_pixel_depth = row_info.pixel_depth;
if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
png_error(png_ptr, "sequential row overflow");
}
else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
png_error(png_ptr, "internal sequential row size calculation error");
#ifdef PNG_READ_INTERLACING_SUPPORTED #ifdef PNG_READ_INTERLACING_SUPPORTED
/* Blow up interlaced rows to full size */ /* Blow up interlaced rows to full size */
if (png_ptr->interlaced && if (png_ptr->interlaced &&
(png_ptr->transformations & PNG_INTERLACE)) (png_ptr->transformations & PNG_INTERLACE))
{ {
if (png_ptr->pass < 6) if (png_ptr->pass < 6)
/* Old interface (pre-1.0.9): png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
* png_do_read_interlace(&(png_ptr->row_info), png_ptr->transformations);
* png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
*/
png_do_read_interlace(png_ptr);
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); png_combine_row(png_ptr, dsp_row, 1/*display*/);
if (row != NULL) if (row != NULL)
png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]); png_combine_row(png_ptr, row, 0/*row*/);
} }
else else
#endif #endif
{ {
if (row != NULL) if (row != NULL)
png_combine_row(png_ptr, row, 0xff); png_combine_row(png_ptr, row, -1/*ignored*/);
if (dsp_row != NULL) if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, 0xff); png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
} }
png_read_finish_row(png_ptr); png_read_finish_row(png_ptr);
@ -858,85 +806,31 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
do do
{ {
PNG_IHDR;
PNG_IDAT;
PNG_IEND;
PNG_PLTE;
#ifdef PNG_READ_bKGD_SUPPORTED
PNG_bKGD;
#endif
#ifdef PNG_READ_cHRM_SUPPORTED
PNG_cHRM;
#endif
#ifdef PNG_READ_gAMA_SUPPORTED
PNG_gAMA;
#endif
#ifdef PNG_READ_hIST_SUPPORTED
PNG_hIST;
#endif
#ifdef PNG_READ_iCCP_SUPPORTED
PNG_iCCP;
#endif
#ifdef PNG_READ_iTXt_SUPPORTED
PNG_iTXt;
#endif
#ifdef PNG_READ_oFFs_SUPPORTED
PNG_oFFs;
#endif
#ifdef PNG_READ_pCAL_SUPPORTED
PNG_pCAL;
#endif
#ifdef PNG_READ_pHYs_SUPPORTED
PNG_pHYs;
#endif
#ifdef PNG_READ_sBIT_SUPPORTED
PNG_sBIT;
#endif
#ifdef PNG_READ_sCAL_SUPPORTED
PNG_sCAL;
#endif
#ifdef PNG_READ_sPLT_SUPPORTED
PNG_sPLT;
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
PNG_sRGB;
#endif
#ifdef PNG_READ_tEXt_SUPPORTED
PNG_tEXt;
#endif
#ifdef PNG_READ_tIME_SUPPORTED
PNG_tIME;
#endif
#ifdef PNG_READ_tRNS_SUPPORTED
PNG_tRNS;
#endif
#ifdef PNG_READ_zTXt_SUPPORTED
PNG_zTXt;
#endif
png_uint_32 length = png_read_chunk_header(png_ptr); png_uint_32 length = png_read_chunk_header(png_ptr);
PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; png_uint_32 chunk_name = png_ptr->chunk_name;
if (!png_memcmp(chunk_name, png_IHDR, 4)) if (chunk_name == png_IHDR)
png_handle_IHDR(png_ptr, info_ptr, length); png_handle_IHDR(png_ptr, info_ptr, length);
else if (!png_memcmp(chunk_name, png_IEND, 4)) else if (chunk_name == png_IEND)
png_handle_IEND(png_ptr, info_ptr, length); png_handle_IEND(png_ptr, info_ptr, length);
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
else if (png_handle_as_unknown(png_ptr, chunk_name)) else if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
PNG_HANDLE_CHUNK_AS_DEFAULT)
{ {
if (!png_memcmp(chunk_name, png_IDAT, 4)) if (chunk_name == png_IDAT)
{ {
if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
png_benign_error(png_ptr, "Too many IDATs found"); png_benign_error(png_ptr, "Too many IDATs found");
} }
png_handle_unknown(png_ptr, info_ptr, length); png_handle_unknown(png_ptr, info_ptr, length);
if (!png_memcmp(chunk_name, png_PLTE, 4)) if (chunk_name == png_PLTE)
png_ptr->mode |= PNG_HAVE_PLTE; png_ptr->mode |= PNG_HAVE_PLTE;
} }
#endif #endif
else if (!png_memcmp(chunk_name, png_IDAT, 4)) else if (chunk_name == png_IDAT)
{ {
/* Zero length IDATs are legal after the last IDAT has been /* Zero length IDATs are legal after the last IDAT has been
* read, but not after other chunks have been read. * read, but not after other chunks have been read.
@ -946,91 +840,91 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
png_crc_finish(png_ptr, length); png_crc_finish(png_ptr, length);
} }
else if (!png_memcmp(chunk_name, png_PLTE, 4)) else if (chunk_name == png_PLTE)
png_handle_PLTE(png_ptr, info_ptr, length); png_handle_PLTE(png_ptr, info_ptr, length);
#ifdef PNG_READ_bKGD_SUPPORTED #ifdef PNG_READ_bKGD_SUPPORTED
else if (!png_memcmp(chunk_name, png_bKGD, 4)) else if (chunk_name == png_bKGD)
png_handle_bKGD(png_ptr, info_ptr, length); png_handle_bKGD(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_READ_cHRM_SUPPORTED
else if (!png_memcmp(chunk_name, png_cHRM, 4)) else if (chunk_name == png_cHRM)
png_handle_cHRM(png_ptr, info_ptr, length); png_handle_cHRM(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_gAMA_SUPPORTED #ifdef PNG_READ_gAMA_SUPPORTED
else if (!png_memcmp(chunk_name, png_gAMA, 4)) else if (chunk_name == png_gAMA)
png_handle_gAMA(png_ptr, info_ptr, length); png_handle_gAMA(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_hIST_SUPPORTED #ifdef PNG_READ_hIST_SUPPORTED
else if (!png_memcmp(chunk_name, png_hIST, 4)) else if (chunk_name == png_hIST)
png_handle_hIST(png_ptr, info_ptr, length); png_handle_hIST(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_oFFs_SUPPORTED #ifdef PNG_READ_oFFs_SUPPORTED
else if (!png_memcmp(chunk_name, png_oFFs, 4)) else if (chunk_name == png_oFFs)
png_handle_oFFs(png_ptr, info_ptr, length); png_handle_oFFs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pCAL_SUPPORTED #ifdef PNG_READ_pCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_pCAL, 4)) else if (chunk_name == png_pCAL)
png_handle_pCAL(png_ptr, info_ptr, length); png_handle_pCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sCAL_SUPPORTED #ifdef PNG_READ_sCAL_SUPPORTED
else if (!png_memcmp(chunk_name, png_sCAL, 4)) else if (chunk_name == png_sCAL)
png_handle_sCAL(png_ptr, info_ptr, length); png_handle_sCAL(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_pHYs_SUPPORTED #ifdef PNG_READ_pHYs_SUPPORTED
else if (!png_memcmp(chunk_name, png_pHYs, 4)) else if (chunk_name == png_pHYs)
png_handle_pHYs(png_ptr, info_ptr, length); png_handle_pHYs(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sBIT_SUPPORTED #ifdef PNG_READ_sBIT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sBIT, 4)) else if (chunk_name == png_sBIT)
png_handle_sBIT(png_ptr, info_ptr, length); png_handle_sBIT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sRGB_SUPPORTED #ifdef PNG_READ_sRGB_SUPPORTED
else if (!png_memcmp(chunk_name, png_sRGB, 4)) else if (chunk_name == png_sRGB)
png_handle_sRGB(png_ptr, info_ptr, length); png_handle_sRGB(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iCCP_SUPPORTED #ifdef PNG_READ_iCCP_SUPPORTED
else if (!png_memcmp(chunk_name, png_iCCP, 4)) else if (chunk_name == png_iCCP)
png_handle_iCCP(png_ptr, info_ptr, length); png_handle_iCCP(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_sPLT_SUPPORTED #ifdef PNG_READ_sPLT_SUPPORTED
else if (!png_memcmp(chunk_name, png_sPLT, 4)) else if (chunk_name == png_sPLT)
png_handle_sPLT(png_ptr, info_ptr, length); png_handle_sPLT(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tEXt_SUPPORTED #ifdef PNG_READ_tEXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_tEXt, 4)) else if (chunk_name == png_tEXt)
png_handle_tEXt(png_ptr, info_ptr, length); png_handle_tEXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tIME_SUPPORTED #ifdef PNG_READ_tIME_SUPPORTED
else if (!png_memcmp(chunk_name, png_tIME, 4)) else if (chunk_name == png_tIME)
png_handle_tIME(png_ptr, info_ptr, length); png_handle_tIME(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_tRNS_SUPPORTED #ifdef PNG_READ_tRNS_SUPPORTED
else if (!png_memcmp(chunk_name, png_tRNS, 4)) else if (chunk_name == png_tRNS)
png_handle_tRNS(png_ptr, info_ptr, length); png_handle_tRNS(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_zTXt_SUPPORTED #ifdef PNG_READ_zTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_zTXt, 4)) else if (chunk_name == png_zTXt)
png_handle_zTXt(png_ptr, info_ptr, length); png_handle_zTXt(png_ptr, info_ptr, length);
#endif #endif
#ifdef PNG_READ_iTXt_SUPPORTED #ifdef PNG_READ_iTXt_SUPPORTED
else if (!png_memcmp(chunk_name, png_iTXt, 4)) else if (chunk_name == png_iTXt)
png_handle_iTXt(png_ptr, info_ptr, length); png_handle_iTXt(png_ptr, info_ptr, length);
#endif #endif
@ -1138,9 +1032,13 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
if (end_info_ptr != NULL) if (end_info_ptr != NULL)
png_info_destroy(png_ptr, end_info_ptr); png_info_destroy(png_ptr, end_info_ptr);
#ifdef PNG_READ_GAMMA_SUPPORTED
png_destroy_gamma_table(png_ptr);
#endif
png_free(png_ptr, png_ptr->zbuf); png_free(png_ptr, png_ptr->zbuf);
png_free(png_ptr, png_ptr->big_row_buf); png_free(png_ptr, png_ptr->big_row_buf);
png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->big_prev_row);
png_free(png_ptr, png_ptr->chunkdata); png_free(png_ptr, png_ptr->chunkdata);
#ifdef PNG_READ_QUANTIZE_SUPPORTED #ifdef PNG_READ_QUANTIZE_SUPPORTED
@ -1148,15 +1046,6 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
png_free(png_ptr, png_ptr->quantize_index); png_free(png_ptr, png_ptr->quantize_index);
#endif #endif
#ifdef PNG_READ_GAMMA_SUPPORTED
png_free(png_ptr, png_ptr->gamma_table);
#endif
#ifdef PNG_READ_BACKGROUND_SUPPORTED
png_free(png_ptr, png_ptr->gamma_from_1);
png_free(png_ptr, png_ptr->gamma_to_1);
#endif
if (png_ptr->free_me & PNG_FREE_PLTE) if (png_ptr->free_me & PNG_FREE_PLTE)
png_zfree(png_ptr, png_ptr->palette); png_zfree(png_ptr, png_ptr->palette);
png_ptr->free_me &= ~PNG_FREE_PLTE; png_ptr->free_me &= ~PNG_FREE_PLTE;
@ -1174,42 +1063,6 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
png_ptr->free_me &= ~PNG_FREE_HIST; png_ptr->free_me &= ~PNG_FREE_HIST;
#endif #endif
#ifdef PNG_READ_GAMMA_SUPPORTED
if (png_ptr->gamma_16_table != NULL)
{
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_table[i]);
}
png_free(png_ptr, png_ptr->gamma_16_table);
}
#ifdef PNG_READ_BACKGROUND_SUPPORTED
if (png_ptr->gamma_16_from_1 != NULL)
{
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
}
png_free(png_ptr, png_ptr->gamma_16_from_1);
}
if (png_ptr->gamma_16_to_1 != NULL)
{
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
}
png_free(png_ptr, png_ptr->gamma_16_to_1);
}
#endif
#endif
inflateEnd(&png_ptr->zstream); inflateEnd(&png_ptr->zstream);
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED #ifdef PNG_PROGRESSIVE_READ_SUPPORTED

View file

@ -1,7 +1,7 @@
/* pngrtran.c - transforms the data in a row for PNG readers /* pngrtran.c - transforms the data in a row for PNG readers
* *
* Last changed in libpng 1.5.5 [September 22, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -1198,53 +1198,44 @@ png_init_rgb_transformations(png_structp png_ptr)
{ {
{ {
/* Expand background and tRNS chunks */ /* Expand background and tRNS chunks */
int gray = png_ptr->background.gray;
int trans_gray = png_ptr->trans_color.gray;
switch (png_ptr->bit_depth) switch (png_ptr->bit_depth)
{ {
case 1: case 1:
png_ptr->background.gray *= (png_uint_16)0xff; gray *= 0xff;
png_ptr->background.red = png_ptr->background.green trans_gray *= 0xff;
= png_ptr->background.blue = png_ptr->background.gray;
if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
{
png_ptr->trans_color.gray *= (png_uint_16)0xff;
png_ptr->trans_color.red = png_ptr->trans_color.green
= png_ptr->trans_color.blue = png_ptr->trans_color.gray;
}
break; break;
case 2: case 2:
png_ptr->background.gray *= (png_uint_16)0x55; gray *= 0x55;
png_ptr->background.red = png_ptr->background.green trans_gray *= 0x55;
= png_ptr->background.blue = png_ptr->background.gray;
if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
{
png_ptr->trans_color.gray *= (png_uint_16)0x55;
png_ptr->trans_color.red = png_ptr->trans_color.green
= png_ptr->trans_color.blue = png_ptr->trans_color.gray;
}
break; break;
case 4: case 4:
png_ptr->background.gray *= (png_uint_16)0x11; gray *= 0x11;
png_ptr->background.red = png_ptr->background.green trans_gray *= 0x11;
= png_ptr->background.blue = png_ptr->background.gray;
if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
{
png_ptr->trans_color.gray *= (png_uint_16)0x11;
png_ptr->trans_color.red = png_ptr->trans_color.green
= png_ptr->trans_color.blue = png_ptr->trans_color.gray;
}
break; break;
default: default:
case 8: case 8:
/* Already 8 bits, fall through */
case 16: case 16:
png_ptr->background.red = png_ptr->background.green /* Already a full 16 bits */
= png_ptr->background.blue = png_ptr->background.gray;
break; break;
} }
png_ptr->background.red = png_ptr->background.green =
png_ptr->background.blue = (png_uint_16)gray;
if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
{
png_ptr->trans_color.red = png_ptr->trans_color.green =
png_ptr->trans_color.blue = (png_uint_16)trans_gray;
}
} }
} /* background expand and (therefore) no alpha association. */ } /* background expand and (therefore) no alpha association. */
#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */ #endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
@ -1650,8 +1641,9 @@ png_init_read_transformations(png_structp png_ptr)
/* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
else /* color_type != PNG_COLOR_TYPE_PALETTE */ else /* color_type != PNG_COLOR_TYPE_PALETTE */
{ {
png_fixed_point g = PNG_FP_1; int gs_sig, g_sig;
png_fixed_point gs = PNG_FP_1; png_fixed_point g = PNG_FP_1; /* Correction to linear */
png_fixed_point gs = PNG_FP_1; /* Correction to screen */
switch (png_ptr->background_gamma_type) switch (png_ptr->background_gamma_type)
{ {
@ -1675,34 +1667,45 @@ png_init_read_transformations(png_structp png_ptr)
png_error(png_ptr, "invalid background gamma type"); png_error(png_ptr, "invalid background gamma type");
} }
png_ptr->background_1.gray = png_gamma_correct(png_ptr, g_sig = png_gamma_significant(g);
png_ptr->background.gray, g); gs_sig = png_gamma_significant(gs);
png_ptr->background.gray = png_gamma_correct(png_ptr, if (g_sig)
png_ptr->background.gray, gs); png_ptr->background_1.gray = png_gamma_correct(png_ptr,
png_ptr->background.gray, g);
if (gs_sig)
png_ptr->background.gray = png_gamma_correct(png_ptr,
png_ptr->background.gray, gs);
if ((png_ptr->background.red != png_ptr->background.green) || if ((png_ptr->background.red != png_ptr->background.green) ||
(png_ptr->background.red != png_ptr->background.blue) || (png_ptr->background.red != png_ptr->background.blue) ||
(png_ptr->background.red != png_ptr->background.gray)) (png_ptr->background.red != png_ptr->background.gray))
{ {
/* RGB or RGBA with color background */ /* RGB or RGBA with color background */
png_ptr->background_1.red = png_gamma_correct(png_ptr, if (g_sig)
png_ptr->background.red, g); {
png_ptr->background_1.red = png_gamma_correct(png_ptr,
png_ptr->background.red, g);
png_ptr->background_1.green = png_gamma_correct(png_ptr, png_ptr->background_1.green = png_gamma_correct(png_ptr,
png_ptr->background.green, g); png_ptr->background.green, g);
png_ptr->background_1.blue = png_gamma_correct(png_ptr, png_ptr->background_1.blue = png_gamma_correct(png_ptr,
png_ptr->background.blue, g); png_ptr->background.blue, g);
}
png_ptr->background.red = png_gamma_correct(png_ptr, if (gs_sig)
png_ptr->background.red, gs); {
png_ptr->background.red = png_gamma_correct(png_ptr,
png_ptr->background.red, gs);
png_ptr->background.green = png_gamma_correct(png_ptr, png_ptr->background.green = png_gamma_correct(png_ptr,
png_ptr->background.green, gs); png_ptr->background.green, gs);
png_ptr->background.blue = png_gamma_correct(png_ptr, png_ptr->background.blue = png_gamma_correct(png_ptr,
png_ptr->background.blue, gs); png_ptr->background.blue, gs);
}
} }
else else
@ -1714,6 +1717,9 @@ png_init_read_transformations(png_structp png_ptr)
png_ptr->background.red = png_ptr->background.green png_ptr->background.red = png_ptr->background.green
= png_ptr->background.blue = png_ptr->background.gray; = png_ptr->background.blue = png_ptr->background.gray;
} }
/* The background is now in screen gamma: */
png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
} /* color_type != PNG_COLOR_TYPE_PALETTE */ } /* color_type != PNG_COLOR_TYPE_PALETTE */
}/* png_ptr->transformations & PNG_BACKGROUND */ }/* png_ptr->transformations & PNG_BACKGROUND */
@ -1788,26 +1794,38 @@ png_init_read_transformations(png_structp png_ptr)
if ((png_ptr->transformations & PNG_SHIFT) && if ((png_ptr->transformations & PNG_SHIFT) &&
(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
{ {
png_uint_16 i; int i;
png_uint_16 istop = png_ptr->num_palette; int istop = png_ptr->num_palette;
int sr = 8 - png_ptr->sig_bit.red; int shift = 8 - png_ptr->sig_bit.red;
int sg = 8 - png_ptr->sig_bit.green;
int sb = 8 - png_ptr->sig_bit.blue;
if (sr < 0 || sr > 8) /* significant bits can be in the range 1 to 7 for a meaninful result, if
sr = 0; * the number of significant bits is 0 then no shift is done (this is an
* error condition which is silently ignored.)
if (sg < 0 || sg > 8) */
sg = 0; if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
if (sb < 0 || sb > 8)
sb = 0;
for (i = 0; i < istop; i++)
{ {
png_ptr->palette[i].red >>= sr; int component = png_ptr->palette[i].red;
png_ptr->palette[i].green >>= sg;
png_ptr->palette[i].blue >>= sb; component >>= shift;
png_ptr->palette[i].red = (png_byte)component;
}
shift = 8 - png_ptr->sig_bit.green;
if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
{
int component = png_ptr->palette[i].green;
component >>= shift;
png_ptr->palette[i].green = (png_byte)component;
}
shift = 8 - png_ptr->sig_bit.blue;
if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
{
int component = png_ptr->palette[i].blue;
component >>= shift;
png_ptr->palette[i].blue = (png_byte)component;
} }
} }
#endif /* PNG_READ_SHIFT_SUPPORTED */ #endif /* PNG_READ_SHIFT_SUPPORTED */
@ -1913,12 +1931,14 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
if (png_ptr->transformations & PNG_GRAY_TO_RGB) if (png_ptr->transformations & PNG_GRAY_TO_RGB)
info_ptr->color_type |= PNG_COLOR_MASK_COLOR; info_ptr->color_type = (png_byte)(info_ptr->color_type |
PNG_COLOR_MASK_COLOR);
#endif #endif
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
if (png_ptr->transformations & PNG_RGB_TO_GRAY) if (png_ptr->transformations & PNG_RGB_TO_GRAY)
info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; info_ptr->color_type = (png_byte)(info_ptr->color_type &
~PNG_COLOR_MASK_COLOR);
#endif #endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED #ifdef PNG_READ_QUANTIZE_SUPPORTED
@ -1958,7 +1978,8 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_STRIP_ALPHA) if (png_ptr->transformations & PNG_STRIP_ALPHA)
{ {
info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; info_ptr->color_type = (png_byte)(info_ptr->color_type &
~PNG_COLOR_MASK_ALPHA);
info_ptr->num_trans = 0; info_ptr->num_trans = 0;
} }
#endif #endif
@ -2015,7 +2036,7 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
* decide how it fits in with the other transformations here. * decide how it fits in with the other transformations here.
*/ */
void /* PRIVATE */ void /* PRIVATE */
png_do_read_transformations(png_structp png_ptr) png_do_read_transformations(png_structp png_ptr, png_row_infop row_info)
{ {
png_debug(1, "in png_do_read_transformations"); png_debug(1, "in png_do_read_transformations");
@ -2046,9 +2067,9 @@ png_do_read_transformations(png_structp png_ptr)
#ifdef PNG_READ_EXPAND_SUPPORTED #ifdef PNG_READ_EXPAND_SUPPORTED
if (png_ptr->transformations & PNG_EXPAND) if (png_ptr->transformations & PNG_EXPAND)
{ {
if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
{ {
png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_expand_palette(row_info, png_ptr->row_buf + 1,
png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
} }
@ -2056,11 +2077,11 @@ png_do_read_transformations(png_structp png_ptr)
{ {
if (png_ptr->num_trans && if (png_ptr->num_trans &&
(png_ptr->transformations & PNG_EXPAND_tRNS)) (png_ptr->transformations & PNG_EXPAND_tRNS))
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_expand(row_info, png_ptr->row_buf + 1,
&(png_ptr->trans_color)); &(png_ptr->trans_color));
else else
png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_expand(row_info, png_ptr->row_buf + 1,
NULL); NULL);
} }
} }
@ -2069,9 +2090,9 @@ png_do_read_transformations(png_structp png_ptr)
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
if ((png_ptr->transformations & PNG_STRIP_ALPHA) && if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
!(png_ptr->transformations & PNG_COMPOSE) && !(png_ptr->transformations & PNG_COMPOSE) &&
(png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_strip_channel(row_info, png_ptr->row_buf + 1,
0 /* at_start == false, because SWAP_ALPHA happens later */); 0 /* at_start == false, because SWAP_ALPHA happens later */);
#endif #endif
@ -2079,7 +2100,7 @@ png_do_read_transformations(png_structp png_ptr)
if (png_ptr->transformations & PNG_RGB_TO_GRAY) if (png_ptr->transformations & PNG_RGB_TO_GRAY)
{ {
int rgb_error = int rgb_error =
png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_do_rgb_to_gray(png_ptr, row_info,
png_ptr->row_buf + 1); png_ptr->row_buf + 1);
if (rgb_error) if (rgb_error)
@ -2133,13 +2154,13 @@ png_do_read_transformations(png_structp png_ptr)
*/ */
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
!(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
#endif #endif
#if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ #if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\
(defined PNG_READ_ALPHA_MODE_SUPPORTED) (defined PNG_READ_ALPHA_MODE_SUPPORTED)
if (png_ptr->transformations & PNG_COMPOSE) if (png_ptr->transformations & PNG_COMPOSE)
png_do_compose(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
#endif #endif
#ifdef PNG_READ_GAMMA_SUPPORTED #ifdef PNG_READ_GAMMA_SUPPORTED
@ -2151,27 +2172,27 @@ png_do_read_transformations(png_structp png_ptr)
(png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
#endif #endif
(png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
#endif #endif
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
if ((png_ptr->transformations & PNG_STRIP_ALPHA) && if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
(png_ptr->transformations & PNG_COMPOSE) && (png_ptr->transformations & PNG_COMPOSE) &&
(png_ptr->row_info.color_type == PNG_COLOR_TYPE_RGB_ALPHA || (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
png_ptr->row_info.color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_strip_channel(row_info, png_ptr->row_buf + 1,
0 /* at_start == false, because SWAP_ALPHA happens later */); 0 /* at_start == false, because SWAP_ALPHA happens later */);
#endif #endif
#ifdef PNG_READ_ALPHA_MODE_SUPPORTED #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
if ((png_ptr->transformations & PNG_ENCODE_ALPHA) && if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
(png_ptr->row_info.color_type & PNG_COLOR_MASK_ALPHA)) (row_info->color_type & PNG_COLOR_MASK_ALPHA))
png_do_encode_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr); png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
#endif #endif
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
if (png_ptr->transformations & PNG_SCALE_16_TO_8) if (png_ptr->transformations & PNG_SCALE_16_TO_8)
png_do_scale_16_to_8(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
@ -2180,16 +2201,16 @@ png_do_read_transformations(png_structp png_ptr)
* calling the API or in a TRANSFORM flag) this is what happens. * calling the API or in a TRANSFORM flag) this is what happens.
*/ */
if (png_ptr->transformations & PNG_16_TO_8) if (png_ptr->transformations & PNG_16_TO_8)
png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_chop(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_QUANTIZE_SUPPORTED #ifdef PNG_READ_QUANTIZE_SUPPORTED
if (png_ptr->transformations & PNG_QUANTIZE) if (png_ptr->transformations & PNG_QUANTIZE)
{ {
png_do_quantize(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_quantize(row_info, png_ptr->row_buf + 1,
png_ptr->palette_lookup, png_ptr->quantize_index); png_ptr->palette_lookup, png_ptr->quantize_index);
if (png_ptr->row_info.rowbytes == 0) if (row_info->rowbytes == 0)
png_error(png_ptr, "png_do_quantize returned rowbytes=0"); png_error(png_ptr, "png_do_quantize returned rowbytes=0");
} }
#endif /* PNG_READ_QUANTIZE_SUPPORTED */ #endif /* PNG_READ_QUANTIZE_SUPPORTED */
@ -2201,62 +2222,62 @@ png_do_read_transformations(png_structp png_ptr)
* better accuracy results faster!) * better accuracy results faster!)
*/ */
if (png_ptr->transformations & PNG_EXPAND_16) if (png_ptr->transformations & PNG_EXPAND_16)
png_do_expand_16(&png_ptr->row_info, png_ptr->row_buf + 1); png_do_expand_16(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
/*NOTE: moved here in 1.5.4 (from much later in this list.) */ /*NOTE: moved here in 1.5.4 (from much later in this list.) */
if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_INVERT_SUPPORTED #ifdef PNG_READ_INVERT_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_MONO) if (png_ptr->transformations & PNG_INVERT_MONO)
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_invert(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_SHIFT_SUPPORTED #ifdef PNG_READ_SHIFT_SUPPORTED
if (png_ptr->transformations & PNG_SHIFT) if (png_ptr->transformations & PNG_SHIFT)
png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_unshift(row_info, png_ptr->row_buf + 1,
&(png_ptr->shift)); &(png_ptr->shift));
#endif #endif
#ifdef PNG_READ_PACK_SUPPORTED #ifdef PNG_READ_PACK_SUPPORTED
if (png_ptr->transformations & PNG_PACK) if (png_ptr->transformations & PNG_PACK)
png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_unpack(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_BGR_SUPPORTED #ifdef PNG_READ_BGR_SUPPORTED
if (png_ptr->transformations & PNG_BGR) if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_bgr(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_PACKSWAP_SUPPORTED #ifdef PNG_READ_PACKSWAP_SUPPORTED
if (png_ptr->transformations & PNG_PACKSWAP) if (png_ptr->transformations & PNG_PACKSWAP)
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_packswap(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_FILLER_SUPPORTED #ifdef PNG_READ_FILLER_SUPPORTED
if (png_ptr->transformations & PNG_FILLER) if (png_ptr->transformations & PNG_FILLER)
png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_read_filler(row_info, png_ptr->row_buf + 1,
(png_uint_32)png_ptr->filler, png_ptr->flags); (png_uint_32)png_ptr->filler, png_ptr->flags);
#endif #endif
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_ALPHA) if (png_ptr->transformations & PNG_INVERT_ALPHA)
png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_ALPHA) if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_READ_16BIT_SUPPORTED #ifdef PNG_READ_16BIT_SUPPORTED
#ifdef PNG_READ_SWAP_SUPPORTED #ifdef PNG_READ_SWAP_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_BYTES) if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_swap(row_info, png_ptr->row_buf + 1);
#endif #endif
#endif #endif
@ -2265,8 +2286,8 @@ png_do_read_transformations(png_structp png_ptr)
{ {
if (png_ptr->read_user_transform_fn != NULL) if (png_ptr->read_user_transform_fn != NULL)
(*(png_ptr->read_user_transform_fn)) /* User read transform function */ (*(png_ptr->read_user_transform_fn)) /* User read transform function */
(png_ptr, /* png_ptr */ (png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */ row_info, /* row_info: */
/* png_uint_32 width; width of row */ /* png_uint_32 width; width of row */
/* png_size_t rowbytes; number of bytes in row */ /* png_size_t rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */ /* png_byte color_type; color type of pixels */
@ -2276,16 +2297,15 @@ png_do_read_transformations(png_structp png_ptr)
png_ptr->row_buf + 1); /* start of pixel data for row */ png_ptr->row_buf + 1); /* start of pixel data for row */
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
if (png_ptr->user_transform_depth) if (png_ptr->user_transform_depth)
png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; row_info->bit_depth = png_ptr->user_transform_depth;
if (png_ptr->user_transform_channels) if (png_ptr->user_transform_channels)
png_ptr->row_info.channels = png_ptr->user_transform_channels; row_info->channels = png_ptr->user_transform_channels;
#endif #endif
png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * row_info->pixel_depth = (png_byte)(row_info->bit_depth *
png_ptr->row_info.channels); row_info->channels);
png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
png_ptr->row_info.width);
} }
#endif #endif
} }
@ -2399,105 +2419,128 @@ void /* PRIVATE */
png_do_unshift(png_row_infop row_info, png_bytep row, png_do_unshift(png_row_infop row_info, png_bytep row,
png_const_color_8p sig_bits) png_const_color_8p sig_bits)
{ {
int color_type;
png_debug(1, "in png_do_unshift"); png_debug(1, "in png_do_unshift");
if ( /* The palette case has already been handled in the _init routine. */
row_info->color_type != PNG_COLOR_TYPE_PALETTE) color_type = row_info->color_type;
if (color_type != PNG_COLOR_TYPE_PALETTE)
{ {
int shift[4]; int shift[4];
int channels = 0; int channels = 0;
int c; int bit_depth = row_info->bit_depth;
png_uint_16 value = 0;
png_uint_32 row_width = row_info->width;
if (row_info->color_type & PNG_COLOR_MASK_COLOR) if (color_type & PNG_COLOR_MASK_COLOR)
{ {
shift[channels++] = row_info->bit_depth - sig_bits->red; shift[channels++] = bit_depth - sig_bits->red;
shift[channels++] = row_info->bit_depth - sig_bits->green; shift[channels++] = bit_depth - sig_bits->green;
shift[channels++] = row_info->bit_depth - sig_bits->blue; shift[channels++] = bit_depth - sig_bits->blue;
} }
else else
{ {
shift[channels++] = row_info->bit_depth - sig_bits->gray; shift[channels++] = bit_depth - sig_bits->gray;
} }
if (row_info->color_type & PNG_COLOR_MASK_ALPHA) if (color_type & PNG_COLOR_MASK_ALPHA)
{ {
shift[channels++] = row_info->bit_depth - sig_bits->alpha; shift[channels++] = bit_depth - sig_bits->alpha;
} }
for (c = 0; c < channels; c++)
{ {
if (shift[c] <= 0) int c, have_shift;
shift[c] = 0;
else for (c = have_shift = 0; c < channels; ++c)
value = 1; {
/* A shift of more than the bit depth is an error condition but it
* gets ignored here.
*/
if (shift[c] <= 0 || shift[c] >= bit_depth)
shift[c] = 0;
else
have_shift = 1;
}
if (!have_shift)
return;
} }
if (!value) switch (bit_depth)
return;
switch (row_info->bit_depth)
{ {
default: default:
/* Must be 1bpp gray: should not be here! */
/* NOTREACHED */
break; break;
case 2: case 2:
/* Must be 2bpp gray */
/* assert(channels == 1 && shift[0] == 1) */
{ {
png_bytep bp; png_bytep bp = row;
png_size_t i; png_bytep bp_end = bp + row_info->rowbytes;
png_size_t istop = row_info->rowbytes;
for (bp = row, i = 0; i < istop; i++) while (bp < bp_end)
{ {
*bp >>= 1; int b = (*bp >> 1) & 0x55;
*bp++ &= 0x55; *bp++ = (png_byte)b;
} }
break; break;
} }
case 4: case 4:
/* Must be 4bpp gray */
/* assert(channels == 1) */
{ {
png_bytep bp = row; png_bytep bp = row;
png_size_t i; png_bytep bp_end = bp + row_info->rowbytes;
png_size_t istop = row_info->rowbytes; int gray_shift = shift[0];
png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | int mask = 0xf >> gray_shift;
(png_byte)((int)0xf >> shift[0]));
for (i = 0; i < istop; i++) mask |= mask << 4;
while (bp < bp_end)
{ {
*bp >>= shift[0]; int b = (*bp >> gray_shift) & mask;
*bp++ &= mask; *bp++ = (png_byte)b;
} }
break; break;
} }
case 8: case 8:
/* Single byte components, G, GA, RGB, RGBA */
{ {
png_bytep bp = row; png_bytep bp = row;
png_uint_32 i; png_bytep bp_end = bp + row_info->rowbytes;
png_uint_32 istop = row_width * channels; int channel = 0;
for (i = 0; i < istop; i++) while (bp < bp_end)
{ {
*bp++ >>= shift[i%channels]; int b = *bp >> shift[channel];
if (++channel >= channels)
channel = 0;
*bp++ = (png_byte)b;
} }
break; break;
} }
#ifdef PNG_READ_16BIT_SUPPORTED #ifdef PNG_READ_16BIT_SUPPORTED
case 16: case 16:
/* Double byte components, G, GA, RGB, RGBA */
{ {
png_bytep bp = row; png_bytep bp = row;
png_uint_32 i; png_bytep bp_end = bp + row_info->rowbytes;
png_uint_32 istop = channels * row_width; int channel = 0;
for (i = 0; i < istop; i++) while (bp < bp_end)
{ {
value = (png_uint_16)((*bp << 8) + *(bp + 1)); int value = (bp[0] << 8) + bp[1];
value >>= shift[i%channels];
value >>= shift[channel];
if (++channel >= channels)
channel = 0;
*bp++ = (png_byte)(value >> 8); *bp++ = (png_byte)(value >> 8);
*bp++ = (png_byte)(value & 0xff); *bp++ = (png_byte)(value & 0xff);
} }
@ -3060,7 +3103,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
} }
} }
} }
row_info->channels += (png_byte)2; row_info->channels = (png_byte)(row_info->channels + 2);
row_info->color_type |= PNG_COLOR_MASK_COLOR; row_info->color_type |= PNG_COLOR_MASK_COLOR;
row_info->pixel_depth = (png_byte)(row_info->channels * row_info->pixel_depth = (png_byte)(row_info->channels *
row_info->bit_depth); row_info->bit_depth);
@ -3306,7 +3349,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
} }
} }
row_info->channels -= 2; row_info->channels = (png_byte)(row_info->channels - 2);
row_info->color_type = (png_byte)(row_info->color_type & row_info->color_type = (png_byte)(row_info->color_type &
~PNG_COLOR_MASK_COLOR); ~PNG_COLOR_MASK_COLOR);
row_info->pixel_depth = (png_byte)(row_info->channels * row_info->pixel_depth = (png_byte)(row_info->channels *
@ -3376,7 +3419,8 @@ png_build_grayscale_palette(int bit_depth, png_colorp palette)
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
#ifdef PNG_READ_BACKGROUND_SUPPORTED #if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\
(defined PNG_READ_ALPHA_MODE_SUPPORTED)
/* Replace any alpha or transparency with the supplied background color. /* Replace any alpha or transparency with the supplied background color.
* "background" is already in the screen gamma, while "background_1" is * "background" is already in the screen gamma, while "background_1" is
* at a gamma of 1.0. Paletted files have already been taken care of. * at a gamma of 1.0. Paletted files have already been taken care of.
@ -4084,7 +4128,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structp png_ptr)
} }
} }
} }
#endif #endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */
#ifdef PNG_READ_GAMMA_SUPPORTED #ifdef PNG_READ_GAMMA_SUPPORTED
/* Gamma correct the image, avoiding the alpha channel. Make sure /* Gamma correct the image, avoiding the alpha channel. Make sure

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/* pngset.c - storage of image information into info struct /* pngset.c - storage of image information into info struct
* *
* Last changed in libpng 1.5.5 [September 22, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -681,9 +681,8 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr,
{ {
int i; int i;
png_debug1(1, "in %s storage function", ((png_ptr == NULL || png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
png_ptr->chunk_name[0] == '\0') ? (unsigned long)png_ptr->chunk_name);
"text" : (png_const_charp)png_ptr->chunk_name));
if (png_ptr == NULL || info_ptr == NULL || num_text == 0) if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
return(0); return(0);

View file

@ -104,13 +104,17 @@ struct png_struct_def
png_size_t rowbytes; /* size of row in bytes */ png_size_t rowbytes; /* size of row in bytes */
png_uint_32 iwidth; /* width of current interlaced row in pixels */ png_uint_32 iwidth; /* width of current interlaced row in pixels */
png_uint_32 row_number; /* current row in interlace pass */ png_uint_32 row_number; /* current row in interlace pass */
png_bytep prev_row; /* buffer to save previous (unfiltered) row */ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
png_bytep row_buf; /* buffer to save current (unfiltered) row */ png_bytep prev_row; /* buffer to save previous (unfiltered) row.
* This is a pointer into big_prev_row
*/
png_bytep row_buf; /* buffer to save current (unfiltered) row.
* This is a pointer into big_row_buf
*/
png_bytep sub_row; /* buffer to save "sub" row when filtering */ png_bytep sub_row; /* buffer to save "sub" row when filtering */
png_bytep up_row; /* buffer to save "up" row when filtering */ png_bytep up_row; /* buffer to save "up" row when filtering */
png_bytep avg_row; /* buffer to save "avg" row when filtering */ png_bytep avg_row; /* buffer to save "avg" row when filtering */
png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
png_row_info row_info; /* used for transformation routines */
png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */
png_uint_32 idat_size; /* current IDAT size for read */ png_uint_32 idat_size; /* current IDAT size for read */
@ -118,7 +122,6 @@ struct png_struct_def
png_colorp palette; /* palette from the input file */ png_colorp palette; /* palette from the input file */
png_uint_16 num_palette; /* number of color entries in palette */ png_uint_16 num_palette; /* number of color entries in palette */
png_uint_16 num_trans; /* number of transparency values */ png_uint_16 num_trans; /* number of transparency values */
png_byte chunk_name[5]; /* null-terminated name of current chunk */
png_byte compression; /* file compression type (always 0) */ png_byte compression; /* file compression type (always 0) */
png_byte filter; /* file filter type (always 0) */ png_byte filter; /* file filter type (always 0) */
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
@ -126,11 +129,17 @@ struct png_struct_def
png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
png_byte color_type; /* color type of file */ png_byte color_type; /* color type of file */
png_byte bit_depth; /* bit depth of file */ png_byte bit_depth; /* bit depth of file */
png_byte usr_bit_depth; /* bit depth of users row */ png_byte usr_bit_depth; /* bit depth of users row: write only */
png_byte pixel_depth; /* number of bits per pixel */ png_byte pixel_depth; /* number of bits per pixel */
png_byte channels; /* number of channels in file */ png_byte channels; /* number of channels in file */
png_byte usr_channels; /* channels at start of write */ png_byte usr_channels; /* channels at start of write: write only */
png_byte sig_bytes; /* magic bytes read/written from start of file */ png_byte sig_bytes; /* magic bytes read/written from start of file */
png_byte maximum_pixel_depth;
/* pixel depth used for the row buffers */
png_byte transformed_pixel_depth;
/* pixel depth after read/write transforms */
png_byte io_chunk_string[5];
/* string name of chunk */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
png_uint_16 filler; /* filler bytes for pixel expansion */ png_uint_16 filler; /* filler bytes for pixel expansion */
@ -152,19 +161,21 @@ struct png_struct_def
png_uint_32 flush_rows; /* number of rows written since last flush */ png_uint_32 flush_rows; /* number of rows written since last flush */
#endif #endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) #ifdef PNG_READ_GAMMA_SUPPORTED
int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
png_fixed_point gamma; /* file gamma value */ png_fixed_point gamma; /* file gamma value */
png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
png_bytep gamma_table; /* gamma table for 8-bit depth files */ png_bytep gamma_table; /* gamma table for 8-bit depth files */
png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
png_bytep gamma_from_1; /* converts from 1.0 to screen */ png_bytep gamma_from_1; /* converts from 1.0 to screen */
png_bytep gamma_to_1; /* converts from file to 1.0 */ png_bytep gamma_to_1; /* converts from file to 1.0 */
png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
#endif #endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
@ -329,9 +340,8 @@ struct png_struct_def
png_unknown_chunk unknown_chunk; png_unknown_chunk unknown_chunk;
#endif #endif
/* New members added in libpng-1.2.26 */ /* New member added in libpng-1.2.26 */
png_size_t old_big_row_buf_size; png_size_t old_big_row_buf_size;
png_size_t old_prev_row_size;
/* New member added in libpng-1.2.30 */ /* New member added in libpng-1.2.30 */
png_charp chunkdata; /* buffer for reading chunk data */ png_charp chunkdata; /* buffer for reading chunk data */
@ -340,5 +350,8 @@ struct png_struct_def
/* New member added in libpng-1.4.0 */ /* New member added in libpng-1.4.0 */
png_uint_32 io_state; png_uint_32 io_state;
#endif #endif
/* New member added in libpng-1.5.6 */
png_bytep big_prev_row;
}; };
#endif /* PNGSTRUCT_H */ #endif /* PNGSTRUCT_H */

View file

@ -1,7 +1,7 @@
/* pngwrite.c - general routines to write a PNG file /* pngwrite.c - general routines to write a PNG file
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -608,6 +608,9 @@ png_write_image(png_structp png_ptr, png_bytepp image)
void PNGAPI void PNGAPI
png_write_row(png_structp png_ptr, png_const_bytep row) png_write_row(png_structp png_ptr, png_const_bytep row)
{ {
/* 1.5.6: moved from png_struct to be a local structure: */
png_row_info row_info;
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
@ -731,36 +734,31 @@ png_write_row(png_structp png_ptr, png_const_bytep row)
#endif #endif
/* Set up row info for transformations */ /* Set up row info for transformations */
png_ptr->row_info.color_type = png_ptr->color_type; row_info.color_type = png_ptr->color_type;
png_ptr->row_info.width = png_ptr->usr_width; row_info.width = png_ptr->usr_width;
png_ptr->row_info.channels = png_ptr->usr_channels; row_info.channels = png_ptr->usr_channels;
png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth; row_info.bit_depth = png_ptr->usr_bit_depth;
png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels);
png_ptr->row_info.channels); row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_debug1(3, "row_info->color_type = %d", row_info.color_type);
png_ptr->row_info.width); png_debug1(3, "row_info->width = %u", row_info.width);
png_debug1(3, "row_info->channels = %d", row_info.channels);
png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth);
png_debug1(3, "row_info->width = %u", png_ptr->row_info.width); png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth);
png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes);
png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth);
png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth);
png_debug1(3, "row_info->rowbytes = %lu",
(unsigned long)png_ptr->row_info.rowbytes);
/* Copy user's row into buffer, leaving room for filter byte. */ /* Copy user's row into buffer, leaving room for filter byte. */
png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); png_memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes);
#ifdef PNG_WRITE_INTERLACING_SUPPORTED #ifdef PNG_WRITE_INTERLACING_SUPPORTED
/* Handle interlacing */ /* Handle interlacing */
if (png_ptr->interlaced && png_ptr->pass < 6 && if (png_ptr->interlaced && png_ptr->pass < 6 &&
(png_ptr->transformations & PNG_INTERLACE)) (png_ptr->transformations & PNG_INTERLACE))
{ {
png_do_write_interlace(&(png_ptr->row_info), png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
png_ptr->row_buf + 1, png_ptr->pass);
/* This should always get caught above, but still ... */ /* This should always get caught above, but still ... */
if (!(png_ptr->row_info.width)) if (!(row_info.width))
{ {
png_write_finish_row(png_ptr); png_write_finish_row(png_ptr);
return; return;
@ -771,9 +769,16 @@ png_write_row(png_structp png_ptr, png_const_bytep row)
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
/* Handle other transformations */ /* Handle other transformations */
if (png_ptr->transformations) if (png_ptr->transformations)
png_do_write_transformations(png_ptr); png_do_write_transformations(png_ptr, &row_info);
#endif #endif
/* At this point the row_info pixel depth must match the 'transformed' depth,
* which is also the output depth.
*/
if (row_info.pixel_depth != png_ptr->pixel_depth ||
row_info.pixel_depth != png_ptr->transformed_pixel_depth)
png_error(png_ptr, "internal write transform logic error");
#ifdef PNG_MNG_FEATURES_SUPPORTED #ifdef PNG_MNG_FEATURES_SUPPORTED
/* Write filter_method 64 (intrapixel differencing) only if /* Write filter_method 64 (intrapixel differencing) only if
* 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
@ -788,12 +793,12 @@ png_write_row(png_structp png_ptr, png_const_bytep row)
(png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
{ {
/* Intrapixel differencing */ /* Intrapixel differencing */
png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1);
} }
#endif #endif
/* Find a filter if necessary, filter the row and write it out. */ /* Find a filter if necessary, filter the row and write it out. */
png_write_find_filter(png_ptr, &(png_ptr->row_info)); png_write_find_filter(png_ptr, &row_info);
if (png_ptr->write_row_fn != NULL) if (png_ptr->write_row_fn != NULL)
(*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
@ -879,13 +884,7 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
png_debug(1, "in png_destroy_write_struct"); png_debug(1, "in png_destroy_write_struct");
if (png_ptr_ptr != NULL) if (png_ptr_ptr != NULL)
{
png_ptr = *png_ptr_ptr; png_ptr = *png_ptr_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
free_fn = png_ptr->free_fn;
mem_ptr = png_ptr->mem_ptr;
#endif
}
#ifdef PNG_USER_MEM_SUPPORTED #ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr != NULL) if (png_ptr != NULL)

View file

@ -1,7 +1,7 @@
/* pngwtran.c - transforms the data in a row for PNG writers /* pngwtran.c - transforms the data in a row for PNG writers
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -20,7 +20,7 @@
* transformations is significant. * transformations is significant.
*/ */
void /* PRIVATE */ void /* PRIVATE */
png_do_write_transformations(png_structp png_ptr) png_do_write_transformations(png_structp png_ptr, png_row_infop row_info)
{ {
png_debug(1, "in png_do_write_transformations"); png_debug(1, "in png_do_write_transformations");
@ -32,8 +32,8 @@ png_do_write_transformations(png_structp png_ptr)
if (png_ptr->write_user_transform_fn != NULL) if (png_ptr->write_user_transform_fn != NULL)
(*(png_ptr->write_user_transform_fn)) /* User write transform (*(png_ptr->write_user_transform_fn)) /* User write transform
function */ function */
(png_ptr, /* png_ptr */ (png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */ row_info, /* row_info: */
/* png_uint_32 width; width of row */ /* png_uint_32 width; width of row */
/* png_size_t rowbytes; number of bytes in row */ /* png_size_t rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */ /* png_byte color_type; color type of pixels */
@ -45,50 +45,50 @@ png_do_write_transformations(png_structp png_ptr)
#ifdef PNG_WRITE_FILLER_SUPPORTED #ifdef PNG_WRITE_FILLER_SUPPORTED
if (png_ptr->transformations & PNG_FILLER) if (png_ptr->transformations & PNG_FILLER)
png_do_strip_channel(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_strip_channel(row_info, png_ptr->row_buf + 1,
!(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
#endif #endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED #ifdef PNG_WRITE_PACKSWAP_SUPPORTED
if (png_ptr->transformations & PNG_PACKSWAP) if (png_ptr->transformations & PNG_PACKSWAP)
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_packswap(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_PACK_SUPPORTED #ifdef PNG_WRITE_PACK_SUPPORTED
if (png_ptr->transformations & PNG_PACK) if (png_ptr->transformations & PNG_PACK)
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_pack(row_info, png_ptr->row_buf + 1,
(png_uint_32)png_ptr->bit_depth); (png_uint_32)png_ptr->bit_depth);
#endif #endif
#ifdef PNG_WRITE_SWAP_SUPPORTED #ifdef PNG_WRITE_SWAP_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_BYTES) if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_swap(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED #ifdef PNG_WRITE_SHIFT_SUPPORTED
if (png_ptr->transformations & PNG_SHIFT) if (png_ptr->transformations & PNG_SHIFT)
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, png_do_shift(row_info, png_ptr->row_buf + 1,
&(png_ptr->shift)); &(png_ptr->shift));
#endif #endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_SWAP_ALPHA) if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_ALPHA) if (png_ptr->transformations & PNG_INVERT_ALPHA)
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_BGR_SUPPORTED #ifdef PNG_WRITE_BGR_SUPPORTED
if (png_ptr->transformations & PNG_BGR) if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_bgr(row_info, png_ptr->row_buf + 1);
#endif #endif
#ifdef PNG_WRITE_INVERT_SUPPORTED #ifdef PNG_WRITE_INVERT_SUPPORTED
if (png_ptr->transformations & PNG_INVERT_MONO) if (png_ptr->transformations & PNG_INVERT_MONO)
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); png_do_invert(row_info, png_ptr->row_buf + 1);
#endif #endif
} }

View file

@ -1,7 +1,7 @@
/* pngwutil.c - utilities to write a PNG file /* pngwutil.c - utilities to write a PNG file
* *
* Last changed in libpng 1.5.5 [September 22, 2011] * Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -82,39 +82,20 @@ png_write_sig(png_structp png_ptr)
png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
} }
/* Write a PNG chunk all at once. The type is an array of ASCII characters
* representing the chunk name. The array must be at least 4 bytes in
* length, and does not need to be null terminated. To be safe, pass the
* pre-defined chunk names here, and if you need a new one, define it
* where the others are defined. The length is the length of the data.
* All the data must be present. If that is not possible, use the
* png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
* functions instead.
*/
void PNGAPI
png_write_chunk(png_structp png_ptr, png_const_bytep chunk_name,
png_const_bytep data, png_size_t length)
{
if (png_ptr == NULL)
return;
png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
png_write_chunk_data(png_ptr, data, (png_size_t)length);
png_write_chunk_end(png_ptr);
}
/* Write the start of a PNG chunk. The type is the chunk type. /* Write the start of a PNG chunk. The type is the chunk type.
* The total_length is the sum of the lengths of all the data you will be * The total_length is the sum of the lengths of all the data you will be
* passing in png_write_chunk_data(). * passing in png_write_chunk_data().
*/ */
void PNGAPI static void
png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name,
png_uint_32 length) png_uint_32 length)
{ {
png_byte buf[8]; png_byte buf[8];
png_debug2(0, "Writing %s chunk, length = %lu", chunk_name, #if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
(unsigned long)length); PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
#endif
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;
@ -128,16 +109,16 @@ png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name,
/* Write the length and the chunk name */ /* Write the length and the chunk name */
png_save_uint_32(buf, length); png_save_uint_32(buf, length);
png_memcpy(buf + 4, chunk_name, 4); png_save_uint_32(buf + 4, chunk_name);
png_write_data(png_ptr, buf, (png_size_t)8); png_write_data(png_ptr, buf, 8);
/* Put the chunk name into png_ptr->chunk_name */ /* Put the chunk name into png_ptr->chunk_name */
png_memcpy(png_ptr->chunk_name, chunk_name, 4); png_ptr->chunk_name = chunk_name;
/* Reset the crc and run it over the chunk name */ /* Reset the crc and run it over the chunk name */
png_reset_crc(png_ptr); png_reset_crc(png_ptr);
png_calculate_crc(png_ptr, chunk_name, 4); png_calculate_crc(png_ptr, buf + 4, 4);
#ifdef PNG_IO_STATE_SUPPORTED #ifdef PNG_IO_STATE_SUPPORTED
/* Inform the I/O callback that chunk data will (possibly) be written. /* Inform the I/O callback that chunk data will (possibly) be written.
@ -147,10 +128,17 @@ png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name,
#endif #endif
} }
/* Write the data of a PNG chunk started with png_write_chunk_start(). void PNGAPI
png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_string,
png_uint_32 length)
{
png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
}
/* Write the data of a PNG chunk started with png_write_chunk_header().
* Note that multiple calls to this function are allowed, and that the * Note that multiple calls to this function are allowed, and that the
* sum of the lengths from these calls *must* add up to the total_length * sum of the lengths from these calls *must* add up to the total_length
* given to png_write_chunk_start(). * given to png_write_chunk_header().
*/ */
void PNGAPI void PNGAPI
png_write_chunk_data(png_structp png_ptr, png_const_bytep data, png_write_chunk_data(png_structp png_ptr, png_const_bytep data,
@ -171,7 +159,7 @@ png_write_chunk_data(png_structp png_ptr, png_const_bytep data,
} }
} }
/* Finish a chunk started with png_write_chunk_start(). */ /* Finish a chunk started with png_write_chunk_header(). */
void PNGAPI void PNGAPI
png_write_chunk_end(png_structp png_ptr) png_write_chunk_end(png_structp png_ptr)
{ {
@ -192,6 +180,40 @@ png_write_chunk_end(png_structp png_ptr)
png_write_data(png_ptr, buf, (png_size_t)4); png_write_data(png_ptr, buf, (png_size_t)4);
} }
/* Write a PNG chunk all at once. The type is an array of ASCII characters
* representing the chunk name. The array must be at least 4 bytes in
* length, and does not need to be null terminated. To be safe, pass the
* pre-defined chunk names here, and if you need a new one, define it
* where the others are defined. The length is the length of the data.
* All the data must be present. If that is not possible, use the
* png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
* functions instead.
*/
static void
png_write_complete_chunk(png_structp png_ptr, png_uint_32 chunk_name,
png_const_bytep data, png_size_t length)
{
if (png_ptr == NULL)
return;
/* On 64 bit architectures 'length' may not fit in a png_uint_32. */
if (length > PNG_UINT_32_MAX)
png_error(png_ptr, "length exceeds PNG maxima");
png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
png_write_chunk_data(png_ptr, data, length);
png_write_chunk_end(png_ptr);
}
/* This is the API that calls the internal function above. */
void PNGAPI
png_write_chunk(png_structp png_ptr, png_const_bytep chunk_string,
png_const_bytep data, png_size_t length)
{
png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
length);
}
/* Initialize the compressor for the appropriate type of compression. */ /* Initialize the compressor for the appropriate type of compression. */
static void static void
png_zlib_claim(png_structp png_ptr, png_uint_32 state) png_zlib_claim(png_structp png_ptr, png_uint_32 state)
@ -560,7 +582,10 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
} }
#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED #ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
if (comp->input_len >= 2 && comp->input_len < 16384) /* The zbuf_size test is because the code below doesn't work if zbuf_size is
* '1'; simply skip it to avoid memory overwrite.
*/
if (comp->input_len >= 2 && comp->input_len < 16384 && png_ptr->zbuf_size > 1)
{ {
unsigned int z_cmf; /* zlib compression method and flags */ unsigned int z_cmf; /* zlib compression method and flags */
@ -652,8 +677,6 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
int bit_depth, int color_type, int compression_type, int filter_type, int bit_depth, int color_type, int compression_type, int filter_type,
int interlace_type) int interlace_type)
{ {
PNG_IHDR;
png_byte buf[13]; /* Buffer to store the IHDR info */ png_byte buf[13]; /* Buffer to store the IHDR info */
png_debug(1, "in png_write_IHDR"); png_debug(1, "in png_write_IHDR");
@ -795,7 +818,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
buf[12] = (png_byte)interlace_type; buf[12] = (png_byte)interlace_type;
/* Write the chunk */ /* Write the chunk */
png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
/* Initialize zlib with PNG info */ /* Initialize zlib with PNG info */
png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zalloc = png_zalloc;
@ -872,7 +895,6 @@ void /* PRIVATE */
png_write_PLTE(png_structp png_ptr, png_const_colorp palette, png_write_PLTE(png_structp png_ptr, png_const_colorp palette,
png_uint_32 num_pal) png_uint_32 num_pal)
{ {
PNG_PLTE;
png_uint_32 i; png_uint_32 i;
png_const_colorp pal_ptr; png_const_colorp pal_ptr;
png_byte buf[3]; png_byte buf[3];
@ -908,7 +930,7 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette,
png_ptr->num_palette = (png_uint_16)num_pal; png_ptr->num_palette = (png_uint_16)num_pal;
png_debug1(3, "num_palette = %d", png_ptr->num_palette); png_debug1(3, "num_palette = %d", png_ptr->num_palette);
png_write_chunk_start(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
#ifdef PNG_POINTER_INDEXING_SUPPORTED #ifdef PNG_POINTER_INDEXING_SUPPORTED
for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
@ -942,8 +964,6 @@ png_write_PLTE(png_structp png_ptr, png_const_colorp palette,
void /* PRIVATE */ void /* PRIVATE */
png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
{ {
PNG_IDAT;
png_debug(1, "in png_write_IDAT"); png_debug(1, "in png_write_IDAT");
#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED #ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
@ -1014,7 +1034,7 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
} }
#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */ #endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
png_write_chunk(png_ptr, png_IDAT, data, length); png_write_complete_chunk(png_ptr, png_IDAT, data, length);
png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->mode |= PNG_HAVE_IDAT;
/* Prior to 1.5.4 this code was replicated in every caller (except at the /* Prior to 1.5.4 this code was replicated in every caller (except at the
@ -1029,11 +1049,9 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
void /* PRIVATE */ void /* PRIVATE */
png_write_IEND(png_structp png_ptr) png_write_IEND(png_structp png_ptr)
{ {
PNG_IEND;
png_debug(1, "in png_write_IEND"); png_debug(1, "in png_write_IEND");
png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
png_ptr->mode |= PNG_HAVE_IEND; png_ptr->mode |= PNG_HAVE_IEND;
} }
@ -1042,14 +1060,13 @@ png_write_IEND(png_structp png_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
{ {
PNG_gAMA;
png_byte buf[4]; png_byte buf[4];
png_debug(1, "in png_write_gAMA"); png_debug(1, "in png_write_gAMA");
/* file_gamma is saved in 1/100,000ths */ /* file_gamma is saved in 1/100,000ths */
png_save_uint_32(buf, (png_uint_32)file_gamma); png_save_uint_32(buf, (png_uint_32)file_gamma);
png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
} }
#endif #endif
@ -1058,7 +1075,6 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
void /* PRIVATE */ void /* PRIVATE */
png_write_sRGB(png_structp png_ptr, int srgb_intent) png_write_sRGB(png_structp png_ptr, int srgb_intent)
{ {
PNG_sRGB;
png_byte buf[1]; png_byte buf[1];
png_debug(1, "in png_write_sRGB"); png_debug(1, "in png_write_sRGB");
@ -1068,7 +1084,7 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent)
"Invalid sRGB rendering intent specified"); "Invalid sRGB rendering intent specified");
buf[0]=(png_byte)srgb_intent; buf[0]=(png_byte)srgb_intent;
png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
} }
#endif #endif
@ -1078,7 +1094,6 @@ void /* PRIVATE */
png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
png_const_charp profile, int profile_len) png_const_charp profile, int profile_len)
{ {
PNG_iCCP;
png_size_t name_len; png_size_t name_len;
png_charp new_name; png_charp new_name;
compression_state comp; compression_state comp;
@ -1139,7 +1154,7 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
(png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp);
/* Make sure we include the NULL after the name and the compression type */ /* Make sure we include the NULL after the name and the compression type */
png_write_chunk_start(png_ptr, png_iCCP, png_write_chunk_header(png_ptr, png_iCCP,
(png_uint_32)(name_len + profile_len + 2)); (png_uint_32)(name_len + profile_len + 2));
new_name[name_len + 1] = 0x00; new_name[name_len + 1] = 0x00;
@ -1163,7 +1178,6 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
void /* PRIVATE */ void /* PRIVATE */
png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
{ {
PNG_sPLT;
png_size_t name_len; png_size_t name_len;
png_charp new_name; png_charp new_name;
png_byte entrybuf[10]; png_byte entrybuf[10];
@ -1180,7 +1194,7 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
return; return;
/* Make sure we include the NULL after the name */ /* Make sure we include the NULL after the name */
png_write_chunk_start(png_ptr, png_sPLT, png_write_chunk_header(png_ptr, png_sPLT,
(png_uint_32)(name_len + 2 + palette_size)); (png_uint_32)(name_len + 2 + palette_size));
png_write_chunk_data(png_ptr, (png_bytep)new_name, png_write_chunk_data(png_ptr, (png_bytep)new_name,
@ -1248,7 +1262,6 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
void /* PRIVATE */ void /* PRIVATE */
png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type)
{ {
PNG_sBIT;
png_byte buf[4]; png_byte buf[4];
png_size_t size; png_size_t size;
@ -1299,7 +1312,7 @@ png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type)
buf[size++] = sbit->alpha; buf[size++] = sbit->alpha;
} }
png_write_chunk(png_ptr, png_sBIT, buf, size); png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
} }
#endif #endif
@ -1311,7 +1324,6 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
png_fixed_point blue_y) png_fixed_point blue_y)
{ {
PNG_cHRM;
png_byte buf[32]; png_byte buf[32];
png_debug(1, "in png_write_cHRM"); png_debug(1, "in png_write_cHRM");
@ -1334,7 +1346,7 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
png_save_uint_32(buf + 24, (png_uint_32)blue_x); png_save_uint_32(buf + 24, (png_uint_32)blue_x);
png_save_uint_32(buf + 28, (png_uint_32)blue_y); png_save_uint_32(buf + 28, (png_uint_32)blue_y);
png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); png_write_complete_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
} }
} }
#endif #endif
@ -1345,7 +1357,6 @@ void /* PRIVATE */
png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
png_const_color_16p tran, int num_trans, int color_type) png_const_color_16p tran, int num_trans, int color_type)
{ {
PNG_tRNS;
png_byte buf[6]; png_byte buf[6];
png_debug(1, "in png_write_tRNS"); png_debug(1, "in png_write_tRNS");
@ -1359,7 +1370,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
} }
/* Write the chunk out as it is */ /* Write the chunk out as it is */
png_write_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans);
} }
else if (color_type == PNG_COLOR_TYPE_GRAY) else if (color_type == PNG_COLOR_TYPE_GRAY)
@ -1374,7 +1385,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
} }
png_save_uint_16(buf, tran->gray); png_save_uint_16(buf, tran->gray);
png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
} }
else if (color_type == PNG_COLOR_TYPE_RGB) else if (color_type == PNG_COLOR_TYPE_RGB)
@ -1394,7 +1405,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
return; return;
} }
png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
} }
else else
@ -1409,7 +1420,6 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
void /* PRIVATE */ void /* PRIVATE */
png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
{ {
PNG_bKGD;
png_byte buf[6]; png_byte buf[6];
png_debug(1, "in png_write_bKGD"); png_debug(1, "in png_write_bKGD");
@ -1428,7 +1438,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
} }
buf[0] = back->index; buf[0] = back->index;
png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
} }
else if (color_type & PNG_COLOR_MASK_COLOR) else if (color_type & PNG_COLOR_MASK_COLOR)
@ -1448,7 +1458,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
return; return;
} }
png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
} }
else else
@ -1462,7 +1472,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
} }
png_save_uint_16(buf, back->gray); png_save_uint_16(buf, back->gray);
png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
} }
} }
#endif #endif
@ -1472,7 +1482,6 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
void /* PRIVATE */ void /* PRIVATE */
png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
{ {
PNG_hIST;
int i; int i;
png_byte buf[3]; png_byte buf[3];
@ -1487,7 +1496,7 @@ png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
return; return;
} }
png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
for (i = 0; i < num_hist; i++) for (i = 0; i < num_hist; i++)
{ {
@ -1637,7 +1646,6 @@ void /* PRIVATE */
png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
png_size_t text_len) png_size_t text_len)
{ {
PNG_tEXt;
png_size_t key_len; png_size_t key_len;
png_charp new_key; png_charp new_key;
@ -1653,7 +1661,7 @@ png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
text_len = png_strlen(text); text_len = png_strlen(text);
/* Make sure we include the 0 after the key */ /* Make sure we include the 0 after the key */
png_write_chunk_start(png_ptr, png_tEXt, png_write_chunk_header(png_ptr, png_tEXt,
(png_uint_32)(key_len + text_len + 1)); (png_uint_32)(key_len + text_len + 1));
/* /*
* We leave it to the application to meet PNG-1.0 requirements on the * We leave it to the application to meet PNG-1.0 requirements on the
@ -1679,7 +1687,6 @@ void /* PRIVATE */
png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
png_size_t text_len, int compression) png_size_t text_len, int compression)
{ {
PNG_zTXt;
png_size_t key_len; png_size_t key_len;
png_byte buf; png_byte buf;
png_charp new_key; png_charp new_key;
@ -1713,7 +1720,7 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
&comp); &comp);
/* Write start of chunk */ /* Write start of chunk */
png_write_chunk_start(png_ptr, png_zTXt, png_write_chunk_header(png_ptr, png_zTXt,
(png_uint_32)(key_len+text_len + 2)); (png_uint_32)(key_len+text_len + 2));
/* Write key */ /* Write key */
@ -1742,7 +1749,6 @@ void /* PRIVATE */
png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
png_const_charp lang, png_const_charp lang_key, png_const_charp text) png_const_charp lang, png_const_charp lang_key, png_const_charp text)
{ {
PNG_iTXt;
png_size_t lang_len, key_len, lang_key_len, text_len; png_size_t lang_len, key_len, lang_key_len, text_len;
png_charp new_lang; png_charp new_lang;
png_charp new_key = NULL; png_charp new_key = NULL;
@ -1787,7 +1793,7 @@ png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key,
* and the NULs after the key, lang, and lang_key parts * and the NULs after the key, lang, and lang_key parts
*/ */
png_write_chunk_start(png_ptr, png_iTXt, (png_uint_32)( png_write_chunk_header(png_ptr, png_iTXt, (png_uint_32)(
5 /* comp byte, comp flag, terminators for key, lang and lang_key */ 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
+ key_len + key_len
+ lang_len + lang_len
@ -1836,7 +1842,6 @@ void /* PRIVATE */
png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
int unit_type) int unit_type)
{ {
PNG_oFFs;
png_byte buf[9]; png_byte buf[9];
png_debug(1, "in png_write_oFFs"); png_debug(1, "in png_write_oFFs");
@ -1848,7 +1853,7 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
png_save_int_32(buf + 4, y_offset); png_save_int_32(buf + 4, y_offset);
buf[8] = (png_byte)unit_type; buf[8] = (png_byte)unit_type;
png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
} }
#endif #endif
#ifdef PNG_WRITE_pCAL_SUPPORTED #ifdef PNG_WRITE_pCAL_SUPPORTED
@ -1858,7 +1863,6 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
png_int_32 X1, int type, int nparams, png_const_charp units, png_int_32 X1, int type, int nparams, png_const_charp units,
png_charpp params) png_charpp params)
{ {
PNG_pCAL;
png_size_t purpose_len, units_len, total_len; png_size_t purpose_len, units_len, total_len;
png_size_tp params_len; png_size_tp params_len;
png_byte buf[10]; png_byte buf[10];
@ -1891,7 +1895,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
} }
png_debug1(3, "pCAL total length = %d", (int)total_len); png_debug1(3, "pCAL total length = %d", (int)total_len);
png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len); png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len);
png_save_int_32(buf, X0); png_save_int_32(buf, X0);
png_save_int_32(buf + 4, X1); png_save_int_32(buf + 4, X1);
@ -1918,7 +1922,6 @@ void /* PRIVATE */
png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width,
png_const_charp height) png_const_charp height)
{ {
PNG_sCAL;
png_byte buf[64]; png_byte buf[64];
png_size_t wlen, hlen, total_len; png_size_t wlen, hlen, total_len;
@ -1939,7 +1942,7 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width,
png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
png_write_chunk(png_ptr, png_sCAL, buf, total_len); png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
} }
#endif #endif
@ -1950,7 +1953,6 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
png_uint_32 y_pixels_per_unit, png_uint_32 y_pixels_per_unit,
int unit_type) int unit_type)
{ {
PNG_pHYs;
png_byte buf[9]; png_byte buf[9];
png_debug(1, "in png_write_pHYs"); png_debug(1, "in png_write_pHYs");
@ -1962,7 +1964,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
png_save_uint_32(buf + 4, y_pixels_per_unit); png_save_uint_32(buf + 4, y_pixels_per_unit);
buf[8] = (png_byte)unit_type; buf[8] = (png_byte)unit_type;
png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
} }
#endif #endif
@ -1973,7 +1975,6 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
void /* PRIVATE */ void /* PRIVATE */
png_write_tIME(png_structp png_ptr, png_const_timep mod_time) png_write_tIME(png_structp png_ptr, png_const_timep mod_time)
{ {
PNG_tIME;
png_byte buf[7]; png_byte buf[7];
png_debug(1, "in png_write_tIME"); png_debug(1, "in png_write_tIME");
@ -1993,7 +1994,7 @@ png_write_tIME(png_structp png_ptr, png_const_timep mod_time)
buf[5] = mod_time->minute; buf[5] = mod_time->minute;
buf[6] = mod_time->second; buf[6] = mod_time->second;
png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
} }
#endif #endif
@ -2005,28 +2006,32 @@ png_write_start_row(png_structp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
/* Start of interlace block in the y direction */ /* Start of interlace block in the y direction */
int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
/* Offset to next interlace block in the y direction */ /* Offset to next interlace block in the y direction */
int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
#endif #endif
png_size_t buf_size; png_alloc_size_t buf_size;
int usr_pixel_depth;
png_debug(1, "in png_write_start_row"); png_debug(1, "in png_write_start_row");
buf_size = (png_size_t)(PNG_ROWBYTES( usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;
/* 1.5.6: added to allow checking in the row write code. */
png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
/* Set up row buffer */ /* Set up row buffer */
png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
(png_alloc_size_t)buf_size);
png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
@ -2043,8 +2048,7 @@ png_write_start_row(png_structp png_ptr)
if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
{ {
/* Set up previous row buffer */ /* Set up previous row buffer */
png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
(png_alloc_size_t)buf_size);
if (png_ptr->do_filter & PNG_FILTER_UP) if (png_ptr->do_filter & PNG_FILTER_UP)
{ {
@ -2112,16 +2116,16 @@ png_write_finish_row(png_structp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
/* Start of interlace block in the y direction */ /* Start of interlace block in the y direction */
int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
/* Offset to next interlace block in the y direction */ /* Offset to next interlace block in the y direction */
int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
#endif #endif
int ret; int ret;
@ -2239,10 +2243,10 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* Start of interlace block */ /* Start of interlace block */
int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
/* Offset to next interlace block */ /* Offset to next interlace block */
int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
png_debug(1, "in png_do_write_interlace"); png_debug(1, "in png_do_write_interlace");
@ -2410,7 +2414,8 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
* been specified by the application, and then writes the row out with the * been specified by the application, and then writes the row out with the
* chosen filter. * chosen filter.
*/ */
static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row); static void png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row,
png_size_t row_bytes);
#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) #define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
#define PNG_HISHIFT 10 #define PNG_HISHIFT 10
@ -2426,7 +2431,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
png_byte filter_to_do = png_ptr->do_filter; png_byte filter_to_do = png_ptr->do_filter;
png_size_t row_bytes = row_info->rowbytes; png_size_t row_bytes = row_info->rowbytes;
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
int num_p_filters = (int)png_ptr->num_prev_filters; int num_p_filters = png_ptr->num_prev_filters;
#endif #endif
png_debug(1, "in png_write_find_filter"); png_debug(1, "in png_write_find_filter");
@ -3063,9 +3068,9 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
} }
} }
#endif /* PNG_WRITE_FILTER_SUPPORTED */ #endif /* PNG_WRITE_FILTER_SUPPORTED */
/* Do the actual writing of the filtered row data from the chosen filter. */
png_write_filtered_row(png_ptr, best_row); /* Do the actual writing of the filtered row data from the chosen filter. */
png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
#ifdef PNG_WRITE_FILTER_SUPPORTED #ifdef PNG_WRITE_FILTER_SUPPORTED
#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
@ -3088,10 +3093,9 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
/* Do the actual writing of a previously filtered row. */ /* Do the actual writing of a previously filtered row. */
static void static void
png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row,
png_size_t avail/*includes filter byte*/)
{ {
png_size_t avail;
png_debug(1, "in png_write_filtered_row"); png_debug(1, "in png_write_filtered_row");
png_debug1(2, "filter = %d", filtered_row[0]); png_debug1(2, "filter = %d", filtered_row[0]);
@ -3099,7 +3103,6 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
png_ptr->zstream.next_in = filtered_row; png_ptr->zstream.next_in = filtered_row;
png_ptr->zstream.avail_in = 0; png_ptr->zstream.avail_in = 0;
avail = png_ptr->row_info.rowbytes + 1;
/* Repeat until we have compressed all the data */ /* Repeat until we have compressed all the data */
do do
{ {