mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[devel] Fixes to rgb_to_gray and cHRM XYZ APIs
This commit is contained in:
parent
0c03fc6f75
commit
736f40f459
17
ANNOUNCE
17
ANNOUNCE
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Libpng 1.5.5beta06 - August 17, 2011
|
Libpng 1.5.5beta06 - August 25, 2011
|
||||||
|
|
||||||
This is not intended to be a public release. It will be replaced
|
This is not intended to be a public release. It will be replaced
|
||||||
within a few weeks by a public version or by another test version.
|
within a few weeks by a public version or by another test version.
|
||||||
@ -62,9 +62,22 @@ Version 1.5.5beta05 [August 17, 2011]
|
|||||||
Added new types and internal functions for CIE RGB end point handling to
|
Added new types and internal functions for CIE RGB end point handling to
|
||||||
pngpriv.h (functions yet to be implemented).
|
pngpriv.h (functions yet to be implemented).
|
||||||
|
|
||||||
Version 1.5.5beta06 [August 17, 2011]
|
Version 1.5.5beta06 [August 25, 2011]
|
||||||
Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt
|
Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt
|
||||||
(Clifford Yap)
|
(Clifford Yap)
|
||||||
|
Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler):
|
||||||
|
The rgb_to_gray code had errors when combined with gamma correction.
|
||||||
|
Some pixels were treated as true grey when they weren't and such pixels
|
||||||
|
and true grey ones were not gamma corrected (the original value of the
|
||||||
|
red component was used instead). APIs to get and set cHRM using color
|
||||||
|
space end points have been added and the rgb_to_gray code that defaults
|
||||||
|
based on cHRM (introduced in 1.5.4) has been corrected. A considerable
|
||||||
|
number of tests has been added to pngvalid for the rgb_to_gray transform.
|
||||||
|
Arithmetic errors in rgb_to_gray whereby the calculated gray value was
|
||||||
|
truncated to the bit depth rather than rounded have been fixed except in
|
||||||
|
the 8-bit non-gamma-corrected case (where consistency seems more important
|
||||||
|
than correctness.) The code still has considerable inaccuracies in the
|
||||||
|
8-bit case because 8-bit linear arithmetic is used.
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
15
CHANGES
15
CHANGES
@ -3546,9 +3546,22 @@ Version 1.5.5beta05 [August 17, 2011]
|
|||||||
Added new types and internal functions for CIE RGB end point handling to
|
Added new types and internal functions for CIE RGB end point handling to
|
||||||
pngpriv.h (functions yet to be implemented).
|
pngpriv.h (functions yet to be implemented).
|
||||||
|
|
||||||
Version 1.5.5beta06 [August 17, 2011]
|
Version 1.5.5beta06 [August 25, 2011]
|
||||||
Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt
|
Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt
|
||||||
(Clifford Yap)
|
(Clifford Yap)
|
||||||
|
Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler):
|
||||||
|
The rgb_to_gray code had errors when combined with gamma correction.
|
||||||
|
Some pixels were treated as true grey when they weren't and such pixels
|
||||||
|
and true grey ones were not gamma corrected (the original value of the
|
||||||
|
red component was used instead). APIs to get and set cHRM using color
|
||||||
|
space end points have been added and the rgb_to_gray code that defaults
|
||||||
|
based on cHRM (introduced in 1.5.4) has been corrected. A considerable
|
||||||
|
number of tests has been added to pngvalid for the rgb_to_gray transform.
|
||||||
|
Arithmetic errors in rgb_to_gray whereby the calculated gray value was
|
||||||
|
truncated to the bit depth rather than rounded have been fixed except in
|
||||||
|
the 8-bit non-gamma-corrected case (where consistency seems more important
|
||||||
|
than correctness.) The code still has considerable inaccuracies in the
|
||||||
|
8-bit case because 8-bit linear arithmetic is used.
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
libpng-manual.txt - A description on how to use and modify libpng
|
libpng-manual.txt - A description on how to use and modify libpng
|
||||||
|
|
||||||
libpng version 1.5.5beta06 - August 17, 2011
|
libpng version 1.5.5beta06 - August 25, 2011
|
||||||
Updated and distributed by Glenn Randers-Pehrson
|
Updated and distributed by Glenn Randers-Pehrson
|
||||||
<glennrp at users.sourceforge.net>
|
<glennrp at users.sourceforge.net>
|
||||||
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
||||||
@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng
|
|||||||
|
|
||||||
Based on:
|
Based on:
|
||||||
|
|
||||||
libpng versions 0.97, January 1998, through 1.5.5beta06 - August 17, 2011
|
libpng versions 0.97, January 1998, through 1.5.5beta06 - August 25, 2011
|
||||||
Updated and distributed by Glenn Randers-Pehrson
|
Updated and distributed by Glenn Randers-Pehrson
|
||||||
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
||||||
|
|
||||||
@ -4509,7 +4509,7 @@ Other rules can be inferred by inspecting the libpng source.
|
|||||||
|
|
||||||
XIV. Y2K Compliance in libpng
|
XIV. Y2K Compliance in libpng
|
||||||
|
|
||||||
August 17, 2011
|
August 25, 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.
|
||||||
|
38
libpng.3
38
libpng.3
@ -1,4 +1,4 @@
|
|||||||
.TH LIBPNG 3 "August 17, 2011"
|
.TH LIBPNG 3 "August 25, 2011"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
libpng \- Portable Network Graphics (PNG) Reference Library 1.5.5beta06
|
libpng \- Portable Network Graphics (PNG) Reference Library 1.5.5beta06
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -128,10 +128,22 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.5.5beta06
|
|||||||
|
|
||||||
\fI\fB
|
\fI\fB
|
||||||
|
|
||||||
\fBpng_uint_32 png_get_chunk_cache_max (png_const_structp \fIpng_ptr\fP\fB);\fP
|
\fBpng_uint_32 png_get_cHRM_XYZ (png_structp \fIpng_ptr,
|
||||||
|
|
||||||
|
\fBpng_const_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*red_X\fP\fB, double \fP\fI*red_Y\fP\fB, double \fI*red_Z,
|
||||||
|
|
||||||
|
\fBdouble \fP\fI*green_X\fP\fB, double \fP\fI*green_Y\fP\fB, double \fP\fI*green_Z\fP\fB, double \fI*blue_X,
|
||||||
|
|
||||||
|
\fBdouble \fP\fI*blue_Y\fP\fB, double \fI*blue_Z\fP\fB);\fP
|
||||||
|
|
||||||
\fI\fB
|
\fI\fB
|
||||||
|
|
||||||
|
\fBpng_uint_32 png_get_cHRM_XYZ_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_const_infop \fP\fIinfo_ptr\fP\fB, png_fixed_point \fP\fI*int_red_X\fP\fB, png_fixed_point \fP\fI*int_red_Y\fP\fB, png_fixed_point \fP\fI*int_red_Z\fP\fB, png_fixed_point \fP\fI*int_green_X\fP\fB, png_fixed_point \fP\fI*int_green_Y\fP\fB, png_fixed_point \fP\fI*int_green_Z\fP\fB, png_fixed_point \fP\fI*int_blue_X\fP\fB, png_fixed_point \fP\fI*int_blue_Y\fP\fB, png_fixed_point \fI*int_blue_Z\fP\fB);\fP
|
||||||
|
|
||||||
|
\fI\fB
|
||||||
|
|
||||||
|
\fBpng_uint_32 png_get_chunk_cache_max (png_const_structp \fIpng_ptr\fP\fB);\fP
|
||||||
|
|
||||||
\fI\fB
|
\fI\fB
|
||||||
|
|
||||||
\fBpng_alloc_size_t png_get_chunk_malloc_max (png_const_structp \fIpng_ptr\fP\fB);\fP
|
\fBpng_alloc_size_t png_get_chunk_malloc_max (png_const_structp \fIpng_ptr\fP\fB);\fP
|
||||||
@ -548,6 +560,16 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.5.5beta06
|
|||||||
|
|
||||||
\fI\fB
|
\fI\fB
|
||||||
|
|
||||||
|
\fBvoid png_set_cHRM_XYZ (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIred_X\fP\fB, double \fP\fIred_Y\fP\fB, double \fP\fIred_Z\fP\fB, double \fP\fIgreen_X\fP\fB, double \fIgreen_Y,
|
||||||
|
|
||||||
|
\fBdouble \fP\fIgreen_Z\fP\fB, double \fP\fIblue_X\fP\fB, double \fP\fIblue_Y\fP\fB, double \fIblue_Z\fP\fB);\fP
|
||||||
|
|
||||||
|
\fI\fB
|
||||||
|
|
||||||
|
\fBvoid png_set_cHRM_XYZ_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_fixed_point \fP\fIint_red_X\fP\fB, png_fixed_point \fP\fIint_red_Y\fP\fB, png_fixed_point \fP\fIint_red_Z\fP\fB, png_fixed_point \fP\fIint_green_X\fP\fB, png_fixed_point \fP\fIint_green_Y\fP\fB, png_fixed_point \fP\fIint_green_Z\fP\fB, png_fixed_point \fP\fIint_blue_X\fP\fB, png_fixed_point \fP\fIint_blue_Y\fP\fB, png_fixed_point \fIint_blue_Z\fP\fB);\fP
|
||||||
|
|
||||||
|
\fI\fB
|
||||||
|
|
||||||
\fBvoid png_set_chunk_cache_max (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIuser_chunk_cache_max\fP\fB);\fP
|
\fBvoid png_set_chunk_cache_max (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIuser_chunk_cache_max\fP\fB);\fP
|
||||||
|
|
||||||
\fI\fB
|
\fI\fB
|
||||||
@ -955,7 +977,7 @@ Following is a copy of the libpng-manual.txt file that accompanies libpng.
|
|||||||
.SH LIBPNG.TXT
|
.SH LIBPNG.TXT
|
||||||
libpng-manual.txt - A description on how to use and modify libpng
|
libpng-manual.txt - A description on how to use and modify libpng
|
||||||
|
|
||||||
libpng version 1.5.5beta06 - August 17, 2011
|
libpng version 1.5.5beta06 - August 25, 2011
|
||||||
Updated and distributed by Glenn Randers-Pehrson
|
Updated and distributed by Glenn Randers-Pehrson
|
||||||
<glennrp at users.sourceforge.net>
|
<glennrp at users.sourceforge.net>
|
||||||
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
||||||
@ -966,7 +988,7 @@ libpng-manual.txt - A description on how to use and modify libpng
|
|||||||
|
|
||||||
Based on:
|
Based on:
|
||||||
|
|
||||||
libpng versions 0.97, January 1998, through 1.5.5beta06 - August 17, 2011
|
libpng versions 0.97, January 1998, through 1.5.5beta06 - August 25, 2011
|
||||||
Updated and distributed by Glenn Randers-Pehrson
|
Updated and distributed by Glenn Randers-Pehrson
|
||||||
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
Copyright (c) 1998-2011 Glenn Randers-Pehrson
|
||||||
|
|
||||||
@ -5465,7 +5487,7 @@ Other rules can be inferred by inspecting the libpng source.
|
|||||||
|
|
||||||
.SH XIV. Y2K Compliance in libpng
|
.SH XIV. Y2K Compliance in libpng
|
||||||
|
|
||||||
August 17, 2011
|
August 25, 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.
|
||||||
@ -5724,7 +5746,7 @@ possible without all of you.
|
|||||||
|
|
||||||
Thanks to Frank J. T. Wojcik for helping with the documentation.
|
Thanks to Frank J. T. Wojcik for helping with the documentation.
|
||||||
|
|
||||||
Libpng version 1.5.5beta06 - August 17, 2011:
|
Libpng version 1.5.5beta06 - August 25, 2011:
|
||||||
Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
|
Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
|
||||||
Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
|
Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net).
|
||||||
|
|
||||||
@ -5747,7 +5769,7 @@ this sentence.
|
|||||||
|
|
||||||
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.5beta06, August 17, 2011, are
|
libpng versions 1.2.6, August 15, 2004, through 1.5.5beta06, August 25, 2011, are
|
||||||
Copyright (c) 2004,2006-2007 Glenn Randers-Pehrson, and are
|
Copyright (c) 2004,2006-2007 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
|
||||||
@ -5846,7 +5868,7 @@ certification mark of the Open Source Initiative.
|
|||||||
|
|
||||||
Glenn Randers-Pehrson
|
Glenn Randers-Pehrson
|
||||||
glennrp at users.sourceforge.net
|
glennrp at users.sourceforge.net
|
||||||
August 17, 2011
|
August 25, 2011
|
||||||
|
|
||||||
.\" end of man page
|
.\" end of man page
|
||||||
|
|
||||||
|
339
png.c
339
png.c
@ -617,13 +617,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.5beta06 - August 17, 2011" PNG_STRING_NEWLINE \
|
"libpng version 1.5.5beta06 - August 25, 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.5beta06 - August 17, 2011\
|
return "libpng version 1.5.5beta06 - August 25, 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 +713,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 +789,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_chunk_benign_error(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,
|
||||||
|
33
png.h
33
png.h
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* png.h - header file for PNG reference library
|
/* png.h - header file for PNG reference library
|
||||||
*
|
*
|
||||||
* libpng version 1.5.5beta06 - August 17, 2011
|
* libpng version 1.5.5beta06 - August 25, 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.5beta06 - August 17, 2011: Glenn
|
* libpng versions 0.97, January 1998, through 1.5.5beta06 - August 25, 2011: Glenn
|
||||||
* See also "Contributing Authors", below.
|
* See also "Contributing Authors", below.
|
||||||
*
|
*
|
||||||
* Note about libpng version numbers:
|
* Note about libpng version numbers:
|
||||||
@ -189,7 +189,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.5beta06, August 17, 2011, are
|
* libpng versions 1.2.6, August 15, 2004, through 1.5.5beta06, August 25, 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:
|
||||||
@ -301,7 +301,7 @@
|
|||||||
* Y2K compliance in libpng:
|
* Y2K compliance in libpng:
|
||||||
* =========================
|
* =========================
|
||||||
*
|
*
|
||||||
* August 17, 2011
|
* August 25, 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.
|
||||||
@ -364,7 +364,7 @@
|
|||||||
/* 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.5beta06"
|
#define PNG_LIBPNG_VER_STRING "1.5.5beta06"
|
||||||
#define PNG_HEADER_VERSION_STRING \
|
#define PNG_HEADER_VERSION_STRING \
|
||||||
" libpng version 1.5.5beta06 - August 17, 2011\n"
|
" libpng version 1.5.5beta06 - August 25, 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
|
||||||
@ -2048,6 +2048,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,
|
||||||
@ -2057,6 +2061,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
|
||||||
@ -2064,12 +2075,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
|
||||||
@ -2577,7 +2598,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
|
||||||
|
95
pngget.c
95
pngget.c
@ -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
|
||||||
|
@ -1166,7 +1166,12 @@ typedef struct png_XYZ
|
|||||||
png_fixed_point blueX, blueY, blueZ;
|
png_fixed_point blueX, blueY, blueZ;
|
||||||
} png_XYZ;
|
} png_XYZ;
|
||||||
|
|
||||||
/* The conversion APIs return 0 on success, non-zero on a parameter error. */
|
/* 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_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 PNGARG((png_XYZ *XYZ, png_xy xy));
|
||||||
PNG_EXTERN int png_XYZ_from_xy_checked PNGARG((png_structp png_ptr,
|
PNG_EXTERN int png_XYZ_from_xy_checked PNGARG((png_structp png_ptr,
|
||||||
|
388
pngrtran.c
388
pngrtran.c
@ -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;
|
||||||
|
|
||||||
|
/* 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*32768L)/100000L);
|
red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
|
||||||
green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
|
green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
|
||||||
|
|
||||||
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;
|
||||||
@ -3089,26 +3094,38 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
|
|||||||
*
|
*
|
||||||
* Y = (6966 * R + 23436 * G + 2366 * B)/32768
|
* Y = (6966 * R + 23436 * G + 2366 * B)/32768
|
||||||
*
|
*
|
||||||
* We use the approximation
|
* 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
|
* Y = (6968 * R + 23434 * G + 2366 * B)/32768
|
||||||
*
|
*
|
||||||
* Starting with libpng-1.5.4, if the image being converted has the
|
* Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
|
||||||
* sRGB chunk, then the sRGB numbers are used by default:
|
* (including an sRGB chunk) then the chromaticities are used to calculate the
|
||||||
|
* coefficients. See the chunk handling in pngrutil.c for more information.
|
||||||
*
|
*
|
||||||
* Y = 0.33000*R + 0.60000*G + 0.06000*B
|
* 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.
|
||||||
*
|
*
|
||||||
* The calculation is to be done in a linear colorspace.
|
* 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
|
||||||
* Other integer coefficents can be used via png_set_rgb_to_gray().
|
* 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");
|
||||||
@ -3116,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);
|
||||||
|
128
pngrutil.c
128
pngrutil.c
@ -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
|
||||||
@ -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 */
|
||||||
|
50
pngset.c
50
pngset.c
@ -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 */
|
||||||
|
@ -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) */
|
||||||
|
1444
pngvalid.c
1444
pngvalid.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user