[CHG] libpng updated to version 1.5.5

This commit is contained in:
Crayon2000 2011-09-27 15:44:18 +00:00
parent 23be825469
commit 4aaf39c61f
10 changed files with 1086 additions and 413 deletions

View file

@ -1,7 +1,7 @@
/* png.c - location for general purpose libpng functions /* png.c - location for general purpose libpng functions
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -14,7 +14,7 @@
#include "pngpriv.h" #include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */ /* Generate a compiler error if there is an old png.h in the search path. */
typedef png_libpng_version_1_5_4 Your_png_h_is_not_version_1_5_4; typedef png_libpng_version_1_5_5 Your_png_h_is_not_version_1_5_5;
/* Tells libpng that we have already handled the first "num_bytes" bytes /* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another * of the PNG file signature. If the PNG data is embedded into another
@ -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 * can simply check the remaining bytes for extra assurance. Returns
* an integer less than, equal to, or greater than zero if sig is found, * 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 * 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 int PNGAPI
png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) 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 */ void /* PRIVATE */
png_reset_crc(png_structp png_ptr) 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 /* Calculate the CRC over a section of data. We can only pass as
@ -133,8 +134,35 @@ png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length)
need_crc = 0; need_crc = 0;
} }
if (need_crc) /* 'uLong' is defined as unsigned long, this means that on some systems it is
png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length); * 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 /* 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 /* 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() * 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 * 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 * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
* necessarily available. * function of your own because "FILE *" isn't necessarily available.
*/ */
void PNGAPI void PNGAPI
png_init_io(png_structp png_ptr, png_FILE_p fp) png_init_io(png_structp png_ptr, png_FILE_p fp)
@ -617,13 +645,13 @@ png_get_copyright(png_const_structp png_ptr)
#else #else
# ifdef __STDC__ # ifdef __STDC__
return PNG_STRING_NEWLINE \ return PNG_STRING_NEWLINE \
"libpng version 1.5.4 - July 7, 2011" PNG_STRING_NEWLINE \ "libpng version 1.5.5 - September 22, 2011" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE; PNG_STRING_NEWLINE;
# else # else
return "libpng version 1.5.4 - July 7, 2011\ return "libpng version 1.5.5 - September 22, 2011\
Copyright (c) 1998-2011 Glenn Randers-Pehrson\ Copyright (c) 1998-2011 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@ -713,18 +741,9 @@ png_access_version_number(void)
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
# ifdef PNG_SIZE_T /* png_convert_size: a PNGAPI but no longer in png.h, so deleted
/* Added at libpng version 1.2.6 */ * at libpng 1.5.5!
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 */
/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
# ifdef PNG_CHECK_cHRM_SUPPORTED # ifdef PNG_CHECK_cHRM_SUPPORTED
@ -798,6 +817,326 @@ png_check_cHRM_fixed(png_structp png_ptr,
} }
# endif /* PNG_CHECK_cHRM_SUPPORTED */ # 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 */ void /* PRIVATE */
png_check_IHDR(png_structp png_ptr, png_check_IHDR(png_structp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth, png_uint_32 width, png_uint_32 height, int bit_depth,
@ -1383,18 +1722,30 @@ png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size,
size -= cdigits; size -= cdigits;
*ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ *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; /* The following use of an unsigned temporary avoids ambiguities in
* the signed arithmetic on exp_b10 and permits GCC at least to do
while (exp_b10 > 0) * better optimization.
*/
{ {
exponent[cdigits++] = (char)(48 + exp_b10 % 10); unsigned int uexp_b10;
exp_b10 /= 10;
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 /* Need another size check here for the exponent digits, so
@ -1452,7 +1803,7 @@ png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size,
else else
num = fp; num = fp;
if (num <= 0x80000000U) /* else overflowed */ if (num <= 0x80000000) /* else overflowed */
{ {
unsigned int ndigits = 0, first = 16 /* flag value */; unsigned int ndigits = 0, first = 16 /* flag value */;
char digits[10]; char digits[10];

View file

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library /* png.h - header file for PNG reference library
* *
* libpng version 1.5.4 - July 7, 2011 * libpng version 1.5.5 - September 22, 2011
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -11,7 +11,7 @@
* Authors and maintainers: * Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.5.4 - July 7, 2011: Glenn * libpng versions 0.97, January 1998, through 1.5.5 - September 22, 2011: Glenn
* See also "Contributing Authors", below. * See also "Contributing Authors", below.
* *
* Note about libpng version numbers: * Note about libpng version numbers:
@ -157,6 +157,9 @@
* 1.5.4beta01-08 15 10504 15.so.15.4[.0] * 1.5.4beta01-08 15 10504 15.so.15.4[.0]
* 1.5.4rc01 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.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]
* *
* Henceforth the source version will match the shared-library major * Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be * and minor numbers; the shared-library major version number will be
@ -188,7 +191,7 @@
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* *
* libpng versions 1.2.6, August 15, 2004, through 1.5.4, July 7, 2011, are * libpng versions 1.2.6, August 15, 2004, through 1.5.5, September 22, 2011, are
* Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are * Copyright (c) 2004, 2006-2011 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5 * distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors: * with the following individual added to the list of Contributing Authors:
@ -300,13 +303,13 @@
* Y2K compliance in libpng: * Y2K compliance in libpng:
* ========================= * =========================
* *
* July 7, 2011 * September 22, 2011
* *
* Since the PNG Development group is an ad-hoc body, we can't make * Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration. * an official declaration.
* *
* This is your unofficial assurance that libpng from version 0.71 and * This is your unofficial assurance that libpng from version 0.71 and
* upward through 1.5.4 are Y2K compliant. It is my belief that * upward through 1.5.5 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant. * earlier versions were also Y2K compliant.
* *
* Libpng only has two year fields. One is a 2-byte unsigned integer * Libpng only has two year fields. One is a 2-byte unsigned integer
@ -361,9 +364,9 @@
*/ */
/* Version information for png.h - this should match the version in png.c */ /* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.5.4" #define PNG_LIBPNG_VER_STRING "1.5.5"
#define PNG_HEADER_VERSION_STRING \ #define PNG_HEADER_VERSION_STRING \
" libpng version 1.5.4 - July 7, 2011\n" " libpng version 1.5.5 - September 22, 2011\n"
#define PNG_LIBPNG_VER_SONUM 15 #define PNG_LIBPNG_VER_SONUM 15
#define PNG_LIBPNG_VER_DLLNUM 15 #define PNG_LIBPNG_VER_DLLNUM 15
@ -371,7 +374,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 5 #define PNG_LIBPNG_VER_MINOR 5
#define PNG_LIBPNG_VER_RELEASE 4 #define PNG_LIBPNG_VER_RELEASE 5
/* This should match the numeric part of the final component of /* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero: * PNG_LIBPNG_VER_STRING, omitting any leading zero:
*/ */
@ -401,7 +404,7 @@
* version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/ */
#define PNG_LIBPNG_VER 10504 /* 1.5.4 */ #define PNG_LIBPNG_VER 10505 /* 1.5.5 */
/* Library configuration: these options cannot be changed after /* Library configuration: these options cannot be changed after
* the library has been built. * the library has been built.
@ -523,7 +526,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h /* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number. * do not agree upon the version number.
*/ */
typedef char* png_libpng_version_1_5_4; typedef char* png_libpng_version_1_5_5;
/* Three color definitions. The order of the red, green, and blue, (and the /* Three color definitions. The order of the red, green, and blue, (and the
* exact size) is not important, although the size of the fields need to * exact size) is not important, although the size of the fields need to
@ -793,7 +796,7 @@ typedef png_info FAR * FAR * png_infopp;
#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ #define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
#define PNG_INFO_sPLT 0x2000 /* 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_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 /* This is used for the transformation routines, as some of them
* change these values for the row. It also should enable using * change these values for the row. It also should enable using
@ -2047,6 +2050,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, 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 *red_y, double *green_x, double *green_y, double *blue_x,
double *blue_y)); 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 */ #ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */
PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
(png_const_structp png_ptr, (png_const_structp png_ptr,
@ -2056,6 +2063,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_green_y, png_fixed_point *int_blue_x,
png_fixed_point *int_blue_y)); png_fixed_point *int_blue_y));
#endif #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 #endif
#ifdef PNG_cHRM_SUPPORTED #ifdef PNG_cHRM_SUPPORTED
@ -2063,12 +2077,22 @@ PNG_FP_EXPORT(135, void, png_set_cHRM,
(png_structp png_ptr, png_infop info_ptr, (png_structp png_ptr, png_infop info_ptr,
double white_x, double white_y, double red_x, double red_y, double green_x, double white_x, double white_y, double red_x, double red_y, double green_x,
double green_y, double blue_x, double blue_y)); 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_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr,
png_infop info_ptr, png_fixed_point int_white_x, 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_white_y, png_fixed_point int_red_x,
png_fixed_point int_red_y, png_fixed_point int_green_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_green_y, png_fixed_point int_blue_x,
png_fixed_point int_blue_y)); 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 #endif
#ifdef PNG_gAMA_SUPPORTED #ifdef PNG_gAMA_SUPPORTED
@ -2282,7 +2306,7 @@ PNG_EXPORT(171, void, png_set_sCAL_s,
handling or default unknown chunk handling is not desired. Any chunks not handling or default unknown chunk handling is not desired. Any chunks not
listed will be handled in the default manner. The IHDR and IEND chunks listed will be handled in the default manner. The IHDR and IEND chunks
must not be listed. must not be listed.
keep = 0: follow default behaviour keep = 0: follow default behavior
= 1: do not keep = 1: do not keep
= 2: keep only if safe-to-copy = 2: keep only if safe-to-copy
= 3: keep even if unsafe-to-copy = 3: keep even if unsafe-to-copy
@ -2492,14 +2516,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 temp = (png_uint_16)((png_uint_16)(fg) \
* (png_uint_16)(alpha) \ * (png_uint_16)(alpha) \
+ (png_uint_16)(bg)*(png_uint_16)(255 \ + (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); } (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
# define png_composite_16(composite, fg, alpha, bg) \ # define png_composite_16(composite, fg, alpha, bg) \
{ png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
* (png_uint_32)(alpha) \ * (png_uint_32)(alpha) \
+ (png_uint_32)(bg)*(png_uint_32)(65535L \ + (png_uint_32)(bg)*(65535 \
- (png_uint_32)(alpha)) + (png_uint_32)32768L); \ - (png_uint_32)(alpha)) + 32768); \
(composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
#else /* Standard method using integer division */ #else /* Standard method using integer division */
@ -2507,12 +2531,12 @@ PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
# define png_composite(composite, fg, alpha, bg) \ # define png_composite(composite, fg, alpha, bg) \
(composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ (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)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
(png_uint_16)127) / 255) 127) / 255)
# define png_composite_16(composite, fg, alpha, bg) \ # define png_composite_16(composite, fg, alpha, bg) \
(composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ (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)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
(png_uint_32)32767) / (png_uint_32)65535L) 32767) / 65535)
#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ #endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
@ -2576,7 +2600,7 @@ PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
* scripts/symbols.def as well. * scripts/symbols.def as well.
*/ */
#ifdef PNG_EXPORT_LAST_ORDINAL #ifdef PNG_EXPORT_LAST_ORDINAL
PNG_EXPORT_LAST_ORDINAL(229); PNG_EXPORT_LAST_ORDINAL(233);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View file

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

