Updated included PNG library to latest release (1.5.6).

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2283 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2011-11-26 17:08:40 +00:00
parent e8776a79d6
commit 4680a49285
15 changed files with 2546 additions and 1474 deletions

View File

@ -1,7 +1,7 @@
/* png.c - location for general purpose libpng functions
*
* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -14,7 +14,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
typedef png_libpng_version_1_5_4 Your_png_h_is_not_version_1_5_4;
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
* of the PNG file signature. If the PNG data is embedded into another
@ -43,7 +43,7 @@ png_set_sig_bytes(png_structp png_ptr, int num_bytes)
* can simply check the remaining bytes for extra assurance. Returns
* an integer less than, equal to, or greater than zero if sig is found,
* respectively, to be less than, to match, or be greater than the correct
* PNG signature (this is the same behaviour as strcmp, memcmp, etc).
* PNG signature (this is the same behavior as strcmp, memcmp, etc).
*/
int PNGAPI
png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
@ -107,7 +107,8 @@ png_zfree(voidpf png_ptr, voidpf ptr)
void /* PRIVATE */
png_reset_crc(png_structp png_ptr)
{
png_ptr->crc = crc32(0, Z_NULL, 0);
/* The cast is safe because the crc is a 32 bit value. */
png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
}
/* Calculate the CRC over a section of data. We can only pass as
@ -120,21 +121,48 @@ png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length)
{
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) ==
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
need_crc = 0;
}
else /* critical */
else /* critical */
{
if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
need_crc = 0;
}
if (need_crc)
png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
/* 'uLong' is defined as unsigned long, this means that on some systems it is
* a 64 bit value. crc32, however, returns 32 bits so the following cast is
* safe. 'uInt' may be no more than 16 bits, so it is necessary to perform a
* loop here.
*/
if (need_crc && length > 0)
{
uLong crc = png_ptr->crc; /* Should never issue a warning */
do
{
uInt safeLength = (uInt)length;
if (safeLength == 0)
safeLength = (uInt)-1; /* evil, but safe */
crc = crc32(crc, ptr, safeLength);
/* The following should never issue compiler warnings, if they do the
* target system has characteristics that will probably violate other
* assumptions within the libpng code.
*/
ptr += safeLength;
length -= safeLength;
}
while (length > 0);
/* And the following is always safe because the crc is only 32 bits. */
png_ptr->crc = (png_uint_32)crc;
}
}
/* Check a user supplied version number, called from both read and write
@ -542,8 +570,8 @@ png_get_io_ptr(png_structp png_ptr)
/* Initialize the default input/output functions for the PNG file. If you
* use your own read or write routines, you can call either png_set_read_fn()
* or png_set_write_fn() instead of png_init_io(). If you have defined
* PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
* necessarily available.
* PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
* function of your own because "FILE *" isn't necessarily available.
*/
void PNGAPI
png_init_io(png_structp png_ptr, png_FILE_p fp)
@ -617,13 +645,13 @@ png_get_copyright(png_const_structp png_ptr)
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
"libpng version 1.5.4 - July 7, 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) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# else
return "libpng version 1.5.4 - July 7, 2011\
return "libpng version 1.5.6 - November 3, 2011\
Copyright (c) 1998-2011 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@ -670,25 +698,43 @@ png_get_header_version(png_const_structp png_ptr)
#endif
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
int PNGAPI
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 */
int i;
png_bytep p;
if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0)
return 0;
png_const_bytep p, p_end;
p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5;
for (i = png_ptr->num_chunk_list; i; i--, p -= 5)
if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list <= 0)
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))
return ((int)*(p + 4));
return 0;
return p[4];
}
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
/* This function, added to libpng-1.0.6g, is untested. */
@ -713,18 +759,9 @@ png_access_version_number(void)
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
# ifdef PNG_SIZE_T
/* Added at libpng version 1.2.6 */
PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
png_size_t PNGAPI
png_convert_size(size_t size)
{
if (size > (png_size_t)-1)
PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
return ((png_size_t)size);
}
# endif /* PNG_SIZE_T */
/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
* at libpng 1.5.5!
*/
/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
# ifdef PNG_CHECK_cHRM_SUPPORTED
@ -798,6 +835,326 @@ png_check_cHRM_fixed(png_structp png_ptr,
}
# endif /* PNG_CHECK_cHRM_SUPPORTED */
#ifdef PNG_cHRM_SUPPORTED
/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
* cHRM, as opposed to using chromaticities. These internal APIs return
* non-zero on a parameter error. The X, Y and Z values are required to be
* positive and less than 1.0.
*/
int png_xy_from_XYZ(png_xy *xy, png_XYZ XYZ)
{
png_int_32 d, dwhite, whiteX, whiteY;
d = XYZ.redX + XYZ.redY + XYZ.redZ;
if (!png_muldiv(&xy->redx, XYZ.redX, PNG_FP_1, d)) return 1;
if (!png_muldiv(&xy->redy, XYZ.redY, PNG_FP_1, d)) return 1;
dwhite = d;
whiteX = XYZ.redX;
whiteY = XYZ.redY;
d = XYZ.greenX + XYZ.greenY + XYZ.greenZ;
if (!png_muldiv(&xy->greenx, XYZ.greenX, PNG_FP_1, d)) return 1;
if (!png_muldiv(&xy->greeny, XYZ.greenY, PNG_FP_1, d)) return 1;
dwhite += d;
whiteX += XYZ.greenX;
whiteY += XYZ.greenY;
d = XYZ.blueX + XYZ.blueY + XYZ.blueZ;
if (!png_muldiv(&xy->bluex, XYZ.blueX, PNG_FP_1, d)) return 1;
if (!png_muldiv(&xy->bluey, XYZ.blueY, PNG_FP_1, d)) return 1;
dwhite += d;
whiteX += XYZ.blueX;
whiteY += XYZ.blueY;
/* The reference white is simply the same of the end-point (X,Y,Z) vectors,
* thus:
*/
if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1;
if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1;
return 0;
}
int png_XYZ_from_xy(png_XYZ *XYZ, png_xy xy)
{
png_fixed_point red_inverse, green_inverse, blue_scale;
png_fixed_point left, right, denominator;
/* Check xy and, implicitly, z. Note that wide gamut color spaces typically
* have end points with 0 tristimulus values (these are impossible end
* points, but they are used to cover the possible colors.)
*/
if (xy.redx < 0 || xy.redx > PNG_FP_1) return 1;
if (xy.redy < 0 || xy.redy > PNG_FP_1-xy.redx) return 1;
if (xy.greenx < 0 || xy.greenx > PNG_FP_1) return 1;
if (xy.greeny < 0 || xy.greeny > PNG_FP_1-xy.greenx) return 1;
if (xy.bluex < 0 || xy.bluex > PNG_FP_1) return 1;
if (xy.bluey < 0 || xy.bluey > PNG_FP_1-xy.bluex) return 1;
if (xy.whitex < 0 || xy.whitex > PNG_FP_1) return 1;
if (xy.whitey < 0 || xy.whitey > PNG_FP_1-xy.whitex) return 1;
/* The reverse calculation is more difficult because the original tristimulus
* value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
* derived values were recorded in the cHRM chunk;
* (red,green,blue,white)x(x,y). This loses one degree of freedom and
* therefore an arbitrary ninth value has to be introduced to undo the
* original transformations.
*
* Think of the original end-points as points in (X,Y,Z) space. The
* chromaticity values (c) have the property:
*
* C
* c = ---------
* X + Y + Z
*
* For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the
* three chromaticity values (x,y,z) for each end-point obey the
* relationship:
*
* x + y + z = 1
*
* This describes the plane in (X,Y,Z) space that intersects each axis at the
* value 1.0; call this the chromaticity plane. Thus the chromaticity
* calculation has scaled each end-point so that it is on the x+y+z=1 plane
* and chromaticity is the intersection of the vector from the origin to the
* (X,Y,Z) value with the chromaticity plane.
*
* To fully invert the chromaticity calculation we would need the three
* end-point scale factors, (red-scale, green-scale, blue-scale), but these
* were not recorded. Instead we calculated the reference white (X,Y,Z) and
* recorded the chromaticity of this. The reference white (X,Y,Z) would have
* given all three of the scale factors since:
*
* color-C = color-c * color-scale
* white-C = red-C + green-C + blue-C
* = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
*
* But cHRM records only white-x and white-y, so we have lost the white scale
* factor:
*
* white-C = white-c*white-scale
*
* To handle this the inverse transformation makes an arbitrary assumption
* about white-scale:
*
* Assume: white-Y = 1.0
* Hence: white-scale = 1/white-y
* Or: red-Y + green-Y + blue-Y = 1.0
*
* Notice the last statement of the assumption gives an equation in three of
* the nine values we want to calculate. 8 more equations come from the
* above routine as summarised at the top above (the chromaticity
* calculation):
*
* Given: color-x = color-X / (color-X + color-Y + color-Z)
* Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
*
* This is 9 simultaneous equations in the 9 variables "color-C" and can be
* solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix
* determinants, however this is not as bad as it seems because only 28 of
* the total of 90 terms in the various matrices are non-zero. Nevertheless
* Cramer's rule is notoriously numerically unstable because the determinant
* calculation involves the difference of large, but similar, numbers. It is
* difficult to be sure that the calculation is stable for real world values
* and it is certain that it becomes unstable where the end points are close
* together.
*
* So this code uses the perhaps slighly less optimal but more understandable
* and totally obvious approach of calculating color-scale.
*
* This algorithm depends on the precision in white-scale and that is
* (1/white-y), so we can immediately see that as white-y approaches 0 the
* accuracy inherent in the cHRM chunk drops off substantially.
*
* libpng arithmetic: a simple invertion of the above equations
* ------------------------------------------------------------
*
* white_scale = 1/white-y
* white-X = white-x * white-scale
* white-Y = 1.0
* white-Z = (1 - white-x - white-y) * white_scale
*
* white-C = red-C + green-C + blue-C
* = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
*
* This gives us three equations in (red-scale,green-scale,blue-scale) where
* all the coefficients are now known:
*
* red-x*red-scale + green-x*green-scale + blue-x*blue-scale
* = white-x/white-y
* red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
* red-z*red-scale + green-z*green-scale + blue-z*blue-scale
* = (1 - white-x - white-y)/white-y
*
* In the last equation color-z is (1 - color-x - color-y) so we can add all
* three equations together to get an alternative third:
*
* red-scale + green-scale + blue-scale = 1/white-y = white-scale
*
* So now we have a Cramer's rule solution where the determinants are just
* 3x3 - far more tractible. Unfortunately 3x3 determinants still involve
* multiplication of three coefficients so we can't guarantee to avoid
* overflow in the libpng fixed point representation. Using Cramer's rule in
* floating point is probably a good choice here, but it's not an option for
* fixed point. Instead proceed to simplify the first two equations by
* eliminating what is likely to be the largest value, blue-scale:
*
* blue-scale = white-scale - red-scale - green-scale
*
* Hence:
*
* (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
* (white-x - blue-x)*white-scale
*
* (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
* 1 - blue-y*white-scale
*
* And now we can trivially solve for (red-scale,green-scale):
*
* green-scale =
* (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
* -----------------------------------------------------------
* green-x - blue-x
*
* red-scale =
* 1 - blue-y*white-scale - (green-y - blue-y) * green-scale
* ---------------------------------------------------------
* red-y - blue-y
*
* Hence:
*
* red-scale =
* ( (green-x - blue-x) * (white-y - blue-y) -
* (green-y - blue-y) * (white-x - blue-x) ) / white-y
* -------------------------------------------------------------------------
* (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
*
* green-scale =
* ( (red-y - blue-y) * (white-x - blue-x) -
* (red-x - blue-x) * (white-y - blue-y) ) / white-y
* -------------------------------------------------------------------------
* (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
*
* Accuracy:
* The input values have 5 decimal digits of accuracy. The values are all in
* the range 0 < value < 1, so simple products are in the same range but may
* need up to 10 decimal digits to preserve the original precision and avoid
* underflow. Because we are using a 32-bit signed representation we cannot
* match this; the best is a little over 9 decimal digits, less than 10.
*
* The approach used here is to preserve the maximum precision within the
* signed representation. Because the red-scale calculation above uses the
* difference between two products of values that must be in the range -1..+1
* it is sufficient to divide the product by 7; ceil(100,000/32767*2). The
* factor is irrelevant in the calculation because it is applied to both
* numerator and denominator.
*
* Note that the values of the differences of the products of the
* chromaticities in the above equations tend to be small, for example for
* the sRGB chromaticities they are:
*
* red numerator: -0.04751
* green numerator: -0.08788
* denominator: -0.2241 (without white-y multiplication)
*
* The resultant Y coefficients from the chromaticities of some widely used
* color space definitions are (to 15 decimal places):
*
* sRGB
* 0.212639005871510 0.715168678767756 0.072192315360734
* Kodak ProPhoto
* 0.288071128229293 0.711843217810102 0.000085653960605
* Adobe RGB
* 0.297344975250536 0.627363566255466 0.075291458493998
* Adobe Wide Gamut RGB
* 0.258728243040113 0.724682314948566 0.016589442011321
*/
/* By the argument, above overflow should be impossible here. The return
* value of 2 indicates an internal error to the caller.
*/
if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.redy - xy.bluey, 7)) return 2;
if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.redx - xy.bluex, 7)) return 2;
denominator = left - right;
/* Now find the red numerator. */
if (!png_muldiv(&left, xy.greenx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2;
if (!png_muldiv(&right, xy.greeny-xy.bluey, xy.whitex-xy.bluex, 7)) return 2;
/* Overflow is possible here and it indicates an extreme set of PNG cHRM
* chunk values. This calculation actually returns the reciprocal of the
* scale value because this allows us to delay the multiplication of white-y
* into the denominator, which tends to produce a small number.
*/
if (!png_muldiv(&red_inverse, xy.whitey, denominator, left-right) ||
red_inverse <= xy.whitey /* r+g+b scales = white scale */)
return 1;
/* Similarly for green_inverse: */
if (!png_muldiv(&left, xy.redy-xy.bluey, xy.whitex-xy.bluex, 7)) return 2;
if (!png_muldiv(&right, xy.redx-xy.bluex, xy.whitey-xy.bluey, 7)) return 2;
if (!png_muldiv(&green_inverse, xy.whitey, denominator, left-right) ||
green_inverse <= xy.whitey)
return 1;
/* And the blue scale, the checks above guarantee this can't overflow but it
* can still produce 0 for extreme cHRM values.
*/
blue_scale = png_reciprocal(xy.whitey) - png_reciprocal(red_inverse) -
png_reciprocal(green_inverse);
if (blue_scale <= 0) return 1;
/* And fill in the png_XYZ: */
if (!png_muldiv(&XYZ->redX, xy.redx, PNG_FP_1, red_inverse)) return 1;
if (!png_muldiv(&XYZ->redY, xy.redy, PNG_FP_1, red_inverse)) return 1;
if (!png_muldiv(&XYZ->redZ, PNG_FP_1 - xy.redx - xy.redy, PNG_FP_1,
red_inverse))
return 1;
if (!png_muldiv(&XYZ->greenX, xy.greenx, PNG_FP_1, green_inverse)) return 1;
if (!png_muldiv(&XYZ->greenY, xy.greeny, PNG_FP_1, green_inverse)) return 1;
if (!png_muldiv(&XYZ->greenZ, PNG_FP_1 - xy.greenx - xy.greeny, PNG_FP_1,
green_inverse))
return 1;
if (!png_muldiv(&XYZ->blueX, xy.bluex, blue_scale, PNG_FP_1)) return 1;
if (!png_muldiv(&XYZ->blueY, xy.bluey, blue_scale, PNG_FP_1)) return 1;
if (!png_muldiv(&XYZ->blueZ, PNG_FP_1 - xy.bluex - xy.bluey, blue_scale,
PNG_FP_1))
return 1;
return 0; /*success*/
}
int png_XYZ_from_xy_checked(png_structp png_ptr, png_XYZ *XYZ, png_xy xy)
{
switch (png_XYZ_from_xy(XYZ, xy))
{
case 0: /* success */
return 1;
case 1:
/* The chunk may be technically valid, but we got png_fixed_point
* overflow while trying to get XYZ values out of it. This is
* entirely benign - the cHRM chunk is pretty extreme.
*/
png_warning(png_ptr,
"extreme cHRM chunk cannot be converted to tristimulus values");
break;
default:
/* libpng is broken; this should be a warning but if it happens we
* want error reports so for the moment it is an error.
*/
png_error(png_ptr, "internal error in png_XYZ_from_xy");
break;
}
/* ERROR RETURN */
return 0;
}
#endif
void /* PRIVATE */
png_check_IHDR(png_structp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth,
@ -1383,18 +1740,30 @@ png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size,
size -= cdigits;
*ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */
if (exp_b10 < 0)
{
*ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
exp_b10 = -exp_b10;
}
cdigits = 0;
while (exp_b10 > 0)
/* The following use of an unsigned temporary avoids ambiguities in
* the signed arithmetic on exp_b10 and permits GCC at least to do
* better optimization.
*/
{
exponent[cdigits++] = (char)(48 + exp_b10 % 10);
exp_b10 /= 10;
unsigned int uexp_b10;
if (exp_b10 < 0)
{
*ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
uexp_b10 = -exp_b10;
}
else
uexp_b10 = exp_b10;
cdigits = 0;
while (uexp_b10 > 0)
{
exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
uexp_b10 /= 10;
}
}
/* Need another size check here for the exponent digits, so
@ -1452,7 +1821,7 @@ png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size,
else
num = fp;
if (num <= 0x80000000U) /* else overflowed */
if (num <= 0x80000000) /* else overflowed */
{
unsigned int ndigits = 0, first = 16 /* flag value */;
char digits[10];
@ -2294,6 +2663,60 @@ png_build_8bit_table(png_structp png_ptr, png_bytepp ptable,
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
* 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
@ -2304,6 +2727,18 @@ png_build_gamma_table(png_structp png_ptr, int bit_depth)
{
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)
{
png_build_8bit_table(png_ptr, &png_ptr->gamma_table,

View File

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.5.4 - July 7, 2011
* libpng version 1.5.6 - November 3, 2011
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -11,7 +11,7 @@
* Authors and maintainers:
* 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.97, January 1998, through 1.5.4 - July 7, 2011: Glenn
* libpng versions 0.97, January 1998, through 1.5.6 - November 3, 2011: Glenn
* See also "Contributing Authors", below.
*
* Note about libpng version numbers:
@ -157,6 +157,12 @@
* 1.5.4beta01-08 15 10504 15.so.15.4[.0]
* 1.5.4rc01 15 10504 15.so.15.4[.0]
* 1.5.4 15 10504 15.so.15.4[.0]
* 1.5.5beta01-08 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.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
* and minor numbers; the shared-library major version number will be
@ -188,7 +194,7 @@
*
* This code is released under the libpng license.
*
* libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 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
* distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors:
@ -300,13 +306,13 @@
* Y2K compliance in libpng:
* =========================
*
* July 7, 2011
* November 3, 2011
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
*
* This is your unofficial assurance that libpng from version 0.71 and
* upward through 1.5.4 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.
*
* Libpng only has two year fields. One is a 2-byte unsigned integer
@ -361,9 +367,9 @@
*/
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.5.4"
#define PNG_LIBPNG_VER_STRING "1.5.6"
#define PNG_HEADER_VERSION_STRING \
" libpng version 1.5.4 - July 7, 2011\n"
" libpng version 1.5.6 - November 3, 2011\n"
#define PNG_LIBPNG_VER_SONUM 15
#define PNG_LIBPNG_VER_DLLNUM 15
@ -371,7 +377,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 5
#define PNG_LIBPNG_VER_RELEASE 4
#define PNG_LIBPNG_VER_RELEASE 6
/* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero:
*/
@ -401,7 +407,7 @@
* 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
*/
#define PNG_LIBPNG_VER 10504 /* 1.5.4 */
#define PNG_LIBPNG_VER 10506 /* 1.5.6 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@ -523,7 +529,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
typedef char* png_libpng_version_1_5_4;
typedef char* png_libpng_version_1_5_6;
/* 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
@ -793,7 +799,7 @@ typedef png_info FAR * FAR * png_infopp;
#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */
#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */
/* This is used for the transformation routines, as some of them
* change these values for the row. It also should enable using
@ -1827,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));
#ifdef PNG_READ_INTERLACING_SUPPORTED
/* 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
* stores its own version of the new data internally and ignores the passed
@ -1834,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_bytep old_row, png_const_bytep new_row));
#endif /* PNG_READ_INTERLACING_SUPPORTED */
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
PNG_EXPORTA(94, png_voidp, png_malloc,
@ -2047,6 +2055,10 @@ PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structp png_ptr,
png_const_infop info_ptr, double *white_x, double *white_y, double *red_x,
double *red_y, double *green_x, double *green_y, double *blue_x,
double *blue_y));
PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_structp png_ptr,
png_const_infop info_ptr, double *red_X, double *red_Y, double *red_Z,
double *green_X, double *green_Y, double *green_Z, double *blue_X,
double *blue_Y, double *blue_Z));
#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */
PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
(png_const_structp png_ptr,
@ -2056,6 +2068,13 @@ PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
png_fixed_point *int_green_y, png_fixed_point *int_blue_x,
png_fixed_point *int_blue_y));
#endif
PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
(png_structp png_ptr, png_const_infop info_ptr,
png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
png_fixed_point *int_blue_Z));
#endif
#ifdef PNG_cHRM_SUPPORTED
@ -2063,12 +2082,22 @@ PNG_FP_EXPORT(135, void, png_set_cHRM,
(png_structp png_ptr, png_infop info_ptr,
double white_x, double white_y, double red_x, double red_y, double green_x,
double green_y, double blue_x, double blue_y));
PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_structp png_ptr,
png_infop info_ptr, double red_X, double red_Y, double red_Z,
double green_X, double green_Y, double green_Z, double blue_X,
double blue_Y, double blue_Z));
PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr,
png_infop info_ptr, png_fixed_point int_white_x,
png_fixed_point int_white_y, png_fixed_point int_red_x,
png_fixed_point int_red_y, png_fixed_point int_green_x,
png_fixed_point int_green_y, png_fixed_point int_blue_x,
png_fixed_point int_blue_y));
PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_structp png_ptr,
png_infop info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
png_fixed_point int_red_Z, png_fixed_point int_green_X,
png_fixed_point int_green_Y, png_fixed_point int_green_Z,
png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
png_fixed_point int_blue_Z));
#endif
#ifdef PNG_gAMA_SUPPORTED
@ -2281,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
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
must not be listed.
keep = 0: follow default behaviour
= 1: do not keep
= 2: keep only if safe-to-copy
= 3: keep even if unsafe-to-copy
must not be listed. Because this turns off the default handling for chunks
that would otherwise be recognized the behavior of libpng transformations may
well become incorrect!
keep = 0: PNG_HANDLE_CHUNK_AS_DEFAULT: follow default behavior
= 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_structp png_ptr, int keep,
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_const_bytep chunk_name));
#endif
@ -2429,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
* 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_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>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
* pass. This is expressed as a shift - effectively log2 of the number or
@ -2465,8 +2508,8 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
* the tile.
*/
#define PNG_PASS_MASK(pass,off) ( \
((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \
((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))
#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
@ -2492,14 +2535,14 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
{ png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
* (png_uint_16)(alpha) \
+ (png_uint_16)(bg)*(png_uint_16)(255 \
- (png_uint_16)(alpha)) + (png_uint_16)128); \
- (png_uint_16)(alpha)) + 128); \
(composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
# define png_composite_16(composite, fg, alpha, bg) \
{ png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
* (png_uint_32)(alpha) \
+ (png_uint_32)(bg)*(png_uint_32)(65535L \
- (png_uint_32)(alpha)) + (png_uint_32)32768L); \
+ (png_uint_32)(bg)*(65535 \
- (png_uint_32)(alpha)) + 32768); \
(composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
#else /* Standard method using integer division */
@ -2507,12 +2550,12 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
# define png_composite(composite, fg, alpha, bg) \
(composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
(png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
(png_uint_16)127) / 255)
127) / 255)
# define png_composite_16(composite, fg, alpha, bg) \
(composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
(png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
(png_uint_32)32767) / (png_uint_32)65535L)
(png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
32767) / 65535)
#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
@ -2576,7 +2619,7 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
* scripts/symbols.def as well.
*/
#ifdef PNG_EXPORT_LAST_ORDINAL
PNG_EXPORT_LAST_ORDINAL(229);
PNG_EXPORT_LAST_ORDINAL(233);
#endif
#ifdef __cplusplus

