[packages/libpng] - updated to 1.6.17 - added tests patch (testsuite fix from git)

qboosh qboosh at pld-linux.org
Fri May 29 19:32:14 CEST 2015


commit 7d10146d13b952adac5150d4c2034743203aec99
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date:   Fri May 29 19:33:39 2015 +0200

    - updated to 1.6.17
    - added tests patch (testsuite fix from git)

 libpng-tests.patch | 911 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 libpng.spec        |  12 +-
 2 files changed, 918 insertions(+), 5 deletions(-)
---
diff --git a/libpng.spec b/libpng.spec
index 7142eed..5ec99e4 100644
--- a/libpng.spec
+++ b/libpng.spec
@@ -10,16 +10,17 @@ Summary(pl.UTF-8):	Biblioteka PNG
 Summary(pt_BR.UTF-8):	Biblioteca PNG
 Summary(tr.UTF-8):	PNG kitaplığı
 Name:		libpng
-Version:	1.6.16
-Release:	2
+Version:	1.6.17
+Release:	1
 Epoch:		2
 License:	distributable
 Group:		Libraries
 Source0:	http://downloads.sourceforge.net/libpng/%{name}-%{version}.tar.xz
-# Source0-md5:	23b7286b5d4a86de950fd2ffc5cac742
+# Source0-md5:	430a9b76b78533235cd4b9b26ce75c7e
 Patch0:		%{name}-pngminus.patch
-Patch1:		http://downloads.sourceforge.net/libpng-apng/%{name}-1.6.16-apng.patch.gz
-# Patch1-md5:	52de72a29e5d0428a0e527be74b99c24
+Patch1:		http://downloads.sourceforge.net/libpng-apng/%{name}-1.6.17-apng.patch.gz
+# Patch1-md5:	f68d34f10bcc7f43b8c3dce5708e1933
+Patch2:		%{name}-tests.patch
 URL:		http://www.libpng.org/pub/png/libpng.html
 BuildRequires:	rpmbuild(macros) >= 1.213
 BuildRequires:	tar >= 1:1.22
@@ -144,6 +145,7 @@ Narzędzia do konwersji plików PNG z lub do plików PNM.
 %setup -q
 %patch0 -p1
 %patch1 -p1
+%patch2 -p1
 
 %build
 %configure
