[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
*
* 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
* (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_5 Your_png_h_is_not_version_1_5_5;
/* 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
@ -133,8 +134,35 @@ png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length)
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.5 - September 22, 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.5 - September 22, 2011\
Copyright (c) 1998-2011 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
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)
# 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 +817,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 +1722,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 */
/* 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.
*/
{
unsigned int uexp_b10;
if (exp_b10 < 0)
{
*ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
exp_b10 = -exp_b10;
uexp_b10 = -exp_b10;
}
else
uexp_b10 = exp_b10;
cdigits = 0;
while (exp_b10 > 0)
while (uexp_b10 > 0)
{
exponent[cdigits++] = (char)(48 + exp_b10 % 10);
exp_b10 /= 10;
exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
uexp_b10 /= 10;
}
}
/* 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
num = fp;
if (num <= 0x80000000U) /* else overflowed */
if (num <= 0x80000000) /* else overflowed */
{
unsigned int ndigits = 0, first = 16 /* flag value */;
char digits[10];

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.5 - September 22, 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.5 - September 22, 2011: Glenn
* See also "Contributing Authors", below.
*
* Note about libpng version numbers:
@ -157,6 +157,9 @@
* 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]
*
* Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be
@ -188,7 +191,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.5, September 22, 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 +303,13 @@
* Y2K compliance in libpng:
* =========================
*
* July 7, 2011
* September 22, 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.5 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 +364,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.5"
#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_DLLNUM 15
@ -371,7 +374,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 5
/* This should match the numeric part of the final component of
* 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.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
* 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
* 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
* 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_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
@ -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,
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 +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_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 +2077,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
@ -2282,7 +2306,7 @@ PNG_EXPORT(171, void, png_set_sCAL_s,
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
keep = 0: follow default behavior
= 1: do not keep
= 2: keep only if safe-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)(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 +2531,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 +2600,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.5 - September 22, 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,26 +260,15 @@
# 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
# endif
# ifndef PNG_IMPEXP
# define PNG_IMPEXP
@ -356,12 +347,6 @@
# 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__))
# endif
@ -374,7 +359,6 @@
__attribute__((__deprecated__))
# endif
# endif
# endif /* PNGLIB_BUILD */
# 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 */
# endif /* _MSC_VER */
#endif /* PNG_PEDANTIC_WARNINGS */

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.5 [September 22, 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
@ -971,7 +1066,7 @@ 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);
}

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.5 [September 22, 2011]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@ -44,7 +44,8 @@
*/
#include <stdlib.h>
#define PNGLIB_BUILD
#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 +56,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:
*/
@ -293,24 +364,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 +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_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)
@ -1078,6 +1148,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,