View File

@ -1,7 +1,7 @@
/* pngconf.h - machine configurable file for libpng
*
* libpng version 1.5.4 - July 7, 2011
* libpng version 1.5.6 - November 3, 2011
*
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@ -164,7 +164,9 @@
* 'type', compiler specific.
*
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
* make a symbol exported from the DLL.
* make a symbol exported from the DLL. Not used in the
* public header files; see pngpriv.h for how it is used
* in the libpng build.
*
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
* from a DLL - used to define PNG_IMPEXP when
@ -258,25 +260,14 @@
# define PNGAPI PNGCAPI
#endif
/* The default for PNG_IMPEXP depends on whether the library is
* being built or used.
/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
* then in an internal header file when building the library, otherwise (when
* using the library) it is set here.
*/
#ifndef PNG_IMPEXP
# ifdef PNGLIB_BUILD
/* Building the library */
# if (defined(DLL_EXPORT)/*from libtool*/ ||\
defined(_WINDLL) || defined(_DLL) || defined(__DLL__) ||\
defined(_USRDLL) ||\
defined(PNG_BUILD_DLL)) && defined(PNG_DLL_EXPORT)
/* Building a DLL. */
# define PNG_IMPEXP PNG_DLL_EXPORT
# endif /* DLL */
# else
/* Using the library */
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
/* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
/* This forces use of a DLL, disallowing static linking */
# define PNG_IMPEXP PNG_DLL_IMPORT
# endif
# ifndef PNG_IMPEXP
@ -356,25 +347,18 @@
# ifndef PNG_ALLOCATED
# define PNG_ALLOCATED __attribute__((__malloc__))
# endif
/* This specifically protects structure members that should only be
* accessed from within the library, therefore should be empty during
* a library build.
*/
# ifndef PNGLIB_BUILD
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __attribute__((__deprecated__))
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __attribute__((__deprecated__))
# endif
# ifndef PNG_PRIVATE
# if 0 /* Doesn't work so we use deprecated instead*/
# define PNG_PRIVATE \
__attribute__((warning("This function is not exported by libpng.")))
# else
# define PNG_PRIVATE \
__attribute__((__deprecated__))
# endif
# ifndef PNG_PRIVATE
# if 0 /* Doesn't work so we use deprecated instead*/
# define PNG_PRIVATE \
__attribute__((warning("This function is not exported by libpng.")))
# else
# define PNG_PRIVATE \
__attribute__((__deprecated__))
# endif
# endif
# endif /* PNGLIB_BUILD */
# endif
# endif /* __GNUC__ */
# if defined(_MSC_VER) && (_MSC_VER >= 1300)
@ -385,23 +369,16 @@
# define PNG_NORETURN __declspec(noreturn)
# endif
# ifndef PNG_ALLOCATED
# if (_MSC_VER >= 1400)
# if defined(_MSC_VER) && (_MSC_VER >= 1300)
# define PNG_ALLOCATED __declspec(restrict)
# endif
# endif
/* This specifically protects structure members that should only be
* accessed from within the library, therefore should be empty during
* a library build.
*/
# ifndef PNGLIB_BUILD
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __declspec(deprecated)
# endif
# ifndef PNG_PRIVATE
# define PNG_PRIVATE __declspec(deprecated)
# endif
# endif /* PNGLIB_BUILD */
# ifndef PNG_DEPRECATED
# define PNG_DEPRECATED __declspec(deprecated)
# endif
# ifndef PNG_PRIVATE
# define PNG_PRIVATE __declspec(deprecated)
# endif
# endif /* _MSC_VER */
#endif /* PNG_PEDANTIC_WARNINGS */