diff --git a/libpng-tests.patch b/libpng-tests.patch
new file mode 100644
index 0000000..f2ef469
--- /dev/null
+++ b/libpng-tests.patch
@@ -0,0 +1,911 @@
+commit a21a5b22c10b900d44d40fe30a203302b2a67f8b
+Author: John Bowler <jbowler at acm.org>
+Date:   Mon Mar 30 21:38:31 2015 -0500
+
+    [libpng16] Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c
+
+#diff --git a/ANNOUNCE b/ANNOUNCE
+#index 73fadac..7e6c842 100644
+#--- a/ANNOUNCE
+#+++ b/ANNOUNCE
+#@@ -1,4 +1,4 @@
+#-Libpng 1.6.18beta01 - March 27, 2015
+#+Libpng 1.6.18beta01 - March 31, 2015
+# 
+# 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.
+#@@ -25,10 +25,11 @@ Other information:
+# 
+# Changes since the last public release (1.6.17):
+# 
+#-Version 1.6.18beta01 [March 27, 2015]
+#+Version 1.6.18beta01 [March 31, 2015]
+#   Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros.  They
+#     have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves
+#     bug report by Andrew Church).
+#+  Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c
+# 
+# Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+# (subscription required; visit
+#diff --git a/CHANGES b/CHANGES
+#index fe07211..35b5979 100644
+#--- a/CHANGES
+#+++ b/CHANGES
+#@@ -5205,10 +5205,11 @@ Version 1.6.17rc06 [March 23, 2015]
+# Version 1.6.17 [March 26, 2015]
+#   No changes.
+# 
+#-Version 1.6.18beta01 [March 27, 2015]
+#+Version 1.6.18beta01 [March 31, 2015]
+#   Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros.  They
+#     have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves
+#     bug report by Andrew Church).
+#+  Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c
+# 
+# Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+# (subscription required; visit
+diff --git a/autogen.sh b/autogen.sh
+index 9af34bd..702a0c1 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -73,8 +73,9 @@ done
+ # present bad things are happening.
+ #
+ # The autotools generated files:
+-libpng_autotools_files="Makefile.in aclocal.m4 config.guess config.h.in\
+-   config.sub configure depcomp install-sh ltmain.sh missing test-driver"
++libpng_autotools_files="Makefile.in aclocal.m4 config.guess config.h.in
++   config.h.in~ config.sub configure depcomp install-sh ltmain.sh missing\
++   test-driver"
+ #
+ # Files generated by versions of configue >2.68 or automake >1.13 (i.e. later
+ # versions than those required by configure.ac):
+diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c
+index 8852f87..60f23dc 100644
+--- a/contrib/libtests/pngvalid.c
++++ b/contrib/libtests/pngvalid.c
+@@ -258,7 +258,7 @@ make_four_random_bytes(png_uint_32* seed, png_bytep bytes)
+    make_random_bytes(seed, bytes, 4);
+ }
+ 
+-#ifdef PNG_READ_SUPPORTED
++#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED
+ static void
+ randomize(void *pv, size_t size)
+ {
+@@ -267,7 +267,9 @@ randomize(void *pv, size_t size)
+ }
+ 
+ #define RANDOMIZE(this) randomize(&(this), sizeof (this))
++#endif /* READ || WRITE_tRNS */
+ 
++#ifdef PNG_READ_SUPPORTED
+ static unsigned int
+ random_mod(unsigned int max)
+ {
+@@ -295,7 +297,8 @@ random_choice(void)
+ /* A numeric ID based on PNG file characteristics.  The 'do_interlace' field
+  * simply records whether pngvalid did the interlace itself or whether it
+  * was done by libpng.  Width and height must be less than 256.  'palette' is an
+- * index of the palette to use for formats with a palette (0 otherwise.)
++ * index of the palette to use for formats with a palette otherwise a boolean
++ * indicating if a tRNS chunk was generated.
+  */
+ #define FILEID(col, depth, palette, interlace, width, height, do_interlace) \
+    ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \
+@@ -316,12 +319,16 @@ standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
+     png_uint_32 w, png_uint_32 h, int do_interlace)
+ {
+    pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
+-   if (npalette > 0)
++   if (colour_type == 3) /* must have a palette */
+    {
+       pos = safecat(buffer, bufsize, pos, "[");
+       pos = safecatn(buffer, bufsize, pos, npalette);
+       pos = safecat(buffer, bufsize, pos, "]");
+    }
++
++   else if (npalette != 0)
++      pos = safecat(buffer, bufsize, pos, "+tRNS");
++
+    pos = safecat(buffer, bufsize, pos, " ");
+    pos = safecatn(buffer, bufsize, pos, bit_depth);
+    pos = safecat(buffer, bufsize, pos, " bit");
+@@ -378,25 +385,32 @@ standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
+ 
+ static int
+ next_format(png_bytep colour_type, png_bytep bit_depth,
+-   unsigned int* palette_number, int no_low_depth_gray)
++   unsigned int* palette_number, int low_depth_gray, int tRNS)
+ {
+    if (*bit_depth == 0)
+    {
+       *colour_type = 0;
+-      if (no_low_depth_gray)
+-         *bit_depth = 8;
+-      else
++      if (low_depth_gray)
+          *bit_depth = 1;
++      else
++         *bit_depth = 8;
+       *palette_number = 0;
+       return 1;
+    }
+ 
+-   if (*colour_type == 3)
++   if  (*colour_type < 4/*no alpha channel*/)
+    {
+-      /* Add multiple palettes for colour type 3. */
+-      if (++*palette_number < PALETTE_COUNT(*bit_depth))
++      /* Add multiple palettes for colour type 3, one image with tRNS
++       * and one without for other non-alpha formats:
++       */
++      unsigned int pn = ++*palette_number;
++      png_byte ct = *colour_type;
++
++      if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) ||
++          (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth)))
+          return 1;
+ 
++      /* No: next bit depth */
+       *palette_number = 0;
+    }
+ 
+@@ -1959,6 +1973,7 @@ typedef struct png_modifier
+ 
+    /* Run tests on reading with a combination of transforms, */
+    unsigned int             test_transform :1;
++   unsigned int             test_tRNS :1; /* Includes tRNS images */
+ 
+    /* When to use the use_input_precision option, this controls the gamma
+     * validation code checks.  If set any value that is within the transformed
+@@ -1990,6 +2005,16 @@ typedef struct png_modifier
+    unsigned int             test_gamma_expand16 :1;
+    unsigned int             test_exhaustive :1;
+ 
++   /* Whether or not to run the low-bit-depth grayscale tests.  This fail on
++    * gamma images in some cases because of gross inaccuracies in the grayscale
++    * gamma handling for low bit depth.
++    */
++   unsigned int             test_lbg :1;
++   unsigned int             test_lbg_gamma_threshold :1;
++   unsigned int             test_lbg_gamma_transform :1;
++   unsigned int             test_lbg_gamma_sbit :1;
++   unsigned int             test_lbg_gamma_composition :1;
++
+    unsigned int             log :1;   /* Log max error */
+ 
+    /* Buffer information, the buffer size limits the size of the chunks that can
+@@ -2042,6 +2067,11 @@ modifier_init(png_modifier *pm)
+    pm->test_standard = 0;
+    pm->test_size = 0;
+    pm->test_transform = 0;
++#  ifdef PNG_WRITE_tRNS_SUPPORTED
++      pm->test_tRNS = 1;
++#  else
++      pm->test_tRNS = 0;
++#  endif
+    pm->use_input_precision = 0;
+    pm->use_input_precision_sbit = 0;
+    pm->use_input_precision_16to8 = 0;
+@@ -2054,6 +2084,11 @@ modifier_init(png_modifier *pm)
+    pm->test_gamma_background = 0;
+    pm->test_gamma_alpha_mode = 0;
+    pm->test_gamma_expand16 = 0;
++   pm->test_lbg = 1;
++   pm->test_lbg_gamma_threshold = 1;
++   pm->test_lbg_gamma_transform = 1;
++   pm->test_lbg_gamma_sbit = 1;
++   pm->test_lbg_gamma_composition = 1;
+    pm->test_exhaustive = 0;
+    pm->log = 0;
+ 
+@@ -3192,6 +3227,45 @@ init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette,
+    }
+ }
+ 
++#ifdef PNG_WRITE_tRNS_SUPPORTED
++static void
++set_random_tRNS(png_structp pp, png_infop pi, PNG_CONST png_byte colour_type,
++   PNG_CONST int bit_depth)
++{
++   /* To make this useful the tRNS color needs to match at least one pixel.
++    * Random values are fine for gray, including the 16-bit case where we know
++    * that the test image contains all the gray values.  For RGB we need more
++    * method as only 65536 different RGB values are generated.
++    */
++   png_color_16 tRNS;
++   const png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);
++
++   RANDOMIZE(tRNS);
++
++   if (colour_type & 2/*RGB*/)
++   {
++      if (bit_depth == 8)
++      {
++         tRNS.blue = tRNS.red ^ tRNS.green;
++         tRNS.red &= mask;
++         tRNS.green &= mask;
++         tRNS.blue &= mask;
++      }
++
++      else /* bit_depth == 16 */
++      {
++         tRNS.green = (png_uint_16)(tRNS.red * 257);
++         tRNS.blue = (png_uint_16)(tRNS.green * 17);
++      }
++   }
++
++   else
++      tRNS.gray &= mask;
++
++   png_set_tRNS(pp, pi, NULL, 0, &tRNS);
++}
++#endif
++
+ /* The number of passes is related to the interlace type. There was no libpng
+  * API to determine this prior to 1.5, so we need an inquiry function:
+  */
+@@ -3525,6 +3599,11 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
+       if (colour_type == 3) /* palette */
+          init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/);
+ 
++#     ifdef PNG_WRITE_tRNS_SUPPORTED
++         else if (palette_number)
++            set_random_tRNS(pp, pi, colour_type, bit_depth);
++#     endif
++
+       png_write_info(pp, pi);
+ 
+       if (png_get_rowbytes(pp, pi) !=
+@@ -3598,19 +3677,20 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
+ }
+ 
+ static void
+-make_transform_images(png_store *ps)
++make_transform_images(png_modifier *pm)
+ {
+    png_byte colour_type = 0;
+    png_byte bit_depth = 0;
+    unsigned int palette_number = 0;
+ 
+    /* This is in case of errors. */
+-   safecat(ps->test, sizeof ps->test, 0, "make standard images");
++   safecat(pm->this.test, sizeof pm->this.test, 0, "make standard images");
+ 
+    /* Use next_format to enumerate all the combinations we test, including
+-    * generating multiple low bit depth palette images.
++    * generating multiple low bit depth palette images. Non-A images (palette
++    * and direct) are created with and without tRNS chunks.
+     */
+-   while (next_format(&colour_type, &bit_depth, &palette_number, 0))
++   while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1))
+    {
+       int interlace_type;
+ 
+@@ -3621,7 +3701,7 @@ make_transform_images(png_store *ps)
+ 
+          standard_name(name, sizeof name, 0, colour_type, bit_depth,
+             palette_number, interlace_type, 0, 0, 0);
+-         make_transform_image(ps, colour_type, bit_depth, palette_number,
++         make_transform_image(&pm->this, colour_type, bit_depth, palette_number,
+             interlace_type, name);
+       }
+    }
+@@ -4287,6 +4367,7 @@ typedef struct standard_display
+    size_t      cbRow;          /* Bytes in a row of the output image */
+    int         do_interlace;   /* Do interlacing internally */
+    int         is_transparent; /* Transparency information was present. */
++   int         has_tRNS;       /* color type GRAY or RGB with a tRNS chunk. */
+    int         speed;          /* Doing a speed test */
+    int         use_update_info;/* Call update_info, not start_image */
+    struct
+@@ -4619,14 +4700,14 @@ standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
+          case 0:
+             dp->transparent.red = dp->transparent.green = dp->transparent.blue =
+                trans_color->gray;
+-            dp->is_transparent = 1;
++            dp->has_tRNS = 1;
+             break;
+ 
+          case 2:
+             dp->transparent.red = trans_color->red;
+             dp->transparent.green = trans_color->green;
+             dp->transparent.blue = trans_color->blue;
+-            dp->is_transparent = 1;
++            dp->has_tRNS = 1;
+             break;
+ 
+          case 3:
+@@ -5518,7 +5599,7 @@ image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display)
+       if (this->colour_type == PNG_COLOR_TYPE_GRAY)
+       {
+          if (this->bit_depth < 8)
+-            this->bit_depth = 8;
++            this->bit_depth = this->sample_depth = 8;
+ 
+          if (this->have_tRNS)
+          {
+@@ -5553,9 +5634,11 @@ image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display)
+                this->alphaf = 0;
+             else
+                this->alphaf = 1;
+-
+-            this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
+          }
++         else
++            this->alphaf = 1;
++
++         this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
+       }
+ 
+       /* The error in the alpha is zero and the sBIT value comes from the
+@@ -5848,8 +5931,9 @@ transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
+    /* If png_set_filler is in action then fake the output color type to include
+     * an alpha channel where appropriate.
+     */
+-   if (dp->output_bit_depth >= 8 && (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
+-       dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
++   if (dp->output_bit_depth >= 8 &&
++       (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
++        dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
+        dp->output_colour_type |= 4;
+ 
+    /* Validate the combination of colour type and bit depth that we are getting
+@@ -6372,6 +6456,13 @@ image_transform_png_set_tRNS_to_alpha_set(PNG_CONST image_transform *this,
+    transform_display *that, png_structp pp, png_infop pi)
+ {
+    png_set_tRNS_to_alpha(pp);
++
++   /* If there was a tRNS chunk that would get expanded and add an alpha
++    * channel is_transparent must be updated:
++    */
++   if (that->this.has_tRNS)
++      that->this.is_transparent = 1;
++
+    this->next->set(this->next, that, pp, pi);
+ }
+ 
+@@ -6430,6 +6521,7 @@ image_transform_png_set_gray_to_rgb_set(PNG_CONST image_transform *this,
+     transform_display *that, png_structp pp, png_infop pi)
+ {
+    png_set_gray_to_rgb(pp);
++   /* NOTE: this doesn't result in tRNS expansion. */
+    this->next->set(this->next, that, pp, pi);
+ }
+ 
+@@ -6489,6 +6581,10 @@ image_transform_png_set_expand_set(PNG_CONST image_transform *this,
+     transform_display *that, png_structp pp, png_infop pi)
+ {
+    png_set_expand(pp);
++
++   if (that->this.has_tRNS)
++      that->this.is_transparent = 1;
++
+    this->next->set(this->next, that, pp, pi);
+ }
+ 
+@@ -6539,6 +6635,7 @@ image_transform_png_set_expand_gray_1_2_4_to_8_set(
+     png_infop pi)
+ {
+    png_set_expand_gray_1_2_4_to_8(pp);
++   /* NOTE: don't expect this to expand tRNS */
+    this->next->set(this->next, that, pp, pi);
+ }
+ 
+@@ -6570,6 +6667,11 @@ image_transform_png_set_expand_16_set(PNG_CONST image_transform *this,
+     transform_display *that, png_structp pp, png_infop pi)
+ {
+    png_set_expand_16(pp);
++
++   /* NOTE: at present libpng does SET_EXPAND as well, so tRNS is expanded. */
++   if (that->this.has_tRNS)
++      that->this.is_transparent = 1;
++
+    this->next->set(this->next, that, pp, pi);
+ }
+ 
+@@ -6940,14 +7042,14 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this,
+           * When DIGITIZE is set because a pre-1.7 version of libpng is being
+           * tested allow a bigger slack.
+           *
+-          * NOTE: this magic number was determined by experiment to be 1.25.
+-          * There's no great merit to the value below, however it only affects
+-          * the limit used for checking for internal calculation errors, not
+-          * the actual limit imposed by pngvalid on the output errors.
++          * NOTE: this magic number was determined by experiment to be about
++          * 1.263.  There's no great merit to the value below, however it only
++          * affects the limit used for checking for internal calculation errors,
++          * not the actual limit imposed by pngvalid on the output errors.
+           */
+          that->pm->limit += pow(
+ #        if DIGITIZE
+-            1.25
++            1.3
+ #        else
+             1.0
+ #        endif
+@@ -7111,7 +7213,8 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
+          const unsigned int sample_depth = that->sample_depth;
+          const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
+             sample_depth);
+-         const unsigned int gamma_depth = (sample_depth == 16 ? 16 :
++         const unsigned int gamma_depth = (sample_depth == 16 ?
++            PNG_MAX_GAMMA_8 :
+             (pm->assume_16_bit_calculations ? PNG_MAX_GAMMA_8 : sample_depth));
+          int isgray;
+          double r, g, b;
+@@ -7125,56 +7228,73 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
+           * will be identical after this operation if there is only one
+           * transform, feel free to delete the png_error checks on this below in
+           * the future (this is just me trying to ensure it works!)
++          *
++          * Interval arithmetic is exact, but to implement it it must be
++          * possible to control the floating point implementation rounding mode.
++          * This cannot be done in ANSI-C, so instead I reduce the 'lo' values
++          * by DBL_EPSILON and increase the 'hi' values by the same.
+           */
++#        define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON))
++#        define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON))
++
+          r = rlo = rhi = that->redf;
+          rlo -= that->rede;
+-         rlo = digitize(rlo, calc_depth, 1/*round*/);
++         rlo = DD(rlo, calc_depth, 1/*round*/);
+          rhi += that->rede;
+-         rhi = digitize(rhi, calc_depth, 1/*round*/);
++         rhi = DU(rhi, calc_depth, 1/*round*/);
+ 
+          g = glo = ghi = that->greenf;
+          glo -= that->greene;
+-         glo = digitize(glo, calc_depth, 1/*round*/);
++         glo = DD(glo, calc_depth, 1/*round*/);
+          ghi += that->greene;
+-         ghi = digitize(ghi, calc_depth, 1/*round*/);
++         ghi = DU(ghi, calc_depth, 1/*round*/);
+ 
+          b = blo = bhi = that->bluef;
+          blo -= that->bluee;
+-         blo = digitize(blo, calc_depth, 1/*round*/);
++         blo = DD(blo, calc_depth, 1/*round*/);
+          bhi += that->greene;
+-         bhi = digitize(bhi, calc_depth, 1/*round*/);
++         bhi = DU(bhi, calc_depth, 1/*round*/);
+ 
+          isgray = r==g && g==b;
+ 
+          if (data.gamma != 1)
+          {
+             PNG_CONST double power = 1/data.gamma;
+-            PNG_CONST double abse = calc_depth == 16 ? .5/65535 : .5/255;
++            PNG_CONST double abse = .5/(sample_depth == 16 ? 65535 : 255);
+ 
+-            /* 'abse' is the absolute error permitted in linear calculations. It
+-             * is used here to capture the error permitted in the handling
+-             * (undoing) of the gamma encoding.  Once again digitization occurs
+-             * to handle the upper and lower bounds of the values.  This is
+-             * where the real errors are introduced.
++            /* If a gamma calculation is done it is done using lookup tables of
++             * precision gamma_depth, so the already digitized value above may
++             * need to be further digitized here.
+              */
++            if (gamma_depth != calc_depth)
++            {
++               rlo = DD(rlo, gamma_depth, 0/*truncate*/);
++               rhi = DU(rhi, gamma_depth, 0/*truncate*/);
++               glo = DD(glo, gamma_depth, 0/*truncate*/);
++               ghi = DU(ghi, gamma_depth, 0/*truncate*/);
++               blo = DD(blo, gamma_depth, 0/*truncate*/);
++               bhi = DU(bhi, gamma_depth, 0/*truncate*/);
++            }
++
++            /* 'abse' is the error in the gamma table calculation itself. */
+             r = pow(r, power);
+-            rlo = digitize(pow(rlo, power)-abse, calc_depth, 1);
+-            rhi = digitize(pow(rhi, power)+abse, calc_depth, 1);
++            rlo = DD(pow(rlo, power)-abse, calc_depth, 1);
++            rhi = DU(pow(rhi, power)+abse, calc_depth, 1);
+ 
+             g = pow(g, power);
+-            glo = digitize(pow(glo, power)-abse, calc_depth, 1);
+-            ghi = digitize(pow(ghi, power)+abse, calc_depth, 1);
++            glo = DD(pow(glo, power)-abse, calc_depth, 1);
++            ghi = DU(pow(ghi, power)+abse, calc_depth, 1);
+ 
+             b = pow(b, power);
+-            blo = digitize(pow(blo, power)-abse, calc_depth, 1);
+-            bhi = digitize(pow(bhi, power)+abse, calc_depth, 1);
++            blo = DD(pow(blo, power)-abse, calc_depth, 1);
++            bhi = DU(pow(bhi, power)+abse, calc_depth, 1);
+          }
+ 
+          /* Now calculate the actual gray values.  Although the error in the
+           * coefficients depends on whether they were specified on the command
+           * line (in which case truncation to 15 bits happened) or not (rounding
+           * was used) the maxium error in an individual coefficient is always
+-          * 1/32768, because even in the rounding case the requirement that
++          * 2/32768, because even in the rounding case the requirement that
+           * coefficients add up to 32768 can cause a larger rounding error.
+           *
+           * The only time when rounding doesn't occur in 1.5.5 and later is when
+@@ -7185,19 +7305,19 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
+ 
+          {
+             PNG_CONST int do_round = data.gamma != 1 || calc_depth == 16;
+-            PNG_CONST double ce = 1. / 32768;
++            PNG_CONST double ce = 2. / 32768;
+ 
+-            graylo = digitize(rlo * (data.red_coefficient-ce) +
++            graylo = DD(rlo * (data.red_coefficient-ce) +
+                glo * (data.green_coefficient-ce) +
+-               blo * (data.blue_coefficient-ce), gamma_depth, do_round);
+-            if (graylo <= 0)
+-               graylo = 0;
++               blo * (data.blue_coefficient-ce), calc_depth, do_round);
++            if (graylo > gray) /* always accept the right answer */
++               graylo = gray;
+ 
+-            grayhi = digitize(rhi * (data.red_coefficient+ce) +
++            grayhi = DU(rhi * (data.red_coefficient+ce) +
+                ghi * (data.green_coefficient+ce) +
+-               bhi * (data.blue_coefficient+ce), gamma_depth, do_round);
+-            if (grayhi >= 1)
+-               grayhi = 1;
++               bhi * (data.blue_coefficient+ce), calc_depth, do_round);
++            if (grayhi < gray)
++               grayhi = gray;
+          }
+ 
+          /* And invert the gamma. */
+@@ -7205,11 +7325,25 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
+          {
+             PNG_CONST double power = data.gamma;
+ 
++            /* And this happens yet again, shifting the values once more. */
++            if (gamma_depth != sample_depth)
++            {
++               rlo = DD(rlo, gamma_depth, 0/*truncate*/);
++               rhi = DU(rhi, gamma_depth, 0/*truncate*/);
++               glo = DD(glo, gamma_depth, 0/*truncate*/);
++               ghi = DU(ghi, gamma_depth, 0/*truncate*/);
++               blo = DD(blo, gamma_depth, 0/*truncate*/);
++               bhi = DU(bhi, gamma_depth, 0/*truncate*/);
++            }
++
+             gray = pow(gray, power);
+-            graylo = digitize(pow(graylo, power), sample_depth, 1);
+-            grayhi = digitize(pow(grayhi, power), sample_depth, 1);
++            graylo = DD(pow(graylo, power), sample_depth, 1);
++            grayhi = DU(pow(grayhi, power), sample_depth, 1);
+          }
+ 
++#        undef DD
++#        undef DU
++
+          /* Now the error can be calculated.
+           *
+           * If r==g==b because there is no overall gamma correction libpng
+@@ -7260,16 +7394,28 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
+          {
+             /* There is no need to do the conversions to and from linear space,
+              * so the calculation should be a lot more accurate.  There is a
+-             * built in 1/32768 error in the coefficients because they only have
+-             * 15 bits and are adjusted to make sure they add up to 32768, so
+-             * the result may have an additional error up to 1/32768.  (Note
+-             * that adding the 1/32768 here avoids needing to increase the
+-             * global error limits to take this into account.)
++             * built in error in the coefficients because they only have 15 bits
++             * and are adjusted to make sure they add up to 32768.  This
++             * involves a integer calculation with truncation of the form:
++             *
++             *     ((int)(coefficient * 100000) * 32768)/100000
++             *
++             * This is done to the red and green coefficients (the ones
++             * provided to the API) then blue is calculated from them so the
++             * result adds up to 32768.  In the worst case this can result in
++             * a -1 error in red and green and a +2 error in blue.  Consequently
++             * the worst case in the calculation below is 2/32768 error.
++             *
++             * TODO: consider fixing this in libpng by rounding the calculation
++             * limiting the error to 1/32768.
++             *
++             * Handling this by adding 2/32768 here avoids needing to increase
++             * the global error limits to take this into account.)
+              */
+             gray = r * data.red_coefficient + g * data.green_coefficient +
+                b * data.blue_coefficient;
+             err = re * data.red_coefficient + ge * data.green_coefficient +
+-               be * data.blue_coefficient + 1./32768 + gray * 5 * DBL_EPSILON;
++               be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON;
+          }
+ 
+          else
+@@ -7304,7 +7450,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
+              * previously added input quantization error at this point.
+              */
+             gray = r * data.red_coefficient + g * data.green_coefficient +
+-               b * data.blue_coefficient - 1./32768 - out_qe;
++               b * data.blue_coefficient - 2./32768 - out_qe;
+             if (gray <= 0)
+                gray = 0;
+             else
+@@ -7314,7 +7460,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
+             }
+ 
+             grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient +
+-               bhi * data.blue_coefficient + 1./32768 + out_qe;
++               bhi * data.blue_coefficient + 2./32768 + out_qe;
+             grayhi *= (1 + 6 * DBL_EPSILON);
+             if (grayhi >= 1)
+                grayhi = 1;
+@@ -7429,6 +7575,9 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this,
+ 
+    else
+    {
++      if (that->this.has_tRNS)
++         that->this.is_transparent = 1;
++
+       bit_depth = that->this.bit_depth;
+       expand = 1;
+    }
+@@ -7506,14 +7655,14 @@ image_transform_png_set_background_mod(PNG_CONST image_transform *this,
+       /* Remove the alpha type and set the alpha (not in that order.) */
+       that->alphaf = 1;
+       that->alphae = 0;
+-
+-      if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
+-         that->colour_type = PNG_COLOR_TYPE_RGB;
+-      else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+-         that->colour_type = PNG_COLOR_TYPE_GRAY;
+-      /* PNG_COLOR_TYPE_PALETTE is not changed */
+    }
+ 
++   if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
++      that->colour_type = PNG_COLOR_TYPE_RGB;
++   else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
++      that->colour_type = PNG_COLOR_TYPE_GRAY;
++   /* PNG_COLOR_TYPE_PALETTE is not changed */
++
+    this->next->mod(this->next, that, pp, display);
+ }
+ 
+@@ -8301,7 +8450,8 @@ perform_transform_test(png_modifier *pm)
+    png_byte bit_depth = 0;
+    unsigned int palette_number = 0;
+ 
+-   while (next_format(&colour_type, &bit_depth, &palette_number, 0))
++   while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg,
++            pm->test_tRNS))
+    {
+       png_uint_32 counter = 0;
+       size_t base_pos;
+@@ -8604,7 +8754,9 @@ init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,
+    vi->outlog = outlog(dp->pm, in_depth, out_depth);
+ 
+    if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 ||
+-      (dp->this.colour_type == 3 && dp->this.is_transparent))
++      (dp->this.colour_type == 3 && dp->this.is_transparent) ||
++      ((dp->this.colour_type == 0 || dp->this.colour_type == 2) &&
++       dp->this.has_tRNS))
+    {
+       vi->do_background = dp->do_background;
+ 
+@@ -8634,7 +8786,7 @@ init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,
+          vi->background_blue = b;
+       }
+    }
+-   else
++   else /* Do not expect any background processing */
+       vi->do_background = 0;
+ 
+    if (vi->do_background == 0)
+@@ -9350,6 +9502,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
+    png_uint_32 y;
+    PNG_CONST store_palette_entry *in_palette = dp->this.palette;
+    PNG_CONST int in_is_transparent = dp->this.is_transparent;
++   int process_tRNS;
+    int out_npalette = -1;
+    int out_is_transparent = 0; /* Just refers to the palette case */
+    store_palette out_palette;
+@@ -9365,6 +9518,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
+ 
+    processing = (vi.gamma_correction > 0 && !dp->threshold_test)
+       || in_bd != out_bd || in_ct != out_ct || vi.do_background;
++   process_tRNS = dp->this.has_tRNS && vi.do_background;
+ 
+    /* TODO: FIX THIS: MAJOR BUG!  If the transformations all happen inside
+     * the palette there is no way of finding out, because libpng fails to
+@@ -9403,8 +9557,8 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
+             /* Handle input alpha - png_set_background will cause the output
+              * alpha to disappear so there is nothing to check.
+              */
+-            if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 || (in_ct == 3 &&
+-               in_is_transparent))
++            if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 ||
++                (in_ct == 3 && in_is_transparent))
+             {
+                PNG_CONST unsigned int input_alpha = in_ct == 3 ?
+                   dp->this.palette[in_index].alpha :
+@@ -9436,6 +9590,35 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
+                }
+             }
+ 
++            else if (process_tRNS)
++            {
++               /* alpha needs to be set appropriately for this pixel, it is
++                * currently 1 and needs to be 0 for an input pixel which matches
++                * the values in tRNS.
++                */
++               switch (in_ct)
++               {
++                  case 0: /* gray */
++                     if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
++                           dp->this.transparent.red)
++                        alpha = 0;
++                     break;
++
++                  case 2: /* RGB */
++                     if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
++                           dp->this.transparent.red &&
++                         sample(std, in_ct, in_bd, x, 1, 0, 0) ==
++                           dp->this.transparent.green &&
++                         sample(std, in_ct, in_bd, x, 2, 0, 0) ==
++                           dp->this.transparent.blue)
++                        alpha = 0;
++                     break;
++
++                  default:
++                     break;
++               }
++            }
++
+             /* Handle grayscale or RGB components. */
+             if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */
+                (void)gamma_component_validate("gray", &vi,
+@@ -9545,7 +9728,7 @@ gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn,
+ 
+       modification_reset(d.pm->modifications);
+ 
+-      /* Get a png_struct for writing the image. */
++      /* Get a png_struct for reading the image. */
+       pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
+       standard_palette_init(&d.this);
+ 
+@@ -9684,9 +9867,13 @@ perform_gamma_threshold_tests(png_modifier *pm)
+    /* Don't test more than one instance of each palette - it's pointless, in
+     * fact this test is somewhat excessive since libpng doesn't make this
+     * decision based on colour type or bit depth!
++    *
++    * CHANGED: now test two palettes and, as a side effect, images with and
++    * without tRNS.
+     */
+-   while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
+-      if (palette_number == 0)
++   while (next_format(&colour_type, &bit_depth, &palette_number,
++                      pm->test_lbg_gamma_threshold, pm->test_tRNS))
++      if (palette_number < 2)
+    {
+       double test_gamma = 1.0;
+       while (test_gamma >= .4)
+@@ -9746,7 +9933,8 @@ static void perform_gamma_transform_tests(png_modifier *pm)
+    png_byte bit_depth = 0;
+    unsigned int palette_number = 0;
+ 
+-   while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
++   while (next_format(&colour_type, &bit_depth, &palette_number,
++                      pm->test_lbg_gamma_transform, pm->test_tRNS))
+    {
+       unsigned int i, j;
+ 
+@@ -9776,7 +9964,8 @@ static void perform_gamma_sbit_tests(png_modifier *pm)
+       png_byte colour_type = 0, bit_depth = 0;
+       unsigned int npalette = 0;
+ 
+-      while (next_format(&colour_type, &bit_depth, &npalette, 1/*gamma*/))
++      while (next_format(&colour_type, &bit_depth, &npalette,
++                         pm->test_lbg_gamma_sbit, pm->test_tRNS))
+          if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&
+             ((colour_type == 3 && sbit < 8) ||
+             (colour_type != 3 && sbit < bit_depth)))
+@@ -9967,8 +10156,17 @@ static void gamma_composition_test(png_modifier *pm,
+    }
+ 
+    background.index = 193; /* rgb(193,193,193) to detect errors */
++
+    if (!(colour_type & PNG_COLOR_MASK_COLOR))
+    {
++      /* Because, currently, png_set_background is always called with
++       * 'need_expand' false in this case and because the gamma test itself
++       * doesn't cause an expand to 8-bit for lower bit depths the colour must
++       * be reduced to the correct range.
++       */
++      if (bit_depth < 8)
++         background.gray &= (png_uint_16)((1U << bit_depth)-1);
++
+       /* Grayscale input, we do not convert to RGB (TBD), so we must set the
+        * background to gray - else libpng seems to fail.
+        */
+@@ -10017,9 +10215,18 @@ perform_gamma_composition_tests(png_modifier *pm, int do_background,
+ 
+    /* Skip the non-alpha cases - there is no setting of a transparency colour at
+     * present.
+-    */
+-   while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
+-      if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0)
++    *
++    * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do,
++    * however the palette case fails miserably so is commented out below.
++    */
++   while (next_format(&colour_type, &bit_depth, &palette_number,
++                      pm->test_lbg_gamma_composition, pm->test_tRNS))
++      if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0
++#if 0 /* TODO: FIXME */
++          /*TODO: FIXME: this should work */
++          || colour_type == 3
++#endif
++          || (colour_type != 3 && palette_number != 0))
+    {
+       unsigned int i, j;
+ 
+@@ -10751,6 +10958,18 @@ int main(int argc, char **argv)
+    pm.ngammas = ARRAY_SIZE(gammas);
+    pm.ngamma_tests = 0; /* default to off */
+ 
++   /* Low bit depth gray images don't do well in the gamma tests, until
++    * this is fixed turn them off for some gamma cases:
++    */
++#  ifdef PNG_WRITE_tRNS_SUPPORTED
++      pm.test_tRNS = 1;
++#  endif
++   pm.test_lbg = 0;
++   pm.test_lbg_gamma_threshold = 1;
++   pm.test_lbg_gamma_transform = 0/*PNG_LIBPNG_VER >= 10700*/;
++   pm.test_lbg_gamma_sbit = 1;
++   pm.test_lbg_gamma_composition = 0;
++
+    /* And the test encodings */
+    pm.encodings = test_encodings;
+    pm.nencodings = ARRAY_SIZE(test_encodings);
+@@ -10863,7 +11082,7 @@ int main(int argc, char **argv)
+          pm.test_gamma_transform = 1;
+          pm.test_gamma_sbit = 1;
+          pm.test_gamma_scale16 = 1;
+-         pm.test_gamma_background = 1;
++         pm.test_gamma_background = 1; /* composition */
+          pm.test_gamma_alpha_mode = 1;
+          }
+ 
+@@ -10912,6 +11131,24 @@ int main(int argc, char **argv)
+       else if (strcmp(*argv, "--noexpand16") == 0)
+          pm.test_gamma_expand16 = 0;
+ 
++      else if (strcmp(*argv, "--low-depth-gray") == 0)
++         pm.test_lbg = pm.test_lbg_gamma_threshold =
++            pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
++            pm.test_lbg_gamma_composition = 1;
++
++      else if (strcmp(*argv, "--nolow-depth-gray") == 0)
++         pm.test_lbg = pm.test_lbg_gamma_threshold =
++            pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
++            pm.test_lbg_gamma_composition = 0;
++
++#     ifdef PNG_WRITE_tRNS_SUPPORTED
++         else if (strcmp(*argv, "--tRNS") == 0)
++            pm.test_tRNS = 1;
++#     endif
++
++      else if (strcmp(*argv, "--notRNS") == 0)
++         pm.test_tRNS = 0;
++
+       else if (strcmp(*argv, "--more-gammas") == 0)
+          pm.ngamma_tests = 3U;
+ 
+@@ -11102,7 +11339,7 @@ int main(int argc, char **argv)
+    Try
+    {
+       /* Make useful base images */
+-      make_transform_images(&pm.this);
++      make_transform_images(&pm);
+ 
+       /* Perform the standard and gamma tests. */
+       if (pm.test_standard)
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/libpng.git/commitdiff/7d10146d13b952adac5150d4c2034743203aec99




More information about the pld-cvs-commit mailing list