View file

@ -1,7 +1,7 @@
/* pngget.c - retrieval of values from info struct /* pngget.c - retrieval of values from info struct
* *
* Last changed in libpng 1.5.1 [February 3, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -459,6 +459,65 @@ png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr,
#endif #endif
#ifdef PNG_cHRM_SUPPORTED #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 # ifdef PNG_FLOATING_POINT_SUPPORTED
png_uint_32 PNGAPI png_uint_32 PNGAPI
png_get_cHRM(png_const_structp png_ptr, png_const_infop info_ptr, 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); 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 # endif
# ifdef PNG_FIXED_POINT_SUPPORTED # ifdef PNG_FIXED_POINT_SUPPORTED
@ -971,7 +1066,7 @@ png_get_user_chunk_ptr(png_const_structp png_ptr)
png_size_t PNGAPI png_size_t PNGAPI
png_get_compression_buffer_size(png_const_structp png_ptr) 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);
} }

View file

@ -6,7 +6,7 @@
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -44,7 +44,8 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#define PNGLIB_BUILD #define PNGLIB_BUILD /*libpng is being built, not used*/
#ifdef PNG_USER_CONFIG #ifdef PNG_USER_CONFIG
# include "pngusr.h" # include "pngusr.h"
/* These should have been defined in pngusr.h */ /* These should have been defined in pngusr.h */
@ -55,10 +56,80 @@
# define PNG_USER_DLLFNAME_POSTFIX "Cb" # define PNG_USER_DLLFNAME_POSTFIX "Cb"
# endif # endif
#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 "png.h"
#include "pnginfo.h" #include "pnginfo.h"
#include "pngstruct.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 is used for 16 bit gamma tables - only the top level pointers are const,
* this could be changed: * this could be changed:
*/ */
@ -293,24 +364,23 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
#define PNG_EXPAND 0x1000 #define PNG_EXPAND 0x1000
#define PNG_GAMMA 0x2000 #define PNG_GAMMA 0x2000
#define PNG_GRAY_TO_RGB 0x4000 #define PNG_GRAY_TO_RGB 0x4000
#define PNG_FILLER 0x8000L #define PNG_FILLER 0x8000
#define PNG_PACKSWAP 0x10000L #define PNG_PACKSWAP 0x10000
#define PNG_SWAP_ALPHA 0x20000L #define PNG_SWAP_ALPHA 0x20000
#define PNG_STRIP_ALPHA 0x40000L #define PNG_STRIP_ALPHA 0x40000
#define PNG_INVERT_ALPHA 0x80000L #define PNG_INVERT_ALPHA 0x80000
#define PNG_USER_TRANSFORM 0x100000L #define PNG_USER_TRANSFORM 0x100000
#define PNG_RGB_TO_GRAY_ERR 0x200000L #define PNG_RGB_TO_GRAY_ERR 0x200000
#define PNG_RGB_TO_GRAY_WARN 0x400000L #define PNG_RGB_TO_GRAY_WARN 0x400000
#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ #define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
#define PNG_ENCODE_ALPHA 0x800000L /* Added to libpng-1.5.4 */ #define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */
#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ #define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */
#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ #define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */
#define PNG_SCALE_16_TO_8 0x4000000L /* Added to libpng-1.5.4 */ #define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */
/* 0x8000000L unused */ /* 0x8000000 unused */
/* 0x10000000L unused */ /* 0x10000000 unused */
/* 0x20000000L unused */ /* 0x20000000 unused */
/* 0x40000000L unused */ /* 0x40000000 unused */
/* Flags for png_create_struct */ /* Flags for png_create_struct */
#define PNG_STRUCT_PNG 0x0001 #define PNG_STRUCT_PNG 0x0001
#define PNG_STRUCT_INFO 0x0002 #define PNG_STRUCT_INFO 0x0002
@ -335,22 +405,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_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */
#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* 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_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */
#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000
#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000
#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L #define PNG_FLAG_LIBRARY_MISMATCH 0x20000
#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L #define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000
#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000
#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L #define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000
/* 0x200000L unused */ /* 0x200000 unused */
/* 0x400000L unused */ /* 0x400000 unused */
#define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000L /* Added to libpng-1.4.0 */ #define PNG_FLAG_BENIGN_ERRORS_WARN 0x800000 /* Added to libpng-1.4.0 */
#define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000L /* 5 lines added */ #define PNG_FLAG_ZTXT_CUSTOM_STRATEGY 0x1000000 /* 5 lines added */
#define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000L /* to libpng-1.5.4 */ #define PNG_FLAG_ZTXT_CUSTOM_LEVEL 0x2000000 /* to libpng-1.5.4 */
#define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000L #define PNG_FLAG_ZTXT_CUSTOM_MEM_LEVEL 0x4000000
#define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000L #define PNG_FLAG_ZTXT_CUSTOM_WINDOW_BITS 0x8000000
#define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000L #define PNG_FLAG_ZTXT_CUSTOM_METHOD 0x10000000
/* 0x20000000L unused */ /* 0x20000000 unused */
/* 0x40000000L unused */ /* 0x40000000 unused */
#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
PNG_FLAG_CRC_ANCILLARY_NOWARN) PNG_FLAG_CRC_ANCILLARY_NOWARN)
@ -1078,6 +1148,35 @@ PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2,
unsigned long *hi_product, unsigned long *lo_product)); unsigned long *hi_product, unsigned long *lo_product));
#endif #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 */ /* Added at libpng version 1.4.0 */
PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth, png_uint_32 width, png_uint_32 height, int bit_depth,