View File

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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
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))
{
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
{
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
{
int iin = 0;
buffer[iout++] = ':';
buffer[iout++] = ' ';
iin = 0;
while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
buffer[iout++] = error_message[iin++];

View File

@ -1,7 +1,7 @@
/* pngget.c - retrieval of values from info struct
*
* Last changed in libpng 1.5.1 [February 3, 2011]
* Last changed in libpng 1.5.6 [November 3, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -459,6 +459,65 @@ png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr,
#endif
#ifdef PNG_cHRM_SUPPORTED
/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
* same time to correct the rgb grayscale coefficient defaults obtained from the
* cHRM chunk in 1.5.4
*/
png_uint_32 PNGFAPI
png_get_cHRM_XYZ_fixed(png_structp png_ptr, png_const_infop info_ptr,
png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
png_fixed_point *int_blue_Z)
{
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
{
png_xy xy;
png_XYZ XYZ;
png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
xy.whitex = info_ptr->x_white;
xy.whitey = info_ptr->y_white;
xy.redx = info_ptr->x_red;
xy.redy = info_ptr->y_red;
xy.greenx = info_ptr->x_green;
xy.greeny = info_ptr->y_green;
xy.bluex = info_ptr->x_blue;
xy.bluey = info_ptr->y_blue;
/* The *_checked function handles error reporting, so just return 0 if
* there is a failure here.
*/
if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
{
if (int_red_X != NULL)
*int_red_X = XYZ.redX;
if (int_red_Y != NULL)
*int_red_Y = XYZ.redY;
if (int_red_Z != NULL)
*int_red_Z = XYZ.redZ;
if (int_green_X != NULL)
*int_green_X = XYZ.greenX;
if (int_green_Y != NULL)
*int_green_Y = XYZ.greenY;
if (int_green_Z != NULL)
*int_green_Z = XYZ.greenZ;
if (int_blue_X != NULL)
*int_blue_X = XYZ.blueX;
if (int_blue_Y != NULL)
*int_blue_Y = XYZ.blueY;
if (int_blue_Z != NULL)
*int_blue_Z = XYZ.blueZ;
return (PNG_INFO_cHRM);
}
}
return (0);
}
# ifdef PNG_FLOATING_POINT_SUPPORTED
png_uint_32 PNGAPI
png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr,
@ -490,6 +549,42 @@ png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr,
return (0);
}
png_uint_32 PNGAPI
png_get_cHRM_XYZ(png_structp png_ptr, png_const_infop info_ptr,
double *red_X, double *red_Y, double *red_Z, double *green_X,
double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
double *blue_Z)
{
png_XYZ XYZ;
if (png_get_cHRM_XYZ_fixed(png_ptr, info_ptr,
&XYZ.redX, &XYZ.redY, &XYZ.redZ, &XYZ.greenX, &XYZ.greenY, &XYZ.greenZ,
&XYZ.blueX, &XYZ.blueY, &XYZ.blueZ) & PNG_INFO_cHRM)
{
if (red_X != NULL)
*red_X = png_float(png_ptr, XYZ.redX, "cHRM red X");
if (red_Y != NULL)
*red_Y = png_float(png_ptr, XYZ.redY, "cHRM red Y");
if (red_Z != NULL)
*red_Z = png_float(png_ptr, XYZ.redZ, "cHRM red Z");
if (green_X != NULL)
*green_X = png_float(png_ptr, XYZ.greenX, "cHRM green X");
if (green_Y != NULL)
*green_Y = png_float(png_ptr, XYZ.greenY, "cHRM green Y");
if (green_Z != NULL)
*green_Z = png_float(png_ptr, XYZ.greenZ, "cHRM green Z");
if (blue_X != NULL)
*blue_X = png_float(png_ptr, XYZ.blueX, "cHRM blue X");
if (blue_Y != NULL)
*blue_Y = png_float(png_ptr, XYZ.blueY, "cHRM blue Y");
if (blue_Z != NULL)
*blue_Z = png_float(png_ptr, XYZ.blueZ, "cHRM blue Z");
return (PNG_INFO_cHRM);
}
return (0);
}
# endif
# ifdef PNG_FIXED_POINT_SUPPORTED
@ -855,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)
{
png_debug1(1, "in %s retrieval function",
(png_ptr->chunk_name[0] == '\0' ? "text" :
(png_const_charp)png_ptr->chunk_name));
png_debug1(1, "in 0x%lx retrieval function",
(unsigned long)png_ptr->chunk_name);
if (text_ptr != NULL)
*text_ptr = info_ptr->text;
@ -971,10 +1065,9 @@ png_get_user_chunk_ptr(png_const_structp png_ptr)
png_size_t PNGAPI
png_get_compression_buffer_size(png_const_structp png_ptr)
{
return (png_ptr ? png_ptr->zbuf_size : 0L);
return (png_ptr ? png_ptr->zbuf_size : 0);
}
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
/* These functions were added to libpng 1.2.6 and were enabled
* by default in libpng-1.4.0 */
@ -1016,16 +1109,14 @@ png_get_io_state (png_structp png_ptr)
png_uint_32 PNGAPI
png_get_io_chunk_type (png_const_structp png_ptr)
{
return ((png_ptr->chunk_name[0] << 24) +
(png_ptr->chunk_name[1] << 16) +
(png_ptr->chunk_name[2] << 8) +
(png_ptr->chunk_name[3]));
return png_ptr->chunk_name;
}
png_const_bytep PNGAPI
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 */

View File

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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 */
png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
{
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_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
png_uint_32 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
@ -273,6 +219,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
{
png_byte chunk_length[4];
png_byte chunk_tag[4];
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_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
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_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)
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)
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);
}
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)
{
@ -321,7 +279,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
}
#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)
{
@ -329,15 +287,15 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
return;
}
if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
if (chunk_name == png_IDAT)
png_ptr->mode |= PNG_HAVE_IDAT;
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;
else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
else if (chunk_name == png_IDAT)
{
if (!(png_ptr->mode & PNG_HAVE_IHDR))
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
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)
{
@ -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);
}
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
* 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
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)
{
@ -408,7 +366,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -421,7 +379,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -434,7 +392,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -447,7 +405,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -460,7 +418,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -473,7 +431,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -486,7 +444,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -499,7 +457,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -512,7 +470,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -525,7 +483,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -538,7 +496,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -551,7 +509,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -564,7 +522,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -577,7 +535,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -590,7 +548,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -603,7 +561,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
#endif
#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)
{
@ -809,11 +767,12 @@ png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
void /* PRIVATE */
png_push_read_IDAT(png_structp png_ptr)
{
PNG_IDAT;
if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
{
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)
{
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_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
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;
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;
@ -838,6 +798,7 @@ png_push_read_IDAT(png_structp png_ptr)
png_ptr->idat_size = png_ptr->push_length;
}
if (png_ptr->idat_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 */
png_push_process_row(png_structp png_ptr)
{
png_ptr->row_info.color_type = png_ptr->color_type;
png_ptr->row_info.width = png_ptr->iwidth;
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;
/* 1.5.6: row_info moved out of png_struct to a local here. */
png_row_info row_info;
png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
png_ptr->row_info.width);
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);
png_read_filter_row(png_ptr, &(png_ptr->row_info),
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_NONE)
{
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
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
png_do_read_transformations(png_ptr, &row_info);
#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
/* Blow up interlaced rows to full size */
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
{
if (png_ptr->pass < 6)
/* old interface (pre-1.0.9):
png_do_read_interlace(&(png_ptr->row_info),
png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
*/
png_do_read_interlace(png_ptr);
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
png_ptr->transformations);
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 */
/* 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 */
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 */
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 */
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
* 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++;
@ -1714,11 +1695,12 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
length)
{
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
if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
PNG_HANDLE_CHUNK_ALWAYS
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
&& 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
/* 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)
{
#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");
skip = length - (png_uint_32)65535L;
length = (png_uint_32)65535L;
skip = length - 65535;
length = 65535;
}
#endif
png_memcpy((png_charp)png_ptr->unknown_chunk.name,
(png_charp)png_ptr->chunk_name,
png_sizeof(png_ptr->unknown_chunk.name));
png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
= '\0';
/* This is just a record for the user; libpng doesn't use the character
* form of the name.
*/
PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
/* The following cast should be safe because of the check above. */
png_ptr->unknown_chunk.size = (png_size_t)length;
if (length == 0)
@ -1755,8 +1741,9 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
else
{
png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
(png_size_t)length);
png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
png_ptr->unknown_chunk.size);
png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data,
png_ptr->unknown_chunk.size);
}
#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 (!(png_ptr->chunk_name[0] & 0x20))
if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
PNG_HANDLE_CHUNK_ALWAYS)
png_chunk_error(png_ptr, "unknown critical chunk");
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);
}
#ifdef PNG_READ_INTERLACING_SUPPORTED
void PNGAPI
png_progressive_combine_row (png_structp png_ptr, png_bytep old_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)
return;
if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
/* new_row is a flag here - if it is NULL then the app callback was called
* 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
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.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* Last changed in libpng 1.5.4 [July 7, 2011]
* Last changed in libpng 1.5.6 [November 3, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@ -44,7 +44,11 @@
*/
#include <stdlib.h>
#define PNGLIB_BUILD
/* This is used to find 'offsetof', used below for alignment tests. */
#include <stddef.h>
#define PNGLIB_BUILD /*libpng is being built, not used*/
#ifdef PNG_USER_CONFIG
# include "pngusr.h"
/* These should have been defined in pngusr.h */
@ -55,10 +59,80 @@
# define PNG_USER_DLLFNAME_POSTFIX "Cb"
# endif
#endif
/* Is this a build of a DLL where compilation of the object modules requires
* different preprocessor settings to those required for a simple library? If
* so PNG_BUILD_DLL must be set.
*
* If libpng is used inside a DLL but that DLL does not export the libpng APIs
* PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a
* static library of libpng then link the DLL against that.
*/
#ifndef PNG_BUILD_DLL
# ifdef DLL_EXPORT
/* This is set by libtool when files are compiled for a DLL; libtool
* always compiles twice, even on systems where it isn't necessary. Set
* PNG_BUILD_DLL in case it is necessary:
*/
# define PNG_BUILD_DLL
# else
# ifdef _WINDLL
/* This is set by the Microsoft Visual Studio IDE in projects that
* build a DLL. It can't easily be removed from those projects (it
* isn't visible in the Visual Studio UI) so it is a fairly reliable
* indication that PNG_IMPEXP needs to be set to the DLL export
* attributes.
*/
# define PNG_BUILD_DLL
# else
# ifdef __DLL__
/* This is set by the Borland C system when compiling for a DLL
* (as above.)
*/
# define PNG_BUILD_DLL
# else
/* Add additional compiler cases here. */
# endif
# endif
# endif
#endif /* Setting PNG_BUILD_DLL if required */
/* See pngconf.h for more details: the builder of the library may set this on
* the command line to the right thing for the specific compilation system or it
* may be automagically set above (at present we know of no system where it does
* need to be set on the command line.)
*
* PNG_IMPEXP must be set here when building the library to prevent pngconf.h
* setting it to the "import" setting for a DLL build.
*/
#ifndef PNG_IMPEXP
# ifdef PNG_BUILD_DLL
# define PNG_IMPEXP PNG_DLL_EXPORT
# else
/* Not building a DLL, or the DLL doesn't require specific export
* definitions.
*/
# define PNG_IMPEXP
# endif
#endif
/* No warnings for private or deprecated functions in the build: */
#ifndef PNG_DEPRECATED
# define PNG_DEPRECATED
#endif
#ifndef PNG_PRIVATE
# define PNG_PRIVATE
#endif
#include "png.h"
#include "pnginfo.h"
#include "pngstruct.h"
/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */
#ifndef PNG_DLL_EXPORT
# define PNG_DLL_EXPORT
#endif
/* This is used for 16 bit gamma tables - only the top level pointers are const,
* this could be changed:
*/
@ -250,6 +324,52 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
# define png_memset memset
# 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 1.5.0beta36 move from pngconf.h */
@ -293,24 +413,23 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
#define PNG_EXPAND 0x1000
#define PNG_GAMMA 0x2000
#define PNG_GRAY_TO_RGB 0x4000
#define PNG_FILLER 0x8000L
#define PNG_PACKSWAP 0x10000L
#define PNG_SWAP_ALPHA 0x20000L
#define PNG_STRIP_ALPHA 0x40000L
#define PNG_INVERT_ALPHA 0x80000L
#define PNG_USER_TRANSFORM 0x100000L
#define PNG_RGB_TO_GRAY_ERR 0x200000L
#define PNG_RGB_TO_GRAY_WARN 0x400000L
#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
#define PNG_ENCODE_ALPHA 0x800000L /* Added to libpng-1.5.4 */
#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */
#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */
#define PNG_SCALE_16_TO_8 0x4000000L /* Added to libpng-1.5.4 */
/* 0x8000000L unused */
/* 0x10000000L unused */
/* 0x20000000L unused */
/* 0x40000000L unused */
#define PNG_FILLER 0x8000
#define PNG_PACKSWAP 0x10000
#define PNG_SWAP_ALPHA 0x20000
#define PNG_STRIP_ALPHA 0x40000
#define PNG_INVERT_ALPHA 0x80000
#define PNG_USER_TRANSFORM 0x100000
#define PNG_RGB_TO_GRAY_ERR 0x200000
#define PNG_RGB_TO_GRAY_WARN 0x400000
#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */
#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */
#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */
#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */
/* 0x8000000 unused */
/* 0x10000000 unused */
/* 0x20000000 unused */
/* 0x40000000 unused */
/* Flags for png_create_struct */
#define PNG_STRUCT_PNG 0x0001
#define PNG_STRUCT_INFO 0x0002
@ -335,22 +454,22 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */
#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */
#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */
#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
/* 0x200000L unused */
/* 0x400000L unused */
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000L /* Added to libpng-1.4.0 */
#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000L /* 5 lines added */
#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000L /* to libpng-1.5.4 */
#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000L
#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000L
#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000L
/* 0x20000000L unused */
/* 0x40000000L unused */
#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000
#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000
#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000
/* 0x200000 unused */
/* 0x400000 unused */
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000 /* Added to libpng-1.4.0 */
#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000 /* 5 lines added */
#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000 /* to libpng-1.5.4 */
#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000
#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000
#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000
/* 0x20000000 unused */
/* 0x40000000 unused */
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN)
@ -432,32 +551,70 @@ PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp,
#endif
#endif
/* Constant strings for known chunk types. If you need to add a chunk,
* define the name here, and add an invocation of the macro wherever it's
* needed.
/* Constants for known chunk types. If you need to add a chunk, define the name
* here. For historical reasons these constants have the form png_<name>; i.e.
* 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_IDAT PNG_CONST png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
#define PNG_IEND PNG_CONST png_byte png_IEND[5] = { 73, 69, 78, 68, '\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_cHRM PNG_CONST png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
#define PNG_gAMA PNG_CONST png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
#define PNG_hIST PNG_CONST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
#define PNG_iCCP PNG_CONST png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
#define PNG_iTXt PNG_CONST png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
#define PNG_oFFs PNG_CONST png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
#define PNG_pCAL PNG_CONST png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
#define PNG_sCAL PNG_CONST png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
#define PNG_pHYs PNG_CONST png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
#define PNG_sBIT PNG_CONST png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
#define PNG_sPLT PNG_CONST png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
#define PNG_sRGB PNG_CONST png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
#define PNG_sTER PNG_CONST png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}
#define PNG_tEXt PNG_CONST png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
#define PNG_tIME PNG_CONST png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
#define PNG_tRNS PNG_CONST png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
#define PNG_zTXt PNG_CONST png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
#define PNG_CHUNK(b1,b2,b3,b4) \
(PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
#define png_IHDR PNG_CHUNK( 73, 72, 68, 82)
#define png_IDAT PNG_CHUNK( 73, 68, 65, 84)
#define png_IEND PNG_CHUNK( 73, 69, 78, 68)
#define png_PLTE PNG_CHUNK( 80, 76, 84, 69)
#define png_bKGD PNG_CHUNK( 98, 75, 71, 68)
#define png_cHRM PNG_CHUNK( 99, 72, 82, 77)
#define png_gAMA PNG_CHUNK(103, 65, 77, 65)
#define png_hIST PNG_CHUNK(104, 73, 83, 84)
#define png_iCCP PNG_CHUNK(105, 67, 67, 80)
#define png_iTXt PNG_CHUNK(105, 84, 88, 116)
#define png_oFFs PNG_CHUNK(111, 70, 70, 115)
#define png_pCAL PNG_CHUNK(112, 67, 65, 76)
#define png_sCAL PNG_CHUNK(115, 67, 65, 76)
#define png_pHYs PNG_CHUNK(112, 72, 89, 115)
#define png_sBIT PNG_CHUNK(115, 66, 73, 84)
#define png_sPLT PNG_CHUNK(115, 80, 76, 84)
#define png_sRGB PNG_CHUNK(115, 82, 71, 66)
#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): */
#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */
@ -714,17 +871,44 @@ PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
/* Internal use only. Called before first row of data */
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,
int mask));
int display));
#ifdef PNG_READ_INTERLACING_SUPPORTED
/* Expand an interlaced row */
/* OLD pre-1.0.9 interface:
/* Expand an interlaced row: the 'row_info' describes the pass data that has
* 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_bytep row, int pass, png_uint_32 transformations));
*/
PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
#endif
/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
@ -735,10 +919,11 @@ PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
png_bytep row, int pass));
#endif
/* Unfilter a row */
PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
png_row_infop row_info, png_bytep row, png_const_bytep prev_row,
int filter));
/* Unfilter a row: check the filter value before calling this, there is no point
* calling it for PNG_FILTER_VALUE_NONE.
*/
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 */
PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr,
@ -988,18 +1173,30 @@ PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
png_uint_32 length));
#endif
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
png_infop info_ptr, png_uint_32 length));
#endif
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 */
#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
#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
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
@ -1078,6 +1275,35 @@ PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2,
unsigned long *hi_product, unsigned long *lo_product));
#endif
#ifdef PNG_cHRM_SUPPORTED
/* Added at libpng version 1.5.5 */
typedef struct png_xy
{
png_fixed_point redx, redy;
png_fixed_point greenx, greeny;
png_fixed_point bluex, bluey;
png_fixed_point whitex, whitey;
} png_xy;
typedef struct png_XYZ
{
png_fixed_point redX, redY, redZ;
png_fixed_point greenX, greenY, greenZ;
png_fixed_point blueX, blueY, blueZ;
} png_XYZ;
/* The conversion APIs return 0 on success, non-zero on a parameter error. They
* allow conversion between the above representations of a color encoding. When
* converting from XYZ end points to chromaticities the absolute magnitude of
* the end points is lost, when converting back the sum of the Y values of the
* three end points will be 1.0
*/
PNG_EXTERN int png_xy_from_XYZ PNGARG((png_xy *xy, png_XYZ XYZ));
PNG_EXTERN int png_XYZ_from_xy PNGARG((png_XYZ *XYZ, png_xy xy));
PNG_EXTERN int png_XYZ_from_xy_checked PNGARG((png_structp png_ptr,
png_XYZ *XYZ, png_xy xy));
#endif
/* Added at libpng version 1.4.0 */
PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth,
@ -1342,6 +1568,7 @@ PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value,
png_fixed_point gamma_value));
PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int 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,
int bit_depth));
#endif

