[libpng16] Removed non-working ICC profile support code. There was too much
code for too little gain; implementing full ICC color correction is maybe
desireable but is left up to applications.
diff --git a/ANNOUNCE b/ANNOUNCE
index 329a3f0..c9fb100 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
-Libpng 1.6.0beta31 - October 27, 2012
+Libpng 1.6.0beta31 - November 1, 2012
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.
@@ -525,7 +525,7 @@
Fixed build when using #define PNG_NO_READ_GAMMA in png_do_compose() in
pngrtran.c (Domani Hannes).
-Version 1.6.0beta31 [October 27, 2012]
+Version 1.6.0beta31 [November 1, 2012]
Undid the erroneous change to vstudio/pngvalid build in libpng-1.6.0beta30.
Made pngvalid so that it will build outside the libpng source tree.
Changed ICC profile support to allow use of an external color management
@@ -550,6 +550,9 @@
question (typically most users who disable it won't).
Fixed GUIDs in projects/vstudio. Some were duplicated or missing,
resulting in VS2010 having to update the files.
+ Removed non-working ICC profile support code. There was too much code
+ for too little gain; implementing full ICC color correction is maybe
+ desireable but is left up to applications.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
diff --git a/CHANGES b/CHANGES
index b38a2ca..6f72fe4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4277,7 +4277,7 @@
Fixed build when using #define PNG_NO_READ_GAMMA in png_do_compose() in
pngrtran.c (Domani Hannes).
-Version 1.6.0beta31 [October 27, 2012]
+Version 1.6.0beta31 [November 1, 2012]
Undid the erroneous change to vstudio/pngvalid build in libpng-1.6.0beta30.
Made pngvalid so that it will build outside the libpng source tree.
Changed ICC profile support to allow use of an external color management
@@ -4302,6 +4302,9 @@
question (typically most users who disable it won't).
Fixed GUIDs in projects/vstudio. Some were duplicated or missing,
resulting in VS2010 having to update the files.
+ Removed non-working ICC profile support code. There was too much code
+ for too little gain; implementing full ICC color correction is maybe
+ desireable but is left up to applications.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
diff --git a/png.c b/png.c
index 27d31d3..4ff33df 100644
--- a/png.c
+++ b/png.c
@@ -668,7 +668,7 @@
* complement format. If this isn't the case, then this routine needs to
* be modified to write data in two's complement format. Note that,
* the following works correctly even if png_int_32 has more than 32 bits
- * (compare the more complex code required on read for sign extention.)
+ * (compare the more complex code required on read for sign extension.)
*/
void PNGAPI
png_save_int_32(png_bytep buf, png_int_32 i)
@@ -766,13 +766,13 @@
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
- "libpng version 1.6.0beta31 - October 26, 2012" PNG_STRING_NEWLINE \
+ "libpng version 1.6.0beta31 - November 1, 2012" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2012 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.6.0beta31 - October 26, 2012\
+ return "libpng version 1.6.0beta31 - November 1, 2012\
Copyright (c) 1998-2012 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@@ -1780,7 +1780,7 @@
if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
{
png_benign_error(png_ptr, "duplicate sRGB information ignored");
- return 0; /* not set */
+ return 0;
}
/* If the standard sRGB cHRM chunk does not match the one from the PNG file
@@ -1816,7 +1816,7 @@
colorspace->flags |=
(PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
- return 1/*set*/;
+ return 1; /* set */
}
#endif /* sRGB */
@@ -1850,7 +1850,6 @@
png_const_bytep profile/* first 132 bytes only */, int color_type)
{
png_uint_32 temp;
- png_uint_32 info = 0; /* bitmask of profile info */
/* Length check; this cannot be ignored in this code because profile_length
* is used later to check the tag table, so even if the profile seems over
@@ -1938,7 +1937,6 @@
if (!(color_type & PNG_COLOR_MASK_COLOR))
return png_icc_profile_error(png_ptr, colorspace, name, temp,
"RGB color space not permitted on grayscale PNG");
- info |= PNG_ICC_RGB;
break;
case 0x47524159: /* 'GRAY' */
@@ -2013,9 +2011,6 @@
switch (temp)
{
case 0x58595A20: /* 'XYZ ' */
- info |= PNG_ICC_PCSXYZ;
- break;
-
case 0x4C616220: /* 'Lab ' */
break;
@@ -2024,676 +2019,9 @@
"unexpected ICC PCS encoding");
}
- /* Store the profile info flags */
- colorspace->icc_info = info;
return 1;
}
-#ifdef PNG_ICC_SUPPORTED
-static png_uint_32
-png_icc_find_tag(png_const_bytep profile, png_uint_32 tag, png_uint_32p length)
- /* Find a single tag in the tag table, returns 0 if the tag is not found,
- * else returns the offset in the profile of the tag and, via *length, the
- * length from the tag table.
- *
- * TODO: this can probably be avoided by caching the values.
- */
-{
- png_uint_32 tag_count = png_get_uint_32(profile+128);
-
- profile += 132;
-
- while (tag_count-- > 0)
- {
- if (png_get_uint_32(profile) == tag)
- {
- *length = png_get_uint_32(profile+8);
- return png_get_uint_32(profile+4);
- }
- profile += 12;
- }
-
- return 0;
-}
-
-/* Useful types used for the math.
- * NOTE: the use of const on array types here actually creates the type (const
- * png_int_32)[], not (const (png_int_32[])), consequently a compiler may object
- * to passing a (png_int_32[]) (which does not have const elements).
- */
-#if __GNUC__ == 4 && __GNUC_MINOR__ == 2
- /* GCC 4.2 has an optimization bug which means that if this code is compiled
- * with any optimization (i.e. not -O0) it somehow manages to make casts to
- * png_const_icc_matrixrp not work in some cases and so warns for some
- * function calls. This works round the problem without harming optimization
- * with other compilers.
- */
-# define PNG_ICC_CONST
-#else
-# define PNG_ICC_CONST const
-#endif
-typedef png_int_32 png_icc_vector[3];
-typedef png_int_32 (*PNG_RESTRICT png_icc_vectorrp)[3];
-typedef PNG_ICC_CONST png_int_32 (*PNG_RESTRICT png_const_icc_vectorrp)[3];
-#define png_cpv(vector) png_constcast(PNG_ICC_CONST png_icc_vector*,&vector)
-
-typedef png_int_32 png_icc_matrix[3][3];
-typedef png_int_32 (*PNG_RESTRICT png_icc_matrixrp)[3][3];
-typedef PNG_ICC_CONST png_int_32 (*PNG_RESTRICT png_const_icc_matrixrp)[3][3];
-#define png_cpm(matrix) png_constcast(PNG_ICC_CONST png_icc_matrix*,&matrix)
-
-/* These two painfully complex routines are to detect under or overflow on
- * addition or subtraction of two 32-bit signed integers. There's probably a
- * better way of doing this.
- *
- * TODO: look at the on-line resources for this kind of bit banging.
- */
-static int
-png_add(png_int_32 * PNG_RESTRICT result, png_int_32 a, png_int_32 b)
-{
- if ((a ^ b) < 0 || /* Signs differ */
- (a >= 0 && b <= 0x7fffffff-a) ||
- (a < 0 && b >= (-0x7fffffff-1)-a))
- {
- *result = a+b;
- return 1;
- }
-
- return 0; /* overflow */
-}
-
-static int
-png_sub(png_int_32 * PNG_RESTRICT result, png_int_32 a, png_int_32 b)
-{
- if ((a ^ b) > 0 || /* Signs the same, and neither is zero */
- (a >= 0 && b >= a-0x7fffffff) ||
- (a < 0 && a >= (-0x7fffffff-1)+b))
- {
- *result = a-b;
- return 1;
- }
-
- return 0; /* overflow */
-}
-
-static int
-png_matrix_x_vector(png_const_icc_matrixrp m, png_const_icc_vectorrp v,
- png_icc_vectorrp o)
- /* Apply the matrix (prefixed) to the column vector, updating the vector with
- * the result.
- */
-{
- int row;
-
- /* NOTE: this makes no attempt to avoid intermediate sum overflow. */
- for (row=0; row<3; ++row)
- {
- int column;
- png_int_32 e = 0;
-
- for (column=0; column<3; ++column)
- {
- png_int_32 temp;
-
- if (!png_muldiv(&temp, (*m)[row][column], (*v)[column], 65536) ||
- !png_add(&e, e, temp))
- return 0; /* overflow */
- }
-
- (*o)[row] = e;
- }
-
- return 1;
-}
-
-static int
-png_matrix_x_TmatrixT(png_const_icc_matrixrp m1, png_const_icc_matrixrp m2,
- png_icc_matrixrp o)
- /* NOTE: this passes in the transpose of the input matrix (because it passes
- * rows, not columns to x_vector) and then transposes the output too. To get
- * correct matrix multiplication of two matrices it is necessary to transpose
- * the second matrix both before and after this function.
- */
-{
- int row;
-
- for (row=0; row<3; ++row)
- if (!png_matrix_x_vector(m1, &(*m2)[row], &(*o)[row]))
- return 0;
-
- return 1;
-}
-
-static int
-png_cofactor(png_int_32 *PNG_RESTRICT d, png_const_icc_matrixrp m, int i, int j)
-{
- /* The determinant of a 2x2 matrix is m[0][0]m[1][1] - m[0][1]m[1][0], i and
- * j are in the range 0..2 and select out m[i][] and m[][j].
- */
- png_int_32 a, b;
- const int i_0 = (i>0?0:1);
- const int i_1 = (i<2?2:1);
- const int j_0 = (j>0?0:1);
- const int j_1 = (j<2?2:1);
-
- if (png_muldiv(&a, (*m)[i_0][j_0], (*m)[i_1][j_1], 65536) &&
- png_muldiv(&b, (*m)[i_0][j_1], (*m)[i_1][j_0], 65536))
- {
- png_int_32 temp;
-
- /* The cofactor is (a-b) times (-1)^(i+j): */
- if (((i+j) & 1) != 0)
- temp = a, a = b, b = temp;
-
- if (png_sub(d, a, b))
- return 1;
- }
-
- return 0; /* overflow */
-}
-
-static int
-png_determinant(png_int_32 * PNG_RESTRICT result, png_const_icc_matrixrp m)
-{
- /* Develop from the first row: */
- int j;
- png_int_32 d = 0;
-
- for (j=0; j<3; ++j)
- {
- png_int_32 cofactor, product;
-
- if (png_cofactor(&cofactor, m, 0, j) &&
- png_muldiv(&product, (*m)[0][j], cofactor, 65536) &&
- png_add(&d, d, product))
- continue;
-
- return 0; /* overflow */
- }
-
- *result = d;
- return 1;
-}
-
-static int
-png_invert_matrix(png_const_icc_matrixrp m, png_icc_matrixrp o)
- /* Invert the given matrix. */
-{
- /* This is the algorithm you learnt in highschool; the cofactor method. Each
- * element (i,j) of the original matrix is replaced by the 2x2 determinant of
- * the matrix obtained by striking out everything in the same row or column
- * as the transposed element (j,i), negated if j+i is odd, and the whole
- * divided by the determinant of the original.
- */
- png_int_32 d;
-
- if (png_determinant(&d, m) && d != 0)
- {
- int i;
-
- for (i=0; i<3; ++i)
- {
- int j;
-
- for (j=0; j<3; ++j)
- {
- png_int_32 cofactor;
-
- if (png_cofactor(&cofactor, m, j, i/*transposed*/) &&
- png_muldiv(&(*o)[i][j], cofactor, 65536, d))
- continue;
-
- return 0; /* overflow in element calculation */
- }
- }
-
- return 1;
- }
-
- return 0; /* overflow in determinant or zero determinant */
-}
-
-static int
-png_icc_XYZ_compare(png_const_bytep xyz1, png_const_bytep xyz2)
- /* The arguments are 12 byte big-endian XYZ values as s15Fixed16 values, they
- * are compared and the routine returns 0 if they are within about +/-1/1024
- * else 1. The input values are always big-endian.
- */
-{
- int i;
-
- for (i=0; i<3; ++i)
- {
- int diff = 0;
- int j;
-
- /* This won't overflow. */
- for (j=0; j<3; ++j)
- diff = (diff << 8) + (*xyz1++ - *xyz2++);
-
- if (diff < -1 || diff > 1)
- return 1; /* Too big a difference */
-
- diff = (diff << 8) + (*xyz1++ - *xyz2++);
-
- /* This is the limit on the difference, 64/65536 or +/- 1/1024 (determined
- * by experiment) at present.
- */
- if (diff <= -64 || diff >= 64)
- return 1;
- }
-
- return 0;
-}
-
-static int
-png_icc_check_wtpt(png_const_structrp png_ptr, png_const_charp name,
- png_const_bytep profile, png_icc_vectorrp adapted_white_point)
- /* The mediaWhitePointTag contains an adapted white point (the observer
- * white point) expressed as XYZ tristimulus values. It is always adapted
- * to the PCS illuminant (but is XYZ even when the PCS is PCSLAB encoded.)
- */
-{
- png_uint_32 tag_length;
- png_uint_32 tag_start = png_icc_find_tag(profile, 0x77747074/*'wtpt'*/,
- &tag_length);
-
- if (tag_start > 0 && tag_length == 20)
- {
- png_const_bytep tag = profile+tag_start;
- png_uint_32 temp = png_get_uint_32(tag);
-
- if (temp == 0x58595A20 /* 'XYZ ' */)
- {
- /* The media white point tag is chromatically adapted using the
- * chromatic adaptation matrix and so the adaptation must be inverted
- * to find the original white point. The tag should match the PCS
- * illuminant for display ('mntr') profiles (9.2.34 of the 2010 spec)
- * and, for color space profiles, it is meaningless and apparently
- * unspecified what happens if it does not.
- *
- * This is just a warning at present - one old sRGB profile triggers
- * it; see the note below on the sRGB profile signatures (for the
- * profile "sRGB Profile.icc".) In that profile the mediaWhitePointTag
- * is incorrectly recorded with the D65 (not D50) values.
- */
- if (adapted_white_point != NULL)
- {
- (*adapted_white_point)[0] = png_get_int_32(tag+ 8);
- (*adapted_white_point)[1] = png_get_int_32(tag+12);
- (*adapted_white_point)[2] = png_get_int_32(tag+16);
- }
-
- if (png_icc_XYZ_compare(profile+68, tag+8) == 0)
- return 1;
-
- /* The media white point differs from the PCS illuminant.
- *
- * This deserves a warning; the PNG data stream is technically invalid
- * because either the ICC profile is wrong or the color data in the
- * image is not encoded in the way the PNG specification expects, such
- * that colors with r==g==b are achromatic.
- *
- * Notice that on write the application can write a cHRM chunk to
- * attempt to minimize the problems this might cause, however the data
- * has the property that the maximum of all the colorants (r,g,b ==
- * 1,1,1) does not correspond to an achromatic color and this is
- * impossible to represent in PNG with just cHRM.
- *
- * If this is a monitor of color-space class profile then the profile
- * is wrong (the white point should always be the same as the image
- * adopted white), otherwise a simple warning is produced.
- */
- temp = png_get_uint_32(profile+12);
-
- if (temp == 0x6D6E7472 /* 'mntr' */ ||
- temp == 0x73706163 /* 'spac' */)
- (void)png_icc_profile_error(png_ptr, NULL, name, temp,
- "media white point differs from image adopted white");
-
- else
- png_warning(png_ptr, "ICC profile indicates that image data does "
- "not conform to the PNG specification");
-
- return 0;
- }
-
- else
- {
- (void)png_icc_profile_error(png_ptr, NULL, name, temp,
- "invalid type for mediaWhitePointTag");
- /* Assume it matches the PCS illuminant */
- }
- }
-
- /* else: no mediaWhitePointTag, already reported */
-
- /* Here if the mediaWhitePointTag is absent or invalid, assume the PCS
- * illuminant; this is an error in the profile, but is mostly harmless.
- */
- if (adapted_white_point != NULL)
- {
- (*adapted_white_point)[0] = png_get_int_32(profile+68);
- (*adapted_white_point)[1] = png_get_int_32(profile+72);
- (*adapted_white_point)[2] = png_get_int_32(profile+76);
- }
-
- return 1;
-}
-
-static int /* 0: fail, 1: identity, 2: not identity */
-png_icc_find_chad(png_const_structrp png_ptr, png_const_charp name,
- png_const_bytep profile, png_icc_matrixrp adaptation_matrix,
- png_icc_matrixrp inverted_adaptation_matrix)
- /* The PNG cHRM chunk records the chromaticities of the colorants.
- * Chromaticities are a measure of the appearance of the colors to a
- * typical human observer in a specified viewing environment. The PNG
- * specification does not list a viewing environment, thus we must
- * assume that the values have not been adjusted (adapted) for a
- * particular viewing environment. This means, implicitly, that a PNG
- * image is actually adapted for a white point equivalent to the
- * maximum colorant values, and this is also implied by storing a
- * chromaticity which has a white point derived simply from maximum
- * colorant values.
- *
- * All of the methods for determining the cHRM values depend on
- * reversing the adaptatation to the PCS adopted white (D50); this is
- * because in all cases one or other PCS value has to be used.
- *
- * This routine determines if 'chad' tag is present (if not the adopted white
- * of the scene is D50 and no adaptation was performed) and returns the
- * inverted matrix.
- */
- {
- png_uint_32 tag_start, tag_length;
-
- tag_start = png_icc_find_tag(profile, 0x63686164/*'chad'*/, &tag_length);
-
- if (tag_start > 0)
- {
- if (tag_length == 44) /* This was checked before */
- {
- png_const_bytep tag = profile+tag_start;
- png_uint_32 temp = png_get_uint_32(tag);
-
- if (temp == 0x73663332 /* 'sf32' */)
- {
- /* And the arguments are 9 15.16 values left to right then top
- * to bottom for the forward adaptation matrix, these must be
- * invertible and we need the inverted matrix here.
- */
- png_int_32 * PNG_RESTRICT op = &(*adaptation_matrix)[0][0];
- int i;
-
- tag += 8;
-
- for (i=0; i<9; ++i, tag += 4)
- *op++ = png_get_int_32(tag);
-
- if (png_invert_matrix(
- png_constcast(png_const_icc_matrixrp, adaptation_matrix),
- inverted_adaptation_matrix))
- return 2;
-
- (void)png_icc_profile_error(png_ptr, NULL, name, temp,
- "singular or overflowed ICC profile chromaticAdaptationTag");
- }
-
- else
- (void)png_icc_profile_error(png_ptr, NULL, name, temp,
- "invalid type for ICC profile chromaticAdaptationTag");
- }
-
- else /* Internal libpng error */
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_length,
- "invalid length for ICC profile chromaticAdaptationTag");
- }
-
- else
- {
- /* No 'chad' means no adaptation, so return the identity matrix and '1' to
- * indicate identity.
- */
- memset(adaptation_matrix, 0, sizeof *adaptation_matrix);
- (*adaptation_matrix)[0][0] = 0x10000;
- (*adaptation_matrix)[1][1] = 0x10000;
- (*adaptation_matrix)[2][2] = 0x10000;
- memcpy(inverted_adaptation_matrix, adaptation_matrix,
- sizeof *inverted_adaptation_matrix);
- return 1;
- }
-
- /* Error return */
- return 0;
-}
-
-static void
-png_icc_set_cHRM_from_endpoints(png_const_structrp png_ptr,
- png_colorspacerp colorspace, png_const_charp name, png_const_bytep profile,
- png_const_uint_16p pcsxyz)
- /* The input XYZ values are the three red, green, blue endpoints still
- * adapted to the PCS illuminant. The adaptation is inverted and the result
- * applied to the profile. The result is also checked against the
- * PCS illuminant, which should match the sum of the end points.
- */
-{
- png_icc_matrix adaptation, inverted_adaptation;
- int chad = png_icc_find_chad(png_ptr, name, profile, &adaptation,
- &inverted_adaptation);
-
- if (chad) /* else error finding 'chad' */
- {
- png_byte end_point_white[3*4];
- png_icc_matrix XYZ, end_points;
-
- /* Sanity check the adapted colorants against the PCS white point -
- * because of the checks performed before calling this routine the adapted
- * colorant white point should always match the PCS illuminant.
- */
- {
- int i;
-
- for (i=0; i<3; ++i)
- {
- png_int_32 c = pcsxyz[i];
-
- c += pcsxyz[i+3];
- c += pcsxyz[i+6];
- /* Convert u1Fixed15Number to s15Fixed16Number */
- png_save_int_32(end_point_white+4*i, 2*c);
- }
-
- if (png_icc_XYZ_compare(profile+68, end_point_white) != 0)
- {
- /* The colorant (media) white point differs from the PCS illuminant.
- */
- (void)png_icc_profile_error(png_ptr, NULL, name,
- colorspace->icc_info,
- "colorant white point differs from image adopted white");
- return;
- }
- }
-
- {
- int row, col;
-
- /* The png_icc_matrix is a matrix of s15Fixed16Number, the pcsxyz
- * returned by the CMS is u1Fixed15, so multiply by 65536/32768
- */
- for (row=0; row<3; ++row) for (col=0; col<3; ++col)
- XYZ[row][col] = 2 * pcsxyz[3*row + col];
- }
-
- if (chad == 1) /* identity */
- memcpy(&end_points, XYZ, sizeof end_points);
-
- else /* apply the matrix */
- {
- /* The input XYZ rows are unadapted using the 'chad' matrix and
- * assigned to the end_points rows.
- */
- if (!png_matrix_x_TmatrixT(png_cpm(inverted_adaptation), png_cpm(XYZ),
- &end_points))
- {
- (void)png_icc_profile_error(png_ptr, NULL, name, 0,
- "overflow unadapting colorant end-points");
- return;
- }
- }
-
- {
- png_XYZ cHRM_XYZ;
-
- /* Now we have colorant XYZ values in their unadapted form
- * (i.e. implicitly with an adopted white of the original scene).
- * This is what PNG uses for cHRM, but they need to be
- * converted to the libpng structure.
- *
- * The scaling required is 100000/0x8000, because the input
- * values have been unadapted however they may be well out of the
- * original 16-bit range, so use png_muldiv here.
- *
- * fp = pcs * 100000 / 32768
- * = pcs * 3125 / 1024;
- */
- if (png_muldiv(&cHRM_XYZ.red_X, end_points[0][0], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.red_Y, end_points[0][1], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.red_Z, end_points[0][2], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.green_X, end_points[1][0], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.green_Y, end_points[1][1], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.green_Z, end_points[1][2], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.blue_X, end_points[2][0], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.blue_Y, end_points[2][1], 3125, 1024) &&
- png_muldiv(&cHRM_XYZ.blue_Z, end_points[2][2], 3125, 1024))
- {
- png_xy xy;
-
- /* This function returns 0 on success: */
- if (!png_colorspace_check_XYZ(&xy, &cHRM_XYZ))
- {
- /* TODO: review this, it currently overwrites an explicit cHRM
- * chunk, this seems safer as the cHRM chunk is often calculated
- * incorrectly. In release builds this overwrites silently,
- * in pre-release it will cause an error.
- */
- (void)png_colorspace_set_xy_and_XYZ(png_ptr,
- colorspace, &xy, &cHRM_XYZ,
- (PNG_LIBPNG_BUILD_BASE_TYPE < PNG_LIBPNG_BUILD_RC) ? 1 : 2);
- return;
- }
-
- /* Else the XYZ value was invalid */
- (void)png_icc_profile_error(png_ptr, NULL, name, 0,
- "invalid colorant end-points");
- }
-
- else
- (void)png_icc_profile_error(png_ptr, NULL, name, 0,
- "overflow converting colorant end-points to cHRM");
- }
- }
-}
-
-#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
-/* This is defined below, so a forward declaration is needed here. */
-static png_int_32 png_log16bit(png_uint_32 x);
-#endif
-
-static void
-png_icc_set_gAMA_from_Y(png_const_structrp png_ptr, png_colorspacerp colorspace,
- png_uint_32 y, int is_u1Fixed15/*scale of y*/)
-{
- /* PNG gAMA approximates the actual transfer function used to encode
- * the image data with a single number in a power law equation:
- *
- * image = sample ^ gAMA
- *
- * So given a test image value (GRAY_TEST) and the value of Y, 'y',
- * which the transform produces we can simply deduce the value of gAMA:
- *
- * gAMA = log(GRAY_TEST)/log(y)
- *
- * However this will produce different answers for each point on the
- * profile, unless the profile really is a simple power law transform
- * (this is hardly ever found in practice.)
- *
- * In fact most image encoding uses some variant of a linear segment
- * followed by a power law - sRGB, ITU REC709 and L*a*b* all do this.
- * We know (from the PNG spec) that sRGB should be encoded with a gAMA
- * of .45455 (1/2.2) and it is easy to find that the sRGB transfer
- * function crosses this power law transfer at about 0.389222. This is
- * 25508 as a 16-bit value or 99.25 in 8-bits.
- */
-# define GRAY_TEST 99 /* /255 */
- /*
- * Feeding this number through the above equations (see
- * contrib/tools/icc-gamma.bc) gives the following results:
- *
- * sRGB: 45455
- * L*a*b*: 42069
- * 2.2 power law: 45455
- * ITU REC-709: 52333 (because of the linear segment)
- * Apple Mac: 65087 (by applying a 1.45 power law to sRGB)
- */
-# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
- double dl;
-
- if (is_u1Fixed15) y *= 2;
-
- /* The constant is 100000*log(99/255) */
- dl = floor(.5 - 94614.36950238362194 / log(y / 65535.));
-
- /* We expect a reasonable gAMA value from this calculation; check for a
- * number in the range 20,000 (.2) to 200,000 (2).
- */
- if (dl > 20000. && dl < 200000.)
- {
- png_int_32 l = (png_int_32)dl;
-# else
- /* The fixed point calculation is somewhat more complex.
- *
- * Because PCSXYZ is scaled by 32768, whereas the input to png_log16bit
- * is scaled by 65535 the value of 'l' corresponds to y*32768/65535,
- * thus the required calculation is:
- *
- * 100000 * 89456.43138
- * gAMA = --------------------
- * l + 65535
- *
- * l = 65536*-log2(y)
- * 89456 = -65536*log2(99/255)
- * 65535 = -65536*log2(32768/65535) (but only for PCSXYZ)
- *
- * 8945643138 = 1581061 * 5658
- */
- png_int_32 l = png_log16bit(y);
-
- if (is_u1Fixed15 && l >= 0)
- l += 65535; /* Overflow will just make this negative */
-
- if (png_muldiv(&l, 1581061, 5658, l) && l >= 20000 && l <= 200000)
- {
-# endif
- if (png_colorspace_check_gamma(png_ptr, colorspace, l,
- 0/*from profile*/))
- {
- /* Store this gamma value. */
- colorspace->gamma = l;
- colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
- }
- }
-
- else
- {
- /* This is just a warning that the algorithm has failed in an
- * apparently extreme way. (This is here mainly to discover
- * profiles on which the algorithm doesn't work.)
- */
- png_warning(png_ptr, "ICC profile gamma value out of range");
- }
-}
-#endif /* PNG_ICC_SUPPORTED */
-
int /* PRIVATE */
png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
png_const_charp name, png_uint_32 profile_length,
@@ -2702,7 +2030,6 @@
png_uint_32 tag_count = png_get_uint_32(profile+128);
png_uint_32 itag;
png_const_bytep tag = profile+132; /* The first tag */
- png_uint_32 tags = colorspace->icc_info; /* Bitmask of significant tags */
/* First scan all the tags in the table and add bits to the icc_info value
* (temporarily in 'tags').
@@ -2712,7 +2039,6 @@
png_uint_32 tag_id = png_get_uint_32(tag+0);
png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
- png_uint_32 tag_flag = 0;
/* The ICC specification does not exclude zero length tags, therefore the
* start might actually be anywhere if there is no data, but this would be
@@ -2730,345 +2056,12 @@
"ICC profile tag start not a multiple of 4");
}
- /* Skip short tags, even if there is enough space for the type signature
- * all the types used by libpng need data.
- */
- if (tag_length < 8)
- {
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "short ICC profile tag skipped");
- continue;
- }
-
/* This is a hard error; potentially it can cause read outside the
* profile.
*/
if (tag_start > profile_length || tag_length > profile_length - tag_start)
return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
"ICC profile tag outside profile");
-
- /* Check the tag_id for the specific tags which must be present for the
- * profile to be valid and for those which are needed to generate cHRM and
- * gAMA values. The errors in here are all soft; they just cause a
- * warning on read and the tag is skipped. On write by they cause a
- * png_app_error, which the application can override.
- */
- switch (tag_id)
- {
- case 0x64657363: /* 'desc' - profileDescriptionTag */
- tags |= PNG_ICC_profileDescriptionTag;
- break;
-
- case 0x63707274: /* 'cprt' - copyrightTag */
- tags |= PNG_ICC_copyrightTag;
- break;
-
- case 0x77747074: /* 'wtpt' - mediaWhitePointTag */
- /* The length is fixed because the tag has to be an XYZType (12
- * bytes).
- */
- if (tag_length != 20)
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_length,
- "invalid media white point length");
-
- else
- tags |= PNG_ICC_mediaWhitePointTag;
- break;
-
- case 0x63686164: /* 'chad' - chromaticAdaptationTag */
- /* The tag must be a 9 element array of s15Fixed16ArrayType, the tag
- * is optional, if absent it indicates that the original adapted
- * white was the same as the PCS adopted white - D50.
- */
- if (tag_length != 44)
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_start,
- "invalid chromatic adaptation matrix length");
-
- else
- tags |= PNG_ICC_chromaticAdaptationTag;
- break;
-
- case 0x7258595A: /* 'rXYZ' - redMatrixColumnTag */
- tag_flag = PNG_ICC_redMatrixColumnTag;
- goto check_MatrixColumnTag_length;
-
- case 0x6758595A: /* 'gXYZ' - greenMatrixColumnTag */
- tag_flag = PNG_ICC_greenMatrixColumnTag;
- goto check_MatrixColumnTag_length;
-
- case 0x6258595A: /* 'bXYZ' - blueMatrixColumnTag */
- tag_flag = PNG_ICC_blueMatrixColumnTag;
- goto check_MatrixColumnTag_length;
-
- check_MatrixColumnTag_length:
- /* Tag must be an XYZType with one XYZNumber element, the PCS
- * encoding should be PCSXYZ, however lcms seems to use these tags
- * to record the end-point XYZ (i.e. it is using MatrixColumnTag in
- * place of colorantTableTag!) This is probably eroneous but is not
- * clearly outlawed by the specification.
- */
- if (tag_length != 20)
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid <rgb>MatrixColumnTag length");
-
- else if (!(tags & PNG_ICC_RGB))
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid <rgb>MatrixColumnTag on monochrome profile");
-
- else
- tags |= tag_flag;
- break;
-
- case 0x72545243: /* 'rTRC' - redTRCTag */
- tag_flag = PNG_ICC_redTRCTag;
- goto check_rgbTRCTag_encoding;
-
- case 0x67545243: /* 'gTRC' - greenTRCTag */
- tag_flag = PNG_ICC_greenTRCTag;
- goto check_rgbTRCTag_encoding;
-
- case 0x62545243: /* 'bTRC' - blueTRCTag */
- tag_flag = PNG_ICC_blueTRCTag;
- goto check_rgbTRCTag_encoding;
-
- check_rgbTRCTag_encoding:
- /* The TRCTags feed into the MatrixColumnTag matrix and this is
- * never going to work if the encoding is PCSLAB, so disallow the
- * TRC tags here. The MatrixColumnTags are still accumulated, this
- * requires special handling below.
- */
- if (!(tags & PNG_ICC_RGB))
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid <rgb>TRCTag on monochrome profile");
-
- else if (!(tags & PNG_ICC_PCSXYZ))
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid <rgb>TRCTag (requires PCSXYZ encoding)");
-
- else
- goto check_TRCTag_length;
-
- break; /* skip on error */
-
- case 0x6B545243: /* 'kTRC' - grayTRCTag */
- if ((tags & PNG_ICC_RGB) != 0)
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid grayTRCTag on RGB profile");
-
- else
- {
- tag_flag = PNG_ICC_grayTRCTag;
- goto check_TRCTag_length;
- }
-
- break; /* skip on error */
-
- check_TRCTag_length:
- /* Permitted types are curveType or parametricCurveType, curveType
- * is shortest, only 12 bytes for an identity response.
- */
- if (tag_length < 12)
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid <rgbk>TRCTag length");
-
- else
- tags |= tag_flag;
- break;
-
- case 0x41324230: /* 'A2B0' - AToB0Tag */
- tag_flag = PNG_ICC_AToB0Tag;
- goto check_AToBxTag_length;
-
- case 0x42324130: /* 'B2A0' - BToA0Tag */
- tag_flag = PNG_ICC_BToA0Tag;
- goto check_AToBxTag_length;
-
- case 0x41324231: /* 'A2B1' - AToB1Tag */
- tag_flag = PNG_ICC_AToB1Tag;
- goto check_AToBxTag_length;
-
- case 0x42324131: /* 'B2A1' - BToA1Tag */
- tag_flag = PNG_ICC_BToA1Tag;
- goto check_AToBxTag_length;
-
- case 0x41324232: /* 'A2B2' - AToB2Tag */
- tag_flag = PNG_ICC_AToB2Tag;
- goto check_AToBxTag_length;
-
- case 0x42324132: /* 'B2A2' - BToA2Tag */
- tag_flag = PNG_ICC_BToA2Tag;
- goto check_AToBxTag_length;
-
- check_AToBxTag_length:
- /* Permitted types are lut8Type, lut16Type and one or other of
- * lutAToBType or lutBToAType (which are the same length.) The
- * CLUT forms have a 32 byte header, the headers on the others are
- * longer. In fact all need more data than this in practice.
- */
- if (tag_length < 32)
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid LUT Tag length");
-
- else
- tags |= tag_flag;
- break;
-
- /* NOTE: the DToB and BToD tags, while permitted, cannot be used on
- * PNG data because it can never be floating point.
- */
-
- case 0x6368726D: /* 'chrm' - chromaticityTag */
- /* May exist for RGB or GRAY color spaces and this determines the
- * number of channels, the permitted type is chromaticityType.
- */
- if (tag_length != 12 + 8*PNG_ICC_CHANNELS(tags))
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid chromaticityTag length");
-
- else
- tags |= PNG_ICC_chromaticityTag;
- break;
-
- case 0x636C7274: /* 'clrt' - colorantTableTag */
- /* The permitted type is colorantTableType and the number of
- * colorants are determined by the number of channels, as above.
- */
- if (tag_length != 12 + 38*PNG_ICC_CHANNELS(tags))
- (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
- "invalid colorantTableTag length");
-
- else
- tags |= PNG_ICC_colorantTableTag;
- break;
-
- case 0x67616D74: /* 'gamt' - gamutTag */
- /* The permitted types are lut8Type, lut16Type or lutBToAType
- * (required by output LUT based profiles.)
- */
- tag_flag = PNG_ICC_gamutTag;
- goto check_AToBxTag_length;
-
- default:
- break;
- }
- }
-
- /* Cache the list of found tags for use later */
- colorspace->icc_info = tags;
-
- /* The required tags depend on the profile class and, within the class,
- * the type of profile - N-component LUT based ('LUT'), Three-component
- * matrix-based ('RGB Matrix'), or monochrome ('monochrome').
- *
- * All profiles except DeviceLink profiles require PNG_ICC_REQUIRED_ALL.
- */
- {
- png_uint_32 profile_class = png_get_uint_32(profile+12);
- png_uint_32 required_tags = PNG_ICC_REQUIRED_BASE;
- png_uint_32 permitted_tags = ~PNG_ICC_ALL_TRC; /* LUT based */
- int LUT_based = 1;
-
- /* Work out a profile independent setting then update this below if the
- * profile had different requirements.
- */
- if (tags & PNG_ICC_ALL_TRC)
- {
- /* A TRCTag is present, check the colorspace to find out what is
- * permitted and required.
- */
- if (tags & PNG_ICC_RGB) /* 3-component */
- {
- required_tags |= PNG_ICC_REQUIRED_RGB_MATRIXTRC;
- permitted_tags |= PNG_ICC_REQUIRED_RGB_MATRIXTRC;
- }
-
- else /* monochrome */
- {
- required_tags |= PNG_ICC_grayTRCTag;
- permitted_tags |= PNG_ICC_grayTRCTag;
- }
-
- LUT_based = 0;
- }
-
- else
- {
- /* No MatrixTRC - must be LUT based, the AToB0Tag is required */
- required_tags |= PNG_ICC_AToB0Tag;
- }
-
- switch (profile_class)
- {
- case 0x73636E72: /* 'scnr' - the input profile class */
- /* All conditions match the default. */
- break;
-
- case 0x6D6E7472: /* 'mntr' - a display device profile */
- /* On a monitor profile the N-Component LUT-based profiles require a
- * BToA0 tag.
- */
- if (LUT_based)
- required_tags |= PNG_ICC_BToA0Tag;
-
- break;
-
- case 0x70727472: /* 'prtr' - an output device profile */
- /* For output profiles the three-component matrix based variant is
- * not permitted, and all the various LUT-based tags are required.
- * For LUT based profiles the colorantTableTag is only required for
- * xCLR profiles, which have already been excluded.
- */
- if (LUT_based)
- required_tags |= PNG_ICC_ALL_LUT | PNG_ICC_gamutTag;
-
- else
- permitted_tags &= ~PNG_ICC_REQUIRED_RGB_MATRIXTRC;
-
- break;
-
- case 0x6C696E6B: /* 'link' */
- case 0x61627374: /* 'abst' */
- /* Already excluded, but for reference: */
- required_tags |= PNG_ICC_AToB0Tag;
- /* 'link' + PNG_ICC_profileSequenceDescTag */
- permitted_tags &= ~(PNG_ICC_ALL_TRC | PNG_ICC_ALL_LUT);
- permitted_tags |= PNG_ICC_AToB0Tag;
- break;
-
- case 0x73706163: /* 'spac' */
- /* The Matrix/TRC tags are not permitted on color-space profiles,
- * and BToA0 must be present.
- */
- required_tags |= PNG_ICC_AToB0Tag | PNG_ICC_BToA0Tag;
- permitted_tags &= ~PNG_ICC_ALL_TRC;
- break;
-
- case 0x6E6D636C: /* 'nmcl' */
- /* Not supported at all. */
- required_tags = PNG_ICC_REQUIRED_BASE;
- permitted_tags = PNG_ICC_REQUIRED_BASE;
- break;
-
- default:
- /* To allow for future expansion just use the base input device
- * settings.
- */
- break;
- }
-
- /* Then the test is that all the required tags are present and all the
- * present tags are permitted. The warning message is somewhat difficult
- * to decode, however occurences are extremely rare. Note that tags which
- * were previously detected to be invalid won't be in the 'tags'
- * information and will probably result in a second warning here.
- */
- if ((required_tags & ~tags) != 0)
- (void)png_icc_profile_error(png_ptr, NULL, name,
- (required_tags & ~tags), "required tags missing");
-
- if ((tags & ~permitted_tags) != 0)
- (void)png_icc_profile_error(png_ptr, NULL, name,
- (tags & ~permitted_tags), "unpermitted tags present");
}
return 1; /* success, maybe with warnings */
@@ -3250,140 +2243,19 @@
}
#endif
+#ifdef PNG_sRGB_SUPPORTED
void /* PRIVATE */
-png_icc_set_gAMA_and_cHRM(png_const_structrp png_ptr,
- png_colorspacerp colorspace, png_const_charp name, png_const_bytep profile,
- uLong adler)
+png_icc_set_sRGB(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
{
-# ifdef PNG_sRGB_SUPPORTED
- {
- /* 1) Is this profile one of the known ICC sRGB profiles? If it is, just
- * set the sRGB information.
- */
- int set = png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler);
-
- /* It is, simply set the profile intent. */
- if (set && png_colorspace_set_sRGB(png_ptr, colorspace,
- (int)/*already checked*/png_get_uint_32(profile+64)))
- {
-# if PNG_LIBPNG_BUILD_BASE_TYPE < PNG_LIBPNG_BUILD_RC
- /* In pre-RC builds run sRGB profiles through the profile checking
- * code; this is because it is a useful validation of that code and
- * because there is some evidence that not all sRGB profiles are
- * created alike. Don't do this for the known-broken sRGB profiles,
- * it just produces extra errors. (So this looks a little
- * confusing; if set is '1', a believed-ok sRGB profile, continue
- * checking, but if it '2' or more stop here.
- */
- if (set >= 2)
-# endif
- return;
- }
- }
-# else
- PNG_UNUSED(adler)
-# ifndef PNG_ICC_SUPPORTED
- PNG_UNUSED(png_ptr)
- PNG_UNUSED(colorspace)
- PNG_UNUSED(profile)
-# endif
-# endif
-
-#ifdef PNG_ICC_SUPPORTED
- /* 2) Attempt to extract the gAMA and cHRM information from non-sRGB
- * profiles. Always set the rendering intent from the profile.
- *
- * Doing this requires a large body of code to parse an ICC profile and
- * implement ICC color correction. This is because the profile tags that
- * store colorant information are rarely, if ever, present in practice.
- * It is therefore necessary to follow the algorithm described in section
- * 10.4 (colorantTableType) and transform the RGB colorants through the
- * full profile.
- *
- * Similarly to calculate a value for the PNG gAMA chunk it is necessary
- * to process at least one gray level through the transform.
- *
- * The code to do this relies on a CMS implementation provided by the
- * application.
+ /* Is this profile one of the known ICC sRGB profiles? If it is, just set
+ * the sRGB information.
*/
- if (png_ptr->cms_transform_fn != NULL) /* Else no support */
- {
- png_uint_32 info = colorspace->icc_info;
- png_alloc_size_t sample_bytes = 0/*error*/;
- png_uint_16 pcsxyz[4/*samples*/ * 3/*components*/];
-
- /* The input array; we want one sample to work out the gAMA chunk value
- * and, for color images, three samples with the colorant endpoints. The
- * sample used for gAMA calculation is discussed below. This gives the
- * following byte array which works for either case (RGB or grayscale):
- */
- static const png_byte samples[] =
- {
- GRAY_TEST, GRAY_TEST, GRAY_TEST, /* see png_icc_set_gAMA_from_Y */
- 255, 0, 0, /* red */
- 0, 255, 0, /* green */
- 0, 0, 255 /* blue */
- };
-
- /* The cHRM chunk is only useful for an RGB image/profile, note that the
- * check on 'set' causes pre-RC builds to do a spurious check on sRGB
- * profiles, this validates the libpng algorithms because the known sRGB
- * profiles are known to be correct (except for the 'broken' ones which
- * are excluded by the 'set >= 2' test above.)
- */
- if ((info & PNG_ICC_RGB) != 0)
- {
- if ((info & PNG_ICC_mediaWhitePointTag) == 0 /* Assume D50 */ ||
- png_icc_check_wtpt(png_ptr, name, profile, NULL))
- {
- /* The mediaWhitePointTag is absent (an error, but we assume
- * it was meant to be D50) or is sufficiently close to the PCS
- * illuminant. This is the normal case.
- *
- * The code does not actually need the media white point,
- * because it is the same as the PCS illuminant if we get to
- * this point.
- */
- sample_bytes = sizeof samples; /* i.e. all of them */
- }
-
- else
- {
- /* The mediaWhitePointTag has a major problem or doesn't match
- * the PCS illuminant. A cHRM chunk cannot be generated for
- * this profile, so just do gAMA:
- */
- sample_bytes = 3; /* Just the gray value */
- }
- }
-
- else
- {
- /* This is a grayscale image/profile, so just do gAMA */
- sample_bytes = 1;
- }
-
- /* Now apply the transform. */
- if (png_ptr->cms_transform_fn(png_ptr, png_ptr->cms_data_ptr, samples,
- sample_bytes, pcsxyz, sizeof pcsxyz, 0/*format*/,
- PNG_sRGB_INTENT_RELATIVE))
- {
- /* First handle the gAMA based on the 'Y' value in pcsxyz, it is either
- * a grayscale 16-bit achromatic value with 1.0 represented as 65535 or
- * a the Y part of a PCSXYZ value with 1.0 represented as 32768.
- */
- png_uint_32 y = (sample_bytes != 1 ? pcsxyz[1] : pcsxyz[0]);
- png_icc_set_gAMA_from_Y(png_ptr, colorspace, y, sample_bytes != 1);
-
- if (sample_bytes == sizeof samples) /* RGB samples too */
- png_icc_set_cHRM_from_endpoints(png_ptr, colorspace, name,
- profile, pcsxyz+3/*skip the gamma sample*/);
- } /* sample_bytes > 0 */
- }
-#else
- PNG_UNUSED(name)
-#endif /* PNG_ICC_SUPPORTED */
+ if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler))
+ (void)png_colorspace_set_sRGB(png_ptr, colorspace,
+ (int)/*already checked*/png_get_uint_32(profile+64));
}
+#endif /* PNG_READ_sRGB_SUPPORTED */
int /* PRIVATE */
png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
@@ -3399,7 +2271,7 @@
png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
profile))
{
- png_icc_set_gAMA_and_cHRM(png_ptr, colorspace, name, profile, 0);
+ png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
return 1;
}
diff --git a/png.h b/png.h
index 897416b..b6f70e2 100644
--- a/png.h
+++ b/png.h
@@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.0beta31 - October 26, 2012
+ * libpng version 1.6.0beta31 - November 1, 2012
* Copyright (c) 1998-2012 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.6.0beta31 - October 26, 2012: Glenn
+ * libpng versions 0.97, January 1998, through 1.6.0beta31 - November 1, 2012: Glenn
* See also "Contributing Authors", below.
*
* Note about libpng version numbers:
@@ -198,7 +198,7 @@
*
* This code is released under the libpng license.
*
- * libpng versions 1.2.6, August 15, 2004, through 1.6.0beta31, October 26, 2012, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.0beta31, November 1, 2012, are
* Copyright (c) 2004, 2006-2012 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:
@@ -310,7 +310,7 @@
* Y2K compliance in libpng:
* =========================
*
- * October 26, 2012
+ * November 1, 2012
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
@@ -378,7 +378,7 @@
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.0beta31"
#define PNG_HEADER_VERSION_STRING \
- " libpng version 1.6.0beta31 - October 26, 2012\n"
+ " libpng version 1.6.0beta31 - November 1, 2012\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
@@ -3204,90 +3204,6 @@
(png_structrp png_ptr, int allowed));
#endif
-/*******************************************************************************
- * CMS (Color Management System) SUPPORT
- *******************************************************************************
- *
- * The PNG file format supports embedding of ICC profiles, however libpng
- * provides only limited support for handling these profiles. In particular
- * libpng includes no support for using the profile to transform data into a
- * different color space. If PNG_ICC_SUPPORTED is set, however, libpng allows
- * an external CMS to be registered into the png_struct after it is created.
- * This simply records a single callback function to transform samples between
- * two color spaces.
- */
-typedef struct png_cms_data *png_cms_datap, * PNG_RESTRICT png_cms_datarp;
- /* An opaque type defined by a specific implementation to hold whatever data
- * is required. The implementation is responsible for all storage management
- * of this data.
- */
-
-typedef PNG_CALLBACK(png_uint_32, *png_cms_transform_ptr,
- (png_const_structrp png_ptr, png_cms_datarp data_ptr, png_const_voidp input,
- png_alloc_size_t input_bytes, png_voidp output,
- png_alloc_size_t output_bytes, int format, int intent));
- /* Transform input[input_bytes] of samples to output[output_bytes]. The
- * format of the input and output is given by 'format'. The function shall
- * transform only so much input as there is space for in the output buffer.
- * 'intent' is the ICC intent required for the transformation.
- *
- * The connection space data (which may be either the input or output) is
- * always either 16-bit achromatic data (as described in Annex F.2 of the v4
- * ICC specification) for grayscale PNG files or 16-bit PCSXYZ data for RGB
- * PNG files. Any alpha channel may be present in the connection space, in
- * which case it is a 16-bit channel and the alpha value follows each sample.
- * Samples are not pre-multiplied by the alpha. The connection space data
- * is stored as an array of png_uint_16 values in the native representation
- * of the machine.
- *
- * For transforms to the connection space the input is in the PNG format
- * using either 8-bit or big-endian 16-bit components. 16-bit quantities use
- * the PNG layout - big-endian in two bytes.
- *
- * By default a transform from the connection space will be to 8-bit sRGB
- * (with an optional alpha value) or 8-bit gray encoded with the inverse of
- * the sRGB transfer function. If png_set_cms_output is called, however, the
- * transform may produce arbitrary output in a format potentially not handled
- * by libpng.
- *
- * It is valid to register a CMS when writing a PNG image, however the CMS
- * will only be used to generate appropriate values for cHRM and gAMA of the
- * profile.
- *
- * The format parameter is made up of the following flags:
- */
-#define PNG_CMS_FORMAT_FLAG_ALPHA 0x01 /* data has alpha channel */
-#define PNG_CMS_FORMAT_FLAG_16BIT 0x02 /* 16-bit image components else 8-bit */
-#define PNG_CMS_FORMAT_FLAG_PCS 0x04 /* input is PCS data, else image data */
-
-#ifdef PNG_ICC_SUPPORTED
-PNG_EXPORT(243, void, png_set_cms, (png_structrp png_ptr,
- png_cms_datap cms_data_ptr, png_cms_transform_ptr cms_transform_function));
- /* Register the CMS transform function. The given pointer will be passed to
- * every call to the function.
- */
-
-#ifdef PNG_READ_SUPPORTED
-PNG_EXPORT(244, void, png_set_cms_output, (png_structrp png_ptr,
- int bytes_per_pixel, int rendering_intent));
- /* Inform libpng that the transform function will write output requiring
- * bytes_per_pixel bytes for each sample. The output need not be in any
- * particular format, for example the transform could produce a print
- * separation. libpng will provide a buffer equal in size to the row width
- * of the image times the bytes_per_pixel value (and the application must
- * provide this size buffer.)
- *
- * This also forces the CMS transform to be used even when it is apparently
- * not necessary (e.g. for sRGB input data, or for PNG files with no ICC
- * profile information and no sRGB data.) The intent overrides the default,
- * which is perceptual.
- */
-#endif
-#endif
-/*******************************************************************************
- * END OF CMS (Color Management System) SUPPORT
- ******************************************************************************/
-
/* Maintainer: Put new public prototypes here ^, in libpng.3, and project
* defs
*/
@@ -3297,7 +3213,7 @@
* scripts/symbols.def as well.
*/
#ifdef PNG_EXPORT_LAST_ORDINAL
- PNG_EXPORT_LAST_ORDINAL(244);
+ PNG_EXPORT_LAST_ORDINAL(242);
#endif
#ifdef __cplusplus
diff --git a/pngpriv.h b/pngpriv.h
index 6c46e47..1a56363 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -1467,16 +1467,15 @@
png_colorspacerp colorspace, png_const_charp name,
png_uint_32 profile_length,
png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
-PNG_INTERNAL_FUNCTION(void,png_icc_set_gAMA_and_cHRM,(
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,(
png_const_structrp png_ptr, png_colorspacerp colorspace,
- png_const_charp name, png_const_bytep profile, uLong adler), PNG_EMPTY);
+ png_const_bytep profile, uLong adler), PNG_EMPTY);
/* 'adler' is the Adler32 checksum of the uncompressed profile data. It may
* be zero to indicate that it is not available. It is used, if provided,
* as a fast check on the profile when checking to see if it is sRGB.
- * The routine may not set gAMA or cHRM if there are problems in the profile,
- * however none of these problems are fatal (the profile has already been
- * checked.)
*/
+#endif
#endif /* iCCP */
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
diff --git a/pngrutil.c b/pngrutil.c
index b76b8dd..bb4c1df 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -1276,7 +1276,7 @@
return;
}
- png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
+ (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
png_colorspace_sync(png_ptr, info_ptr);
}
#endif /* PNG_READ_sRGB_SUPPORTED */
@@ -1447,13 +1447,12 @@
png_crc_finish(png_ptr, length);
finished = 1;
- /* Set the gAMA and cHRM information, this
- * checks for a known sRGB profile. The
- * result is 0 on error.
- */
- png_icc_set_gAMA_and_cHRM(png_ptr,
- &png_ptr->colorspace, keyword, profile,
- png_ptr->zstream.adler);
+# ifdef PNG_sRGB_SUPPORTED
+ /* Check for a match against sRGB */
+ png_icc_set_sRGB(png_ptr,
+ &png_ptr->colorspace, profile,
+ png_ptr->zstream.adler);
+# endif
/* Steal the profile for info_ptr. */
if (info_ptr != NULL)
diff --git a/pngset.c b/pngset.c
index 30a348e..85a1c14 100644
--- a/pngset.c
+++ b/pngset.c
@@ -578,7 +578,7 @@
if (png_ptr == NULL || info_ptr == NULL)
return;
- png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
+ (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
png_colorspace_sync_info(png_ptr, info_ptr);
}
@@ -1549,35 +1549,4 @@
png_ptr->num_palette_max = -1;
}
#endif
-
-#ifdef PNG_ICC_SUPPORTED
-void PNGAPI
-png_set_cms(png_structrp png_ptr, png_cms_datap cms_data_ptr,
- png_cms_transform_ptr cms_transform_function)
-{
- png_ptr->cms_transform_fn = cms_transform_function;
- png_ptr->cms_data_ptr = cms_data_ptr;
-}
-
-#ifdef PNG_READ_SUPPORTED
-void PNGAPI
-png_set_cms_output(png_structrp png_ptr, int bytes_per_pixel,
- int rendering_intent)
-{
- if (png_ptr->mode & PNG_IS_READ_STRUCT)
- {
- png_ptr->cms_bytes_per_pixel = bytes_per_pixel;
- png_ptr->cms_intent = rendering_intent;
-
- /* A CMS must be registered before calling this */
- if (png_ptr->cms_transform_fn == NULL)
- png_app_error(png_ptr, "no CMS registered to transform output");
- }
-
- else
- png_app_error(png_ptr, "attempt to do CMS tranform on write");
-}
-#endif /* PNG_READ_SUPPORTED */
-#endif /* PNG_ICC_SUPPORTED */
-
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
diff --git a/pngstruct.h b/pngstruct.h
index ab1d789..3179165 100644
--- a/pngstruct.h
+++ b/pngstruct.h
@@ -119,7 +119,6 @@
#ifdef PNG_COLORSPACE_SUPPORTED
png_xy end_points_xy; /* End points as chromaticities */
png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */
- png_uint_32 icc_info; /* Record of information from the colorspace */
png_uint_16 rendering_intent; /* Rendering intent of a profile */
#endif
@@ -129,74 +128,6 @@
typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
-/* ICC specific flags for the 'icc_info' field. */
-/* The first four bits are for information defined from the profile, the
- * remainder of the bits indicate the presence of specific tags. The #define
- * names are derived from the tag name in the ICC 2010 (v4) specification.
- */
-# define PNG_ICC_PCSXYZ 0x00000001U /* PCSXYS, else PCSLAB */
-# define PNG_ICC_RGB 0x00000002U /* 'RGB ', else 'GRAY ' */
- /* 0x00000004U reserved */
- /* 0x00000008U reserved */
-
- /* A utility to return the number of channels on the A side of the transform
- * given an info value (can be optimized).
- */
-# define PNG_ICC_CHANNELS(info) ((((info)&PNG_ICC_RGB)?2U:0U)+1U)
-
- /* The profile description and copyright must be present in all valid ICC
- * profiles, however libpng does not use them so absence is just reported as
- * a warning. The media white point should be present too, but if it isn't
- * all we lose is the ability to know if it differs from the adopted white
- * (i.e. the information that the device maxima are actually colored;
- * a non-white substrate for a printer, or an uncorrected scan for example.)
- * The chromaticAdaptationTag tells us that the adopted white of the original
- * differs from the PCS adopted white (which is identical to the PCS
- * illuminant and should always be D50).
- */
-# define PNG_ICC_profileDescriptionTag 0x00000010U /* required */
-# define PNG_ICC_copyrightTag 0x00000020U /* required */
-# define PNG_ICC_mediaWhitePointTag 0x00000040U /* required */
-# define PNG_ICC_chromaticAdaptationTag 0x00000080U /* optional */
-
- /* Tags that are required in all profiles (except DeviceLink): */
-# define PNG_ICC_REQUIRED_BASE 0x00000070U
-
- /* Other tags have to appear in specific profiles. In general a profile must
- * either contain appropriate TRC and (for RGB profiles) matrix tags *or* it
- * must contain AToB0 and BToA0 - the CLUT based transforms to an absolute
- * colorimetric PCS. In the TRC case the PCS encoding must be PCSXYZ.
- */
-# define PNG_ICC_redMatrixColumnTag 0x00000100U
-# define PNG_ICC_greenMatrixColumnTag 0x00000200U
-# define PNG_ICC_blueMatrixColumnTag 0x00000400U
- /* 0x00000800U reserved */
-# define PNG_ICC_redTRCTag 0x00001000U
-# define PNG_ICC_greenTRCTag 0x00002000U
-# define PNG_ICC_blueTRCTag 0x00004000U
-# define PNG_ICC_grayTRCTag 0x00008000U
-# define PNG_ICC_REQUIRED_RGB_MATRIXTRC 0x00007700U /* Required for RGB TRC */
-# define PNG_ICC_ALL_TRC 0x0000f000U /* Includes all TRCTags */
-# define PNG_ICC_REQUIRED_MATRIX 0x00000700U /* All MatrixColumnTags */
-
-# define PNG_ICC_AToB0Tag 0x00010000U
-# define PNG_ICC_BToA0Tag 0x00020000U
-# define PNG_ICC_AToB1Tag 0x00040000U
-# define PNG_ICC_BToA1Tag 0x00080000U
-# define PNG_ICC_AToB2Tag 0x00100000U
-# define PNG_ICC_BToA2Tag 0x00200000U
-# define PNG_ICC_AToB_TAGS 0x00050000U /* Just AToB0 and AToB1 */
-# define PNG_ICC_ALL_LUT 0x003f0000U
- /* 0x00400000U reserved */
- /* 0x00800000U reserved */
-
- /* The ICC profile specification allows for shortcuts in the cHRM calculation
- * via the colorant table (clrt) or the chromaticity tag (chrm).
- */
-# define PNG_ICC_chromaticityTag 0x01000000U
-# define PNG_ICC_colorantTableTag 0x02000000U
-# define PNG_ICC_gamutTag 0x04000000U
-
/* General flags for the 'flags' field */
#define PNG_COLORSPACE_HAVE_GAMMA 0x0001
#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002
@@ -548,17 +479,5 @@
png_colorspace colorspace;
#endif
#endif
-
-#ifdef PNG_ICC_SUPPORTED
- /* Full ICC support requires an external CMS be registered in the png_struct
- * after it is created. The registration stores this information.
- */
- png_cms_transform_ptr cms_transform_fn;
- png_cms_datap cms_data_ptr;
-#ifdef PNG_READ_SUPPORTED
- int cms_bytes_per_pixel; /* non-standard output size */
- int cms_intent; /* for non-standard output */
-#endif
-#endif /* PNG_ICC_SUPPORTED */
};
#endif /* PNGSTRUCT_H */
diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa
index e42f450..b66ca80 100644
--- a/scripts/pnglibconf.dfa
+++ b/scripts/pnglibconf.dfa
@@ -151,7 +151,7 @@
# These are currently experimental features; define them if you want (NOTE:
# experimental options must be disabled before they are defined in this file!)
-option ICC disabled
+# NONE
# Note that PNG_USR_CONFIG only has an effect when building
# pnglibconf.h
@@ -318,20 +318,6 @@
option SAFE_LIMITS enables USER_LIMITS disabled
= SAFE_LIMITS SAFE_LIMITS
-# ICC profile support; basic ICC profile support is enabled if iCCP chunk read
-# or write is enabled. The application must perform all iCCP profile handling
-# itself. If full support is enabled with the option below libpng will attempt
-# to do more processing using the profile data itself, this includes setting
-# appropriate values for cHRM and gAMA chunks if not present in the stream.
-#
-# ICC profile support is not build in to core libpng because of the size of the
-# code required; an external ICC implementation must be passed to libpng to
-# enable it.
-#
-# WARNING: this option is CURRENTLY UNTESTED because a test CMS implementation
-# has not yet been written, as a result it is disabled in current beta builds.
-option ICC requires iCCP enables SAVE_INT_32
-
# All of the following options relate to code capabilities for
# processing image data before creating a PNG or after reading one.
# You can remove these capabilities safely and still be PNG
diff --git a/scripts/pnglibconf.h.prebuilt b/scripts/pnglibconf.h.prebuilt
index 59cc1ce..759e16b 100644
--- a/scripts/pnglibconf.h.prebuilt
+++ b/scripts/pnglibconf.h.prebuilt
@@ -3,7 +3,7 @@
/* pnglibconf.h - library build configuration */
-/* Libpng 1.6.0beta31 - October 26, 2012 */
+/* Libpng 1.6.0beta31 - November 1, 2012 */
/* Copyright (c) 1998-2012 Glenn Randers-Pehrson */
@@ -63,7 +63,6 @@
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
#define PNG_hIST_SUPPORTED
#define PNG_iCCP_SUPPORTED
-/*#undef PNG_ICC_SUPPORTED*/
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_INFO_IMAGE_SUPPORTED
#define PNG_IO_STATE_SUPPORTED
diff --git a/scripts/symbols.def b/scripts/symbols.def
index 92c0a70..8f83118 100644
--- a/scripts/symbols.def
+++ b/scripts/symbols.def
@@ -247,5 +247,3 @@
png_image_write_to_stdio @240
png_convert_to_rfc1123_buffer @241
png_set_check_for_invalid_index @242
- png_set_cms @243
- png_set_cms_output @244
diff --git a/scripts/symbols.dfn b/scripts/symbols.dfn
index 7d0d3d0..d790929 100644
--- a/scripts/symbols.dfn
+++ b/scripts/symbols.dfn
@@ -42,7 +42,6 @@
#define PNG_READ_BIG_ENDIAN_SUPPORTED /* should do nothing! */
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
-#define PNG_ICC_SUPPORTED /* currently disabled */
#undef PNG_H
#include "../png.h"