View file

@ -1,7 +1,7 @@
/* pngrtran.c - transforms the data in a row for PNG readers /* pngrtran.c - transforms the data in a row for PNG readers
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -968,13 +968,17 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
{ {
png_uint_16 red_int, green_int; png_uint_16 red_int, green_int;
red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); /* NOTE: this calculation does not round, but this behavior is retained
green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); * for consistency, the inaccuracy is very small. The code here always
* overwrites the coefficients, regardless of whether they have been
* defaulted or set already.
*/
red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
png_ptr->rgb_to_gray_red_coeff = red_int; png_ptr->rgb_to_gray_red_coeff = red_int;
png_ptr->rgb_to_gray_green_coeff = green_int; png_ptr->rgb_to_gray_green_coeff = green_int;
png_ptr->rgb_to_gray_blue_coeff = png_ptr->rgb_to_gray_coefficients_set = 1;
(png_uint_16)(32768 - red_int - green_int);
} }
else else
@ -983,17 +987,18 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
png_warning(png_ptr, png_warning(png_ptr,
"ignoring out of range rgb_to_gray coefficients"); "ignoring out of range rgb_to_gray coefficients");
/* Use the defaults, from the cHRM chunk if set, else the built in Rec /* Use the defaults, from the cHRM chunk if set, else the historical
* 709 values (which correspond to sRGB, so we don't have to worry * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
* about the sRGB chunk!) * png_do_rgb_to_gray for more discussion of the values. In this case
* the coefficients are not marked as 'set' and are not overwritten if
* something has already provided a default.
*/ */
if (png_ptr->rgb_to_gray_red_coeff == 0 && if (png_ptr->rgb_to_gray_red_coeff == 0 &&
png_ptr->rgb_to_gray_green_coeff == 0 && png_ptr->rgb_to_gray_green_coeff == 0)
png_ptr->rgb_to_gray_blue_coeff == 0)
{ {
png_ptr->rgb_to_gray_red_coeff = 6968; /* .212671 * 32768 + .5 */ png_ptr->rgb_to_gray_red_coeff = 6968;
png_ptr->rgb_to_gray_green_coeff = 23434; /* .715160 * 32768 + .5 */ png_ptr->rgb_to_gray_green_coeff = 23434;
png_ptr->rgb_to_gray_blue_coeff = 2366; /* png_ptr->rgb_to_gray_blue_coeff = 2366; */
} }
} }
} }
@ -1401,7 +1406,7 @@ png_init_read_transformations(png_structp png_ptr)
if (png_ptr->transformations & PNG_BACKGROUND_EXPAND) if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
{ {
/* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
* the file was greyscale the background value is gray. * the file was grayscale the background value is gray.
*/ */
if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
@ -1635,7 +1640,7 @@ png_init_read_transformations(png_structp png_ptr)
/* Prevent the transformations being done again. /* Prevent the transformations being done again.
* *
* NOTE: this is highly dubious; it zaps the transformations in * NOTE: this is highly dubious; it removes the transformations in
* place. This seems inconsistent with the general treatment of the * place. This seems inconsistent with the general treatment of the
* transformations elsewhere. * transformations elsewhere.
*/ */
@ -3066,33 +3071,61 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
/* Reduce RGB files to grayscale, with or without alpha /* Reduce RGB files to grayscale, with or without alpha
* using the equation given in Poynton's ColorFAQ at * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
* <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008) * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but
* New link: * versions dated 1998 through November 2002 have been archived at
* <http://www.poynton.com/notes/colour_and_gamma/> * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
* ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
* Charles Poynton poynton at poynton.com * Charles Poynton poynton at poynton.com
* *
* Y = 0.212671 * R + 0.715160 * G + 0.072169 * B * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
* *
* We approximate this with
*
* Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
*
* which can be expressed with integers as * which can be expressed with integers as
* *
* Y = (6969 * R + 23434 * G + 2365 * B)/32768 * Y = (6969 * R + 23434 * G + 2365 * B)/32768
* *
* The calculation is to be done in a linear colorspace. * Poynton's current link (as of January 2003 through July 2011):
* <http://www.poynton.com/notes/colour_and_gamma/>
* has changed the numbers slightly:
* *
* Other integer coefficents can be used via png_set_rgb_to_gray(). * Y = 0.2126*R + 0.7152*G + 0.0722*B
*
* which can be expressed with integers as
*
* Y = (6966 * R + 23436 * G + 2366 * B)/32768
*
* Historically, however, libpng uses numbers derived from the ITU-R Rec 709
* end point chromaticities and the D65 white point. Depending on the
* precision used for the D65 white point this produces a variety of different
* numbers, however if the four decimal place value used in ITU-R Rec 709 is
* used (0.3127,0.3290) the Y calculation would be:
*
* Y = (6968 * R + 23435 * G + 2366 * B)/32768
*
* While this is correct the rounding results in an overflow for white, because
* the sum of the rounded coefficients is 32769, not 32768. Consequently
* libpng uses, instead, the closest non-overflowing approximation:
*
* Y = (6968 * R + 23434 * G + 2366 * B)/32768
*
* Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
* (including an sRGB chunk) then the chromaticities are used to calculate the
* coefficients. See the chunk handling in pngrutil.c for more information.
*
* In all cases the calculation is to be done in a linear colorspace. If no
* gamma information is available to correct the encoding of the original RGB
* values this results in an implicit assumption that the original PNG RGB
* values were linear.
*
* Other integer coefficents can be used via png_set_rgb_to_gray(). Because
* the API takes just red and green coefficients the blue coefficient is
* calculated to make the sum 32768. This will result in different rounding
* to that used above.
*/ */
int /* PRIVATE */ int /* PRIVATE */
png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
{ {
png_uint_32 i;
png_uint_32 row_width = row_info->width;
int rgb_error = 0; int rgb_error = 0;
png_debug(1, "in png_do_rgb_to_gray"); png_debug(1, "in png_do_rgb_to_gray");
@ -3100,234 +3133,179 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) && if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&
(row_info->color_type & PNG_COLOR_MASK_COLOR)) (row_info->color_type & PNG_COLOR_MASK_COLOR))
{ {
png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff; PNG_CONST png_uint_32 bc = 32768 - rc - gc;
PNG_CONST png_uint_32 row_width = row_info->width;
PNG_CONST int have_alpha =
(row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
if (row_info->color_type == PNG_COLOR_TYPE_RGB) if (row_info->bit_depth == 8)
{ {
if (row_info->bit_depth == 8)
{
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) /* Notice that gamma to/from 1 are not necessarily inverses (if
* there is an overall gamma correction). Prior to 1.5.5 this code
* checked the linearized values for equality; this doesn't match
* the documentation, the original values must be checked.
*/
if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
{
png_bytep sp = row;
png_bytep dp = row;
png_uint_32 i;
for (i = 0; i < row_width; i++)
{ {
png_bytep sp = row; png_byte red = *(sp++);
png_bytep dp = row; png_byte green = *(sp++);
png_byte blue = *(sp++);
for (i = 0; i < row_width; i++) if (red != green || red != blue)
{ {
png_byte red = png_ptr->gamma_to_1[*(sp++)]; red = png_ptr->gamma_to_1[red];
png_byte green = png_ptr->gamma_to_1[*(sp++)]; green = png_ptr->gamma_to_1[green];
png_byte blue = png_ptr->gamma_to_1[*(sp++)]; blue = png_ptr->gamma_to_1[blue];
if (red != green || red != blue) rgb_error |= 1;
{ *(dp++) = png_ptr->gamma_from_1[
rgb_error |= 1; (rc*red + gc*green + bc*blue + 16384)>>15];
*(dp++) = png_ptr->gamma_from_1[
(rc*red + gc*green + bc*blue)>>15];
}
else
*(dp++) = *(sp - 1);
} }
}
else else
#endif
{
png_bytep sp = row;
png_bytep dp = row;
for (i = 0; i < row_width; i++)
{ {
png_byte red = *(sp++); /* If there is no overall correction the table will not be
png_byte green = *(sp++); * set.
png_byte blue = *(sp++); */
if (png_ptr->gamma_table != NULL)
red = png_ptr->gamma_table[red];
if (red != green || red != blue) *(dp++) = red;
{
rgb_error |= 1;
*(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
}
else
*(dp++) = *(sp - 1);
} }
if (have_alpha)
*(dp++) = *(sp++);
} }
} }
else
else /* RGB bit_depth == 16 */ #endif
{ {
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytep sp = row;
if (png_ptr->gamma_16_to_1 != NULL && png_bytep dp = row;
png_ptr->gamma_16_from_1 != NULL) png_uint_32 i;
for (i = 0; i < row_width; i++)
{ {
png_bytep sp = row; png_byte red = *(sp++);
png_bytep dp = row; png_byte green = *(sp++);
for (i = 0; i < row_width; i++) png_byte blue = *(sp++);
if (red != green || red != blue)
{ {
png_uint_16 red, green, blue, w; rgb_error |= 1;
/*NOTE: this is the historical approach which simply
* truncates the results.
*/
*(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
}
red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; else
green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; *(dp++) = red;
blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
if (red == green && red == blue) if (have_alpha)
w = red; *(dp++) = *(sp++);
}
}
}
else else /* RGB bit_depth == 16 */
{ {
png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
{
png_bytep sp = row;
png_bytep dp = row;
png_uint_32 i;
for (i = 0; i < row_width; i++)
{
png_uint_16 red, green, blue, w;
red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
if (red == green && red == blue)
{
if (png_ptr->gamma_16_table != NULL)
w = png_ptr->gamma_16_table[(red&0xff)
>> png_ptr->gamma_shift][red>>8]; >> png_ptr->gamma_shift][red>>8];
png_uint_16 green_1 =
png_ptr->gamma_16_to_1[(green&0xff) >>
png_ptr->gamma_shift][green>>8];
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff)
>> png_ptr->gamma_shift][blue>>8];
png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ bc*blue_1)>>15);
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
png_ptr->gamma_shift][gray16 >> 8];
rgb_error |= 1;
}
*(dp++) = (png_byte)((w>>8) & 0xff);
*(dp++) = (png_byte)(w & 0xff);
}
}
else
#endif
{
png_bytep sp = row;
png_bytep dp = row;
for (i = 0; i < row_width; i++)
{
png_uint_16 red, green, blue, gray16;
red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
if (red != green || red != blue)
rgb_error |= 1;
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
*(dp++) = (png_byte)((gray16>>8) & 0xff);
*(dp++) = (png_byte)(gray16 & 0xff);
}
}
}
}
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
if (row_info->bit_depth == 8)
{
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
{
png_bytep sp = row;
png_bytep dp = row;
for (i = 0; i < row_width; i++)
{
png_byte red = png_ptr->gamma_to_1[*(sp++)];
png_byte green = png_ptr->gamma_to_1[*(sp++)];
png_byte blue = png_ptr->gamma_to_1[*(sp++)];
if (red != green || red != blue)
rgb_error |= 1;
*(dp++) = png_ptr->gamma_from_1
[(rc*red + gc*green + bc*blue)>>15];
*(dp++) = *(sp++); /* alpha */
}
}
else
#endif
{
png_bytep sp = row;
png_bytep dp = row;
for (i = 0; i < row_width; i++)
{
png_byte red = *(sp++);
png_byte green = *(sp++);
png_byte blue = *(sp++);
if (red != green || red != blue)
rgb_error |= 1;
*(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
*(dp++) = *(sp++); /* alpha */
}
}
}
else /* RGBA bit_depth == 16 */
{
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
if (png_ptr->gamma_16_to_1 != NULL &&
png_ptr->gamma_16_from_1 != NULL)
{
png_bytep sp = row;
png_bytep dp = row;
for (i = 0; i < row_width; i++)
{
png_uint_16 red, green, blue, w;
red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
if (red == green && red == blue)
w = red;
else else
{ w = red;
png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> }
png_ptr->gamma_shift][red>>8];
png_uint_16 green_1 = else
png_ptr->gamma_16_to_1[(green&0xff) >> {
png_ptr->gamma_shift][green>>8]; png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff)
>> png_ptr->gamma_shift][red>>8];
png_uint_16 green_1 =
png_ptr->gamma_16_to_1[(green&0xff) >>
png_ptr->gamma_shift][green>>8];
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff)
>> png_ptr->gamma_shift][blue>>8];
png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ bc*blue_1 + 16384)>>15);
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
png_ptr->gamma_shift][gray16 >> 8];
rgb_error |= 1;
}
png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> *(dp++) = (png_byte)((w>>8) & 0xff);
png_ptr->gamma_shift][blue>>8]; *(dp++) = (png_byte)(w & 0xff);
png_uint_16 gray16 = (png_uint_16)((rc * red_1 if (have_alpha)
+ gc * green_1 + bc * blue_1)>>15); {
*(dp++) = *(sp++);
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
png_ptr->gamma_shift][gray16 >> 8];
rgb_error |= 1;
}
*(dp++) = (png_byte)((w>>8) & 0xff);
*(dp++) = (png_byte)(w & 0xff);
*(dp++) = *(sp++); /* alpha */
*(dp++) = *(sp++); *(dp++) = *(sp++);
} }
} }
else }
else
#endif #endif
{
png_bytep sp = row;
png_bytep dp = row;
png_uint_32 i;
for (i = 0; i < row_width; i++)
{ {
png_bytep sp = row; png_uint_16 red, green, blue, gray16;
png_bytep dp = row;
for (i = 0; i < row_width; i++) red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
if (red != green || red != blue)
rgb_error |= 1;
/* From 1.5.5 in the 16 bit case do the accurate convertion even
* in the 'fast' case - this is because this is where the code
* ends up when handling linear 16 bit data.
*/
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
15);
*(dp++) = (png_byte)((gray16>>8) & 0xff);
*(dp++) = (png_byte)(gray16 & 0xff);
if (have_alpha)
{ {
png_uint_16 red, green, blue, gray16; *(dp++) = *(sp++);
red = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2;
green = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2;
blue = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2;
if (red != green || red != blue)
rgb_error |= 1;
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
*(dp++) = (png_byte)((gray16>>8) & 0xff);
*(dp++) = (png_byte)(gray16 & 0xff);
*(dp++) = *(sp++); /* alpha */
*(dp++) = *(sp++); *(dp++) = *(sp++);
} }
} }
} }
} }
row_info->channels -= 2; row_info->channels -= 2;
row_info->color_type = (png_byte)(row_info->color_type & row_info->color_type = (png_byte)(row_info->color_type &
~PNG_COLOR_MASK_COLOR); ~PNG_COLOR_MASK_COLOR);
@ -4762,7 +4740,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
#endif #endif
#ifdef PNG_READ_EXPAND_16_SUPPORTED #ifdef PNG_READ_EXPAND_16_SUPPORTED
/* If the bit depth is 8 and the colour type is not a palette type expand the /* If the bit depth is 8 and the color type is not a palette type expand the
* whole row to 16 bits. Has no effect otherwise. * whole row to 16 bits. Has no effect otherwise.
*/ */
void /* PRIVATE */ void /* PRIVATE */
@ -4939,8 +4917,8 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL); png_uint_32 red = (s0 + s1 + 65536) & 0xffff;
png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL); png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
*(rp ) = (png_byte)((red >> 8) & 0xff); *(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp + 1) = (png_byte)(red & 0xff); *(rp + 1) = (png_byte)(red & 0xff);
*(rp + 4) = (png_byte)((blue >> 8) & 0xff); *(rp + 4) = (png_byte)((blue >> 8) & 0xff);