View File

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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 (;;)
{
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_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
* 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)
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);
else if (!png_memcmp(chunk_name, png_IEND, 4))
else if (chunk_name == png_IEND)
png_handle_IEND(png_ptr, info_ptr, length);
#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_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;
else if (!png_memcmp(chunk_name, png_IDAT, 4))
else if (chunk_name == png_IDAT)
{
if (!(png_ptr->mode & PNG_HAVE_IHDR))
png_error(png_ptr, "Missing IHDR before IDAT");
@ -285,10 +231,10 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
}
}
#endif
else if (!png_memcmp(chunk_name, png_PLTE, 4))
else if (chunk_name == png_PLTE)
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))
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
else if (!png_memcmp(chunk_name, png_bKGD, 4))
else if (chunk_name == png_bKGD)
png_handle_bKGD(png_ptr, info_ptr, length);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
@ -402,13 +348,7 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
if (png_ptr == NULL)
return;
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr);
else
png_warning(png_ptr,
"Ignoring extra png_read_update_info() call;"
" row buffer not reallocated");
png_read_start_row(png_ptr);
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
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");
if (png_ptr == NULL)
return;
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");
if (png_ptr != NULL)
png_read_start_row(png_ptr);
}
#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
@ -444,23 +377,30 @@ png_start_read_image(png_structp png_ptr)
void PNGAPI
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;
png_row_info row_info;
if (png_ptr == NULL)
return;
png_debug2(1, "in png_read_row (row %lu, pass %d)",
(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))
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)
{
/* 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
/* 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))
{
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 (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*/);
png_read_finish_row(png_ptr);
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 (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*/);
png_read_finish_row(png_ptr);
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 (dsp_row != NULL && (png_ptr->row_number & 4))
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_read_finish_row(png_ptr);
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 (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*/);
png_read_finish_row(png_ptr);
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 (dsp_row != NULL && (png_ptr->row_number & 2))
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_combine_row(png_ptr, dsp_row, 1/*display*/);
png_read_finish_row(png_ptr);
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 (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*/);
png_read_finish_row(png_ptr);
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_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_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);
png_ptr->row_info.color_type = png_ptr->color_type;
png_ptr->row_info.width = png_ptr->iwidth;
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,
png_ptr->row_info.width);
if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
{
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");
}
if (png_ptr->row_buf[0])
png_read_filter_row(png_ptr, &(png_ptr->row_info),
png_ptr->row_buf + 1, png_ptr->prev_row + 1,
(int)(png_ptr->row_buf[0]));
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 count:
*/
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
#ifdef PNG_MNG_FEATURES_SUPPORTED
if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
(png_ptr->filter_type == PNG_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
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
png_do_read_transformations(png_ptr, &row_info);
#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
/* Blow up interlaced rows to full size */
if (png_ptr->interlaced &&
(png_ptr->transformations & PNG_INTERLACE))
{
if (png_ptr->pass < 6)
/* Old interface (pre-1.0.9):
* png_do_read_interlace(&(png_ptr->row_info),
* png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
*/
png_do_read_interlace(png_ptr);
png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
png_ptr->transformations);
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)
png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]);
png_combine_row(png_ptr, row, 0/*row*/);
}
else
#endif
{
if (row != NULL)
png_combine_row(png_ptr, row, 0xff);
png_combine_row(png_ptr, row, -1/*ignored*/);
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);
@ -858,85 +806,31 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
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_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);
else if (!png_memcmp(chunk_name, png_IEND, 4))
else if (chunk_name == png_IEND)
png_handle_IEND(png_ptr, info_ptr, length);
#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))
png_benign_error(png_ptr, "Too many IDATs found");
}
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;
}
#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
* 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);
}
else if (!png_memcmp(chunk_name, png_PLTE, 4))
else if (chunk_name == png_PLTE)
png_handle_PLTE(png_ptr, info_ptr, length);
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
#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);
#endif
@ -1138,9 +1032,13 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr,
if (end_info_ptr != NULL)
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->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);
#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);
#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)
png_zfree(png_ptr, png_ptr->palette);
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;
#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);
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED

File diff suppressed because it is too large Load Diff

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
*
* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -64,6 +64,39 @@ png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
}
}
void PNGFAPI
png_set_cHRM_XYZ_fixed(png_structp png_ptr, png_infop info_ptr,
png_fixed_point int_red_X, png_fixed_point int_red_Y,
png_fixed_point int_red_Z, png_fixed_point int_green_X,
png_fixed_point int_green_Y, png_fixed_point int_green_Z,
png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
png_fixed_point int_blue_Z)
{
png_XYZ XYZ;
png_xy xy;
png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
if (png_ptr == NULL || info_ptr == NULL)
return;
XYZ.redX = int_red_X;
XYZ.redY = int_red_Y;
XYZ.redZ = int_red_Z;
XYZ.greenX = int_green_X;
XYZ.greenY = int_green_Y;
XYZ.greenZ = int_green_Z;
XYZ.blueX = int_blue_X;
XYZ.blueY = int_blue_Y;
XYZ.blueZ = int_blue_Z;
if (png_xy_from_XYZ(&xy, XYZ))
png_error(png_ptr, "XYZ values out of representable range");
png_set_cHRM_fixed(png_ptr, info_ptr, xy.whitex, xy.whitey, xy.redx, xy.redy,
xy.greenx, xy.greeny, xy.bluex, xy.bluey);
}
# ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
@ -80,6 +113,23 @@ png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
png_fixed(png_ptr, blue_x, "cHRM Blue X"),
png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
}
void PNGAPI
png_set_cHRM_XYZ(png_structp png_ptr, png_infop info_ptr, double red_X,
double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
double blue_X, double blue_Y, double blue_Z)
{
png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
png_fixed(png_ptr, red_X, "cHRM Red X"),
png_fixed(png_ptr, red_Y, "cHRM Red Y"),
png_fixed(png_ptr, red_Z, "cHRM Red Z"),
png_fixed(png_ptr, green_X, "cHRM Red X"),
png_fixed(png_ptr, green_Y, "cHRM Red Y"),
png_fixed(png_ptr, green_Z, "cHRM Red Z"),
png_fixed(png_ptr, blue_X, "cHRM Red X"),
png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
}
# endif /* PNG_FLOATING_POINT_SUPPORTED */
#endif /* PNG_cHRM_SUPPORTED */
@ -99,7 +149,7 @@ png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
* possible for 1/gamma to overflow the limit of 21474 and this means the
* gamma value must be at least 5/100000 and hence at most 20000.0. For
* safety the limits here are a little narrower. The values are 0.00016 to
* 6250.0, which are truely ridiculous gammma values (and will produce
* 6250.0, which are truly ridiculous gammma values (and will produce
* displays that are all black or all white.)
*/
if (file_gamma < 16 || file_gamma > 625000000)
@ -552,10 +602,10 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
# ifdef PNG_cHRM_SUPPORTED
png_set_cHRM_fixed(png_ptr, info_ptr,
/* color x y */
/* white */ 31270L, 32900L,
/* red */ 64000L, 33000L,
/* green */ 30000L, 60000L,
/* blue */ 15000L, 6000L
/* white */ 31270, 32900,
/* red */ 64000, 33000,
/* green */ 30000, 60000,
/* blue */ 15000, 6000
);
# endif /* cHRM */
}
@ -570,7 +620,7 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
{
png_charp new_iccp_name;
png_bytep new_iccp_profile;
png_uint_32 length;
png_size_t length;
png_debug1(1, "in %s storage function", "iCCP");
@ -631,9 +681,8 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr,
{
int i;
png_debug1(1, "in %s storage function", ((png_ptr == NULL ||
png_ptr->chunk_name[0] == '\0') ?
"text" : (png_const_charp)png_ptr->chunk_name));
png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
(unsigned long)png_ptr->chunk_name);
if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
return(0);
@ -916,10 +965,10 @@ png_set_sPLT(png_structp png_ptr,
{
png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
png_const_sPLT_tp from = entries + i;
png_uint_32 length;
png_size_t length;
length = png_strlen(from->name) + 1;
to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length);
to->name = (png_charp)png_malloc_warn(png_ptr, length);
if (to->name == NULL)
{
@ -930,7 +979,7 @@ png_set_sPLT(png_structp png_ptr,
png_memcpy(to->name, from->name, length);
to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
(png_size_t)(from->nentries * png_sizeof(png_sPLT_entry)));
from->nentries * png_sizeof(png_sPLT_entry));
if (to->entries == NULL)
{

View File

@ -5,7 +5,7 @@
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* Last changed in libpng 1.5.4 [July 7, 2011]
* Last changed in libpng 1.5.5 [September 22, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@ -104,13 +104,17 @@ struct png_struct_def
png_size_t rowbytes; /* size of row in bytes */
png_uint_32 iwidth; /* width of current interlaced row in pixels */
png_uint_32 row_number; /* current row in interlace pass */
png_bytep prev_row; /* buffer to save previous (unfiltered) row */
png_bytep row_buf; /* buffer to save current (unfiltered) row */
png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
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 up_row; /* buffer to save "up" 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_row_info row_info; /* used for transformation routines */
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 */
@ -118,7 +122,6 @@ struct png_struct_def
png_colorp palette; /* palette from the input file */
png_uint_16 num_palette; /* number of color entries in palette */
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 filter; /* file filter type (always 0) */
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 color_type; /* color type 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 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 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)
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 */
#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 */
png_fixed_point gamma; /* file gamma value */
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_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_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_to_1; /* converts from file to 1.0 */
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
@ -255,13 +266,20 @@ struct png_struct_def
png_bytep chunk_list;
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
/* Added in 1.5.5 to record an sRGB chunk in the png. */
png_byte is_sRGB;
#endif
/* New members added in libpng-1.0.3 */
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
png_byte rgb_to_gray_status;
/* Added in libpng 1.5.5 to record setting of coefficients: */
png_byte rgb_to_gray_coefficients_set;
/* These were changed from png_byte in libpng-1.0.6 */
png_uint_16 rgb_to_gray_red_coeff;
png_uint_16 rgb_to_gray_green_coeff;
png_uint_16 rgb_to_gray_blue_coeff;
/* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
#endif
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
@ -322,9 +340,8 @@ struct png_struct_def
png_unknown_chunk unknown_chunk;
#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_prev_row_size;
/* New member added in libpng-1.2.30 */
png_charp chunkdata; /* buffer for reading chunk data */
@ -333,5 +350,8 @@ struct png_struct_def
/* New member added in libpng-1.4.0 */
png_uint_32 io_state;
#endif
/* New member added in libpng-1.5.6 */
png_bytep big_prev_row;
};
#endif /* PNGSTRUCT_H */

View File

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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
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)
return;
@ -731,36 +734,31 @@ png_write_row(png_structp png_ptr, png_const_bytep row)
#endif
/* Set up row info for transformations */
png_ptr->row_info.color_type = png_ptr->color_type;
png_ptr->row_info.width = png_ptr->usr_width;
png_ptr->row_info.channels = png_ptr->usr_channels;
png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
png_ptr->row_info.channels);
row_info.color_type = png_ptr->color_type;
row_info.width = png_ptr->usr_width;
row_info.channels = png_ptr->usr_channels;
row_info.bit_depth = png_ptr->usr_bit_depth;
row_info.pixel_depth = (png_byte)(row_info.bit_depth * 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_ptr->row_info.width);
png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type);
png_debug1(3, "row_info->width = %u", png_ptr->row_info.width);
png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels);
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);
png_debug1(3, "row_info->color_type = %d", row_info.color_type);
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->bit_depth = %d", row_info.bit_depth);
png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth);
png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes);
/* 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
/* Handle interlacing */
if (png_ptr->interlaced && png_ptr->pass < 6 &&
(png_ptr->transformations & PNG_INTERLACE))
{
png_do_write_interlace(&(png_ptr->row_info),
png_ptr->row_buf + 1, png_ptr->pass);
png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
/* This should always get caught above, but still ... */
if (!(png_ptr->row_info.width))
if (!(row_info.width))
{
png_write_finish_row(png_ptr);
return;
@ -771,9 +769,16 @@ png_write_row(png_structp png_ptr, png_const_bytep row)
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
/* Handle other transformations */
if (png_ptr->transformations)
png_do_write_transformations(png_ptr);
png_do_write_transformations(png_ptr, &row_info);
#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
/* Write filter_method 64 (intrapixel differencing) only if
* 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))
{
/* 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
/* 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)
(*(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");
if (png_ptr_ptr != NULL)
{
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
if (png_ptr != NULL)

View File

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -20,7 +20,7 @@
* transformations is significant.
*/
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");
@ -32,8 +32,8 @@ png_do_write_transformations(png_structp png_ptr)
if (png_ptr->write_user_transform_fn != NULL)
(*(png_ptr->write_user_transform_fn)) /* User write transform
function */
(png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */
(png_ptr, /* png_ptr */
row_info, /* row_info: */
/* png_uint_32 width; width of row */
/* png_size_t rowbytes; number of bytes in row */
/* 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
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));
#endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
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
#ifdef PNG_WRITE_PACK_SUPPORTED
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);
#endif
#ifdef PNG_WRITE_SWAP_SUPPORTED
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
#ifdef PNG_WRITE_SHIFT_SUPPORTED
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));
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
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
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
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
#ifdef PNG_WRITE_BGR_SUPPORTED
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
#ifdef PNG_WRITE_INVERT_SUPPORTED
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
}

View File

@ -1,7 +1,7 @@
/* pngwutil.c - utilities 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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;
}
/* 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.
* The total_length is the sum of the lengths of all the data you will be
* passing in png_write_chunk_data().
*/
void PNGAPI
png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name,
static void
png_write_chunk_header(png_structp png_ptr, png_uint_32 chunk_name,
png_uint_32 length)
{
png_byte buf[8];
png_debug2(0, "Writing %s chunk, length = %lu", chunk_name,
(unsigned long)length);
#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
#endif
if (png_ptr == NULL)
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 */
png_save_uint_32(buf, length);
png_memcpy(buf + 4, chunk_name, 4);
png_write_data(png_ptr, buf, (png_size_t)8);
png_save_uint_32(buf + 4, chunk_name);
png_write_data(png_ptr, buf, 8);
/* 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 */
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
/* 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
}
/* 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
* 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
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
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);
}
/* 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. */
static void
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
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 */
@ -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 interlace_type)
{
PNG_IHDR;
png_byte buf[13]; /* Buffer to store the IHDR info */
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;
/* 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 */
png_ptr->zstream.zalloc = png_zalloc;
@ -872,7 +895,6 @@ void /* PRIVATE */
png_write_PLTE(png_structp png_ptr, png_const_colorp palette,
png_uint_32 num_pal)
{
PNG_PLTE;
png_uint_32 i;
png_const_colorp pal_ptr;
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_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
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 */
png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
{
PNG_IDAT;
png_debug(1, "in png_write_IDAT");
#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 */
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;
/* 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 */
png_write_IEND(png_structp png_ptr)
{
PNG_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;
}
@ -1042,14 +1060,13 @@ png_write_IEND(png_structp png_ptr)
void /* PRIVATE */
png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
{
PNG_gAMA;
png_byte buf[4];
png_debug(1, "in png_write_gAMA");
/* file_gamma is saved in 1/100,000ths */
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
@ -1058,7 +1075,6 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
void /* PRIVATE */
png_write_sRGB(png_structp png_ptr, int srgb_intent)
{
PNG_sRGB;
png_byte buf[1];
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");
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
@ -1078,7 +1094,6 @@ void /* PRIVATE */
png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
png_const_charp profile, int profile_len)
{
PNG_iCCP;
png_size_t name_len;
png_charp new_name;
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);
/* 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));
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 */
png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
{
PNG_sPLT;
png_size_t name_len;
png_charp new_name;
png_byte entrybuf[10];
@ -1180,7 +1194,7 @@ png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette)
return;
/* 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_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 */
png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type)
{
PNG_sBIT;
png_byte buf[4];
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;
}
png_write_chunk(png_ptr, png_sBIT, buf, size);
png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
}
#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 blue_y)
{
PNG_cHRM;
png_byte buf[32];
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 + 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
@ -1345,7 +1357,6 @@ void /* PRIVATE */
png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
png_const_color_16p tran, int num_trans, int color_type)
{
PNG_tRNS;
png_byte buf[6];
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 */
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)
@ -1374,7 +1385,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
}
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)
@ -1394,7 +1405,7 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
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
@ -1409,7 +1420,6 @@ png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha,
void /* PRIVATE */
png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
{
PNG_bKGD;
png_byte buf[6];
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;
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)
@ -1448,7 +1458,7 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
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
@ -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_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
@ -1472,7 +1482,6 @@ png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type)
void /* PRIVATE */
png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
{
PNG_hIST;
int i;
png_byte buf[3];
@ -1487,7 +1496,7 @@ png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist)
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++)
{
@ -1637,7 +1646,6 @@ void /* PRIVATE */
png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
png_size_t text_len)
{
PNG_tEXt;
png_size_t key_len;
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);
/* 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));
/*
* 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_size_t text_len, int compression)
{
PNG_zTXt;
png_size_t key_len;
png_byte buf;
png_charp new_key;
@ -1713,7 +1720,7 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
&comp);
/* 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));
/* Write key */
@ -1742,7 +1749,6 @@ void /* PRIVATE */
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_iTXt;
png_size_t lang_len, key_len, lang_key_len, text_len;
png_charp new_lang;
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
*/
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 */
+ key_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,
int unit_type)
{
PNG_oFFs;
png_byte buf[9];
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);
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
#ifdef PNG_WRITE_pCAL_SUPPORTED
@ -1858,9 +1863,8 @@ 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_charpp params)
{
PNG_pCAL;
png_size_t purpose_len, units_len, total_len;
png_uint_32p params_len;
png_size_tp params_len;
png_byte buf[10];
png_charp new_purpose;
int i;
@ -1876,8 +1880,8 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
png_debug1(3, "pCAL units length = %d", (int)units_len);
total_len = purpose_len + units_len + 10;
params_len = (png_uint_32p)png_malloc(png_ptr,
(png_alloc_size_t)(nparams * png_sizeof(png_uint_32)));
params_len = (png_size_tp)png_malloc(png_ptr,
(png_alloc_size_t)(nparams * png_sizeof(png_size_t)));
/* Find the length of each parameter, making sure we don't count the
* null terminator for the last parameter.
@ -1887,13 +1891,12 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
png_debug2(3, "pCAL parameter %d length = %lu", i,
(unsigned long)params_len[i]);
total_len += (png_size_t)params_len[i];
total_len += params_len[i];
}
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_data(png_ptr, (png_const_bytep)new_purpose,
(png_size_t)purpose_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_save_int_32(buf, X0);
png_save_int_32(buf + 4, X1);
buf[8] = (png_byte)type;
@ -1905,8 +1908,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
for (i = 0; i < nparams; i++)
{
png_write_chunk_data(png_ptr, (png_const_bytep)params[i],
(png_size_t)params_len[i]);
png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
}
png_free(png_ptr, params_len);
@ -1920,7 +1922,6 @@ void /* PRIVATE */
png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width,
png_const_charp height)
{
PNG_sCAL;
png_byte buf[64];
png_size_t wlen, hlen, total_len;
@ -1941,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_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
@ -1952,7 +1953,6 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
png_uint_32 y_pixels_per_unit,
int unit_type)
{
PNG_pHYs;
png_byte buf[9];
png_debug(1, "in png_write_pHYs");
@ -1964,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);
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
@ -1975,7 +1975,6 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
void /* PRIVATE */
png_write_tIME(png_structp png_ptr, png_const_timep mod_time)
{
PNG_tIME;
png_byte buf[7];
png_debug(1, "in png_write_tIME");
@ -1995,7 +1994,7 @@ png_write_tIME(png_structp png_ptr, png_const_timep mod_time)
buf[5] = mod_time->minute;
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
@ -2007,28 +2006,32 @@ png_write_start_row(png_structp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* 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 */
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 */
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 */
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
png_size_t buf_size;
png_alloc_size_t buf_size;
int usr_pixel_depth;
png_debug(1, "in png_write_start_row");
buf_size = (png_size_t)(PNG_ROWBYTES(
png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1);
usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
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 */
png_ptr->row_buf = (png_bytep)png_malloc(png_ptr,
(png_alloc_size_t)buf_size);
png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
@ -2045,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))
{
/* Set up previous row buffer */
png_ptr->prev_row = (png_bytep)png_calloc(png_ptr,
(png_alloc_size_t)buf_size);
png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
if (png_ptr->do_filter & PNG_FILTER_UP)
{
@ -2114,16 +2116,16 @@ png_write_finish_row(png_structp png_ptr)
/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
/* 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 */
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 */
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 */
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
int ret;
@ -2241,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 */
/* 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 */
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");
@ -2412,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
* 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_HISHIFT 10
@ -2428,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_size_t row_bytes = row_info->rowbytes;
#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
png_debug(1, "in png_write_find_filter");
@ -3065,9 +3068,9 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info)
}
}
#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_WEIGHTED_FILTER_SUPPORTED
@ -3090,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. */
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_debug1(2, "filter = %d", filtered_row[0]);
@ -3101,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.avail_in = 0;
avail = png_ptr->row_info.rowbytes + 1;
/* Repeat until we have compressed all the data */
do
{