[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"