View file

@ -1,7 +1,7 @@
/* pngrutil.c - utilities to read a PNG file /* pngrutil.c - utilities to read a PNG file
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -87,10 +87,10 @@ png_int_32 (PNGAPI
png_get_int_32)(png_const_bytep buf) png_get_int_32)(png_const_bytep buf)
{ {
png_uint_32 uval = png_get_uint_32(buf); png_uint_32 uval = png_get_uint_32(buf);
if ((uval & 0x80000000L) == 0) /* non-negative */ if ((uval & 0x80000000) == 0) /* non-negative */
return uval; return uval;
uval = (uval ^ 0xffffffffL) + 1; /* 2's complement: -x = ~x+1 */ uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */
return -(png_int_32)uval; return -(png_int_32)uval;
} }
@ -458,7 +458,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
{ {
/* Success (maybe) - really uncompress the chunk. */ /* Success (maybe) - really uncompress the chunk. */
png_size_t new_size = 0; png_size_t new_size = 0;
png_charp text = png_malloc_warn(png_ptr, png_charp text = (png_charp)png_malloc_warn(png_ptr,
prefix_size + expanded_size + 1); prefix_size + expanded_size + 1);
if (text != NULL) if (text != NULL)
@ -501,7 +501,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
* amount of compressed data. * amount of compressed data.
*/ */
{ {
png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1);
if (text != NULL) if (text != NULL)
{ {
@ -827,7 +827,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
# ifdef PNG_READ_sRGB_SUPPORTED # ifdef PNG_READ_sRGB_SUPPORTED
if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
{ {
if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) if (PNG_OUT_OF_RANGE(igamma, 45500, 500))
{ {
PNG_WARNING_PARAMETERS(p) PNG_WARNING_PARAMETERS(p)
png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma); png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
@ -994,10 +994,10 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{ {
if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) ||
PNG_OUT_OF_RANGE(y_white, 32900, 1000) || PNG_OUT_OF_RANGE(y_white, 32900, 1000) ||
PNG_OUT_OF_RANGE(x_red, 64000L, 1000) || PNG_OUT_OF_RANGE(x_red, 64000, 1000) ||
PNG_OUT_OF_RANGE(y_red, 33000, 1000) || PNG_OUT_OF_RANGE(y_red, 33000, 1000) ||
PNG_OUT_OF_RANGE(x_green, 30000, 1000) || PNG_OUT_OF_RANGE(x_green, 30000, 1000) ||
PNG_OUT_OF_RANGE(y_green, 60000L, 1000) || PNG_OUT_OF_RANGE(y_green, 60000, 1000) ||
PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || PNG_OUT_OF_RANGE(x_blue, 15000, 1000) ||
PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) PNG_OUT_OF_RANGE(y_blue, 6000, 1000))
{ {
@ -1022,27 +1022,80 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
/* Store the _white values as default coefficients for the rgb to gray /* Store the _white values as default coefficients for the rgb to gray
* operation if it is supported. * operation if it is supported. Check if the transform is already set to
* avoid destroying the transform values.
*/ */
if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) if (!png_ptr->rgb_to_gray_coefficients_set)
{ {
/* png_set_background has not been called, the coefficients must be in /* png_set_background has not been called and we haven't seen an sRGB
* range for the following to work without overflow. * chunk yet. Find the XYZ of the three end points.
*/ */
if (y_red <= (1<<17) && y_green <= (1<<17) && y_blue <= (1<<17)) png_XYZ XYZ;
{ png_xy xy;
/* The y values are chromaticities: Y/X+Y+Z, the weights for the gray
* transformation are simply the normalized Y values for red, green and
* blue scaled by 32768.
*/
png_uint_32 w = y_red + y_green + y_blue;
png_ptr->rgb_to_gray_red_coeff = (png_uint_16)(((png_uint_32)y_red * xy.redx = x_red;
32768)/w); xy.redy = y_red;
png_ptr->rgb_to_gray_green_coeff = (png_uint_16)(((png_uint_32)y_green xy.greenx = x_green;
* 32768)/w); xy.greeny = y_green;
png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(((png_uint_32)y_blue * xy.bluex = x_blue;
32768)/w); xy.bluey = y_blue;
xy.whitex = x_white;
xy.whitey = y_white;
if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
{
/* The success case, because XYZ_from_xy normalises to a reference
* white Y of 1.0 we just need to scale the numbers. This should
* always work just fine. It is an internal error if this overflows.
*/
{
png_fixed_point r, g, b;
if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) &&
r >= 0 && r <= 32768 &&
png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) &&
g >= 0 && g <= 32768 &&
png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) &&
b >= 0 && b <= 32768 &&
r+g+b <= 32769)
{
/* We allow 0 coefficients here. r+g+b may be 32769 if two or
* all of the coefficients were rounded up. Handle this by
* reducing the *largest* coefficient by 1; this matches the
* approach used for the default coefficients in pngrtran.c
*/
int add = 0;
if (r+g+b > 32768)
add = -1;
else if (r+g+b < 32768)
add = 1;
if (add != 0)
{
if (g >= r && g >= b)
g += add;
else if (r >= g && r >= b)
r += add;
else
b += add;
}
/* Check for an internal error. */
if (r+g+b != 32768)
png_error(png_ptr,
"internal error handling cHRM coefficients");
png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
}
/* This is a png_error at present even though it could be ignored -
* it should never happen, but it is important that if it does, the
* bug is fixed.
*/
else
png_error(png_ptr, "internal error handling cHRM->XYZ");
}
} }
} }
#endif #endif
@ -1106,7 +1159,7 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
{ {
if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500)) if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500))
{ {
PNG_WARNING_PARAMETERS(p) PNG_WARNING_PARAMETERS(p)
@ -1123,10 +1176,10 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->x_red, 64000L, 1000) || PNG_OUT_OF_RANGE(info_ptr->x_red, 64000, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->y_green, 60000L, 1000) || PNG_OUT_OF_RANGE(info_ptr->y_green, 60000, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) ||
PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000))
{ {
@ -1135,6 +1188,47 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
} }
#endif /* PNG_READ_cHRM_SUPPORTED */ #endif /* PNG_READ_cHRM_SUPPORTED */
/* This is recorded for use when handling the cHRM chunk above. An sRGB
* chunk unconditionally overwrites the coefficients for grayscale conversion
* too.
*/
png_ptr->is_sRGB = 1;
# ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
/* Don't overwrite user supplied values: */
if (!png_ptr->rgb_to_gray_coefficients_set)
{
/* These numbers come from the sRGB specification (or, since one has to
* pay much money to get a copy, the wikipedia sRGB page) the
* chromaticity values quoted have been inverted to get the reverse
* transformation from RGB to XYZ and the 'Y' coefficients scaled by
* 32768 (then rounded).
*
* sRGB and ITU Rec-709 both truncate the values for the D65 white
* point to four digits and, even though it actually stores five
* digits, the PNG spec gives the truncated value.
*
* This means that when the chromaticities are converted back to XYZ
* end points we end up with (6968,23435,2366), which, as described in
* pngrtran.c, would overflow. If the five digit precision and up is
* used we get, instead:
*
* 6968*R + 23435*G + 2365*B
*
* (Notice that this rounds the blue coefficient down, rather than the
* choice used in pngrtran.c which is to round the green one down.)
*/
png_ptr->rgb_to_gray_red_coeff = 6968; /* 0.212639005871510 */
png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */
/* png_ptr->rgb_to_gray_blue_coeff = 2366; 0.072192315360734 */
/* The following keeps the cHRM chunk from destroying the
* coefficients again in the event that it follows the sRGB chunk.
*/
png_ptr->rgb_to_gray_coefficients_set = 1;
}
# endif
png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
} }
#endif /* PNG_READ_sRGB_SUPPORTED */ #endif /* PNG_READ_sRGB_SUPPORTED */