View file

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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;
red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
/* NOTE: this calculation does not round, but this behavior is retained
* 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_green_coeff = green_int;
png_ptr->rgb_to_gray_blue_coeff =
(png_uint_16)(32768 - red_int - green_int);
png_ptr->rgb_to_gray_coefficients_set = 1;
}
else
@ -983,17 +987,18 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
png_warning(png_ptr,
"ignoring out of range rgb_to_gray coefficients");
/* Use the defaults, from the cHRM chunk if set, else the built in Rec
* 709 values (which correspond to sRGB, so we don't have to worry
* about the sRGB chunk!)
/* Use the defaults, from the cHRM chunk if set, else the historical
* values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
* 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 &&
png_ptr->rgb_to_gray_green_coeff == 0 &&
png_ptr->rgb_to_gray_blue_coeff == 0)
png_ptr->rgb_to_gray_green_coeff == 0)
{
png_ptr->rgb_to_gray_red_coeff = 6968; /* .212671 * 32768 + .5 */
png_ptr->rgb_to_gray_green_coeff = 23434; /* .715160 * 32768 + .5 */
png_ptr->rgb_to_gray_blue_coeff = 2366;
png_ptr->rgb_to_gray_red_coeff = 6968;
png_ptr->rgb_to_gray_green_coeff = 23434;
/* 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)
{
/* 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))
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.
*
* 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
* 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
/* Reduce RGB files to grayscale, with or without alpha
* using the equation given in Poynton's ColorFAQ at
* <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008)
* New link:
* <http://www.poynton.com/notes/colour_and_gamma/>
* using the equation given in Poynton's ColorFAQ of 1998-01-04 at
* <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but
* versions dated 1998 through November 2002 have been archived at
* http://web.archive.org/web/20000816232553/http://www.inforamp.net/
* ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
* Charles Poynton poynton at poynton.com
*
* 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
*
* 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 */
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;
png_debug(1, "in png_do_rgb_to_gray");
@ -3100,35 +3133,57 @@ 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) &&
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{
png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
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 rc = png_ptr->rgb_to_gray_red_coeff;
PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_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 defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
/* 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_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++)];
png_byte red = *(sp++);
png_byte green = *(sp++);
png_byte blue = *(sp++);
if (red != green || red != blue)
{
red = png_ptr->gamma_to_1[red];
green = png_ptr->gamma_to_1[green];
blue = png_ptr->gamma_to_1[blue];
rgb_error |= 1;
*(dp++) = png_ptr->gamma_from_1[
(rc*red + gc*green + bc*blue)>>15];
(rc*red + gc*green + bc*blue + 16384)>>15];
}
else
*(dp++) = *(sp - 1);
{
/* If there is no overall correction the table will not be
* set.
*/
if (png_ptr->gamma_table != NULL)
red = png_ptr->gamma_table[red];
*(dp++) = red;
}
if (have_alpha)
*(dp++) = *(sp++);
}
}
else
@ -3136,6 +3191,8 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
{
png_bytep sp = row;
png_bytep dp = row;
png_uint_32 i;
for (i = 0; i < row_width; i++)
{
png_byte red = *(sp++);
@ -3145,11 +3202,17 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
if (red != green || red != blue)
{
rgb_error |= 1;
/*NOTE: this is the historical approach which simply
* truncates the results.
*/
*(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
}
else
*(dp++) = *(sp - 1);
*(dp++) = red;
if (have_alpha)
*(dp++) = *(sp++);
}
}
}
@ -3157,11 +3220,12 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
else /* RGB 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)
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;
@ -3171,7 +3235,14 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
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];
else
w = red;
}
else
{
@ -3183,7 +3254,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
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);
+ bc*blue_1 + 16384)>>15);
w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
png_ptr->gamma_shift][gray16 >> 8];
rgb_error |= 1;
@ -3191,6 +3262,12 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
*(dp++) = (png_byte)((w>>8) & 0xff);
*(dp++) = (png_byte)(w & 0xff);
if (have_alpha)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
}
}
}
else
@ -3198,6 +3275,8 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
{
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, gray16;
@ -3209,125 +3288,24 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
if (red != green || red != blue)
rgb_error |= 1;
gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
/* 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 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
if (have_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
{
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)>>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);
*(dp++) = *(sp++); /* alpha */
*(dp++) = *(sp++);
}
}
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);
*(dp++) = *(sp++); /* alpha */
*(dp++) = *(sp++);
}
}
}
}
row_info->channels -= 2;
row_info->color_type = (png_byte)(row_info->color_type &
~PNG_COLOR_MASK_COLOR);
@ -4762,7 +4740,7 @@ png_do_expand(png_row_infop row_info, png_bytep row,
#endif
#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.
*/
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 s1 = (*(rp + 2) << 8) | *(rp + 3);
png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
png_uint_32 red = (s0 + s1 + 65536) & 0xffff;
png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
*(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp + 1) = (png_byte)(red & 0xff);
*(rp + 4) = (png_byte)((blue >> 8) & 0xff);

View file

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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_uint_32 uval = png_get_uint_32(buf);
if ((uval & 0x80000000L) == 0) /* non-negative */
if ((uval & 0x80000000) == 0) /* non-negative */
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;
}
@ -458,7 +458,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
{
/* Success (maybe) - really uncompress the chunk. */
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);
if (text != NULL)
@ -501,7 +501,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
* 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)
{
@ -827,7 +827,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
# ifdef PNG_READ_sRGB_SUPPORTED
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_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) ||
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(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(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
/* 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
* range for the following to work without overflow.
/* png_set_background has not been called and we haven't seen an sRGB
* chunk yet. Find the XYZ of the three end points.
*/
if (y_red <= (1<<17) && y_green <= (1<<17) && y_blue <= (1<<17))
{
/* The y values are chromaticities: Y/X+Y+Z, the weights for the gray
* transformation are simply the normalized Y values for red, green and
* blue scaled by 32768.
*/
png_uint_32 w = y_red + y_green + y_blue;
png_XYZ XYZ;
png_xy xy;
png_ptr->rgb_to_gray_red_coeff = (png_uint_16)(((png_uint_32)y_red *
32768)/w);
png_ptr->rgb_to_gray_green_coeff = (png_uint_16)(((png_uint_32)y_green
* 32768)/w);
png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(((png_uint_32)y_blue *
32768)/w);
xy.redx = x_red;
xy.redy = y_red;
xy.greenx = x_green;
xy.greeny = y_green;
xy.bluex = x_blue;
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
@ -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 (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)
@ -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 (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->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->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->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 */
/* 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);
}
#endif /* PNG_READ_sRGB_SUPPORTED */

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.5 [September 22, 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");
@ -916,10 +966,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 +980,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
@ -255,13 +255,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) */

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.5 [September 22, 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.)
@ -1860,7 +1860,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
{
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 +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);
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 +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);
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_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 +1904,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);