]> git.pld-linux.org Git - packages/libpng.git/blob - libpng-tests.patch
f2ef469cf92b1613796169a2bffa501a459a8cba
[packages/libpng.git] / libpng-tests.patch
1 commit a21a5b22c10b900d44d40fe30a203302b2a67f8b
2 Author: John Bowler <jbowler@acm.org>
3 Date:   Mon Mar 30 21:38:31 2015 -0500
4
5     [libpng16] Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c
6
7 #diff --git a/ANNOUNCE b/ANNOUNCE
8 #index 73fadac..7e6c842 100644
9 #--- a/ANNOUNCE
10 #+++ b/ANNOUNCE
11 #@@ -1,4 +1,4 @@
12 #-Libpng 1.6.18beta01 - March 27, 2015
13 #+Libpng 1.6.18beta01 - March 31, 2015
14
15 # This is not intended to be a public release.  It will be replaced
16 # within a few weeks by a public version or by another test version.
17 #@@ -25,10 +25,11 @@ Other information:
18
19 # Changes since the last public release (1.6.17):
20
21 #-Version 1.6.18beta01 [March 27, 2015]
22 #+Version 1.6.18beta01 [March 31, 2015]
23 #   Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros.  They
24 #     have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves
25 #     bug report by Andrew Church).
26 #+  Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c
27
28 # Send comments/corrections/commendations to png-mng-implement at lists.sf.net
29 # (subscription required; visit
30 #diff --git a/CHANGES b/CHANGES
31 #index fe07211..35b5979 100644
32 #--- a/CHANGES
33 #+++ b/CHANGES
34 #@@ -5205,10 +5205,11 @@ Version 1.6.17rc06 [March 23, 2015]
35 # Version 1.6.17 [March 26, 2015]
36 #   No changes.
37
38 #-Version 1.6.18beta01 [March 27, 2015]
39 #+Version 1.6.18beta01 [March 31, 2015]
40 #   Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros.  They
41 #     have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves
42 #     bug report by Andrew Church).
43 #+  Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c
44
45 # Send comments/corrections/commendations to png-mng-implement at lists.sf.net
46 # (subscription required; visit
47 diff --git a/autogen.sh b/autogen.sh
48 index 9af34bd..702a0c1 100755
49 --- a/autogen.sh
50 +++ b/autogen.sh
51 @@ -73,8 +73,9 @@ done
52  # present bad things are happening.
53  #
54  # The autotools generated files:
55 -libpng_autotools_files="Makefile.in aclocal.m4 config.guess config.h.in\
56 -   config.sub configure depcomp install-sh ltmain.sh missing test-driver"
57 +libpng_autotools_files="Makefile.in aclocal.m4 config.guess config.h.in
58 +   config.h.in~ config.sub configure depcomp install-sh ltmain.sh missing\
59 +   test-driver"
60  #
61  # Files generated by versions of configue >2.68 or automake >1.13 (i.e. later
62  # versions than those required by configure.ac):
63 diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c
64 index 8852f87..60f23dc 100644
65 --- a/contrib/libtests/pngvalid.c
66 +++ b/contrib/libtests/pngvalid.c
67 @@ -258,7 +258,7 @@ make_four_random_bytes(png_uint_32* seed, png_bytep bytes)
68     make_random_bytes(seed, bytes, 4);
69  }
70  
71 -#ifdef PNG_READ_SUPPORTED
72 +#if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED
73  static void
74  randomize(void *pv, size_t size)
75  {
76 @@ -267,7 +267,9 @@ randomize(void *pv, size_t size)
77  }
78  
79  #define RANDOMIZE(this) randomize(&(this), sizeof (this))
80 +#endif /* READ || WRITE_tRNS */
81  
82 +#ifdef PNG_READ_SUPPORTED
83  static unsigned int
84  random_mod(unsigned int max)
85  {
86 @@ -295,7 +297,8 @@ random_choice(void)
87  /* A numeric ID based on PNG file characteristics.  The 'do_interlace' field
88   * simply records whether pngvalid did the interlace itself or whether it
89   * was done by libpng.  Width and height must be less than 256.  'palette' is an
90 - * index of the palette to use for formats with a palette (0 otherwise.)
91 + * index of the palette to use for formats with a palette otherwise a boolean
92 + * indicating if a tRNS chunk was generated.
93   */
94  #define FILEID(col, depth, palette, interlace, width, height, do_interlace) \
95     ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \
96 @@ -316,12 +319,16 @@ standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
97      png_uint_32 w, png_uint_32 h, int do_interlace)
98  {
99     pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
100 -   if (npalette > 0)
101 +   if (colour_type == 3) /* must have a palette */
102     {
103        pos = safecat(buffer, bufsize, pos, "[");
104        pos = safecatn(buffer, bufsize, pos, npalette);
105        pos = safecat(buffer, bufsize, pos, "]");
106     }
107 +
108 +   else if (npalette != 0)
109 +      pos = safecat(buffer, bufsize, pos, "+tRNS");
110 +
111     pos = safecat(buffer, bufsize, pos, " ");
112     pos = safecatn(buffer, bufsize, pos, bit_depth);
113     pos = safecat(buffer, bufsize, pos, " bit");
114 @@ -378,25 +385,32 @@ standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
115  
116  static int
117  next_format(png_bytep colour_type, png_bytep bit_depth,
118 -   unsigned int* palette_number, int no_low_depth_gray)
119 +   unsigned int* palette_number, int low_depth_gray, int tRNS)
120  {
121     if (*bit_depth == 0)
122     {
123        *colour_type = 0;
124 -      if (no_low_depth_gray)
125 -         *bit_depth = 8;
126 -      else
127 +      if (low_depth_gray)
128           *bit_depth = 1;
129 +      else
130 +         *bit_depth = 8;
131        *palette_number = 0;
132        return 1;
133     }
134  
135 -   if (*colour_type == 3)
136 +   if  (*colour_type < 4/*no alpha channel*/)
137     {
138 -      /* Add multiple palettes for colour type 3. */
139 -      if (++*palette_number < PALETTE_COUNT(*bit_depth))
140 +      /* Add multiple palettes for colour type 3, one image with tRNS
141 +       * and one without for other non-alpha formats:
142 +       */
143 +      unsigned int pn = ++*palette_number;
144 +      png_byte ct = *colour_type;
145 +
146 +      if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) ||
147 +          (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth)))
148           return 1;
149  
150 +      /* No: next bit depth */
151        *palette_number = 0;
152     }
153  
154 @@ -1959,6 +1973,7 @@ typedef struct png_modifier
155  
156     /* Run tests on reading with a combination of transforms, */
157     unsigned int             test_transform :1;
158 +   unsigned int             test_tRNS :1; /* Includes tRNS images */
159  
160     /* When to use the use_input_precision option, this controls the gamma
161      * validation code checks.  If set any value that is within the transformed
162 @@ -1990,6 +2005,16 @@ typedef struct png_modifier
163     unsigned int             test_gamma_expand16 :1;
164     unsigned int             test_exhaustive :1;
165  
166 +   /* Whether or not to run the low-bit-depth grayscale tests.  This fail on
167 +    * gamma images in some cases because of gross inaccuracies in the grayscale
168 +    * gamma handling for low bit depth.
169 +    */
170 +   unsigned int             test_lbg :1;
171 +   unsigned int             test_lbg_gamma_threshold :1;
172 +   unsigned int             test_lbg_gamma_transform :1;
173 +   unsigned int             test_lbg_gamma_sbit :1;
174 +   unsigned int             test_lbg_gamma_composition :1;
175 +
176     unsigned int             log :1;   /* Log max error */
177  
178     /* Buffer information, the buffer size limits the size of the chunks that can
179 @@ -2042,6 +2067,11 @@ modifier_init(png_modifier *pm)
180     pm->test_standard = 0;
181     pm->test_size = 0;
182     pm->test_transform = 0;
183 +#  ifdef PNG_WRITE_tRNS_SUPPORTED
184 +      pm->test_tRNS = 1;
185 +#  else
186 +      pm->test_tRNS = 0;
187 +#  endif
188     pm->use_input_precision = 0;
189     pm->use_input_precision_sbit = 0;
190     pm->use_input_precision_16to8 = 0;
191 @@ -2054,6 +2084,11 @@ modifier_init(png_modifier *pm)
192     pm->test_gamma_background = 0;
193     pm->test_gamma_alpha_mode = 0;
194     pm->test_gamma_expand16 = 0;
195 +   pm->test_lbg = 1;
196 +   pm->test_lbg_gamma_threshold = 1;
197 +   pm->test_lbg_gamma_transform = 1;
198 +   pm->test_lbg_gamma_sbit = 1;
199 +   pm->test_lbg_gamma_composition = 1;
200     pm->test_exhaustive = 0;
201     pm->log = 0;
202  
203 @@ -3192,6 +3227,45 @@ init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette,
204     }
205  }
206  
207 +#ifdef PNG_WRITE_tRNS_SUPPORTED
208 +static void
209 +set_random_tRNS(png_structp pp, png_infop pi, PNG_CONST png_byte colour_type,
210 +   PNG_CONST int bit_depth)
211 +{
212 +   /* To make this useful the tRNS color needs to match at least one pixel.
213 +    * Random values are fine for gray, including the 16-bit case where we know
214 +    * that the test image contains all the gray values.  For RGB we need more
215 +    * method as only 65536 different RGB values are generated.
216 +    */
217 +   png_color_16 tRNS;
218 +   const png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);
219 +
220 +   RANDOMIZE(tRNS);
221 +
222 +   if (colour_type & 2/*RGB*/)
223 +   {
224 +      if (bit_depth == 8)
225 +      {
226 +         tRNS.blue = tRNS.red ^ tRNS.green;
227 +         tRNS.red &= mask;
228 +         tRNS.green &= mask;
229 +         tRNS.blue &= mask;
230 +      }
231 +
232 +      else /* bit_depth == 16 */
233 +      {
234 +         tRNS.green = (png_uint_16)(tRNS.red * 257);
235 +         tRNS.blue = (png_uint_16)(tRNS.green * 17);
236 +      }
237 +   }
238 +
239 +   else
240 +      tRNS.gray &= mask;
241 +
242 +   png_set_tRNS(pp, pi, NULL, 0, &tRNS);
243 +}
244 +#endif
245 +
246  /* The number of passes is related to the interlace type. There was no libpng
247   * API to determine this prior to 1.5, so we need an inquiry function:
248   */
249 @@ -3525,6 +3599,11 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
250        if (colour_type == 3) /* palette */
251           init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/);
252  
253 +#     ifdef PNG_WRITE_tRNS_SUPPORTED
254 +         else if (palette_number)
255 +            set_random_tRNS(pp, pi, colour_type, bit_depth);
256 +#     endif
257 +
258        png_write_info(pp, pi);
259  
260        if (png_get_rowbytes(pp, pi) !=
261 @@ -3598,19 +3677,20 @@ make_transform_image(png_store* PNG_CONST ps, png_byte PNG_CONST colour_type,
262  }
263  
264  static void
265 -make_transform_images(png_store *ps)
266 +make_transform_images(png_modifier *pm)
267  {
268     png_byte colour_type = 0;
269     png_byte bit_depth = 0;
270     unsigned int palette_number = 0;
271  
272     /* This is in case of errors. */
273 -   safecat(ps->test, sizeof ps->test, 0, "make standard images");
274 +   safecat(pm->this.test, sizeof pm->this.test, 0, "make standard images");
275  
276     /* Use next_format to enumerate all the combinations we test, including
277 -    * generating multiple low bit depth palette images.
278 +    * generating multiple low bit depth palette images. Non-A images (palette
279 +    * and direct) are created with and without tRNS chunks.
280      */
281 -   while (next_format(&colour_type, &bit_depth, &palette_number, 0))
282 +   while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1))
283     {
284        int interlace_type;
285  
286 @@ -3621,7 +3701,7 @@ make_transform_images(png_store *ps)
287  
288           standard_name(name, sizeof name, 0, colour_type, bit_depth,
289              palette_number, interlace_type, 0, 0, 0);
290 -         make_transform_image(ps, colour_type, bit_depth, palette_number,
291 +         make_transform_image(&pm->this, colour_type, bit_depth, palette_number,
292              interlace_type, name);
293        }
294     }
295 @@ -4287,6 +4367,7 @@ typedef struct standard_display
296     size_t      cbRow;          /* Bytes in a row of the output image */
297     int         do_interlace;   /* Do interlacing internally */
298     int         is_transparent; /* Transparency information was present. */
299 +   int         has_tRNS;       /* color type GRAY or RGB with a tRNS chunk. */
300     int         speed;          /* Doing a speed test */
301     int         use_update_info;/* Call update_info, not start_image */
302     struct
303 @@ -4619,14 +4700,14 @@ standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
304           case 0:
305              dp->transparent.red = dp->transparent.green = dp->transparent.blue =
306                 trans_color->gray;
307 -            dp->is_transparent = 1;
308 +            dp->has_tRNS = 1;
309              break;
310  
311           case 2:
312              dp->transparent.red = trans_color->red;
313              dp->transparent.green = trans_color->green;
314              dp->transparent.blue = trans_color->blue;
315 -            dp->is_transparent = 1;
316 +            dp->has_tRNS = 1;
317              break;
318  
319           case 3:
320 @@ -5518,7 +5599,7 @@ image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display)
321        if (this->colour_type == PNG_COLOR_TYPE_GRAY)
322        {
323           if (this->bit_depth < 8)
324 -            this->bit_depth = 8;
325 +            this->bit_depth = this->sample_depth = 8;
326  
327           if (this->have_tRNS)
328           {
329 @@ -5553,9 +5634,11 @@ image_pixel_add_alpha(image_pixel *this, PNG_CONST standard_display *display)
330                 this->alphaf = 0;
331              else
332                 this->alphaf = 1;
333 -
334 -            this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
335           }
336 +         else
337 +            this->alphaf = 1;
338 +
339 +         this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
340        }
341  
342        /* The error in the alpha is zero and the sBIT value comes from the
343 @@ -5848,8 +5931,9 @@ transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
344     /* If png_set_filler is in action then fake the output color type to include
345      * an alpha channel where appropriate.
346      */
347 -   if (dp->output_bit_depth >= 8 && (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
348 -       dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
349 +   if (dp->output_bit_depth >= 8 &&
350 +       (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
351 +        dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
352         dp->output_colour_type |= 4;
353  
354     /* Validate the combination of colour type and bit depth that we are getting
355 @@ -6372,6 +6456,13 @@ image_transform_png_set_tRNS_to_alpha_set(PNG_CONST image_transform *this,
356     transform_display *that, png_structp pp, png_infop pi)
357  {
358     png_set_tRNS_to_alpha(pp);
359 +
360 +   /* If there was a tRNS chunk that would get expanded and add an alpha
361 +    * channel is_transparent must be updated:
362 +    */
363 +   if (that->this.has_tRNS)
364 +      that->this.is_transparent = 1;
365 +
366     this->next->set(this->next, that, pp, pi);
367  }
368  
369 @@ -6430,6 +6521,7 @@ image_transform_png_set_gray_to_rgb_set(PNG_CONST image_transform *this,
370      transform_display *that, png_structp pp, png_infop pi)
371  {
372     png_set_gray_to_rgb(pp);
373 +   /* NOTE: this doesn't result in tRNS expansion. */
374     this->next->set(this->next, that, pp, pi);
375  }
376  
377 @@ -6489,6 +6581,10 @@ image_transform_png_set_expand_set(PNG_CONST image_transform *this,
378      transform_display *that, png_structp pp, png_infop pi)
379  {
380     png_set_expand(pp);
381 +
382 +   if (that->this.has_tRNS)
383 +      that->this.is_transparent = 1;
384 +
385     this->next->set(this->next, that, pp, pi);
386  }
387  
388 @@ -6539,6 +6635,7 @@ image_transform_png_set_expand_gray_1_2_4_to_8_set(
389      png_infop pi)
390  {
391     png_set_expand_gray_1_2_4_to_8(pp);
392 +   /* NOTE: don't expect this to expand tRNS */
393     this->next->set(this->next, that, pp, pi);
394  }
395  
396 @@ -6570,6 +6667,11 @@ image_transform_png_set_expand_16_set(PNG_CONST image_transform *this,
397      transform_display *that, png_structp pp, png_infop pi)
398  {
399     png_set_expand_16(pp);
400 +
401 +   /* NOTE: at present libpng does SET_EXPAND as well, so tRNS is expanded. */
402 +   if (that->this.has_tRNS)
403 +      that->this.is_transparent = 1;
404 +
405     this->next->set(this->next, that, pp, pi);
406  }
407  
408 @@ -6940,14 +7042,14 @@ image_transform_png_set_rgb_to_gray_ini(PNG_CONST image_transform *this,
409            * When DIGITIZE is set because a pre-1.7 version of libpng is being
410            * tested allow a bigger slack.
411            *
412 -          * NOTE: this magic number was determined by experiment to be 1.25.
413 -          * There's no great merit to the value below, however it only affects
414 -          * the limit used for checking for internal calculation errors, not
415 -          * the actual limit imposed by pngvalid on the output errors.
416 +          * NOTE: this magic number was determined by experiment to be about
417 +          * 1.263.  There's no great merit to the value below, however it only
418 +          * affects the limit used for checking for internal calculation errors,
419 +          * not the actual limit imposed by pngvalid on the output errors.
420            */
421           that->pm->limit += pow(
422  #        if DIGITIZE
423 -            1.25
424 +            1.3
425  #        else
426              1.0
427  #        endif
428 @@ -7111,7 +7213,8 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
429           const unsigned int sample_depth = that->sample_depth;
430           const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
431              sample_depth);
432 -         const unsigned int gamma_depth = (sample_depth == 16 ? 16 :
433 +         const unsigned int gamma_depth = (sample_depth == 16 ?
434 +            PNG_MAX_GAMMA_8 :
435              (pm->assume_16_bit_calculations ? PNG_MAX_GAMMA_8 : sample_depth));
436           int isgray;
437           double r, g, b;
438 @@ -7125,56 +7228,73 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
439            * will be identical after this operation if there is only one
440            * transform, feel free to delete the png_error checks on this below in
441            * the future (this is just me trying to ensure it works!)
442 +          *
443 +          * Interval arithmetic is exact, but to implement it it must be
444 +          * possible to control the floating point implementation rounding mode.
445 +          * This cannot be done in ANSI-C, so instead I reduce the 'lo' values
446 +          * by DBL_EPSILON and increase the 'hi' values by the same.
447            */
448 +#        define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON))
449 +#        define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON))
450 +
451           r = rlo = rhi = that->redf;
452           rlo -= that->rede;
453 -         rlo = digitize(rlo, calc_depth, 1/*round*/);
454 +         rlo = DD(rlo, calc_depth, 1/*round*/);
455           rhi += that->rede;
456 -         rhi = digitize(rhi, calc_depth, 1/*round*/);
457 +         rhi = DU(rhi, calc_depth, 1/*round*/);
458  
459           g = glo = ghi = that->greenf;
460           glo -= that->greene;
461 -         glo = digitize(glo, calc_depth, 1/*round*/);
462 +         glo = DD(glo, calc_depth, 1/*round*/);
463           ghi += that->greene;
464 -         ghi = digitize(ghi, calc_depth, 1/*round*/);
465 +         ghi = DU(ghi, calc_depth, 1/*round*/);
466  
467           b = blo = bhi = that->bluef;
468           blo -= that->bluee;
469 -         blo = digitize(blo, calc_depth, 1/*round*/);
470 +         blo = DD(blo, calc_depth, 1/*round*/);
471           bhi += that->greene;
472 -         bhi = digitize(bhi, calc_depth, 1/*round*/);
473 +         bhi = DU(bhi, calc_depth, 1/*round*/);
474  
475           isgray = r==g && g==b;
476  
477           if (data.gamma != 1)
478           {
479              PNG_CONST double power = 1/data.gamma;
480 -            PNG_CONST double abse = calc_depth == 16 ? .5/65535 : .5/255;
481 +            PNG_CONST double abse = .5/(sample_depth == 16 ? 65535 : 255);
482  
483 -            /* 'abse' is the absolute error permitted in linear calculations. It
484 -             * is used here to capture the error permitted in the handling
485 -             * (undoing) of the gamma encoding.  Once again digitization occurs
486 -             * to handle the upper and lower bounds of the values.  This is
487 -             * where the real errors are introduced.
488 +            /* If a gamma calculation is done it is done using lookup tables of
489 +             * precision gamma_depth, so the already digitized value above may
490 +             * need to be further digitized here.
491               */
492 +            if (gamma_depth != calc_depth)
493 +            {
494 +               rlo = DD(rlo, gamma_depth, 0/*truncate*/);
495 +               rhi = DU(rhi, gamma_depth, 0/*truncate*/);
496 +               glo = DD(glo, gamma_depth, 0/*truncate*/);
497 +               ghi = DU(ghi, gamma_depth, 0/*truncate*/);
498 +               blo = DD(blo, gamma_depth, 0/*truncate*/);
499 +               bhi = DU(bhi, gamma_depth, 0/*truncate*/);
500 +            }
501 +
502 +            /* 'abse' is the error in the gamma table calculation itself. */
503              r = pow(r, power);
504 -            rlo = digitize(pow(rlo, power)-abse, calc_depth, 1);
505 -            rhi = digitize(pow(rhi, power)+abse, calc_depth, 1);
506 +            rlo = DD(pow(rlo, power)-abse, calc_depth, 1);
507 +            rhi = DU(pow(rhi, power)+abse, calc_depth, 1);
508  
509              g = pow(g, power);
510 -            glo = digitize(pow(glo, power)-abse, calc_depth, 1);
511 -            ghi = digitize(pow(ghi, power)+abse, calc_depth, 1);
512 +            glo = DD(pow(glo, power)-abse, calc_depth, 1);
513 +            ghi = DU(pow(ghi, power)+abse, calc_depth, 1);
514  
515              b = pow(b, power);
516 -            blo = digitize(pow(blo, power)-abse, calc_depth, 1);
517 -            bhi = digitize(pow(bhi, power)+abse, calc_depth, 1);
518 +            blo = DD(pow(blo, power)-abse, calc_depth, 1);
519 +            bhi = DU(pow(bhi, power)+abse, calc_depth, 1);
520           }
521  
522           /* Now calculate the actual gray values.  Although the error in the
523            * coefficients depends on whether they were specified on the command
524            * line (in which case truncation to 15 bits happened) or not (rounding
525            * was used) the maxium error in an individual coefficient is always
526 -          * 1/32768, because even in the rounding case the requirement that
527 +          * 2/32768, because even in the rounding case the requirement that
528            * coefficients add up to 32768 can cause a larger rounding error.
529            *
530            * The only time when rounding doesn't occur in 1.5.5 and later is when
531 @@ -7185,19 +7305,19 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
532  
533           {
534              PNG_CONST int do_round = data.gamma != 1 || calc_depth == 16;
535 -            PNG_CONST double ce = 1. / 32768;
536 +            PNG_CONST double ce = 2. / 32768;
537  
538 -            graylo = digitize(rlo * (data.red_coefficient-ce) +
539 +            graylo = DD(rlo * (data.red_coefficient-ce) +
540                 glo * (data.green_coefficient-ce) +
541 -               blo * (data.blue_coefficient-ce), gamma_depth, do_round);
542 -            if (graylo <= 0)
543 -               graylo = 0;
544 +               blo * (data.blue_coefficient-ce), calc_depth, do_round);
545 +            if (graylo > gray) /* always accept the right answer */
546 +               graylo = gray;
547  
548 -            grayhi = digitize(rhi * (data.red_coefficient+ce) +
549 +            grayhi = DU(rhi * (data.red_coefficient+ce) +
550                 ghi * (data.green_coefficient+ce) +
551 -               bhi * (data.blue_coefficient+ce), gamma_depth, do_round);
552 -            if (grayhi >= 1)
553 -               grayhi = 1;
554 +               bhi * (data.blue_coefficient+ce), calc_depth, do_round);
555 +            if (grayhi < gray)
556 +               grayhi = gray;
557           }
558  
559           /* And invert the gamma. */
560 @@ -7205,11 +7325,25 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
561           {
562              PNG_CONST double power = data.gamma;
563  
564 +            /* And this happens yet again, shifting the values once more. */
565 +            if (gamma_depth != sample_depth)
566 +            {
567 +               rlo = DD(rlo, gamma_depth, 0/*truncate*/);
568 +               rhi = DU(rhi, gamma_depth, 0/*truncate*/);
569 +               glo = DD(glo, gamma_depth, 0/*truncate*/);
570 +               ghi = DU(ghi, gamma_depth, 0/*truncate*/);
571 +               blo = DD(blo, gamma_depth, 0/*truncate*/);
572 +               bhi = DU(bhi, gamma_depth, 0/*truncate*/);
573 +            }
574 +
575              gray = pow(gray, power);
576 -            graylo = digitize(pow(graylo, power), sample_depth, 1);
577 -            grayhi = digitize(pow(grayhi, power), sample_depth, 1);
578 +            graylo = DD(pow(graylo, power), sample_depth, 1);
579 +            grayhi = DU(pow(grayhi, power), sample_depth, 1);
580           }
581  
582 +#        undef DD
583 +#        undef DU
584 +
585           /* Now the error can be calculated.
586            *
587            * If r==g==b because there is no overall gamma correction libpng
588 @@ -7260,16 +7394,28 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
589           {
590              /* There is no need to do the conversions to and from linear space,
591               * so the calculation should be a lot more accurate.  There is a
592 -             * built in 1/32768 error in the coefficients because they only have
593 -             * 15 bits and are adjusted to make sure they add up to 32768, so
594 -             * the result may have an additional error up to 1/32768.  (Note
595 -             * that adding the 1/32768 here avoids needing to increase the
596 -             * global error limits to take this into account.)
597 +             * built in error in the coefficients because they only have 15 bits
598 +             * and are adjusted to make sure they add up to 32768.  This
599 +             * involves a integer calculation with truncation of the form:
600 +             *
601 +             *     ((int)(coefficient * 100000) * 32768)/100000
602 +             *
603 +             * This is done to the red and green coefficients (the ones
604 +             * provided to the API) then blue is calculated from them so the
605 +             * result adds up to 32768.  In the worst case this can result in
606 +             * a -1 error in red and green and a +2 error in blue.  Consequently
607 +             * the worst case in the calculation below is 2/32768 error.
608 +             *
609 +             * TODO: consider fixing this in libpng by rounding the calculation
610 +             * limiting the error to 1/32768.
611 +             *
612 +             * Handling this by adding 2/32768 here avoids needing to increase
613 +             * the global error limits to take this into account.)
614               */
615              gray = r * data.red_coefficient + g * data.green_coefficient +
616                 b * data.blue_coefficient;
617              err = re * data.red_coefficient + ge * data.green_coefficient +
618 -               be * data.blue_coefficient + 1./32768 + gray * 5 * DBL_EPSILON;
619 +               be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON;
620           }
621  
622           else
623 @@ -7304,7 +7450,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
624               * previously added input quantization error at this point.
625               */
626              gray = r * data.red_coefficient + g * data.green_coefficient +
627 -               b * data.blue_coefficient - 1./32768 - out_qe;
628 +               b * data.blue_coefficient - 2./32768 - out_qe;
629              if (gray <= 0)
630                 gray = 0;
631              else
632 @@ -7314,7 +7460,7 @@ image_transform_png_set_rgb_to_gray_mod(PNG_CONST image_transform *this,
633              }
634  
635              grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient +
636 -               bhi * data.blue_coefficient + 1./32768 + out_qe;
637 +               bhi * data.blue_coefficient + 2./32768 + out_qe;
638              grayhi *= (1 + 6 * DBL_EPSILON);
639              if (grayhi >= 1)
640                 grayhi = 1;
641 @@ -7429,6 +7575,9 @@ image_transform_png_set_background_set(PNG_CONST image_transform *this,
642  
643     else
644     {
645 +      if (that->this.has_tRNS)
646 +         that->this.is_transparent = 1;
647 +
648        bit_depth = that->this.bit_depth;
649        expand = 1;
650     }
651 @@ -7506,14 +7655,14 @@ image_transform_png_set_background_mod(PNG_CONST image_transform *this,
652        /* Remove the alpha type and set the alpha (not in that order.) */
653        that->alphaf = 1;
654        that->alphae = 0;
655 -
656 -      if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
657 -         that->colour_type = PNG_COLOR_TYPE_RGB;
658 -      else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
659 -         that->colour_type = PNG_COLOR_TYPE_GRAY;
660 -      /* PNG_COLOR_TYPE_PALETTE is not changed */
661     }
662  
663 +   if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
664 +      that->colour_type = PNG_COLOR_TYPE_RGB;
665 +   else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
666 +      that->colour_type = PNG_COLOR_TYPE_GRAY;
667 +   /* PNG_COLOR_TYPE_PALETTE is not changed */
668 +
669     this->next->mod(this->next, that, pp, display);
670  }
671  
672 @@ -8301,7 +8450,8 @@ perform_transform_test(png_modifier *pm)
673     png_byte bit_depth = 0;
674     unsigned int palette_number = 0;
675  
676 -   while (next_format(&colour_type, &bit_depth, &palette_number, 0))
677 +   while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg,
678 +            pm->test_tRNS))
679     {
680        png_uint_32 counter = 0;
681        size_t base_pos;
682 @@ -8604,7 +8754,9 @@ init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,
683     vi->outlog = outlog(dp->pm, in_depth, out_depth);
684  
685     if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 ||
686 -      (dp->this.colour_type == 3 && dp->this.is_transparent))
687 +      (dp->this.colour_type == 3 && dp->this.is_transparent) ||
688 +      ((dp->this.colour_type == 0 || dp->this.colour_type == 2) &&
689 +       dp->this.has_tRNS))
690     {
691        vi->do_background = dp->do_background;
692  
693 @@ -8634,7 +8786,7 @@ init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,
694           vi->background_blue = b;
695        }
696     }
697 -   else
698 +   else /* Do not expect any background processing */
699        vi->do_background = 0;
700  
701     if (vi->do_background == 0)
702 @@ -9350,6 +9502,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
703     png_uint_32 y;
704     PNG_CONST store_palette_entry *in_palette = dp->this.palette;
705     PNG_CONST int in_is_transparent = dp->this.is_transparent;
706 +   int process_tRNS;
707     int out_npalette = -1;
708     int out_is_transparent = 0; /* Just refers to the palette case */
709     store_palette out_palette;
710 @@ -9365,6 +9518,7 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
711  
712     processing = (vi.gamma_correction > 0 && !dp->threshold_test)
713        || in_bd != out_bd || in_ct != out_ct || vi.do_background;
714 +   process_tRNS = dp->this.has_tRNS && vi.do_background;
715  
716     /* TODO: FIX THIS: MAJOR BUG!  If the transformations all happen inside
717      * the palette there is no way of finding out, because libpng fails to
718 @@ -9403,8 +9557,8 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
719              /* Handle input alpha - png_set_background will cause the output
720               * alpha to disappear so there is nothing to check.
721               */
722 -            if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 || (in_ct == 3 &&
723 -               in_is_transparent))
724 +            if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 ||
725 +                (in_ct == 3 && in_is_transparent))
726              {
727                 PNG_CONST unsigned int input_alpha = in_ct == 3 ?
728                    dp->this.palette[in_index].alpha :
729 @@ -9436,6 +9590,35 @@ gamma_image_validate(gamma_display *dp, png_const_structp pp,
730                 }
731              }
732  
733 +            else if (process_tRNS)
734 +            {
735 +               /* alpha needs to be set appropriately for this pixel, it is
736 +                * currently 1 and needs to be 0 for an input pixel which matches
737 +                * the values in tRNS.
738 +                */
739 +               switch (in_ct)
740 +               {
741 +                  case 0: /* gray */
742 +                     if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
743 +                           dp->this.transparent.red)
744 +                        alpha = 0;
745 +                     break;
746 +
747 +                  case 2: /* RGB */
748 +                     if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
749 +                           dp->this.transparent.red &&
750 +                         sample(std, in_ct, in_bd, x, 1, 0, 0) ==
751 +                           dp->this.transparent.green &&
752 +                         sample(std, in_ct, in_bd, x, 2, 0, 0) ==
753 +                           dp->this.transparent.blue)
754 +                        alpha = 0;
755 +                     break;
756 +
757 +                  default:
758 +                     break;
759 +               }
760 +            }
761 +
762              /* Handle grayscale or RGB components. */
763              if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */
764                 (void)gamma_component_validate("gray", &vi,
765 @@ -9545,7 +9728,7 @@ gamma_test(png_modifier *pmIn, PNG_CONST png_byte colour_typeIn,
766  
767        modification_reset(d.pm->modifications);
768  
769 -      /* Get a png_struct for writing the image. */
770 +      /* Get a png_struct for reading the image. */
771        pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
772        standard_palette_init(&d.this);
773  
774 @@ -9684,9 +9867,13 @@ perform_gamma_threshold_tests(png_modifier *pm)
775     /* Don't test more than one instance of each palette - it's pointless, in
776      * fact this test is somewhat excessive since libpng doesn't make this
777      * decision based on colour type or bit depth!
778 +    *
779 +    * CHANGED: now test two palettes and, as a side effect, images with and
780 +    * without tRNS.
781      */
782 -   while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
783 -      if (palette_number == 0)
784 +   while (next_format(&colour_type, &bit_depth, &palette_number,
785 +                      pm->test_lbg_gamma_threshold, pm->test_tRNS))
786 +      if (palette_number < 2)
787     {
788        double test_gamma = 1.0;
789        while (test_gamma >= .4)
790 @@ -9746,7 +9933,8 @@ static void perform_gamma_transform_tests(png_modifier *pm)
791     png_byte bit_depth = 0;
792     unsigned int palette_number = 0;
793  
794 -   while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
795 +   while (next_format(&colour_type, &bit_depth, &palette_number,
796 +                      pm->test_lbg_gamma_transform, pm->test_tRNS))
797     {
798        unsigned int i, j;
799  
800 @@ -9776,7 +9964,8 @@ static void perform_gamma_sbit_tests(png_modifier *pm)
801        png_byte colour_type = 0, bit_depth = 0;
802        unsigned int npalette = 0;
803  
804 -      while (next_format(&colour_type, &bit_depth, &npalette, 1/*gamma*/))
805 +      while (next_format(&colour_type, &bit_depth, &npalette,
806 +                         pm->test_lbg_gamma_sbit, pm->test_tRNS))
807           if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&
808              ((colour_type == 3 && sbit < 8) ||
809              (colour_type != 3 && sbit < bit_depth)))
810 @@ -9967,8 +10156,17 @@ static void gamma_composition_test(png_modifier *pm,
811     }
812  
813     background.index = 193; /* rgb(193,193,193) to detect errors */
814 +
815     if (!(colour_type & PNG_COLOR_MASK_COLOR))
816     {
817 +      /* Because, currently, png_set_background is always called with
818 +       * 'need_expand' false in this case and because the gamma test itself
819 +       * doesn't cause an expand to 8-bit for lower bit depths the colour must
820 +       * be reduced to the correct range.
821 +       */
822 +      if (bit_depth < 8)
823 +         background.gray &= (png_uint_16)((1U << bit_depth)-1);
824 +
825        /* Grayscale input, we do not convert to RGB (TBD), so we must set the
826         * background to gray - else libpng seems to fail.
827         */
828 @@ -10017,9 +10215,18 @@ perform_gamma_composition_tests(png_modifier *pm, int do_background,
829  
830     /* Skip the non-alpha cases - there is no setting of a transparency colour at
831      * present.
832 -    */
833 -   while (next_format(&colour_type, &bit_depth, &palette_number, 1/*gamma*/))
834 -      if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0)
835 +    *
836 +    * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do,
837 +    * however the palette case fails miserably so is commented out below.
838 +    */
839 +   while (next_format(&colour_type, &bit_depth, &palette_number,
840 +                      pm->test_lbg_gamma_composition, pm->test_tRNS))
841 +      if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0
842 +#if 0 /* TODO: FIXME */
843 +          /*TODO: FIXME: this should work */
844 +          || colour_type == 3
845 +#endif
846 +          || (colour_type != 3 && palette_number != 0))
847     {
848        unsigned int i, j;
849  
850 @@ -10751,6 +10958,18 @@ int main(int argc, char **argv)
851     pm.ngammas = ARRAY_SIZE(gammas);
852     pm.ngamma_tests = 0; /* default to off */
853  
854 +   /* Low bit depth gray images don't do well in the gamma tests, until
855 +    * this is fixed turn them off for some gamma cases:
856 +    */
857 +#  ifdef PNG_WRITE_tRNS_SUPPORTED
858 +      pm.test_tRNS = 1;
859 +#  endif
860 +   pm.test_lbg = 0;
861 +   pm.test_lbg_gamma_threshold = 1;
862 +   pm.test_lbg_gamma_transform = 0/*PNG_LIBPNG_VER >= 10700*/;
863 +   pm.test_lbg_gamma_sbit = 1;
864 +   pm.test_lbg_gamma_composition = 0;
865 +
866     /* And the test encodings */
867     pm.encodings = test_encodings;
868     pm.nencodings = ARRAY_SIZE(test_encodings);
869 @@ -10863,7 +11082,7 @@ int main(int argc, char **argv)
870           pm.test_gamma_transform = 1;
871           pm.test_gamma_sbit = 1;
872           pm.test_gamma_scale16 = 1;
873 -         pm.test_gamma_background = 1;
874 +         pm.test_gamma_background = 1; /* composition */
875           pm.test_gamma_alpha_mode = 1;
876           }
877  
878 @@ -10912,6 +11131,24 @@ int main(int argc, char **argv)
879        else if (strcmp(*argv, "--noexpand16") == 0)
880           pm.test_gamma_expand16 = 0;
881  
882 +      else if (strcmp(*argv, "--low-depth-gray") == 0)
883 +         pm.test_lbg = pm.test_lbg_gamma_threshold =
884 +            pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
885 +            pm.test_lbg_gamma_composition = 1;
886 +
887 +      else if (strcmp(*argv, "--nolow-depth-gray") == 0)
888 +         pm.test_lbg = pm.test_lbg_gamma_threshold =
889 +            pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
890 +            pm.test_lbg_gamma_composition = 0;
891 +
892 +#     ifdef PNG_WRITE_tRNS_SUPPORTED
893 +         else if (strcmp(*argv, "--tRNS") == 0)
894 +            pm.test_tRNS = 1;
895 +#     endif
896 +
897 +      else if (strcmp(*argv, "--notRNS") == 0)
898 +         pm.test_tRNS = 0;
899 +
900        else if (strcmp(*argv, "--more-gammas") == 0)
901           pm.ngamma_tests = 3U;
902  
903 @@ -11102,7 +11339,7 @@ int main(int argc, char **argv)
904     Try
905     {
906        /* Make useful base images */
907 -      make_transform_images(&pm.this);
908 +      make_transform_images(&pm);
909  
910        /* Perform the standard and gamma tests. */
911        if (pm.test_standard)
This page took 1.03662 seconds and 2 git commands to generate.