View file

@ -1,7 +1,7 @@
/* pngset.c - storage of image information into info struct /* pngset.c - storage of image information into info struct
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -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 # ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI void PNGAPI
png_set_cHRM(png_structp png_ptr, png_infop info_ptr, 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_x, "cHRM Blue X"),
png_fixed(png_ptr, blue_y, "cHRM Blue Y")); 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_FLOATING_POINT_SUPPORTED */
#endif /* PNG_cHRM_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 * 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 * 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 * 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.) * displays that are all black or all white.)
*/ */
if (file_gamma < 16 || file_gamma > 625000000) 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 # ifdef PNG_cHRM_SUPPORTED
png_set_cHRM_fixed(png_ptr, info_ptr, png_set_cHRM_fixed(png_ptr, info_ptr,
/* color x y */ /* color x y */
/* white */ 31270L, 32900L, /* white */ 31270, 32900,
/* red */ 64000L, 33000L, /* red */ 64000, 33000,
/* green */ 30000L, 60000L, /* green */ 30000, 60000,
/* blue */ 15000L, 6000L /* blue */ 15000, 6000
); );
# endif /* cHRM */ # endif /* cHRM */
} }
@ -570,7 +620,7 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
{ {
png_charp new_iccp_name; png_charp new_iccp_name;
png_bytep new_iccp_profile; png_bytep new_iccp_profile;
png_uint_32 length; png_size_t length;
png_debug1(1, "in %s storage function", "iCCP"); png_debug1(1, "in %s storage function", "iCCP");
@ -916,10 +966,10 @@ png_set_sPLT(png_structp png_ptr,
{ {
png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
png_const_sPLT_tp from = entries + i; png_const_sPLT_tp from = entries + i;
png_uint_32 length; png_size_t length;
length = png_strlen(from->name) + 1; 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) if (to->name == NULL)
{ {
@ -930,7 +980,7 @@ png_set_sPLT(png_structp png_ptr,
png_memcpy(to->name, from->name, length); png_memcpy(to->name, from->name, length);
to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, 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) if (to->entries == NULL)
{ {

View file

@ -5,7 +5,7 @@
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer * For conditions of distribution and use, see the disclaimer
@ -255,13 +255,20 @@ struct png_struct_def
png_bytep chunk_list; png_bytep chunk_list;
#endif #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 */ /* New members added in libpng-1.0.3 */
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
png_byte rgb_to_gray_status; 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 */ /* 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_red_coeff;
png_uint_16 rgb_to_gray_green_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 #endif
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ /* New member added in libpng-1.0.4 (renamed in 1.0.9) */

View file

@ -1,7 +1,7 @@
/* pngwutil.c - utilities to write a PNG file /* pngwutil.c - utilities to write a PNG file
* *
* Last changed in libpng 1.5.4 [July 7, 2011] * Last changed in libpng 1.5.5 [September 22, 2011]
* Copyright (c) 1998-2011 Glenn Randers-Pehrson * Copyright (c) 1998-2011 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -1860,7 +1860,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
{ {
PNG_pCAL; PNG_pCAL;
png_size_t purpose_len, units_len, total_len; png_size_t purpose_len, units_len, total_len;
png_uint_32p params_len; png_size_tp params_len;
png_byte buf[10]; png_byte buf[10];
png_charp new_purpose; png_charp new_purpose;
int i; int i;
@ -1876,8 +1876,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); png_debug1(3, "pCAL units length = %d", (int)units_len);
total_len = purpose_len + units_len + 10; total_len = purpose_len + units_len + 10;
params_len = (png_uint_32p)png_malloc(png_ptr, params_len = (png_size_tp)png_malloc(png_ptr,
(png_alloc_size_t)(nparams * png_sizeof(png_uint_32))); (png_alloc_size_t)(nparams * png_sizeof(png_size_t)));
/* Find the length of each parameter, making sure we don't count the /* Find the length of each parameter, making sure we don't count the
* null terminator for the last parameter. * null terminator for the last parameter.
@ -1887,13 +1887,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); params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
png_debug2(3, "pCAL parameter %d length = %lu", i, png_debug2(3, "pCAL parameter %d length = %lu", i,
(unsigned long)params_len[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_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_start(png_ptr, png_pCAL, (png_uint_32)total_len);
png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, purpose_len);
(png_size_t)purpose_len);
png_save_int_32(buf, X0); png_save_int_32(buf, X0);
png_save_int_32(buf + 4, X1); png_save_int_32(buf + 4, X1);
buf[8] = (png_byte)type; buf[8] = (png_byte)type;
@ -1905,8 +1904,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
for (i = 0; i < nparams; i++) for (i = 0; i < nparams; i++)
{ {
png_write_chunk_data(png_ptr, (png_const_bytep)params[i], png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
(png_size_t)params_len[i]);
} }
png_free(png_ptr, params_len); png_free(png_ptr, params_len);