• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* pngrtran.c - transforms the data in a row for PNG readers
3  *
4  * Last changed in libpng 1.6.22 [May 26, 2016]
5  * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8  *
9  * This code is released under the libpng license.
10  * For conditions of distribution and use, see the disclaimer
11  * and license in png.h
12  *
13  * This file contains functions optionally called by an application
14  * in order to tell libpng how to handle data when reading a PNG.
15  * Transformations that are used in both reading and writing are
16  * in pngtrans.c.
17  */
18 
19 #include "pngpriv.h"
20 
21 #ifdef PNG_READ_SUPPORTED
22 
23 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
24 void PNGAPI
png_set_crc_action(png_structrp png_ptr,int crit_action,int ancil_action)25 png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
26 {
27    png_debug(1, "in png_set_crc_action");
28 
29    if (png_ptr == NULL)
30       return;
31 
32    /* Tell libpng how we react to CRC errors in critical chunks */
33    switch (crit_action)
34    {
35       case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
36          break;
37 
38       case PNG_CRC_WARN_USE:                               /* Warn/use data */
39          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
40          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
41          break;
42 
43       case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
44          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
45          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
46                            PNG_FLAG_CRC_CRITICAL_IGNORE;
47          break;
48 
49       case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
50          png_warning(png_ptr,
51             "Can't discard critical data on CRC error");
52       case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
53 
54       case PNG_CRC_DEFAULT:
55       default:
56          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
57          break;
58    }
59 
60    /* Tell libpng how we react to CRC errors in ancillary chunks */
61    switch (ancil_action)
62    {
63       case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
64          break;
65 
66       case PNG_CRC_WARN_USE:                              /* Warn/use data */
67          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
68          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
69          break;
70 
71       case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
72          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
73          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
74                            PNG_FLAG_CRC_ANCILLARY_NOWARN;
75          break;
76 
77       case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
78          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
79          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
80          break;
81 
82       case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
83 
84       case PNG_CRC_DEFAULT:
85       default:
86          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
87          break;
88    }
89 }
90 
91 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
92 /* Is it OK to set a transformation now?  Only if png_start_read_image or
93  * png_read_update_info have not been called.  It is not necessary for the IHDR
94  * to have been read in all cases; the need_IHDR parameter allows for this
95  * check too.
96  */
97 static int
png_rtran_ok(png_structrp png_ptr,int need_IHDR)98 png_rtran_ok(png_structrp png_ptr, int need_IHDR)
99 {
100    if (png_ptr != NULL)
101    {
102       if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
103          png_app_error(png_ptr,
104             "invalid after png_start_read_image or png_read_update_info");
105 
106       else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
107          png_app_error(png_ptr, "invalid before the PNG header has been read");
108 
109       else
110       {
111          /* Turn on failure to initialize correctly for all transforms. */
112          png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
113 
114          return 1; /* Ok */
115       }
116    }
117 
118    return 0; /* no png_error possible! */
119 }
120 #endif
121 
122 #ifdef PNG_READ_BACKGROUND_SUPPORTED
123 /* Handle alpha and tRNS via a background color */
124 void PNGFAPI
png_set_background_fixed(png_structrp png_ptr,png_const_color_16p background_color,int background_gamma_code,int need_expand,png_fixed_point background_gamma)125 png_set_background_fixed(png_structrp png_ptr,
126     png_const_color_16p background_color, int background_gamma_code,
127     int need_expand, png_fixed_point background_gamma)
128 {
129    png_debug(1, "in png_set_background_fixed");
130 
131    if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
132       return;
133 
134    if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
135    {
136       png_warning(png_ptr, "Application must supply a known background gamma");
137       return;
138    }
139 
140    png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
141    png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
142    png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
143 
144    png_ptr->background = *background_color;
145    png_ptr->background_gamma = background_gamma;
146    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
147    if (need_expand != 0)
148       png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
149    else
150       png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
151 }
152 
153 #  ifdef PNG_FLOATING_POINT_SUPPORTED
154 void PNGAPI
png_set_background(png_structrp png_ptr,png_const_color_16p background_color,int background_gamma_code,int need_expand,double background_gamma)155 png_set_background(png_structrp png_ptr,
156     png_const_color_16p background_color, int background_gamma_code,
157     int need_expand, double background_gamma)
158 {
159    png_set_background_fixed(png_ptr, background_color, background_gamma_code,
160       need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
161 }
162 #  endif /* FLOATING_POINT */
163 #endif /* READ_BACKGROUND */
164 
165 /* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
166  * one that pngrtran does first (scale) happens.  This is necessary to allow the
167  * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
168  */
169 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
170 void PNGAPI
png_set_scale_16(png_structrp png_ptr)171 png_set_scale_16(png_structrp png_ptr)
172 {
173    png_debug(1, "in png_set_scale_16");
174 
175    if (png_rtran_ok(png_ptr, 0) == 0)
176       return;
177 
178    png_ptr->transformations |= PNG_SCALE_16_TO_8;
179 }
180 #endif
181 
182 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
183 /* Chop 16-bit depth files to 8-bit depth */
184 void PNGAPI
png_set_strip_16(png_structrp png_ptr)185 png_set_strip_16(png_structrp png_ptr)
186 {
187    png_debug(1, "in png_set_strip_16");
188 
189    if (png_rtran_ok(png_ptr, 0) == 0)
190       return;
191 
192    png_ptr->transformations |= PNG_16_TO_8;
193 }
194 #endif
195 
196 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
197 void PNGAPI
png_set_strip_alpha(png_structrp png_ptr)198 png_set_strip_alpha(png_structrp png_ptr)
199 {
200    png_debug(1, "in png_set_strip_alpha");
201 
202    if (png_rtran_ok(png_ptr, 0) == 0)
203       return;
204 
205    png_ptr->transformations |= PNG_STRIP_ALPHA;
206 }
207 #endif
208 
209 #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
210 static png_fixed_point
translate_gamma_flags(png_structrp png_ptr,png_fixed_point output_gamma,int is_screen)211 translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
212    int is_screen)
213 {
214    /* Check for flag values.  The main reason for having the old Mac value as a
215     * flag is that it is pretty near impossible to work out what the correct
216     * value is from Apple documentation - a working Mac system is needed to
217     * discover the value!
218     */
219    if (output_gamma == PNG_DEFAULT_sRGB ||
220       output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
221    {
222       /* If there is no sRGB support this just sets the gamma to the standard
223        * sRGB value.  (This is a side effect of using this function!)
224        */
225 #     ifdef PNG_READ_sRGB_SUPPORTED
226          png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
227 #     else
228          PNG_UNUSED(png_ptr)
229 #     endif
230       if (is_screen != 0)
231          output_gamma = PNG_GAMMA_sRGB;
232       else
233          output_gamma = PNG_GAMMA_sRGB_INVERSE;
234    }
235 
236    else if (output_gamma == PNG_GAMMA_MAC_18 ||
237       output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
238    {
239       if (is_screen != 0)
240          output_gamma = PNG_GAMMA_MAC_OLD;
241       else
242          output_gamma = PNG_GAMMA_MAC_INVERSE;
243    }
244 
245    return output_gamma;
246 }
247 
248 #  ifdef PNG_FLOATING_POINT_SUPPORTED
249 static png_fixed_point
convert_gamma_value(png_structrp png_ptr,double output_gamma)250 convert_gamma_value(png_structrp png_ptr, double output_gamma)
251 {
252    /* The following silently ignores cases where fixed point (times 100,000)
253     * gamma values are passed to the floating point API.  This is safe and it
254     * means the fixed point constants work just fine with the floating point
255     * API.  The alternative would just lead to undetected errors and spurious
256     * bug reports.  Negative values fail inside the _fixed API unless they
257     * correspond to the flag values.
258     */
259    if (output_gamma > 0 && output_gamma < 128)
260       output_gamma *= PNG_FP_1;
261 
262    /* This preserves -1 and -2 exactly: */
263    output_gamma = floor(output_gamma + .5);
264 
265    if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
266       png_fixed_error(png_ptr, "gamma value");
267 
268    return (png_fixed_point)output_gamma;
269 }
270 #  endif
271 #endif /* READ_ALPHA_MODE || READ_GAMMA */
272 
273 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
274 void PNGFAPI
png_set_alpha_mode_fixed(png_structrp png_ptr,int mode,png_fixed_point output_gamma)275 png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
276    png_fixed_point output_gamma)
277 {
278    int compose = 0;
279    png_fixed_point file_gamma;
280 
281    png_debug(1, "in png_set_alpha_mode");
282 
283    if (png_rtran_ok(png_ptr, 0) == 0)
284       return;
285 
286    output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
287 
288    /* Validate the value to ensure it is in a reasonable range. The value
289     * is expected to be 1 or greater, but this range test allows for some
290     * viewing correction values.  The intent is to weed out users of this API
291     * who use the inverse of the gamma value accidentally!  Since some of these
292     * values are reasonable this may have to be changed:
293     *
294     * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit
295     * gamma of 36, and its reciprocal.)
296     */
297    if (output_gamma < 1000 || output_gamma > 10000000)
298       png_error(png_ptr, "output gamma out of expected range");
299 
300    /* The default file gamma is the inverse of the output gamma; the output
301     * gamma may be changed below so get the file value first:
302     */
303    file_gamma = png_reciprocal(output_gamma);
304 
305    /* There are really 8 possibilities here, composed of any combination
306     * of:
307     *
308     *    premultiply the color channels
309     *    do not encode non-opaque pixels
310     *    encode the alpha as well as the color channels
311     *
312     * The differences disappear if the input/output ('screen') gamma is 1.0,
313     * because then the encoding is a no-op and there is only the choice of
314     * premultiplying the color channels or not.
315     *
316     * png_set_alpha_mode and png_set_background interact because both use
317     * png_compose to do the work.  Calling both is only useful when
318     * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
319     * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
320     */
321    switch (mode)
322    {
323       case PNG_ALPHA_PNG:        /* default: png standard */
324          /* No compose, but it may be set by png_set_background! */
325          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
326          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
327          break;
328 
329       case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
330          compose = 1;
331          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
332          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
333          /* The output is linear: */
334          output_gamma = PNG_FP_1;
335          break;
336 
337       case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */
338          compose = 1;
339          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
340          png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
341          /* output_gamma records the encoding of opaque pixels! */
342          break;
343 
344       case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */
345          compose = 1;
346          png_ptr->transformations |= PNG_ENCODE_ALPHA;
347          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
348          break;
349 
350       default:
351          png_error(png_ptr, "invalid alpha mode");
352    }
353 
354    /* Only set the default gamma if the file gamma has not been set (this has
355     * the side effect that the gamma in a second call to png_set_alpha_mode will
356     * be ignored.)
357     */
358    if (png_ptr->colorspace.gamma == 0)
359    {
360       png_ptr->colorspace.gamma = file_gamma;
361       png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
362    }
363 
364    /* But always set the output gamma: */
365    png_ptr->screen_gamma = output_gamma;
366 
367    /* Finally, if pre-multiplying, set the background fields to achieve the
368     * desired result.
369     */
370    if (compose != 0)
371    {
372       /* And obtain alpha pre-multiplication by composing on black: */
373       memset(&png_ptr->background, 0, (sizeof png_ptr->background));
374       png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
375       png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
376       png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
377 
378       if ((png_ptr->transformations & PNG_COMPOSE) != 0)
379          png_error(png_ptr,
380             "conflicting calls to set alpha mode and background");
381 
382       png_ptr->transformations |= PNG_COMPOSE;
383    }
384 }
385 
386 #  ifdef PNG_FLOATING_POINT_SUPPORTED
387 void PNGAPI
png_set_alpha_mode(png_structrp png_ptr,int mode,double output_gamma)388 png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
389 {
390    png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
391       output_gamma));
392 }
393 #  endif
394 #endif
395 
396 #ifdef PNG_READ_QUANTIZE_SUPPORTED
397 /* Dither file to 8-bit.  Supply a palette, the current number
398  * of elements in the palette, the maximum number of elements
399  * allowed, and a histogram if possible.  If the current number
400  * of colors is greater than the maximum number, the palette will be
401  * modified to fit in the maximum number.  "full_quantize" indicates
402  * whether we need a quantizing cube set up for RGB images, or if we
403  * simply are reducing the number of colors in a paletted image.
404  */
405 
406 typedef struct png_dsort_struct
407 {
408    struct png_dsort_struct * next;
409    png_byte left;
410    png_byte right;
411 } png_dsort;
412 typedef png_dsort *   png_dsortp;
413 typedef png_dsort * * png_dsortpp;
414 
415 void PNGAPI
png_set_quantize(png_structrp png_ptr,png_colorp palette,int num_palette,int maximum_colors,png_const_uint_16p histogram,int full_quantize)416 png_set_quantize(png_structrp png_ptr, png_colorp palette,
417     int num_palette, int maximum_colors, png_const_uint_16p histogram,
418     int full_quantize)
419 {
420    png_debug(1, "in png_set_quantize");
421 
422    if (png_rtran_ok(png_ptr, 0) == 0)
423       return;
424 
425    png_ptr->transformations |= PNG_QUANTIZE;
426 
427    if (full_quantize == 0)
428    {
429       int i;
430 
431       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
432           (png_uint_32)(num_palette * (sizeof (png_byte))));
433       for (i = 0; i < num_palette; i++)
434          png_ptr->quantize_index[i] = (png_byte)i;
435    }
436 
437    if (num_palette > maximum_colors)
438    {
439       if (histogram != NULL)
440       {
441          /* This is easy enough, just throw out the least used colors.
442           * Perhaps not the best solution, but good enough.
443           */
444 
445          int i;
446 
447          /* Initialize an array to sort colors */
448          png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
449              (png_uint_32)(num_palette * (sizeof (png_byte))));
450 
451          /* Initialize the quantize_sort array */
452          for (i = 0; i < num_palette; i++)
453             png_ptr->quantize_sort[i] = (png_byte)i;
454 
455          /* Find the least used palette entries by starting a
456           * bubble sort, and running it until we have sorted
457           * out enough colors.  Note that we don't care about
458           * sorting all the colors, just finding which are
459           * least used.
460           */
461 
462          for (i = num_palette - 1; i >= maximum_colors; i--)
463          {
464             int done; /* To stop early if the list is pre-sorted */
465             int j;
466 
467             done = 1;
468             for (j = 0; j < i; j++)
469             {
470                if (histogram[png_ptr->quantize_sort[j]]
471                    < histogram[png_ptr->quantize_sort[j + 1]])
472                {
473                   png_byte t;
474 
475                   t = png_ptr->quantize_sort[j];
476                   png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
477                   png_ptr->quantize_sort[j + 1] = t;
478                   done = 0;
479                }
480             }
481 
482             if (done != 0)
483                break;
484          }
485 
486          /* Swap the palette around, and set up a table, if necessary */
487          if (full_quantize != 0)
488          {
489             int j = num_palette;
490 
491             /* Put all the useful colors within the max, but don't
492              * move the others.
493              */
494             for (i = 0; i < maximum_colors; i++)
495             {
496                if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
497                {
498                   do
499                      j--;
500                   while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
501 
502                   palette[i] = palette[j];
503                }
504             }
505          }
506          else
507          {
508             int j = num_palette;
509 
510             /* Move all the used colors inside the max limit, and
511              * develop a translation table.
512              */
513             for (i = 0; i < maximum_colors; i++)
514             {
515                /* Only move the colors we need to */
516                if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
517                {
518                   png_color tmp_color;
519 
520                   do
521                      j--;
522                   while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
523 
524                   tmp_color = palette[j];
525                   palette[j] = palette[i];
526                   palette[i] = tmp_color;
527                   /* Indicate where the color went */
528                   png_ptr->quantize_index[j] = (png_byte)i;
529                   png_ptr->quantize_index[i] = (png_byte)j;
530                }
531             }
532 
533             /* Find closest color for those colors we are not using */
534             for (i = 0; i < num_palette; i++)
535             {
536                if ((int)png_ptr->quantize_index[i] >= maximum_colors)
537                {
538                   int min_d, k, min_k, d_index;
539 
540                   /* Find the closest color to one we threw out */
541                   d_index = png_ptr->quantize_index[i];
542                   min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
543                   for (k = 1, min_k = 0; k < maximum_colors; k++)
544                   {
545                      int d;
546 
547                      d = PNG_COLOR_DIST(palette[d_index], palette[k]);
548 
549                      if (d < min_d)
550                      {
551                         min_d = d;
552                         min_k = k;
553                      }
554                   }
555                   /* Point to closest color */
556                   png_ptr->quantize_index[i] = (png_byte)min_k;
557                }
558             }
559          }
560          png_free(png_ptr, png_ptr->quantize_sort);
561          png_ptr->quantize_sort = NULL;
562       }
563       else
564       {
565          /* This is much harder to do simply (and quickly).  Perhaps
566           * we need to go through a median cut routine, but those
567           * don't always behave themselves with only a few colors
568           * as input.  So we will just find the closest two colors,
569           * and throw out one of them (chosen somewhat randomly).
570           * [We don't understand this at all, so if someone wants to
571           *  work on improving it, be our guest - AED, GRP]
572           */
573          int i;
574          int max_d;
575          int num_new_palette;
576          png_dsortp t;
577          png_dsortpp hash;
578 
579          t = NULL;
580 
581          /* Initialize palette index arrays */
582          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
583              (png_uint_32)(num_palette * (sizeof (png_byte))));
584          png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
585              (png_uint_32)(num_palette * (sizeof (png_byte))));
586 
587          /* Initialize the sort array */
588          for (i = 0; i < num_palette; i++)
589          {
590             png_ptr->index_to_palette[i] = (png_byte)i;
591             png_ptr->palette_to_index[i] = (png_byte)i;
592          }
593 
594          hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
595              (sizeof (png_dsortp))));
596 
597          num_new_palette = num_palette;
598 
599          /* Initial wild guess at how far apart the farthest pixel
600           * pair we will be eliminating will be.  Larger
601           * numbers mean more areas will be allocated, Smaller
602           * numbers run the risk of not saving enough data, and
603           * having to do this all over again.
604           *
605           * I have not done extensive checking on this number.
606           */
607          max_d = 96;
608 
609          while (num_new_palette > maximum_colors)
610          {
611             for (i = 0; i < num_new_palette - 1; i++)
612             {
613                int j;
614 
615                for (j = i + 1; j < num_new_palette; j++)
616                {
617                   int d;
618 
619                   d = PNG_COLOR_DIST(palette[i], palette[j]);
620 
621                   if (d <= max_d)
622                   {
623 
624                      t = (png_dsortp)png_malloc_warn(png_ptr,
625                          (png_uint_32)(sizeof (png_dsort)));
626 
627                      if (t == NULL)
628                          break;
629 
630                      t->next = hash[d];
631                      t->left = (png_byte)i;
632                      t->right = (png_byte)j;
633                      hash[d] = t;
634                   }
635                }
636                if (t == NULL)
637                   break;
638             }
639 
640             if (t != NULL)
641             for (i = 0; i <= max_d; i++)
642             {
643                if (hash[i] != NULL)
644                {
645                   png_dsortp p;
646 
647                   for (p = hash[i]; p; p = p->next)
648                   {
649                      if ((int)png_ptr->index_to_palette[p->left]
650                          < num_new_palette &&
651                          (int)png_ptr->index_to_palette[p->right]
652                          < num_new_palette)
653                      {
654                         int j, next_j;
655 
656                         if (num_new_palette & 0x01)
657                         {
658                            j = p->left;
659                            next_j = p->right;
660                         }
661                         else
662                         {
663                            j = p->right;
664                            next_j = p->left;
665                         }
666 
667                         num_new_palette--;
668                         palette[png_ptr->index_to_palette[j]]
669                             = palette[num_new_palette];
670                         if (full_quantize == 0)
671                         {
672                            int k;
673 
674                            for (k = 0; k < num_palette; k++)
675                            {
676                               if (png_ptr->quantize_index[k] ==
677                                   png_ptr->index_to_palette[j])
678                                  png_ptr->quantize_index[k] =
679                                      png_ptr->index_to_palette[next_j];
680 
681                               if ((int)png_ptr->quantize_index[k] ==
682                                   num_new_palette)
683                                  png_ptr->quantize_index[k] =
684                                      png_ptr->index_to_palette[j];
685                            }
686                         }
687 
688                         png_ptr->index_to_palette[png_ptr->palette_to_index
689                             [num_new_palette]] = png_ptr->index_to_palette[j];
690 
691                         png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
692                             = png_ptr->palette_to_index[num_new_palette];
693 
694                         png_ptr->index_to_palette[j] =
695                             (png_byte)num_new_palette;
696 
697                         png_ptr->palette_to_index[num_new_palette] =
698                             (png_byte)j;
699                      }
700                      if (num_new_palette <= maximum_colors)
701                         break;
702                   }
703                   if (num_new_palette <= maximum_colors)
704                      break;
705                }
706             }
707 
708             for (i = 0; i < 769; i++)
709             {
710                if (hash[i] != NULL)
711                {
712                   png_dsortp p = hash[i];
713                   while (p)
714                   {
715                      t = p->next;
716                      png_free(png_ptr, p);
717                      p = t;
718                   }
719                }
720                hash[i] = 0;
721             }
722             max_d += 96;
723          }
724          png_free(png_ptr, hash);
725          png_free(png_ptr, png_ptr->palette_to_index);
726          png_free(png_ptr, png_ptr->index_to_palette);
727          png_ptr->palette_to_index = NULL;
728          png_ptr->index_to_palette = NULL;
729       }
730       num_palette = maximum_colors;
731    }
732    if (png_ptr->palette == NULL)
733    {
734       png_ptr->palette = palette;
735    }
736    png_ptr->num_palette = (png_uint_16)num_palette;
737 
738    if (full_quantize != 0)
739    {
740       int i;
741       png_bytep distance;
742       int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
743           PNG_QUANTIZE_BLUE_BITS;
744       int num_red = (1 << PNG_QUANTIZE_RED_BITS);
745       int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
746       int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
747       png_size_t num_entries = ((png_size_t)1 << total_bits);
748 
749       png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
750           (png_uint_32)(num_entries * (sizeof (png_byte))));
751 
752       distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
753           (sizeof (png_byte))));
754 
755       memset(distance, 0xff, num_entries * (sizeof (png_byte)));
756 
757       for (i = 0; i < num_palette; i++)
758       {
759          int ir, ig, ib;
760          int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
761          int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
762          int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
763 
764          for (ir = 0; ir < num_red; ir++)
765          {
766             /* int dr = abs(ir - r); */
767             int dr = ((ir > r) ? ir - r : r - ir);
768             int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
769                 PNG_QUANTIZE_GREEN_BITS));
770 
771             for (ig = 0; ig < num_green; ig++)
772             {
773                /* int dg = abs(ig - g); */
774                int dg = ((ig > g) ? ig - g : g - ig);
775                int dt = dr + dg;
776                int dm = ((dr > dg) ? dr : dg);
777                int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
778 
779                for (ib = 0; ib < num_blue; ib++)
780                {
781                   int d_index = index_g | ib;
782                   /* int db = abs(ib - b); */
783                   int db = ((ib > b) ? ib - b : b - ib);
784                   int dmax = ((dm > db) ? dm : db);
785                   int d = dmax + dt + db;
786 
787                   if (d < (int)distance[d_index])
788                   {
789                      distance[d_index] = (png_byte)d;
790                      png_ptr->palette_lookup[d_index] = (png_byte)i;
791                   }
792                }
793             }
794          }
795       }
796 
797       png_free(png_ptr, distance);
798    }
799 }
800 #endif /* READ_QUANTIZE */
801 
802 #ifdef PNG_READ_GAMMA_SUPPORTED
803 void PNGFAPI
png_set_gamma_fixed(png_structrp png_ptr,png_fixed_point scrn_gamma,png_fixed_point file_gamma)804 png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
805    png_fixed_point file_gamma)
806 {
807    png_debug(1, "in png_set_gamma_fixed");
808 
809    if (png_rtran_ok(png_ptr, 0) == 0)
810       return;
811 
812    /* New in libpng-1.5.4 - reserve particular negative values as flags. */
813    scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
814    file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
815 
816    /* Checking the gamma values for being >0 was added in 1.5.4 along with the
817     * premultiplied alpha support; this actually hides an undocumented feature
818     * of the previous implementation which allowed gamma processing to be
819     * disabled in background handling.  There is no evidence (so far) that this
820     * was being used; however, png_set_background itself accepted and must still
821     * accept '0' for the gamma value it takes, because it isn't always used.
822     *
823     * Since this is an API change (albeit a very minor one that removes an
824     * undocumented API feature) the following checks were only enabled in
825     * libpng-1.6.0.
826     */
827    if (file_gamma <= 0)
828       png_error(png_ptr, "invalid file gamma in png_set_gamma");
829 
830    if (scrn_gamma <= 0)
831       png_error(png_ptr, "invalid screen gamma in png_set_gamma");
832 
833    /* Set the gamma values unconditionally - this overrides the value in the PNG
834     * file if a gAMA chunk was present.  png_set_alpha_mode provides a
835     * different, easier, way to default the file gamma.
836     */
837    png_ptr->colorspace.gamma = file_gamma;
838    png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
839    png_ptr->screen_gamma = scrn_gamma;
840 }
841 
842 #  ifdef PNG_FLOATING_POINT_SUPPORTED
843 void PNGAPI
png_set_gamma(png_structrp png_ptr,double scrn_gamma,double file_gamma)844 png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
845 {
846    png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
847       convert_gamma_value(png_ptr, file_gamma));
848 }
849 #  endif /* FLOATING_POINT */
850 #endif /* READ_GAMMA */
851 
852 #ifdef PNG_READ_EXPAND_SUPPORTED
853 /* Expand paletted images to RGB, expand grayscale images of
854  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
855  * to alpha channels.
856  */
857 void PNGAPI
png_set_expand(png_structrp png_ptr)858 png_set_expand(png_structrp png_ptr)
859 {
860    png_debug(1, "in png_set_expand");
861 
862    if (png_rtran_ok(png_ptr, 0) == 0)
863       return;
864 
865    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
866 }
867 
868 /* GRR 19990627:  the following three functions currently are identical
869  *  to png_set_expand().  However, it is entirely reasonable that someone
870  *  might wish to expand an indexed image to RGB but *not* expand a single,
871  *  fully transparent palette entry to a full alpha channel--perhaps instead
872  *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
873  *  the transparent color with a particular RGB value, or drop tRNS entirely.
874  *  IOW, a future version of the library may make the transformations flag
875  *  a bit more fine-grained, with separate bits for each of these three
876  *  functions.
877  *
878  *  More to the point, these functions make it obvious what libpng will be
879  *  doing, whereas "expand" can (and does) mean any number of things.
880  *
881  *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
882  *  to expand only the sample depth but not to expand the tRNS to alpha
883  *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
884  */
885 
886 /* Expand paletted images to RGB. */
887 void PNGAPI
png_set_palette_to_rgb(png_structrp png_ptr)888 png_set_palette_to_rgb(png_structrp png_ptr)
889 {
890    png_debug(1, "in png_set_palette_to_rgb");
891 
892    if (png_rtran_ok(png_ptr, 0) == 0)
893       return;
894 
895    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
896 }
897 
898 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
899 void PNGAPI
png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)900 png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
901 {
902    png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
903 
904    if (png_rtran_ok(png_ptr, 0) == 0)
905       return;
906 
907    png_ptr->transformations |= PNG_EXPAND;
908 }
909 
910 /* Expand tRNS chunks to alpha channels. */
911 void PNGAPI
png_set_tRNS_to_alpha(png_structrp png_ptr)912 png_set_tRNS_to_alpha(png_structrp png_ptr)
913 {
914    png_debug(1, "in png_set_tRNS_to_alpha");
915 
916    if (png_rtran_ok(png_ptr, 0) == 0)
917       return;
918 
919    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
920 }
921 #endif /* READ_EXPAND */
922 
923 #ifdef PNG_READ_EXPAND_16_SUPPORTED
924 /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
925  * it may not work correctly.)
926  */
927 void PNGAPI
png_set_expand_16(png_structrp png_ptr)928 png_set_expand_16(png_structrp png_ptr)
929 {
930    png_debug(1, "in png_set_expand_16");
931 
932    if (png_rtran_ok(png_ptr, 0) == 0)
933       return;
934 
935    png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
936 }
937 #endif
938 
939 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
940 void PNGAPI
png_set_gray_to_rgb(png_structrp png_ptr)941 png_set_gray_to_rgb(png_structrp png_ptr)
942 {
943    png_debug(1, "in png_set_gray_to_rgb");
944 
945    if (png_rtran_ok(png_ptr, 0) == 0)
946       return;
947 
948    /* Because rgb must be 8 bits or more: */
949    png_set_expand_gray_1_2_4_to_8(png_ptr);
950    png_ptr->transformations |= PNG_GRAY_TO_RGB;
951 }
952 #endif
953 
954 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
955 void PNGFAPI
png_set_rgb_to_gray_fixed(png_structrp png_ptr,int error_action,png_fixed_point red,png_fixed_point green)956 png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
957     png_fixed_point red, png_fixed_point green)
958 {
959    png_debug(1, "in png_set_rgb_to_gray");
960 
961    /* Need the IHDR here because of the check on color_type below. */
962    /* TODO: fix this */
963    if (png_rtran_ok(png_ptr, 1) == 0)
964       return;
965 
966    switch (error_action)
967    {
968       case PNG_ERROR_ACTION_NONE:
969          png_ptr->transformations |= PNG_RGB_TO_GRAY;
970          break;
971 
972       case PNG_ERROR_ACTION_WARN:
973          png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
974          break;
975 
976       case PNG_ERROR_ACTION_ERROR:
977          png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
978          break;
979 
980       default:
981          png_error(png_ptr, "invalid error action to rgb_to_gray");
982    }
983 
984    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
985 #ifdef PNG_READ_EXPAND_SUPPORTED
986       png_ptr->transformations |= PNG_EXPAND;
987 #else
988    {
989       /* Make this an error in 1.6 because otherwise the application may assume
990        * that it just worked and get a memory overwrite.
991        */
992       png_error(png_ptr,
993         "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
994 
995       /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
996    }
997 #endif
998    {
999       if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
1000       {
1001          png_uint_16 red_int, green_int;
1002 
1003          /* NOTE: this calculation does not round, but this behavior is retained
1004           * for consistency; the inaccuracy is very small.  The code here always
1005           * overwrites the coefficients, regardless of whether they have been
1006           * defaulted or set already.
1007           */
1008          red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
1009          green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
1010 
1011          png_ptr->rgb_to_gray_red_coeff   = red_int;
1012          png_ptr->rgb_to_gray_green_coeff = green_int;
1013          png_ptr->rgb_to_gray_coefficients_set = 1;
1014       }
1015 
1016       else
1017       {
1018          if (red >= 0 && green >= 0)
1019             png_app_warning(png_ptr,
1020                "ignoring out of range rgb_to_gray coefficients");
1021 
1022          /* Use the defaults, from the cHRM chunk if set, else the historical
1023           * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
1024           * png_do_rgb_to_gray for more discussion of the values.  In this case
1025           * the coefficients are not marked as 'set' and are not overwritten if
1026           * something has already provided a default.
1027           */
1028          if (png_ptr->rgb_to_gray_red_coeff == 0 &&
1029             png_ptr->rgb_to_gray_green_coeff == 0)
1030          {
1031             png_ptr->rgb_to_gray_red_coeff   = 6968;
1032             png_ptr->rgb_to_gray_green_coeff = 23434;
1033             /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
1034          }
1035       }
1036    }
1037 }
1038 
1039 #ifdef PNG_FLOATING_POINT_SUPPORTED
1040 /* Convert a RGB image to a grayscale of the same width.  This allows us,
1041  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
1042  */
1043 
1044 void PNGAPI
png_set_rgb_to_gray(png_structrp png_ptr,int error_action,double red,double green)1045 png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
1046    double green)
1047 {
1048    png_set_rgb_to_gray_fixed(png_ptr, error_action,
1049       png_fixed(png_ptr, red, "rgb to gray red coefficient"),
1050       png_fixed(png_ptr, green, "rgb to gray green coefficient"));
1051 }
1052 #endif /* FLOATING POINT */
1053 
1054 #endif /* RGB_TO_GRAY */
1055 
1056 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
1057     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
1058 void PNGAPI
png_set_read_user_transform_fn(png_structrp png_ptr,png_user_transform_ptr read_user_transform_fn)1059 png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
1060     read_user_transform_fn)
1061 {
1062    png_debug(1, "in png_set_read_user_transform_fn");
1063 
1064 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1065    png_ptr->transformations |= PNG_USER_TRANSFORM;
1066    png_ptr->read_user_transform_fn = read_user_transform_fn;
1067 #endif
1068 }
1069 #endif
1070 
1071 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
1072 #ifdef PNG_READ_GAMMA_SUPPORTED
1073 /* In the case of gamma transformations only do transformations on images where
1074  * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
1075  * slows things down slightly, and also needlessly introduces small errors.
1076  */
1077 static int /* PRIVATE */
png_gamma_threshold(png_fixed_point screen_gamma,png_fixed_point file_gamma)1078 png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
1079 {
1080    /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
1081     * correction as a difference of the overall transform from 1.0
1082     *
1083     * We want to compare the threshold with s*f - 1, if we get
1084     * overflow here it is because of wacky gamma values so we
1085     * turn on processing anyway.
1086     */
1087    png_fixed_point gtest;
1088    return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
1089        png_gamma_significant(gtest);
1090 }
1091 #endif
1092 
1093 /* Initialize everything needed for the read.  This includes modifying
1094  * the palette.
1095  */
1096 
1097 /* For the moment 'png_init_palette_transformations' and
1098  * 'png_init_rgb_transformations' only do some flag canceling optimizations.
1099  * The intent is that these two routines should have palette or rgb operations
1100  * extracted from 'png_init_read_transformations'.
1101  */
1102 static void /* PRIVATE */
png_init_palette_transformations(png_structrp png_ptr)1103 png_init_palette_transformations(png_structrp png_ptr)
1104 {
1105    /* Called to handle the (input) palette case.  In png_do_read_transformations
1106     * the first step is to expand the palette if requested, so this code must
1107     * take care to only make changes that are invariant with respect to the
1108     * palette expansion, or only do them if there is no expansion.
1109     *
1110     * STRIP_ALPHA has already been handled in the caller (by setting num_trans
1111     * to 0.)
1112     */
1113    int input_has_alpha = 0;
1114    int input_has_transparency = 0;
1115 
1116    if (png_ptr->num_trans > 0)
1117    {
1118       int i;
1119 
1120       /* Ignore if all the entries are opaque (unlikely!) */
1121       for (i=0; i<png_ptr->num_trans; ++i)
1122       {
1123          if (png_ptr->trans_alpha[i] == 255)
1124             continue;
1125          else if (png_ptr->trans_alpha[i] == 0)
1126             input_has_transparency = 1;
1127          else
1128          {
1129             input_has_transparency = 1;
1130             input_has_alpha = 1;
1131             break;
1132          }
1133       }
1134    }
1135 
1136    /* If no alpha we can optimize. */
1137    if (input_has_alpha == 0)
1138    {
1139       /* Any alpha means background and associative alpha processing is
1140        * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
1141        * and ENCODE_ALPHA are irrelevant.
1142        */
1143       png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1144       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1145 
1146       if (input_has_transparency == 0)
1147          png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1148    }
1149 
1150 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1151    /* png_set_background handling - deals with the complexity of whether the
1152     * background color is in the file format or the screen format in the case
1153     * where an 'expand' will happen.
1154     */
1155 
1156    /* The following code cannot be entered in the alpha pre-multiplication case
1157     * because PNG_BACKGROUND_EXPAND is cancelled below.
1158     */
1159    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
1160        (png_ptr->transformations & PNG_EXPAND) != 0)
1161    {
1162       {
1163          png_ptr->background.red   =
1164              png_ptr->palette[png_ptr->background.index].red;
1165          png_ptr->background.green =
1166              png_ptr->palette[png_ptr->background.index].green;
1167          png_ptr->background.blue  =
1168              png_ptr->palette[png_ptr->background.index].blue;
1169 
1170 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1171         if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
1172         {
1173            if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1174            {
1175               /* Invert the alpha channel (in tRNS) unless the pixels are
1176                * going to be expanded, in which case leave it for later
1177                */
1178               int i, istop = png_ptr->num_trans;
1179 
1180               for (i=0; i<istop; i++)
1181                  png_ptr->trans_alpha[i] = (png_byte)(255 -
1182                     png_ptr->trans_alpha[i]);
1183            }
1184         }
1185 #endif /* READ_INVERT_ALPHA */
1186       }
1187    } /* background expand and (therefore) no alpha association. */
1188 #endif /* READ_EXPAND && READ_BACKGROUND */
1189 }
1190 
1191 static void /* PRIVATE */
png_init_rgb_transformations(png_structrp png_ptr)1192 png_init_rgb_transformations(png_structrp png_ptr)
1193 {
1194    /* Added to libpng-1.5.4: check the color type to determine whether there
1195     * is any alpha or transparency in the image and simply cancel the
1196     * background and alpha mode stuff if there isn't.
1197     */
1198    int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1199    int input_has_transparency = png_ptr->num_trans > 0;
1200 
1201    /* If no alpha we can optimize. */
1202    if (input_has_alpha == 0)
1203    {
1204       /* Any alpha means background and associative alpha processing is
1205        * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
1206        * and ENCODE_ALPHA are irrelevant.
1207        */
1208 #     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1209          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1210          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1211 #     endif
1212 
1213       if (input_has_transparency == 0)
1214          png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1215    }
1216 
1217 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1218    /* png_set_background handling - deals with the complexity of whether the
1219     * background color is in the file format or the screen format in the case
1220     * where an 'expand' will happen.
1221     */
1222 
1223    /* The following code cannot be entered in the alpha pre-multiplication case
1224     * because PNG_BACKGROUND_EXPAND is cancelled below.
1225     */
1226    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
1227        (png_ptr->transformations & PNG_EXPAND) != 0 &&
1228        (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
1229        /* i.e., GRAY or GRAY_ALPHA */
1230    {
1231       {
1232          /* Expand background and tRNS chunks */
1233          int gray = png_ptr->background.gray;
1234          int trans_gray = png_ptr->trans_color.gray;
1235 
1236          switch (png_ptr->bit_depth)
1237          {
1238             case 1:
1239                gray *= 0xff;
1240                trans_gray *= 0xff;
1241                break;
1242 
1243             case 2:
1244                gray *= 0x55;
1245                trans_gray *= 0x55;
1246                break;
1247 
1248             case 4:
1249                gray *= 0x11;
1250                trans_gray *= 0x11;
1251                break;
1252 
1253             default:
1254 
1255             case 8:
1256                /* FALL THROUGH (Already 8 bits) */
1257 
1258             case 16:
1259                /* Already a full 16 bits */
1260                break;
1261          }
1262 
1263          png_ptr->background.red = png_ptr->background.green =
1264             png_ptr->background.blue = (png_uint_16)gray;
1265 
1266          if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
1267          {
1268             png_ptr->trans_color.red = png_ptr->trans_color.green =
1269                png_ptr->trans_color.blue = (png_uint_16)trans_gray;
1270          }
1271       }
1272    } /* background expand and (therefore) no alpha association. */
1273 #endif /* READ_EXPAND && READ_BACKGROUND */
1274 }
1275 
1276 void /* PRIVATE */
png_init_read_transformations(png_structrp png_ptr)1277 png_init_read_transformations(png_structrp png_ptr)
1278 {
1279    png_debug(1, "in png_init_read_transformations");
1280 
1281    /* This internal function is called from png_read_start_row in pngrutil.c
1282     * and it is called before the 'rowbytes' calculation is done, so the code
1283     * in here can change or update the transformations flags.
1284     *
1285     * First do updates that do not depend on the details of the PNG image data
1286     * being processed.
1287     */
1288 
1289 #ifdef PNG_READ_GAMMA_SUPPORTED
1290    /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
1291     * png_set_alpha_mode and this is another source for a default file gamma so
1292     * the test needs to be performed later - here.  In addition prior to 1.5.4
1293     * the tests were repeated for the PALETTE color type here - this is no
1294     * longer necessary (and doesn't seem to have been necessary before.)
1295     */
1296    {
1297       /* The following temporary indicates if overall gamma correction is
1298        * required.
1299        */
1300       int gamma_correction = 0;
1301 
1302       if (png_ptr->colorspace.gamma != 0) /* has been set */
1303       {
1304          if (png_ptr->screen_gamma != 0) /* screen set too */
1305             gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
1306                png_ptr->screen_gamma);
1307 
1308          else
1309             /* Assume the output matches the input; a long time default behavior
1310              * of libpng, although the standard has nothing to say about this.
1311              */
1312             png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
1313       }
1314 
1315       else if (png_ptr->screen_gamma != 0)
1316          /* The converse - assume the file matches the screen, note that this
1317           * perhaps undesireable default can (from 1.5.4) be changed by calling
1318           * png_set_alpha_mode (even if the alpha handling mode isn't required
1319           * or isn't changed from the default.)
1320           */
1321          png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
1322 
1323       else /* neither are set */
1324          /* Just in case the following prevents any processing - file and screen
1325           * are both assumed to be linear and there is no way to introduce a
1326           * third gamma value other than png_set_background with 'UNIQUE', and,
1327           * prior to 1.5.4
1328           */
1329          png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
1330 
1331       /* We have a gamma value now. */
1332       png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
1333 
1334       /* Now turn the gamma transformation on or off as appropriate.  Notice
1335        * that PNG_GAMMA just refers to the file->screen correction.  Alpha
1336        * composition may independently cause gamma correction because it needs
1337        * linear data (e.g. if the file has a gAMA chunk but the screen gamma
1338        * hasn't been specified.)  In any case this flag may get turned off in
1339        * the code immediately below if the transform can be handled outside the
1340        * row loop.
1341        */
1342       if (gamma_correction != 0)
1343          png_ptr->transformations |= PNG_GAMMA;
1344 
1345       else
1346          png_ptr->transformations &= ~PNG_GAMMA;
1347    }
1348 #endif
1349 
1350    /* Certain transformations have the effect of preventing other
1351     * transformations that happen afterward in png_do_read_transformations;
1352     * resolve the interdependencies here.  From the code of
1353     * png_do_read_transformations the order is:
1354     *
1355     *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
1356     *  2) PNG_STRIP_ALPHA (if no compose)
1357     *  3) PNG_RGB_TO_GRAY
1358     *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
1359     *  5) PNG_COMPOSE
1360     *  6) PNG_GAMMA
1361     *  7) PNG_STRIP_ALPHA (if compose)
1362     *  8) PNG_ENCODE_ALPHA
1363     *  9) PNG_SCALE_16_TO_8
1364     * 10) PNG_16_TO_8
1365     * 11) PNG_QUANTIZE (converts to palette)
1366     * 12) PNG_EXPAND_16
1367     * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
1368     * 14) PNG_INVERT_MONO
1369     * 15) PNG_INVERT_ALPHA
1370     * 16) PNG_SHIFT
1371     * 17) PNG_PACK
1372     * 18) PNG_BGR
1373     * 19) PNG_PACKSWAP
1374     * 20) PNG_FILLER (includes PNG_ADD_ALPHA)
1375     * 21) PNG_SWAP_ALPHA
1376     * 22) PNG_SWAP_BYTES
1377     * 23) PNG_USER_TRANSFORM [must be last]
1378     */
1379 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1380    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
1381        (png_ptr->transformations & PNG_COMPOSE) == 0)
1382    {
1383       /* Stripping the alpha channel happens immediately after the 'expand'
1384        * transformations, before all other transformation, so it cancels out
1385        * the alpha handling.  It has the side effect negating the effect of
1386        * PNG_EXPAND_tRNS too:
1387        */
1388       png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
1389          PNG_EXPAND_tRNS);
1390       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1391 
1392       /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
1393        * so transparency information would remain just so long as it wasn't
1394        * expanded.  This produces unexpected API changes if the set of things
1395        * that do PNG_EXPAND_tRNS changes (perfectly possible given the
1396        * documentation - which says ask for what you want, accept what you
1397        * get.)  This makes the behavior consistent from 1.5.4:
1398        */
1399       png_ptr->num_trans = 0;
1400    }
1401 #endif /* STRIP_ALPHA supported, no COMPOSE */
1402 
1403 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1404    /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
1405     * settings will have no effect.
1406     */
1407    if (png_gamma_significant(png_ptr->screen_gamma) == 0)
1408    {
1409       png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1410       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1411    }
1412 #endif
1413 
1414 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1415    /* Make sure the coefficients for the rgb to gray conversion are set
1416     * appropriately.
1417     */
1418    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
1419       png_colorspace_set_rgb_coefficients(png_ptr);
1420 #endif
1421 
1422 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1423 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1424    /* Detect gray background and attempt to enable optimization for
1425     * gray --> RGB case.
1426     *
1427     * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
1428     * RGB_ALPHA (in which case need_expand is superfluous anyway), the
1429     * background color might actually be gray yet not be flagged as such.
1430     * This is not a problem for the current code, which uses
1431     * PNG_BACKGROUND_IS_GRAY only to decide when to do the
1432     * png_do_gray_to_rgb() transformation.
1433     *
1434     * TODO: this code needs to be revised to avoid the complexity and
1435     * interdependencies.  The color type of the background should be recorded in
1436     * png_set_background, along with the bit depth, then the code has a record
1437     * of exactly what color space the background is currently in.
1438     */
1439    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
1440    {
1441       /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
1442        * the file was grayscale the background value is gray.
1443        */
1444       if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
1445          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1446    }
1447 
1448    else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1449    {
1450       /* PNG_COMPOSE: png_set_background was called with need_expand false,
1451        * so the color is in the color space of the output or png_set_alpha_mode
1452        * was called and the color is black.  Ignore RGB_TO_GRAY because that
1453        * happens before GRAY_TO_RGB.
1454        */
1455       if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
1456       {
1457          if (png_ptr->background.red == png_ptr->background.green &&
1458              png_ptr->background.red == png_ptr->background.blue)
1459          {
1460             png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1461             png_ptr->background.gray = png_ptr->background.red;
1462          }
1463       }
1464    }
1465 #endif /* READ_EXPAND && READ_BACKGROUND */
1466 #endif /* READ_GRAY_TO_RGB */
1467 
1468    /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
1469     * can be performed directly on the palette, and some (such as rgb to gray)
1470     * can be optimized inside the palette.  This is particularly true of the
1471     * composite (background and alpha) stuff, which can be pretty much all done
1472     * in the palette even if the result is expanded to RGB or gray afterward.
1473     *
1474     * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
1475     * earlier and the palette stuff is actually handled on the first row.  This
1476     * leads to the reported bug that the palette returned by png_get_PLTE is not
1477     * updated.
1478     */
1479    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1480       png_init_palette_transformations(png_ptr);
1481 
1482    else
1483       png_init_rgb_transformations(png_ptr);
1484 
1485 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1486    defined(PNG_READ_EXPAND_16_SUPPORTED)
1487    if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
1488        (png_ptr->transformations & PNG_COMPOSE) != 0 &&
1489        (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
1490        png_ptr->bit_depth != 16)
1491    {
1492       /* TODO: fix this.  Because the expand_16 operation is after the compose
1493        * handling the background color must be 8, not 16, bits deep, but the
1494        * application will supply a 16-bit value so reduce it here.
1495        *
1496        * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
1497        * present, so that case is ok (until do_expand_16 is moved.)
1498        *
1499        * NOTE: this discards the low 16 bits of the user supplied background
1500        * color, but until expand_16 works properly there is no choice!
1501        */
1502 #     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
1503       CHOP(png_ptr->background.red);
1504       CHOP(png_ptr->background.green);
1505       CHOP(png_ptr->background.blue);
1506       CHOP(png_ptr->background.gray);
1507 #     undef CHOP
1508    }
1509 #endif /* READ_BACKGROUND && READ_EXPAND_16 */
1510 
1511 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1512    (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
1513    defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
1514    if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
1515        (png_ptr->transformations & PNG_COMPOSE) != 0 &&
1516        (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
1517        png_ptr->bit_depth == 16)
1518    {
1519       /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
1520        * component this will also happen after PNG_COMPOSE and so the background
1521        * color must be pre-expanded here.
1522        *
1523        * TODO: fix this too.
1524        */
1525       png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
1526       png_ptr->background.green =
1527          (png_uint_16)(png_ptr->background.green * 257);
1528       png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
1529       png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
1530    }
1531 #endif
1532 
1533    /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
1534     * background support (see the comments in scripts/pnglibconf.dfa), this
1535     * allows pre-multiplication of the alpha channel to be implemented as
1536     * compositing on black.  This is probably sub-optimal and has been done in
1537     * 1.5.4 betas simply to enable external critique and testing (i.e. to
1538     * implement the new API quickly, without lots of internal changes.)
1539     */
1540 
1541 #ifdef PNG_READ_GAMMA_SUPPORTED
1542 #  ifdef PNG_READ_BACKGROUND_SUPPORTED
1543       /* Includes ALPHA_MODE */
1544       png_ptr->background_1 = png_ptr->background;
1545 #  endif
1546 
1547    /* This needs to change - in the palette image case a whole set of tables are
1548     * built when it would be quicker to just calculate the correct value for
1549     * each palette entry directly.  Also, the test is too tricky - why check
1550     * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
1551     * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
1552     * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
1553     * the gamma tables will not be built even if composition is required on a
1554     * gamma encoded value.
1555     *
1556     * In 1.5.4 this is addressed below by an additional check on the individual
1557     * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
1558     * tables.
1559     */
1560    if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
1561        ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
1562         (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
1563          png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
1564         ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
1565          (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
1566           png_gamma_significant(png_ptr->screen_gamma) != 0
1567 #  ifdef PNG_READ_BACKGROUND_SUPPORTED
1568          || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
1569            png_gamma_significant(png_ptr->background_gamma) != 0)
1570 #  endif
1571         )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
1572        png_gamma_significant(png_ptr->screen_gamma) != 0))
1573    {
1574       png_build_gamma_table(png_ptr, png_ptr->bit_depth);
1575 
1576 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1577       if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1578       {
1579          /* Issue a warning about this combination: because RGB_TO_GRAY is
1580           * optimized to do the gamma transform if present yet do_background has
1581           * to do the same thing if both options are set a
1582           * double-gamma-correction happens.  This is true in all versions of
1583           * libpng to date.
1584           */
1585          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
1586             png_warning(png_ptr,
1587                "libpng does not support gamma+background+rgb_to_gray");
1588 
1589          if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
1590          {
1591             /* We don't get to here unless there is a tRNS chunk with non-opaque
1592              * entries - see the checking code at the start of this function.
1593              */
1594             png_color back, back_1;
1595             png_colorp palette = png_ptr->palette;
1596             int num_palette = png_ptr->num_palette;
1597             int i;
1598             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
1599             {
1600 
1601                back.red = png_ptr->gamma_table[png_ptr->background.red];
1602                back.green = png_ptr->gamma_table[png_ptr->background.green];
1603                back.blue = png_ptr->gamma_table[png_ptr->background.blue];
1604 
1605                back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
1606                back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
1607                back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
1608             }
1609             else
1610             {
1611                png_fixed_point g, gs;
1612 
1613                switch (png_ptr->background_gamma_type)
1614                {
1615                   case PNG_BACKGROUND_GAMMA_SCREEN:
1616                      g = (png_ptr->screen_gamma);
1617                      gs = PNG_FP_1;
1618                      break;
1619 
1620                   case PNG_BACKGROUND_GAMMA_FILE:
1621                      g = png_reciprocal(png_ptr->colorspace.gamma);
1622                      gs = png_reciprocal2(png_ptr->colorspace.gamma,
1623                         png_ptr->screen_gamma);
1624                      break;
1625 
1626                   case PNG_BACKGROUND_GAMMA_UNIQUE:
1627                      g = png_reciprocal(png_ptr->background_gamma);
1628                      gs = png_reciprocal2(png_ptr->background_gamma,
1629                         png_ptr->screen_gamma);
1630                      break;
1631                   default:
1632                      g = PNG_FP_1;    /* back_1 */
1633                      gs = PNG_FP_1;   /* back */
1634                      break;
1635                }
1636 
1637                if (png_gamma_significant(gs) != 0)
1638                {
1639                   back.red = png_gamma_8bit_correct(png_ptr->background.red,
1640                       gs);
1641                   back.green = png_gamma_8bit_correct(png_ptr->background.green,
1642                       gs);
1643                   back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1644                       gs);
1645                }
1646 
1647                else
1648                {
1649                   back.red   = (png_byte)png_ptr->background.red;
1650                   back.green = (png_byte)png_ptr->background.green;
1651                   back.blue  = (png_byte)png_ptr->background.blue;
1652                }
1653 
1654                if (png_gamma_significant(g) != 0)
1655                {
1656                   back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
1657                      g);
1658                   back_1.green = png_gamma_8bit_correct(
1659                      png_ptr->background.green, g);
1660                   back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1661                      g);
1662                }
1663 
1664                else
1665                {
1666                   back_1.red   = (png_byte)png_ptr->background.red;
1667                   back_1.green = (png_byte)png_ptr->background.green;
1668                   back_1.blue  = (png_byte)png_ptr->background.blue;
1669                }
1670             }
1671 
1672             for (i = 0; i < num_palette; i++)
1673             {
1674                if (i < (int)png_ptr->num_trans &&
1675                    png_ptr->trans_alpha[i] != 0xff)
1676                {
1677                   if (png_ptr->trans_alpha[i] == 0)
1678                   {
1679                      palette[i] = back;
1680                   }
1681                   else /* if (png_ptr->trans_alpha[i] != 0xff) */
1682                   {
1683                      png_byte v, w;
1684 
1685                      v = png_ptr->gamma_to_1[palette[i].red];
1686                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
1687                      palette[i].red = png_ptr->gamma_from_1[w];
1688 
1689                      v = png_ptr->gamma_to_1[palette[i].green];
1690                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
1691                      palette[i].green = png_ptr->gamma_from_1[w];
1692 
1693                      v = png_ptr->gamma_to_1[palette[i].blue];
1694                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
1695                      palette[i].blue = png_ptr->gamma_from_1[w];
1696                   }
1697                }
1698                else
1699                {
1700                   palette[i].red = png_ptr->gamma_table[palette[i].red];
1701                   palette[i].green = png_ptr->gamma_table[palette[i].green];
1702                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1703                }
1704             }
1705 
1706             /* Prevent the transformations being done again.
1707              *
1708              * NOTE: this is highly dubious; it removes the transformations in
1709              * place.  This seems inconsistent with the general treatment of the
1710              * transformations elsewhere.
1711              */
1712             png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
1713          } /* color_type == PNG_COLOR_TYPE_PALETTE */
1714 
1715          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
1716          else /* color_type != PNG_COLOR_TYPE_PALETTE */
1717          {
1718             int gs_sig, g_sig;
1719             png_fixed_point g = PNG_FP_1;  /* Correction to linear */
1720             png_fixed_point gs = PNG_FP_1; /* Correction to screen */
1721 
1722             switch (png_ptr->background_gamma_type)
1723             {
1724                case PNG_BACKGROUND_GAMMA_SCREEN:
1725                   g = png_ptr->screen_gamma;
1726                   /* gs = PNG_FP_1; */
1727                   break;
1728 
1729                case PNG_BACKGROUND_GAMMA_FILE:
1730                   g = png_reciprocal(png_ptr->colorspace.gamma);
1731                   gs = png_reciprocal2(png_ptr->colorspace.gamma,
1732                      png_ptr->screen_gamma);
1733                   break;
1734 
1735                case PNG_BACKGROUND_GAMMA_UNIQUE:
1736                   g = png_reciprocal(png_ptr->background_gamma);
1737                   gs = png_reciprocal2(png_ptr->background_gamma,
1738                       png_ptr->screen_gamma);
1739                   break;
1740 
1741                default:
1742                   png_error(png_ptr, "invalid background gamma type");
1743             }
1744 
1745             g_sig = png_gamma_significant(g);
1746             gs_sig = png_gamma_significant(gs);
1747 
1748             if (g_sig != 0)
1749                png_ptr->background_1.gray = png_gamma_correct(png_ptr,
1750                    png_ptr->background.gray, g);
1751 
1752             if (gs_sig != 0)
1753                png_ptr->background.gray = png_gamma_correct(png_ptr,
1754                    png_ptr->background.gray, gs);
1755 
1756             if ((png_ptr->background.red != png_ptr->background.green) ||
1757                 (png_ptr->background.red != png_ptr->background.blue) ||
1758                 (png_ptr->background.red != png_ptr->background.gray))
1759             {
1760                /* RGB or RGBA with color background */
1761                if (g_sig != 0)
1762                {
1763                   png_ptr->background_1.red = png_gamma_correct(png_ptr,
1764                       png_ptr->background.red, g);
1765 
1766                   png_ptr->background_1.green = png_gamma_correct(png_ptr,
1767                       png_ptr->background.green, g);
1768 
1769                   png_ptr->background_1.blue = png_gamma_correct(png_ptr,
1770                       png_ptr->background.blue, g);
1771                }
1772 
1773                if (gs_sig != 0)
1774                {
1775                   png_ptr->background.red = png_gamma_correct(png_ptr,
1776                       png_ptr->background.red, gs);
1777 
1778                   png_ptr->background.green = png_gamma_correct(png_ptr,
1779                       png_ptr->background.green, gs);
1780 
1781                   png_ptr->background.blue = png_gamma_correct(png_ptr,
1782                       png_ptr->background.blue, gs);
1783                }
1784             }
1785 
1786             else
1787             {
1788                /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1789                png_ptr->background_1.red = png_ptr->background_1.green
1790                    = png_ptr->background_1.blue = png_ptr->background_1.gray;
1791 
1792                png_ptr->background.red = png_ptr->background.green
1793                    = png_ptr->background.blue = png_ptr->background.gray;
1794             }
1795 
1796             /* The background is now in screen gamma: */
1797             png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
1798          } /* color_type != PNG_COLOR_TYPE_PALETTE */
1799       }/* png_ptr->transformations & PNG_BACKGROUND */
1800 
1801       else
1802       /* Transformation does not include PNG_BACKGROUND */
1803 #endif /* READ_BACKGROUND */
1804       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
1805 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1806          /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
1807          && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
1808          (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
1809 #endif
1810          )
1811       {
1812          png_colorp palette = png_ptr->palette;
1813          int num_palette = png_ptr->num_palette;
1814          int i;
1815 
1816          /* NOTE: there are other transformations that should probably be in
1817           * here too.
1818           */
1819          for (i = 0; i < num_palette; i++)
1820          {
1821             palette[i].red = png_ptr->gamma_table[palette[i].red];
1822             palette[i].green = png_ptr->gamma_table[palette[i].green];
1823             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1824          }
1825 
1826          /* Done the gamma correction. */
1827          png_ptr->transformations &= ~PNG_GAMMA;
1828       } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
1829    }
1830 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1831    else
1832 #endif
1833 #endif /* READ_GAMMA */
1834 
1835 #ifdef PNG_READ_BACKGROUND_SUPPORTED
1836    /* No GAMMA transformation (see the hanging else 4 lines above) */
1837    if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
1838        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1839    {
1840       int i;
1841       int istop = (int)png_ptr->num_trans;
1842       png_color back;
1843       png_colorp palette = png_ptr->palette;
1844 
1845       back.red   = (png_byte)png_ptr->background.red;
1846       back.green = (png_byte)png_ptr->background.green;
1847       back.blue  = (png_byte)png_ptr->background.blue;
1848 
1849       for (i = 0; i < istop; i++)
1850       {
1851          if (png_ptr->trans_alpha[i] == 0)
1852          {
1853             palette[i] = back;
1854          }
1855 
1856          else if (png_ptr->trans_alpha[i] != 0xff)
1857          {
1858             /* The png_composite() macro is defined in png.h */
1859             png_composite(palette[i].red, palette[i].red,
1860                 png_ptr->trans_alpha[i], back.red);
1861 
1862             png_composite(palette[i].green, palette[i].green,
1863                 png_ptr->trans_alpha[i], back.green);
1864 
1865             png_composite(palette[i].blue, palette[i].blue,
1866                 png_ptr->trans_alpha[i], back.blue);
1867          }
1868       }
1869 
1870       png_ptr->transformations &= ~PNG_COMPOSE;
1871    }
1872 #endif /* READ_BACKGROUND */
1873 
1874 #ifdef PNG_READ_SHIFT_SUPPORTED
1875    if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
1876        (png_ptr->transformations & PNG_EXPAND) == 0 &&
1877        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1878    {
1879       int i;
1880       int istop = png_ptr->num_palette;
1881       int shift = 8 - png_ptr->sig_bit.red;
1882 
1883       png_ptr->transformations &= ~PNG_SHIFT;
1884 
1885       /* significant bits can be in the range 1 to 7 for a meaninful result, if
1886        * the number of significant bits is 0 then no shift is done (this is an
1887        * error condition which is silently ignored.)
1888        */
1889       if (shift > 0 && shift < 8)
1890          for (i=0; i<istop; ++i)
1891          {
1892             int component = png_ptr->palette[i].red;
1893 
1894             component >>= shift;
1895             png_ptr->palette[i].red = (png_byte)component;
1896          }
1897 
1898       shift = 8 - png_ptr->sig_bit.green;
1899       if (shift > 0 && shift < 8)
1900          for (i=0; i<istop; ++i)
1901          {
1902             int component = png_ptr->palette[i].green;
1903 
1904             component >>= shift;
1905             png_ptr->palette[i].green = (png_byte)component;
1906          }
1907 
1908       shift = 8 - png_ptr->sig_bit.blue;
1909       if (shift > 0 && shift < 8)
1910          for (i=0; i<istop; ++i)
1911          {
1912             int component = png_ptr->palette[i].blue;
1913 
1914             component >>= shift;
1915             png_ptr->palette[i].blue = (png_byte)component;
1916          }
1917    }
1918 #endif /* READ_SHIFT */
1919 }
1920 
1921 /* Modify the info structure to reflect the transformations.  The
1922  * info should be updated so a PNG file could be written with it,
1923  * assuming the transformations result in valid PNG data.
1924  */
1925 void /* PRIVATE */
png_read_transform_info(png_structrp png_ptr,png_inforp info_ptr)1926 png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
1927 {
1928    png_debug(1, "in png_read_transform_info");
1929 
1930 #ifdef PNG_READ_EXPAND_SUPPORTED
1931    if ((png_ptr->transformations & PNG_EXPAND) != 0)
1932    {
1933       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1934       {
1935          /* This check must match what actually happens in
1936           * png_do_expand_palette; if it ever checks the tRNS chunk to see if
1937           * it is all opaque we must do the same (at present it does not.)
1938           */
1939          if (png_ptr->num_trans > 0)
1940             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1941 
1942          else
1943             info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1944 
1945          info_ptr->bit_depth = 8;
1946          info_ptr->num_trans = 0;
1947 
1948          if (png_ptr->palette == NULL)
1949             png_error (png_ptr, "Palette is NULL in indexed image");
1950       }
1951       else
1952       {
1953          if (png_ptr->num_trans != 0)
1954          {
1955             if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
1956                info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1957          }
1958          if (info_ptr->bit_depth < 8)
1959             info_ptr->bit_depth = 8;
1960 
1961          info_ptr->num_trans = 0;
1962       }
1963    }
1964 #endif
1965 
1966 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
1967    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
1968    /* The following is almost certainly wrong unless the background value is in
1969     * the screen space!
1970     */
1971    if ((png_ptr->transformations & PNG_COMPOSE) != 0)
1972       info_ptr->background = png_ptr->background;
1973 #endif
1974 
1975 #ifdef PNG_READ_GAMMA_SUPPORTED
1976    /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
1977     * however it seems that the code in png_init_read_transformations, which has
1978     * been called before this from png_read_update_info->png_read_start_row
1979     * sometimes does the gamma transform and cancels the flag.
1980     *
1981     * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
1982     * the screen_gamma value.  The following probably results in weirdness if
1983     * the info_ptr is used by the app after the rows have been read.
1984     */
1985    info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
1986 #endif
1987 
1988    if (info_ptr->bit_depth == 16)
1989    {
1990 #  ifdef PNG_READ_16BIT_SUPPORTED
1991 #     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1992          if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
1993             info_ptr->bit_depth = 8;
1994 #     endif
1995 
1996 #     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1997          if ((png_ptr->transformations & PNG_16_TO_8) != 0)
1998             info_ptr->bit_depth = 8;
1999 #     endif
2000 
2001 #  else
2002       /* No 16-bit support: force chopping 16-bit input down to 8, in this case
2003        * the app program can chose if both APIs are available by setting the
2004        * correct scaling to use.
2005        */
2006 #     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2007          /* For compatibility with previous versions use the strip method by
2008           * default.  This code works because if PNG_SCALE_16_TO_8 is already
2009           * set the code below will do that in preference to the chop.
2010           */
2011          png_ptr->transformations |= PNG_16_TO_8;
2012          info_ptr->bit_depth = 8;
2013 #     else
2014 
2015 #        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2016             png_ptr->transformations |= PNG_SCALE_16_TO_8;
2017             info_ptr->bit_depth = 8;
2018 #        else
2019 
2020             CONFIGURATION ERROR: you must enable at least one 16 to 8 method
2021 #        endif
2022 #    endif
2023 #endif /* !READ_16BIT */
2024    }
2025 
2026 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2027    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
2028       info_ptr->color_type = (png_byte)(info_ptr->color_type |
2029          PNG_COLOR_MASK_COLOR);
2030 #endif
2031 
2032 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2033    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
2034       info_ptr->color_type = (png_byte)(info_ptr->color_type &
2035          ~PNG_COLOR_MASK_COLOR);
2036 #endif
2037 
2038 #ifdef PNG_READ_QUANTIZE_SUPPORTED
2039    if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
2040    {
2041       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
2042           (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
2043           png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
2044       {
2045          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
2046       }
2047    }
2048 #endif
2049 
2050 #ifdef PNG_READ_EXPAND_16_SUPPORTED
2051    if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
2052        info_ptr->bit_depth == 8 &&
2053        info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
2054    {
2055       info_ptr->bit_depth = 16;
2056    }
2057 #endif
2058 
2059 #ifdef PNG_READ_PACK_SUPPORTED
2060    if ((png_ptr->transformations & PNG_PACK) != 0 &&
2061        (info_ptr->bit_depth < 8))
2062       info_ptr->bit_depth = 8;
2063 #endif
2064 
2065    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2066       info_ptr->channels = 1;
2067 
2068    else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
2069       info_ptr->channels = 3;
2070 
2071    else
2072       info_ptr->channels = 1;
2073 
2074 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
2075    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
2076    {
2077       info_ptr->color_type = (png_byte)(info_ptr->color_type &
2078          ~PNG_COLOR_MASK_ALPHA);
2079       info_ptr->num_trans = 0;
2080    }
2081 #endif
2082 
2083    if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
2084       info_ptr->channels++;
2085 
2086 #ifdef PNG_READ_FILLER_SUPPORTED
2087    /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
2088    if ((png_ptr->transformations & PNG_FILLER) != 0 &&
2089        (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
2090        info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
2091    {
2092       info_ptr->channels++;
2093       /* If adding a true alpha channel not just filler */
2094       if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
2095          info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
2096    }
2097 #endif
2098 
2099 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
2100 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
2101    if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
2102    {
2103       if (png_ptr->user_transform_depth != 0)
2104          info_ptr->bit_depth = png_ptr->user_transform_depth;
2105 
2106       if (png_ptr->user_transform_channels != 0)
2107          info_ptr->channels = png_ptr->user_transform_channels;
2108    }
2109 #endif
2110 
2111    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
2112        info_ptr->bit_depth);
2113 
2114    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
2115 
2116    /* Adding in 1.5.4: cache the above value in png_struct so that we can later
2117     * check in png_rowbytes that the user buffer won't get overwritten.  Note
2118     * that the field is not always set - if png_read_update_info isn't called
2119     * the application has to either not do any transforms or get the calculation
2120     * right itself.
2121     */
2122    png_ptr->info_rowbytes = info_ptr->rowbytes;
2123 
2124 #ifndef PNG_READ_EXPAND_SUPPORTED
2125    if (png_ptr != NULL)
2126       return;
2127 #endif
2128 }
2129 
2130 #ifdef PNG_READ_PACK_SUPPORTED
2131 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
2132  * without changing the actual values.  Thus, if you had a row with
2133  * a bit depth of 1, you would end up with bytes that only contained
2134  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
2135  * png_do_shift() after this.
2136  */
2137 static void
png_do_unpack(png_row_infop row_info,png_bytep row)2138 png_do_unpack(png_row_infop row_info, png_bytep row)
2139 {
2140    png_debug(1, "in png_do_unpack");
2141 
2142    if (row_info->bit_depth < 8)
2143    {
2144       png_uint_32 i;
2145       png_uint_32 row_width=row_info->width;
2146 
2147       switch (row_info->bit_depth)
2148       {
2149          case 1:
2150          {
2151             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
2152             png_bytep dp = row + (png_size_t)row_width - 1;
2153             png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
2154             for (i = 0; i < row_width; i++)
2155             {
2156                *dp = (png_byte)((*sp >> shift) & 0x01);
2157 
2158                if (shift == 7)
2159                {
2160                   shift = 0;
2161                   sp--;
2162                }
2163 
2164                else
2165                   shift++;
2166 
2167                dp--;
2168             }
2169             break;
2170          }
2171 
2172          case 2:
2173          {
2174 
2175             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
2176             png_bytep dp = row + (png_size_t)row_width - 1;
2177             png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
2178             for (i = 0; i < row_width; i++)
2179             {
2180                *dp = (png_byte)((*sp >> shift) & 0x03);
2181 
2182                if (shift == 6)
2183                {
2184                   shift = 0;
2185                   sp--;
2186                }
2187 
2188                else
2189                   shift += 2;
2190 
2191                dp--;
2192             }
2193             break;
2194          }
2195 
2196          case 4:
2197          {
2198             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
2199             png_bytep dp = row + (png_size_t)row_width - 1;
2200             png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
2201             for (i = 0; i < row_width; i++)
2202             {
2203                *dp = (png_byte)((*sp >> shift) & 0x0f);
2204 
2205                if (shift == 4)
2206                {
2207                   shift = 0;
2208                   sp--;
2209                }
2210 
2211                else
2212                   shift = 4;
2213 
2214                dp--;
2215             }
2216             break;
2217          }
2218 
2219          default:
2220             break;
2221       }
2222       row_info->bit_depth = 8;
2223       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2224       row_info->rowbytes = row_width * row_info->channels;
2225    }
2226 }
2227 #endif
2228 
2229 #ifdef PNG_READ_SHIFT_SUPPORTED
2230 /* Reverse the effects of png_do_shift.  This routine merely shifts the
2231  * pixels back to their significant bits values.  Thus, if you have
2232  * a row of bit depth 8, but only 5 are significant, this will shift
2233  * the values back to 0 through 31.
2234  */
2235 static void
png_do_unshift(png_row_infop row_info,png_bytep row,png_const_color_8p sig_bits)2236 png_do_unshift(png_row_infop row_info, png_bytep row,
2237     png_const_color_8p sig_bits)
2238 {
2239    int color_type;
2240 
2241    png_debug(1, "in png_do_unshift");
2242 
2243    /* The palette case has already been handled in the _init routine. */
2244    color_type = row_info->color_type;
2245 
2246    if (color_type != PNG_COLOR_TYPE_PALETTE)
2247    {
2248       int shift[4];
2249       int channels = 0;
2250       int bit_depth = row_info->bit_depth;
2251 
2252       if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
2253       {
2254          shift[channels++] = bit_depth - sig_bits->red;
2255          shift[channels++] = bit_depth - sig_bits->green;
2256          shift[channels++] = bit_depth - sig_bits->blue;
2257       }
2258 
2259       else
2260       {
2261          shift[channels++] = bit_depth - sig_bits->gray;
2262       }
2263 
2264       if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
2265       {
2266          shift[channels++] = bit_depth - sig_bits->alpha;
2267       }
2268 
2269       {
2270          int c, have_shift;
2271 
2272          for (c = have_shift = 0; c < channels; ++c)
2273          {
2274             /* A shift of more than the bit depth is an error condition but it
2275              * gets ignored here.
2276              */
2277             if (shift[c] <= 0 || shift[c] >= bit_depth)
2278                shift[c] = 0;
2279 
2280             else
2281                have_shift = 1;
2282          }
2283 
2284          if (have_shift == 0)
2285             return;
2286       }
2287 
2288       switch (bit_depth)
2289       {
2290          default:
2291          /* Must be 1bpp gray: should not be here! */
2292             /* NOTREACHED */
2293             break;
2294 
2295          case 2:
2296          /* Must be 2bpp gray */
2297          /* assert(channels == 1 && shift[0] == 1) */
2298          {
2299             png_bytep bp = row;
2300             png_bytep bp_end = bp + row_info->rowbytes;
2301 
2302             while (bp < bp_end)
2303             {
2304                int b = (*bp >> 1) & 0x55;
2305                *bp++ = (png_byte)b;
2306             }
2307             break;
2308          }
2309 
2310          case 4:
2311          /* Must be 4bpp gray */
2312          /* assert(channels == 1) */
2313          {
2314             png_bytep bp = row;
2315             png_bytep bp_end = bp + row_info->rowbytes;
2316             int gray_shift = shift[0];
2317             int mask =  0xf >> gray_shift;
2318 
2319             mask |= mask << 4;
2320 
2321             while (bp < bp_end)
2322             {
2323                int b = (*bp >> gray_shift) & mask;
2324                *bp++ = (png_byte)b;
2325             }
2326             break;
2327          }
2328 
2329          case 8:
2330          /* Single byte components, G, GA, RGB, RGBA */
2331          {
2332             png_bytep bp = row;
2333             png_bytep bp_end = bp + row_info->rowbytes;
2334             int channel = 0;
2335 
2336             while (bp < bp_end)
2337             {
2338                int b = *bp >> shift[channel];
2339                if (++channel >= channels)
2340                   channel = 0;
2341                *bp++ = (png_byte)b;
2342             }
2343             break;
2344          }
2345 
2346 #ifdef PNG_READ_16BIT_SUPPORTED
2347          case 16:
2348          /* Double byte components, G, GA, RGB, RGBA */
2349          {
2350             png_bytep bp = row;
2351             png_bytep bp_end = bp + row_info->rowbytes;
2352             int channel = 0;
2353 
2354             while (bp < bp_end)
2355             {
2356                int value = (bp[0] << 8) + bp[1];
2357 
2358                value >>= shift[channel];
2359                if (++channel >= channels)
2360                   channel = 0;
2361                *bp++ = (png_byte)(value >> 8);
2362                *bp++ = (png_byte)value;
2363             }
2364             break;
2365          }
2366 #endif
2367       }
2368    }
2369 }
2370 #endif
2371 
2372 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2373 /* Scale rows of bit depth 16 down to 8 accurately */
2374 static void
png_do_scale_16_to_8(png_row_infop row_info,png_bytep row)2375 png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
2376 {
2377    png_debug(1, "in png_do_scale_16_to_8");
2378 
2379    if (row_info->bit_depth == 16)
2380    {
2381       png_bytep sp = row; /* source */
2382       png_bytep dp = row; /* destination */
2383       png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2384 
2385       while (sp < ep)
2386       {
2387          /* The input is an array of 16-bit components, these must be scaled to
2388           * 8 bits each.  For a 16-bit value V the required value (from the PNG
2389           * specification) is:
2390           *
2391           *    (V * 255) / 65535
2392           *
2393           * This reduces to round(V / 257), or floor((V + 128.5)/257)
2394           *
2395           * Represent V as the two byte value vhi.vlo.  Make a guess that the
2396           * result is the top byte of V, vhi, then the correction to this value
2397           * is:
2398           *
2399           *    error = floor(((V-vhi.vhi) + 128.5) / 257)
2400           *          = floor(((vlo-vhi) + 128.5) / 257)
2401           *
2402           * This can be approximated using integer arithmetic (and a signed
2403           * shift):
2404           *
2405           *    error = (vlo-vhi+128) >> 8;
2406           *
2407           * The approximate differs from the exact answer only when (vlo-vhi) is
2408           * 128; it then gives a correction of +1 when the exact correction is
2409           * 0.  This gives 128 errors.  The exact answer (correct for all 16-bit
2410           * input values) is:
2411           *
2412           *    error = (vlo-vhi+128)*65535 >> 24;
2413           *
2414           * An alternative arithmetic calculation which also gives no errors is:
2415           *
2416           *    (V * 255 + 32895) >> 16
2417           */
2418 
2419          png_int_32 tmp = *sp++; /* must be signed! */
2420          tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
2421          *dp++ = (png_byte)tmp;
2422       }
2423 
2424       row_info->bit_depth = 8;
2425       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2426       row_info->rowbytes = row_info->width * row_info->channels;
2427    }
2428 }
2429 #endif
2430 
2431 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2432 static void
2433 /* Simply discard the low byte.  This was the default behavior prior
2434  * to libpng-1.5.4.
2435  */
png_do_chop(png_row_infop row_info,png_bytep row)2436 png_do_chop(png_row_infop row_info, png_bytep row)
2437 {
2438    png_debug(1, "in png_do_chop");
2439 
2440    if (row_info->bit_depth == 16)
2441    {
2442       png_bytep sp = row; /* source */
2443       png_bytep dp = row; /* destination */
2444       png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2445 
2446       while (sp < ep)
2447       {
2448          *dp++ = *sp;
2449          sp += 2; /* skip low byte */
2450       }
2451 
2452       row_info->bit_depth = 8;
2453       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2454       row_info->rowbytes = row_info->width * row_info->channels;
2455    }
2456 }
2457 #endif
2458 
2459 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
2460 static void
png_do_read_swap_alpha(png_row_infop row_info,png_bytep row)2461 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
2462 {
2463    png_debug(1, "in png_do_read_swap_alpha");
2464 
2465    {
2466       png_uint_32 row_width = row_info->width;
2467       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2468       {
2469          /* This converts from RGBA to ARGB */
2470          if (row_info->bit_depth == 8)
2471          {
2472             png_bytep sp = row + row_info->rowbytes;
2473             png_bytep dp = sp;
2474             png_byte save;
2475             png_uint_32 i;
2476 
2477             for (i = 0; i < row_width; i++)
2478             {
2479                save = *(--sp);
2480                *(--dp) = *(--sp);
2481                *(--dp) = *(--sp);
2482                *(--dp) = *(--sp);
2483                *(--dp) = save;
2484             }
2485          }
2486 
2487 #ifdef PNG_READ_16BIT_SUPPORTED
2488          /* This converts from RRGGBBAA to AARRGGBB */
2489          else
2490          {
2491             png_bytep sp = row + row_info->rowbytes;
2492             png_bytep dp = sp;
2493             png_byte save[2];
2494             png_uint_32 i;
2495 
2496             for (i = 0; i < row_width; i++)
2497             {
2498                save[0] = *(--sp);
2499                save[1] = *(--sp);
2500                *(--dp) = *(--sp);
2501                *(--dp) = *(--sp);
2502                *(--dp) = *(--sp);
2503                *(--dp) = *(--sp);
2504                *(--dp) = *(--sp);
2505                *(--dp) = *(--sp);
2506                *(--dp) = save[0];
2507                *(--dp) = save[1];
2508             }
2509          }
2510 #endif
2511       }
2512 
2513       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2514       {
2515          /* This converts from GA to AG */
2516          if (row_info->bit_depth == 8)
2517          {
2518             png_bytep sp = row + row_info->rowbytes;
2519             png_bytep dp = sp;
2520             png_byte save;
2521             png_uint_32 i;
2522 
2523             for (i = 0; i < row_width; i++)
2524             {
2525                save = *(--sp);
2526                *(--dp) = *(--sp);
2527                *(--dp) = save;
2528             }
2529          }
2530 
2531 #ifdef PNG_READ_16BIT_SUPPORTED
2532          /* This converts from GGAA to AAGG */
2533          else
2534          {
2535             png_bytep sp = row + row_info->rowbytes;
2536             png_bytep dp = sp;
2537             png_byte save[2];
2538             png_uint_32 i;
2539 
2540             for (i = 0; i < row_width; i++)
2541             {
2542                save[0] = *(--sp);
2543                save[1] = *(--sp);
2544                *(--dp) = *(--sp);
2545                *(--dp) = *(--sp);
2546                *(--dp) = save[0];
2547                *(--dp) = save[1];
2548             }
2549          }
2550 #endif
2551       }
2552    }
2553 }
2554 #endif
2555 
2556 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
2557 static void
png_do_read_invert_alpha(png_row_infop row_info,png_bytep row)2558 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
2559 {
2560    png_uint_32 row_width;
2561    png_debug(1, "in png_do_read_invert_alpha");
2562 
2563    row_width = row_info->width;
2564    if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2565    {
2566       if (row_info->bit_depth == 8)
2567       {
2568          /* This inverts the alpha channel in RGBA */
2569          png_bytep sp = row + row_info->rowbytes;
2570          png_bytep dp = sp;
2571          png_uint_32 i;
2572 
2573          for (i = 0; i < row_width; i++)
2574          {
2575             *(--dp) = (png_byte)(255 - *(--sp));
2576 
2577 /*          This does nothing:
2578             *(--dp) = *(--sp);
2579             *(--dp) = *(--sp);
2580             *(--dp) = *(--sp);
2581             We can replace it with:
2582 */
2583             sp-=3;
2584             dp=sp;
2585          }
2586       }
2587 
2588 #ifdef PNG_READ_16BIT_SUPPORTED
2589       /* This inverts the alpha channel in RRGGBBAA */
2590       else
2591       {
2592          png_bytep sp = row + row_info->rowbytes;
2593          png_bytep dp = sp;
2594          png_uint_32 i;
2595 
2596          for (i = 0; i < row_width; i++)
2597          {
2598             *(--dp) = (png_byte)(255 - *(--sp));
2599             *(--dp) = (png_byte)(255 - *(--sp));
2600 
2601 /*          This does nothing:
2602             *(--dp) = *(--sp);
2603             *(--dp) = *(--sp);
2604             *(--dp) = *(--sp);
2605             *(--dp) = *(--sp);
2606             *(--dp) = *(--sp);
2607             *(--dp) = *(--sp);
2608             We can replace it with:
2609 */
2610             sp-=6;
2611             dp=sp;
2612          }
2613       }
2614 #endif
2615    }
2616    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2617    {
2618       if (row_info->bit_depth == 8)
2619       {
2620          /* This inverts the alpha channel in GA */
2621          png_bytep sp = row + row_info->rowbytes;
2622          png_bytep dp = sp;
2623          png_uint_32 i;
2624 
2625          for (i = 0; i < row_width; i++)
2626          {
2627             *(--dp) = (png_byte)(255 - *(--sp));
2628             *(--dp) = *(--sp);
2629          }
2630       }
2631 
2632 #ifdef PNG_READ_16BIT_SUPPORTED
2633       else
2634       {
2635          /* This inverts the alpha channel in GGAA */
2636          png_bytep sp  = row + row_info->rowbytes;
2637          png_bytep dp = sp;
2638          png_uint_32 i;
2639 
2640          for (i = 0; i < row_width; i++)
2641          {
2642             *(--dp) = (png_byte)(255 - *(--sp));
2643             *(--dp) = (png_byte)(255 - *(--sp));
2644 /*
2645             *(--dp) = *(--sp);
2646             *(--dp) = *(--sp);
2647 */
2648             sp-=2;
2649             dp=sp;
2650          }
2651       }
2652 #endif
2653    }
2654 }
2655 #endif
2656 
2657 #ifdef PNG_READ_FILLER_SUPPORTED
2658 /* Add filler channel if we have RGB color */
2659 static void
png_do_read_filler(png_row_infop row_info,png_bytep row,png_uint_32 filler,png_uint_32 flags)2660 png_do_read_filler(png_row_infop row_info, png_bytep row,
2661     png_uint_32 filler, png_uint_32 flags)
2662 {
2663    png_uint_32 i;
2664    png_uint_32 row_width = row_info->width;
2665 
2666 #ifdef PNG_READ_16BIT_SUPPORTED
2667    png_byte hi_filler = (png_byte)(filler>>8);
2668 #endif
2669    png_byte lo_filler = (png_byte)filler;
2670 
2671    png_debug(1, "in png_do_read_filler");
2672 
2673    if (
2674        row_info->color_type == PNG_COLOR_TYPE_GRAY)
2675    {
2676       if (row_info->bit_depth == 8)
2677       {
2678          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2679          {
2680             /* This changes the data from G to GX */
2681             png_bytep sp = row + (png_size_t)row_width;
2682             png_bytep dp =  sp + (png_size_t)row_width;
2683             for (i = 1; i < row_width; i++)
2684             {
2685                *(--dp) = lo_filler;
2686                *(--dp) = *(--sp);
2687             }
2688             *(--dp) = lo_filler;
2689             row_info->channels = 2;
2690             row_info->pixel_depth = 16;
2691             row_info->rowbytes = row_width * 2;
2692          }
2693 
2694          else
2695          {
2696             /* This changes the data from G to XG */
2697             png_bytep sp = row + (png_size_t)row_width;
2698             png_bytep dp = sp  + (png_size_t)row_width;
2699             for (i = 0; i < row_width; i++)
2700             {
2701                *(--dp) = *(--sp);
2702                *(--dp) = lo_filler;
2703             }
2704             row_info->channels = 2;
2705             row_info->pixel_depth = 16;
2706             row_info->rowbytes = row_width * 2;
2707          }
2708       }
2709 
2710 #ifdef PNG_READ_16BIT_SUPPORTED
2711       else if (row_info->bit_depth == 16)
2712       {
2713          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2714          {
2715             /* This changes the data from GG to GGXX */
2716             png_bytep sp = row + (png_size_t)row_width * 2;
2717             png_bytep dp = sp  + (png_size_t)row_width * 2;
2718             for (i = 1; i < row_width; i++)
2719             {
2720                *(--dp) = lo_filler;
2721                *(--dp) = hi_filler;
2722                *(--dp) = *(--sp);
2723                *(--dp) = *(--sp);
2724             }
2725             *(--dp) = lo_filler;
2726             *(--dp) = hi_filler;
2727             row_info->channels = 2;
2728             row_info->pixel_depth = 32;
2729             row_info->rowbytes = row_width * 4;
2730          }
2731 
2732          else
2733          {
2734             /* This changes the data from GG to XXGG */
2735             png_bytep sp = row + (png_size_t)row_width * 2;
2736             png_bytep dp = sp  + (png_size_t)row_width * 2;
2737             for (i = 0; i < row_width; i++)
2738             {
2739                *(--dp) = *(--sp);
2740                *(--dp) = *(--sp);
2741                *(--dp) = lo_filler;
2742                *(--dp) = hi_filler;
2743             }
2744             row_info->channels = 2;
2745             row_info->pixel_depth = 32;
2746             row_info->rowbytes = row_width * 4;
2747          }
2748       }
2749 #endif
2750    } /* COLOR_TYPE == GRAY */
2751    else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2752    {
2753       if (row_info->bit_depth == 8)
2754       {
2755          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2756          {
2757             /* This changes the data from RGB to RGBX */
2758             png_bytep sp = row + (png_size_t)row_width * 3;
2759             png_bytep dp = sp  + (png_size_t)row_width;
2760             for (i = 1; i < row_width; i++)
2761             {
2762                *(--dp) = lo_filler;
2763                *(--dp) = *(--sp);
2764                *(--dp) = *(--sp);
2765                *(--dp) = *(--sp);
2766             }
2767             *(--dp) = lo_filler;
2768             row_info->channels = 4;
2769             row_info->pixel_depth = 32;
2770             row_info->rowbytes = row_width * 4;
2771          }
2772 
2773          else
2774          {
2775             /* This changes the data from RGB to XRGB */
2776             png_bytep sp = row + (png_size_t)row_width * 3;
2777             png_bytep dp = sp + (png_size_t)row_width;
2778             for (i = 0; i < row_width; i++)
2779             {
2780                *(--dp) = *(--sp);
2781                *(--dp) = *(--sp);
2782                *(--dp) = *(--sp);
2783                *(--dp) = lo_filler;
2784             }
2785             row_info->channels = 4;
2786             row_info->pixel_depth = 32;
2787             row_info->rowbytes = row_width * 4;
2788          }
2789       }
2790 
2791 #ifdef PNG_READ_16BIT_SUPPORTED
2792       else if (row_info->bit_depth == 16)
2793       {
2794          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2795          {
2796             /* This changes the data from RRGGBB to RRGGBBXX */
2797             png_bytep sp = row + (png_size_t)row_width * 6;
2798             png_bytep dp = sp  + (png_size_t)row_width * 2;
2799             for (i = 1; i < row_width; i++)
2800             {
2801                *(--dp) = lo_filler;
2802                *(--dp) = hi_filler;
2803                *(--dp) = *(--sp);
2804                *(--dp) = *(--sp);
2805                *(--dp) = *(--sp);
2806                *(--dp) = *(--sp);
2807                *(--dp) = *(--sp);
2808                *(--dp) = *(--sp);
2809             }
2810             *(--dp) = lo_filler;
2811             *(--dp) = hi_filler;
2812             row_info->channels = 4;
2813             row_info->pixel_depth = 64;
2814             row_info->rowbytes = row_width * 8;
2815          }
2816 
2817          else
2818          {
2819             /* This changes the data from RRGGBB to XXRRGGBB */
2820             png_bytep sp = row + (png_size_t)row_width * 6;
2821             png_bytep dp = sp  + (png_size_t)row_width * 2;
2822             for (i = 0; i < row_width; i++)
2823             {
2824                *(--dp) = *(--sp);
2825                *(--dp) = *(--sp);
2826                *(--dp) = *(--sp);
2827                *(--dp) = *(--sp);
2828                *(--dp) = *(--sp);
2829                *(--dp) = *(--sp);
2830                *(--dp) = lo_filler;
2831                *(--dp) = hi_filler;
2832             }
2833 
2834             row_info->channels = 4;
2835             row_info->pixel_depth = 64;
2836             row_info->rowbytes = row_width * 8;
2837          }
2838       }
2839 #endif
2840    } /* COLOR_TYPE == RGB */
2841 }
2842 #endif
2843 
2844 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2845 /* Expand grayscale files to RGB, with or without alpha */
2846 static void
png_do_gray_to_rgb(png_row_infop row_info,png_bytep row)2847 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
2848 {
2849    png_uint_32 i;
2850    png_uint_32 row_width = row_info->width;
2851 
2852    png_debug(1, "in png_do_gray_to_rgb");
2853 
2854    if (row_info->bit_depth >= 8 &&
2855        (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
2856    {
2857       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2858       {
2859          if (row_info->bit_depth == 8)
2860          {
2861             /* This changes G to RGB */
2862             png_bytep sp = row + (png_size_t)row_width - 1;
2863             png_bytep dp = sp  + (png_size_t)row_width * 2;
2864             for (i = 0; i < row_width; i++)
2865             {
2866                *(dp--) = *sp;
2867                *(dp--) = *sp;
2868                *(dp--) = *(sp--);
2869             }
2870          }
2871 
2872          else
2873          {
2874             /* This changes GG to RRGGBB */
2875             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2876             png_bytep dp = sp  + (png_size_t)row_width * 4;
2877             for (i = 0; i < row_width; i++)
2878             {
2879                *(dp--) = *sp;
2880                *(dp--) = *(sp - 1);
2881                *(dp--) = *sp;
2882                *(dp--) = *(sp - 1);
2883                *(dp--) = *(sp--);
2884                *(dp--) = *(sp--);
2885             }
2886          }
2887       }
2888 
2889       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2890       {
2891          if (row_info->bit_depth == 8)
2892          {
2893             /* This changes GA to RGBA */
2894             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2895             png_bytep dp = sp  + (png_size_t)row_width * 2;
2896             for (i = 0; i < row_width; i++)
2897             {
2898                *(dp--) = *(sp--);
2899                *(dp--) = *sp;
2900                *(dp--) = *sp;
2901                *(dp--) = *(sp--);
2902             }
2903          }
2904 
2905          else
2906          {
2907             /* This changes GGAA to RRGGBBAA */
2908             png_bytep sp = row + (png_size_t)row_width * 4 - 1;
2909             png_bytep dp = sp  + (png_size_t)row_width * 4;
2910             for (i = 0; i < row_width; i++)
2911             {
2912                *(dp--) = *(sp--);
2913                *(dp--) = *(sp--);
2914                *(dp--) = *sp;
2915                *(dp--) = *(sp - 1);
2916                *(dp--) = *sp;
2917                *(dp--) = *(sp - 1);
2918                *(dp--) = *(sp--);
2919                *(dp--) = *(sp--);
2920             }
2921          }
2922       }
2923       row_info->channels = (png_byte)(row_info->channels + 2);
2924       row_info->color_type |= PNG_COLOR_MASK_COLOR;
2925       row_info->pixel_depth = (png_byte)(row_info->channels *
2926           row_info->bit_depth);
2927       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2928    }
2929 }
2930 #endif
2931 
2932 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2933 /* Reduce RGB files to grayscale, with or without alpha
2934  * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
2935  * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
2936  * versions dated 1998 through November 2002 have been archived at
2937  * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
2938  * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
2939  * Charles Poynton poynton at poynton.com
2940  *
2941  *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2942  *
2943  *  which can be expressed with integers as
2944  *
2945  *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
2946  *
2947  * Poynton's current link (as of January 2003 through July 2011):
2948  * <http://www.poynton.com/notes/colour_and_gamma/>
2949  * has changed the numbers slightly:
2950  *
2951  *     Y = 0.2126*R + 0.7152*G + 0.0722*B
2952  *
2953  *  which can be expressed with integers as
2954  *
2955  *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
2956  *
2957  *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
2958  *  end point chromaticities and the D65 white point.  Depending on the
2959  *  precision used for the D65 white point this produces a variety of different
2960  *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
2961  *  used (0.3127,0.3290) the Y calculation would be:
2962  *
2963  *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
2964  *
2965  *  While this is correct the rounding results in an overflow for white, because
2966  *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
2967  *  libpng uses, instead, the closest non-overflowing approximation:
2968  *
2969  *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
2970  *
2971  *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
2972  *  (including an sRGB chunk) then the chromaticities are used to calculate the
2973  *  coefficients.  See the chunk handling in pngrutil.c for more information.
2974  *
2975  *  In all cases the calculation is to be done in a linear colorspace.  If no
2976  *  gamma information is available to correct the encoding of the original RGB
2977  *  values this results in an implicit assumption that the original PNG RGB
2978  *  values were linear.
2979  *
2980  *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
2981  *  the API takes just red and green coefficients the blue coefficient is
2982  *  calculated to make the sum 32768.  This will result in different rounding
2983  *  to that used above.
2984  */
2985 static int
png_do_rgb_to_gray(png_structrp png_ptr,png_row_infop row_info,png_bytep row)2986 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
2987 
2988 {
2989    int rgb_error = 0;
2990 
2991    png_debug(1, "in png_do_rgb_to_gray");
2992 
2993    if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
2994        (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
2995    {
2996       PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
2997       PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
2998       PNG_CONST png_uint_32 bc = 32768 - rc - gc;
2999       PNG_CONST png_uint_32 row_width = row_info->width;
3000       PNG_CONST int have_alpha =
3001          (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
3002 
3003       if (row_info->bit_depth == 8)
3004       {
3005 #ifdef PNG_READ_GAMMA_SUPPORTED
3006          /* Notice that gamma to/from 1 are not necessarily inverses (if
3007           * there is an overall gamma correction).  Prior to 1.5.5 this code
3008           * checked the linearized values for equality; this doesn't match
3009           * the documentation, the original values must be checked.
3010           */
3011          if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3012          {
3013             png_bytep sp = row;
3014             png_bytep dp = row;
3015             png_uint_32 i;
3016 
3017             for (i = 0; i < row_width; i++)
3018             {
3019                png_byte red   = *(sp++);
3020                png_byte green = *(sp++);
3021                png_byte blue  = *(sp++);
3022 
3023                if (red != green || red != blue)
3024                {
3025                   red = png_ptr->gamma_to_1[red];
3026                   green = png_ptr->gamma_to_1[green];
3027                   blue = png_ptr->gamma_to_1[blue];
3028 
3029                   rgb_error |= 1;
3030                   *(dp++) = png_ptr->gamma_from_1[
3031                       (rc*red + gc*green + bc*blue + 16384)>>15];
3032                }
3033 
3034                else
3035                {
3036                   /* If there is no overall correction the table will not be
3037                    * set.
3038                    */
3039                   if (png_ptr->gamma_table != NULL)
3040                      red = png_ptr->gamma_table[red];
3041 
3042                   *(dp++) = red;
3043                }
3044 
3045                if (have_alpha != 0)
3046                   *(dp++) = *(sp++);
3047             }
3048          }
3049          else
3050 #endif
3051          {
3052             png_bytep sp = row;
3053             png_bytep dp = row;
3054             png_uint_32 i;
3055 
3056             for (i = 0; i < row_width; i++)
3057             {
3058                png_byte red   = *(sp++);
3059                png_byte green = *(sp++);
3060                png_byte blue  = *(sp++);
3061 
3062                if (red != green || red != blue)
3063                {
3064                   rgb_error |= 1;
3065                   /* NOTE: this is the historical approach which simply
3066                    * truncates the results.
3067                    */
3068                   *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
3069                }
3070 
3071                else
3072                   *(dp++) = red;
3073 
3074                if (have_alpha != 0)
3075                   *(dp++) = *(sp++);
3076             }
3077          }
3078       }
3079 
3080       else /* RGB bit_depth == 16 */
3081       {
3082 #ifdef PNG_READ_GAMMA_SUPPORTED
3083          if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
3084          {
3085             png_bytep sp = row;
3086             png_bytep dp = row;
3087             png_uint_32 i;
3088 
3089             for (i = 0; i < row_width; i++)
3090             {
3091                png_uint_16 red, green, blue, w;
3092                png_byte hi,lo;
3093 
3094                hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
3095                hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3096                hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
3097 
3098                if (red == green && red == blue)
3099                {
3100                   if (png_ptr->gamma_16_table != NULL)
3101                      w = png_ptr->gamma_16_table[(red & 0xff)
3102                          >> png_ptr->gamma_shift][red >> 8];
3103 
3104                   else
3105                      w = red;
3106                }
3107 
3108                else
3109                {
3110                   png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red & 0xff)
3111                       >> png_ptr->gamma_shift][red>>8];
3112                   png_uint_16 green_1 =
3113                       png_ptr->gamma_16_to_1[(green & 0xff) >>
3114                       png_ptr->gamma_shift][green>>8];
3115                   png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue & 0xff)
3116                       >> png_ptr->gamma_shift][blue>>8];
3117                   png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
3118                       + bc*blue_1 + 16384)>>15);
3119                   w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
3120                       png_ptr->gamma_shift][gray16 >> 8];
3121                   rgb_error |= 1;
3122                }
3123 
3124                *(dp++) = (png_byte)((w>>8) & 0xff);
3125                *(dp++) = (png_byte)(w & 0xff);
3126 
3127                if (have_alpha != 0)
3128                {
3129                   *(dp++) = *(sp++);
3130                   *(dp++) = *(sp++);
3131                }
3132             }
3133          }
3134          else
3135 #endif
3136          {
3137             png_bytep sp = row;
3138             png_bytep dp = row;
3139             png_uint_32 i;
3140 
3141             for (i = 0; i < row_width; i++)
3142             {
3143                png_uint_16 red, green, blue, gray16;
3144                png_byte hi,lo;
3145 
3146                hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
3147                hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3148                hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
3149 
3150                if (red != green || red != blue)
3151                   rgb_error |= 1;
3152 
3153                /* From 1.5.5 in the 16-bit case do the accurate conversion even
3154                 * in the 'fast' case - this is because this is where the code
3155                 * ends up when handling linear 16-bit data.
3156                 */
3157                gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
3158                   15);
3159                *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
3160                *(dp++) = (png_byte)(gray16 & 0xff);
3161 
3162                if (have_alpha != 0)
3163                {
3164                   *(dp++) = *(sp++);
3165                   *(dp++) = *(sp++);
3166                }
3167             }
3168          }
3169       }
3170 
3171       row_info->channels = (png_byte)(row_info->channels - 2);
3172       row_info->color_type = (png_byte)(row_info->color_type &
3173           ~PNG_COLOR_MASK_COLOR);
3174       row_info->pixel_depth = (png_byte)(row_info->channels *
3175           row_info->bit_depth);
3176       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3177    }
3178    return rgb_error;
3179 }
3180 #endif
3181 
3182 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
3183    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
3184 /* Replace any alpha or transparency with the supplied background color.
3185  * "background" is already in the screen gamma, while "background_1" is
3186  * at a gamma of 1.0.  Paletted files have already been taken care of.
3187  */
3188 static void
png_do_compose(png_row_infop row_info,png_bytep row,png_structrp png_ptr)3189 png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3190 {
3191 #ifdef PNG_READ_GAMMA_SUPPORTED
3192    png_const_bytep gamma_table = png_ptr->gamma_table;
3193    png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
3194    png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
3195    png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
3196    png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
3197    png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
3198    int gamma_shift = png_ptr->gamma_shift;
3199    int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
3200 #endif
3201 
3202    png_bytep sp;
3203    png_uint_32 i;
3204    png_uint_32 row_width = row_info->width;
3205    int shift;
3206 
3207    png_debug(1, "in png_do_compose");
3208 
3209    {
3210       switch (row_info->color_type)
3211       {
3212          case PNG_COLOR_TYPE_GRAY:
3213          {
3214             switch (row_info->bit_depth)
3215             {
3216                case 1:
3217                {
3218                   sp = row;
3219                   shift = 7;
3220                   for (i = 0; i < row_width; i++)
3221                   {
3222                      if ((png_uint_16)((*sp >> shift) & 0x01)
3223                         == png_ptr->trans_color.gray)
3224                      {
3225                         unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
3226                         tmp |= png_ptr->background.gray << shift;
3227                         *sp = (png_byte)(tmp & 0xff);
3228                      }
3229 
3230                      if (shift == 0)
3231                      {
3232                         shift = 7;
3233                         sp++;
3234                      }
3235 
3236                      else
3237                         shift--;
3238                   }
3239                   break;
3240                }
3241 
3242                case 2:
3243                {
3244 #ifdef PNG_READ_GAMMA_SUPPORTED
3245                   if (gamma_table != NULL)
3246                   {
3247                      sp = row;
3248                      shift = 6;
3249                      for (i = 0; i < row_width; i++)
3250                      {
3251                         if ((png_uint_16)((*sp >> shift) & 0x03)
3252                             == png_ptr->trans_color.gray)
3253                         {
3254                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3255                            tmp |= png_ptr->background.gray << shift;
3256                            *sp = (png_byte)(tmp & 0xff);
3257                         }
3258 
3259                         else
3260                         {
3261                            unsigned int p = (*sp >> shift) & 0x03;
3262                            unsigned int g = (gamma_table [p | (p << 2) |
3263                                (p << 4) | (p << 6)] >> 6) & 0x03;
3264                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3265                            tmp |= g << shift;
3266                            *sp = (png_byte)(tmp & 0xff);
3267                         }
3268 
3269                         if (shift == 0)
3270                         {
3271                            shift = 6;
3272                            sp++;
3273                         }
3274 
3275                         else
3276                            shift -= 2;
3277                      }
3278                   }
3279 
3280                   else
3281 #endif
3282                   {
3283                      sp = row;
3284                      shift = 6;
3285                      for (i = 0; i < row_width; i++)
3286                      {
3287                         if ((png_uint_16)((*sp >> shift) & 0x03)
3288                             == png_ptr->trans_color.gray)
3289                         {
3290                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3291                            tmp |= png_ptr->background.gray << shift;
3292                            *sp = (png_byte)(tmp & 0xff);
3293                         }
3294 
3295                         if (shift == 0)
3296                         {
3297                            shift = 6;
3298                            sp++;
3299                         }
3300 
3301                         else
3302                            shift -= 2;
3303                      }
3304                   }
3305                   break;
3306                }
3307 
3308                case 4:
3309                {
3310 #ifdef PNG_READ_GAMMA_SUPPORTED
3311                   if (gamma_table != NULL)
3312                   {
3313                      sp = row;
3314                      shift = 4;
3315                      for (i = 0; i < row_width; i++)
3316                      {
3317                         if ((png_uint_16)((*sp >> shift) & 0x0f)
3318                             == png_ptr->trans_color.gray)
3319                         {
3320                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3321                            tmp |= png_ptr->background.gray << shift;
3322                            *sp = (png_byte)(tmp & 0xff);
3323                         }
3324 
3325                         else
3326                         {
3327                            unsigned int p = (*sp >> shift) & 0x0f;
3328                            unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
3329                               0x0f;
3330                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3331                            tmp |= g << shift;
3332                            *sp = (png_byte)(tmp & 0xff);
3333                         }
3334 
3335                         if (shift == 0)
3336                         {
3337                            shift = 4;
3338                            sp++;
3339                         }
3340 
3341                         else
3342                            shift -= 4;
3343                      }
3344                   }
3345 
3346                   else
3347 #endif
3348                   {
3349                      sp = row;
3350                      shift = 4;
3351                      for (i = 0; i < row_width; i++)
3352                      {
3353                         if ((png_uint_16)((*sp >> shift) & 0x0f)
3354                             == png_ptr->trans_color.gray)
3355                         {
3356                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3357                            tmp |= png_ptr->background.gray << shift;
3358                            *sp = (png_byte)(tmp & 0xff);
3359                         }
3360 
3361                         if (shift == 0)
3362                         {
3363                            shift = 4;
3364                            sp++;
3365                         }
3366 
3367                         else
3368                            shift -= 4;
3369                      }
3370                   }
3371                   break;
3372                }
3373 
3374                case 8:
3375                {
3376 #ifdef PNG_READ_GAMMA_SUPPORTED
3377                   if (gamma_table != NULL)
3378                   {
3379                      sp = row;
3380                      for (i = 0; i < row_width; i++, sp++)
3381                      {
3382                         if (*sp == png_ptr->trans_color.gray)
3383                            *sp = (png_byte)png_ptr->background.gray;
3384 
3385                         else
3386                            *sp = gamma_table[*sp];
3387                      }
3388                   }
3389                   else
3390 #endif
3391                   {
3392                      sp = row;
3393                      for (i = 0; i < row_width; i++, sp++)
3394                      {
3395                         if (*sp == png_ptr->trans_color.gray)
3396                            *sp = (png_byte)png_ptr->background.gray;
3397                      }
3398                   }
3399                   break;
3400                }
3401 
3402                case 16:
3403                {
3404 #ifdef PNG_READ_GAMMA_SUPPORTED
3405                   if (gamma_16 != NULL)
3406                   {
3407                      sp = row;
3408                      for (i = 0; i < row_width; i++, sp += 2)
3409                      {
3410                         png_uint_16 v;
3411 
3412                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3413 
3414                         if (v == png_ptr->trans_color.gray)
3415                         {
3416                            /* Background is already in screen gamma */
3417                            *sp = (png_byte)((png_ptr->background.gray >> 8)
3418                                 & 0xff);
3419                            *(sp + 1) = (png_byte)(png_ptr->background.gray
3420                                 & 0xff);
3421                         }
3422 
3423                         else
3424                         {
3425                            v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3426                            *sp = (png_byte)((v >> 8) & 0xff);
3427                            *(sp + 1) = (png_byte)(v & 0xff);
3428                         }
3429                      }
3430                   }
3431                   else
3432 #endif
3433                   {
3434                      sp = row;
3435                      for (i = 0; i < row_width; i++, sp += 2)
3436                      {
3437                         png_uint_16 v;
3438 
3439                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3440 
3441                         if (v == png_ptr->trans_color.gray)
3442                         {
3443                            *sp = (png_byte)((png_ptr->background.gray >> 8)
3444                                 & 0xff);
3445                            *(sp + 1) = (png_byte)(png_ptr->background.gray
3446                                 & 0xff);
3447                         }
3448                      }
3449                   }
3450                   break;
3451                }
3452 
3453                default:
3454                   break;
3455             }
3456             break;
3457          }
3458 
3459          case PNG_COLOR_TYPE_RGB:
3460          {
3461             if (row_info->bit_depth == 8)
3462             {
3463 #ifdef PNG_READ_GAMMA_SUPPORTED
3464                if (gamma_table != NULL)
3465                {
3466                   sp = row;
3467                   for (i = 0; i < row_width; i++, sp += 3)
3468                   {
3469                      if (*sp == png_ptr->trans_color.red &&
3470                          *(sp + 1) == png_ptr->trans_color.green &&
3471                          *(sp + 2) == png_ptr->trans_color.blue)
3472                      {
3473                         *sp = (png_byte)png_ptr->background.red;
3474                         *(sp + 1) = (png_byte)png_ptr->background.green;
3475                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3476                      }
3477 
3478                      else
3479                      {
3480                         *sp = gamma_table[*sp];
3481                         *(sp + 1) = gamma_table[*(sp + 1)];
3482                         *(sp + 2) = gamma_table[*(sp + 2)];
3483                      }
3484                   }
3485                }
3486                else
3487 #endif
3488                {
3489                   sp = row;
3490                   for (i = 0; i < row_width; i++, sp += 3)
3491                   {
3492                      if (*sp == png_ptr->trans_color.red &&
3493                          *(sp + 1) == png_ptr->trans_color.green &&
3494                          *(sp + 2) == png_ptr->trans_color.blue)
3495                      {
3496                         *sp = (png_byte)png_ptr->background.red;
3497                         *(sp + 1) = (png_byte)png_ptr->background.green;
3498                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3499                      }
3500                   }
3501                }
3502             }
3503             else /* if (row_info->bit_depth == 16) */
3504             {
3505 #ifdef PNG_READ_GAMMA_SUPPORTED
3506                if (gamma_16 != NULL)
3507                {
3508                   sp = row;
3509                   for (i = 0; i < row_width; i++, sp += 6)
3510                   {
3511                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3512 
3513                      png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3514                          + *(sp + 3));
3515 
3516                      png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3517                          + *(sp + 5));
3518 
3519                      if (r == png_ptr->trans_color.red &&
3520                          g == png_ptr->trans_color.green &&
3521                          b == png_ptr->trans_color.blue)
3522                      {
3523                         /* Background is already in screen gamma */
3524                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3525                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3526                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3527                                 & 0xff);
3528                         *(sp + 3) = (png_byte)(png_ptr->background.green
3529                                 & 0xff);
3530                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3531                                 & 0xff);
3532                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3533                      }
3534 
3535                      else
3536                      {
3537                         png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3538                         *sp = (png_byte)((v >> 8) & 0xff);
3539                         *(sp + 1) = (png_byte)(v & 0xff);
3540 
3541                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3542                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3543                         *(sp + 3) = (png_byte)(v & 0xff);
3544 
3545                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3546                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3547                         *(sp + 5) = (png_byte)(v & 0xff);
3548                      }
3549                   }
3550                }
3551 
3552                else
3553 #endif
3554                {
3555                   sp = row;
3556                   for (i = 0; i < row_width; i++, sp += 6)
3557                   {
3558                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3559 
3560                      png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3561                          + *(sp + 3));
3562 
3563                      png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3564                          + *(sp + 5));
3565 
3566                      if (r == png_ptr->trans_color.red &&
3567                          g == png_ptr->trans_color.green &&
3568                          b == png_ptr->trans_color.blue)
3569                      {
3570                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3571                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3572                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3573                                 & 0xff);
3574                         *(sp + 3) = (png_byte)(png_ptr->background.green
3575                                 & 0xff);
3576                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3577                                 & 0xff);
3578                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3579                      }
3580                   }
3581                }
3582             }
3583             break;
3584          }
3585 
3586          case PNG_COLOR_TYPE_GRAY_ALPHA:
3587          {
3588             if (row_info->bit_depth == 8)
3589             {
3590 #ifdef PNG_READ_GAMMA_SUPPORTED
3591                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3592                    gamma_table != NULL)
3593                {
3594                   sp = row;
3595                   for (i = 0; i < row_width; i++, sp += 2)
3596                   {
3597                      png_uint_16 a = *(sp + 1);
3598 
3599                      if (a == 0xff)
3600                         *sp = gamma_table[*sp];
3601 
3602                      else if (a == 0)
3603                      {
3604                         /* Background is already in screen gamma */
3605                         *sp = (png_byte)png_ptr->background.gray;
3606                      }
3607 
3608                      else
3609                      {
3610                         png_byte v, w;
3611 
3612                         v = gamma_to_1[*sp];
3613                         png_composite(w, v, a, png_ptr->background_1.gray);
3614                         if (optimize == 0)
3615                            w = gamma_from_1[w];
3616                         *sp = w;
3617                      }
3618                   }
3619                }
3620                else
3621 #endif
3622                {
3623                   sp = row;
3624                   for (i = 0; i < row_width; i++, sp += 2)
3625                   {
3626                      png_byte a = *(sp + 1);
3627 
3628                      if (a == 0)
3629                         *sp = (png_byte)png_ptr->background.gray;
3630 
3631                      else if (a < 0xff)
3632                         png_composite(*sp, *sp, a, png_ptr->background.gray);
3633                   }
3634                }
3635             }
3636             else /* if (png_ptr->bit_depth == 16) */
3637             {
3638 #ifdef PNG_READ_GAMMA_SUPPORTED
3639                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3640                    gamma_16_to_1 != NULL)
3641                {
3642                   sp = row;
3643                   for (i = 0; i < row_width; i++, sp += 4)
3644                   {
3645                      png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3646                          + *(sp + 3));
3647 
3648                      if (a == (png_uint_16)0xffff)
3649                      {
3650                         png_uint_16 v;
3651 
3652                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3653                         *sp = (png_byte)((v >> 8) & 0xff);
3654                         *(sp + 1) = (png_byte)(v & 0xff);
3655                      }
3656 
3657                      else if (a == 0)
3658                      {
3659                         /* Background is already in screen gamma */
3660                         *sp = (png_byte)((png_ptr->background.gray >> 8)
3661                                 & 0xff);
3662                         *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3663                      }
3664 
3665                      else
3666                      {
3667                         png_uint_16 g, v, w;
3668 
3669                         g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3670                         png_composite_16(v, g, a, png_ptr->background_1.gray);
3671                         if (optimize != 0)
3672                            w = v;
3673                         else
3674                            w = gamma_16_from_1[(v & 0xff) >>
3675                                gamma_shift][v >> 8];
3676                         *sp = (png_byte)((w >> 8) & 0xff);
3677                         *(sp + 1) = (png_byte)(w & 0xff);
3678                      }
3679                   }
3680                }
3681                else
3682 #endif
3683                {
3684                   sp = row;
3685                   for (i = 0; i < row_width; i++, sp += 4)
3686                   {
3687                      png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3688                          + *(sp + 3));
3689 
3690                      if (a == 0)
3691                      {
3692                         *sp = (png_byte)((png_ptr->background.gray >> 8)
3693                                 & 0xff);
3694                         *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3695                      }
3696 
3697                      else if (a < 0xffff)
3698                      {
3699                         png_uint_16 g, v;
3700 
3701                         g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3702                         png_composite_16(v, g, a, png_ptr->background.gray);
3703                         *sp = (png_byte)((v >> 8) & 0xff);
3704                         *(sp + 1) = (png_byte)(v & 0xff);
3705                      }
3706                   }
3707                }
3708             }
3709             break;
3710          }
3711 
3712          case PNG_COLOR_TYPE_RGB_ALPHA:
3713          {
3714             if (row_info->bit_depth == 8)
3715             {
3716 #ifdef PNG_READ_GAMMA_SUPPORTED
3717                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3718                    gamma_table != NULL)
3719                {
3720                   sp = row;
3721                   for (i = 0; i < row_width; i++, sp += 4)
3722                   {
3723                      png_byte a = *(sp + 3);
3724 
3725                      if (a == 0xff)
3726                      {
3727                         *sp = gamma_table[*sp];
3728                         *(sp + 1) = gamma_table[*(sp + 1)];
3729                         *(sp + 2) = gamma_table[*(sp + 2)];
3730                      }
3731 
3732                      else if (a == 0)
3733                      {
3734                         /* Background is already in screen gamma */
3735                         *sp = (png_byte)png_ptr->background.red;
3736                         *(sp + 1) = (png_byte)png_ptr->background.green;
3737                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3738                      }
3739 
3740                      else
3741                      {
3742                         png_byte v, w;
3743 
3744                         v = gamma_to_1[*sp];
3745                         png_composite(w, v, a, png_ptr->background_1.red);
3746                         if (optimize == 0) w = gamma_from_1[w];
3747                         *sp = w;
3748 
3749                         v = gamma_to_1[*(sp + 1)];
3750                         png_composite(w, v, a, png_ptr->background_1.green);
3751                         if (optimize == 0) w = gamma_from_1[w];
3752                         *(sp + 1) = w;
3753 
3754                         v = gamma_to_1[*(sp + 2)];
3755                         png_composite(w, v, a, png_ptr->background_1.blue);
3756                         if (optimize == 0) w = gamma_from_1[w];
3757                         *(sp + 2) = w;
3758                      }
3759                   }
3760                }
3761                else
3762 #endif
3763                {
3764                   sp = row;
3765                   for (i = 0; i < row_width; i++, sp += 4)
3766                   {
3767                      png_byte a = *(sp + 3);
3768 
3769                      if (a == 0)
3770                      {
3771                         *sp = (png_byte)png_ptr->background.red;
3772                         *(sp + 1) = (png_byte)png_ptr->background.green;
3773                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3774                      }
3775 
3776                      else if (a < 0xff)
3777                      {
3778                         png_composite(*sp, *sp, a, png_ptr->background.red);
3779 
3780                         png_composite(*(sp + 1), *(sp + 1), a,
3781                             png_ptr->background.green);
3782 
3783                         png_composite(*(sp + 2), *(sp + 2), a,
3784                             png_ptr->background.blue);
3785                      }
3786                   }
3787                }
3788             }
3789             else /* if (row_info->bit_depth == 16) */
3790             {
3791 #ifdef PNG_READ_GAMMA_SUPPORTED
3792                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3793                    gamma_16_to_1 != NULL)
3794                {
3795                   sp = row;
3796                   for (i = 0; i < row_width; i++, sp += 8)
3797                   {
3798                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3799                          << 8) + (png_uint_16)(*(sp + 7)));
3800 
3801                      if (a == (png_uint_16)0xffff)
3802                      {
3803                         png_uint_16 v;
3804 
3805                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3806                         *sp = (png_byte)((v >> 8) & 0xff);
3807                         *(sp + 1) = (png_byte)(v & 0xff);
3808 
3809                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3810                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3811                         *(sp + 3) = (png_byte)(v & 0xff);
3812 
3813                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3814                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3815                         *(sp + 5) = (png_byte)(v & 0xff);
3816                      }
3817 
3818                      else if (a == 0)
3819                      {
3820                         /* Background is already in screen gamma */
3821                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3822                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3823                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3824                                 & 0xff);
3825                         *(sp + 3) = (png_byte)(png_ptr->background.green
3826                                 & 0xff);
3827                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3828                                 & 0xff);
3829                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3830                      }
3831 
3832                      else
3833                      {
3834                         png_uint_16 v, w;
3835 
3836                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3837                         png_composite_16(w, v, a, png_ptr->background_1.red);
3838                         if (optimize == 0)
3839                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3840                                 8];
3841                         *sp = (png_byte)((w >> 8) & 0xff);
3842                         *(sp + 1) = (png_byte)(w & 0xff);
3843 
3844                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3845                         png_composite_16(w, v, a, png_ptr->background_1.green);
3846                         if (optimize == 0)
3847                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3848                                 8];
3849 
3850                         *(sp + 2) = (png_byte)((w >> 8) & 0xff);
3851                         *(sp + 3) = (png_byte)(w & 0xff);
3852 
3853                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3854                         png_composite_16(w, v, a, png_ptr->background_1.blue);
3855                         if (optimize == 0)
3856                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3857                                 8];
3858 
3859                         *(sp + 4) = (png_byte)((w >> 8) & 0xff);
3860                         *(sp + 5) = (png_byte)(w & 0xff);
3861                      }
3862                   }
3863                }
3864 
3865                else
3866 #endif
3867                {
3868                   sp = row;
3869                   for (i = 0; i < row_width; i++, sp += 8)
3870                   {
3871                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3872                          << 8) + (png_uint_16)(*(sp + 7)));
3873 
3874                      if (a == 0)
3875                      {
3876                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3877                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3878                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3879                                 & 0xff);
3880                         *(sp + 3) = (png_byte)(png_ptr->background.green
3881                                 & 0xff);
3882                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3883                                 & 0xff);
3884                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3885                      }
3886 
3887                      else if (a < 0xffff)
3888                      {
3889                         png_uint_16 v;
3890 
3891                         png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3892                         png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3893                             + *(sp + 3));
3894                         png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3895                             + *(sp + 5));
3896 
3897                         png_composite_16(v, r, a, png_ptr->background.red);
3898                         *sp = (png_byte)((v >> 8) & 0xff);
3899                         *(sp + 1) = (png_byte)(v & 0xff);
3900 
3901                         png_composite_16(v, g, a, png_ptr->background.green);
3902                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3903                         *(sp + 3) = (png_byte)(v & 0xff);
3904 
3905                         png_composite_16(v, b, a, png_ptr->background.blue);
3906                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3907                         *(sp + 5) = (png_byte)(v & 0xff);
3908                      }
3909                   }
3910                }
3911             }
3912             break;
3913          }
3914 
3915          default:
3916             break;
3917       }
3918    }
3919 }
3920 #endif /* READ_BACKGROUND || READ_ALPHA_MODE */
3921 
3922 #ifdef PNG_READ_GAMMA_SUPPORTED
3923 /* Gamma correct the image, avoiding the alpha channel.  Make sure
3924  * you do this after you deal with the transparency issue on grayscale
3925  * or RGB images. If your bit depth is 8, use gamma_table, if it
3926  * is 16, use gamma_16_table and gamma_shift.  Build these with
3927  * build_gamma_table().
3928  */
3929 static void
png_do_gamma(png_row_infop row_info,png_bytep row,png_structrp png_ptr)3930 png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3931 {
3932    png_const_bytep gamma_table = png_ptr->gamma_table;
3933    png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
3934    int gamma_shift = png_ptr->gamma_shift;
3935 
3936    png_bytep sp;
3937    png_uint_32 i;
3938    png_uint_32 row_width=row_info->width;
3939 
3940    png_debug(1, "in png_do_gamma");
3941 
3942    if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
3943        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
3944    {
3945       switch (row_info->color_type)
3946       {
3947          case PNG_COLOR_TYPE_RGB:
3948          {
3949             if (row_info->bit_depth == 8)
3950             {
3951                sp = row;
3952                for (i = 0; i < row_width; i++)
3953                {
3954                   *sp = gamma_table[*sp];
3955                   sp++;
3956                   *sp = gamma_table[*sp];
3957                   sp++;
3958                   *sp = gamma_table[*sp];
3959                   sp++;
3960                }
3961             }
3962 
3963             else /* if (row_info->bit_depth == 16) */
3964             {
3965                sp = row;
3966                for (i = 0; i < row_width; i++)
3967                {
3968                   png_uint_16 v;
3969 
3970                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3971                   *sp = (png_byte)((v >> 8) & 0xff);
3972                   *(sp + 1) = (png_byte)(v & 0xff);
3973                   sp += 2;
3974 
3975                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3976                   *sp = (png_byte)((v >> 8) & 0xff);
3977                   *(sp + 1) = (png_byte)(v & 0xff);
3978                   sp += 2;
3979 
3980                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3981                   *sp = (png_byte)((v >> 8) & 0xff);
3982                   *(sp + 1) = (png_byte)(v & 0xff);
3983                   sp += 2;
3984                }
3985             }
3986             break;
3987          }
3988 
3989          case PNG_COLOR_TYPE_RGB_ALPHA:
3990          {
3991             if (row_info->bit_depth == 8)
3992             {
3993                sp = row;
3994                for (i = 0; i < row_width; i++)
3995                {
3996                   *sp = gamma_table[*sp];
3997                   sp++;
3998 
3999                   *sp = gamma_table[*sp];
4000                   sp++;
4001 
4002                   *sp = gamma_table[*sp];
4003                   sp++;
4004 
4005                   sp++;
4006                }
4007             }
4008 
4009             else /* if (row_info->bit_depth == 16) */
4010             {
4011                sp = row;
4012                for (i = 0; i < row_width; i++)
4013                {
4014                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4015                   *sp = (png_byte)((v >> 8) & 0xff);
4016                   *(sp + 1) = (png_byte)(v & 0xff);
4017                   sp += 2;
4018 
4019                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4020                   *sp = (png_byte)((v >> 8) & 0xff);
4021                   *(sp + 1) = (png_byte)(v & 0xff);
4022                   sp += 2;
4023 
4024                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4025                   *sp = (png_byte)((v >> 8) & 0xff);
4026                   *(sp + 1) = (png_byte)(v & 0xff);
4027                   sp += 4;
4028                }
4029             }
4030             break;
4031          }
4032 
4033          case PNG_COLOR_TYPE_GRAY_ALPHA:
4034          {
4035             if (row_info->bit_depth == 8)
4036             {
4037                sp = row;
4038                for (i = 0; i < row_width; i++)
4039                {
4040                   *sp = gamma_table[*sp];
4041                   sp += 2;
4042                }
4043             }
4044 
4045             else /* if (row_info->bit_depth == 16) */
4046             {
4047                sp = row;
4048                for (i = 0; i < row_width; i++)
4049                {
4050                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4051                   *sp = (png_byte)((v >> 8) & 0xff);
4052                   *(sp + 1) = (png_byte)(v & 0xff);
4053                   sp += 4;
4054                }
4055             }
4056             break;
4057          }
4058 
4059          case PNG_COLOR_TYPE_GRAY:
4060          {
4061             if (row_info->bit_depth == 2)
4062             {
4063                sp = row;
4064                for (i = 0; i < row_width; i += 4)
4065                {
4066                   int a = *sp & 0xc0;
4067                   int b = *sp & 0x30;
4068                   int c = *sp & 0x0c;
4069                   int d = *sp & 0x03;
4070 
4071                   *sp = (png_byte)(
4072                       ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
4073                       ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
4074                       ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
4075                       ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
4076                   sp++;
4077                }
4078             }
4079 
4080             if (row_info->bit_depth == 4)
4081             {
4082                sp = row;
4083                for (i = 0; i < row_width; i += 2)
4084                {
4085                   int msb = *sp & 0xf0;
4086                   int lsb = *sp & 0x0f;
4087 
4088                   *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
4089                       | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
4090                   sp++;
4091                }
4092             }
4093 
4094             else if (row_info->bit_depth == 8)
4095             {
4096                sp = row;
4097                for (i = 0; i < row_width; i++)
4098                {
4099                   *sp = gamma_table[*sp];
4100                   sp++;
4101                }
4102             }
4103 
4104             else if (row_info->bit_depth == 16)
4105             {
4106                sp = row;
4107                for (i = 0; i < row_width; i++)
4108                {
4109                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4110                   *sp = (png_byte)((v >> 8) & 0xff);
4111                   *(sp + 1) = (png_byte)(v & 0xff);
4112                   sp += 2;
4113                }
4114             }
4115             break;
4116          }
4117 
4118          default:
4119             break;
4120       }
4121    }
4122 }
4123 #endif
4124 
4125 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4126 /* Encode the alpha channel to the output gamma (the input channel is always
4127  * linear.)  Called only with color types that have an alpha channel.  Needs the
4128  * from_1 tables.
4129  */
4130 static void
png_do_encode_alpha(png_row_infop row_info,png_bytep row,png_structrp png_ptr)4131 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4132 {
4133    png_uint_32 row_width = row_info->width;
4134 
4135    png_debug(1, "in png_do_encode_alpha");
4136 
4137    if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4138    {
4139       if (row_info->bit_depth == 8)
4140       {
4141          PNG_CONST png_bytep table = png_ptr->gamma_from_1;
4142 
4143          if (table != NULL)
4144          {
4145             PNG_CONST int step =
4146                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
4147 
4148             /* The alpha channel is the last component: */
4149             row += step - 1;
4150 
4151             for (; row_width > 0; --row_width, row += step)
4152                *row = table[*row];
4153 
4154             return;
4155          }
4156       }
4157 
4158       else if (row_info->bit_depth == 16)
4159       {
4160          PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
4161          PNG_CONST int gamma_shift = png_ptr->gamma_shift;
4162 
4163          if (table != NULL)
4164          {
4165             PNG_CONST int step =
4166                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
4167 
4168             /* The alpha channel is the last component: */
4169             row += step - 2;
4170 
4171             for (; row_width > 0; --row_width, row += step)
4172             {
4173                png_uint_16 v;
4174 
4175                v = table[*(row + 1) >> gamma_shift][*row];
4176                *row = (png_byte)((v >> 8) & 0xff);
4177                *(row + 1) = (png_byte)(v & 0xff);
4178             }
4179 
4180             return;
4181          }
4182       }
4183    }
4184 
4185    /* Only get to here if called with a weird row_info; no harm has been done,
4186     * so just issue a warning.
4187     */
4188    png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
4189 }
4190 #endif
4191 
4192 #ifdef PNG_READ_EXPAND_SUPPORTED
4193 /* Expands a palette row to an RGB or RGBA row depending
4194  * upon whether you supply trans and num_trans.
4195  */
4196 static void
png_do_expand_palette(png_row_infop row_info,png_bytep row,png_const_colorp palette,png_const_bytep trans_alpha,int num_trans)4197 png_do_expand_palette(png_row_infop row_info, png_bytep row,
4198    png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
4199 {
4200    int shift, value;
4201    png_bytep sp, dp;
4202    png_uint_32 i;
4203    png_uint_32 row_width=row_info->width;
4204 
4205    png_debug(1, "in png_do_expand_palette");
4206 
4207    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4208    {
4209       if (row_info->bit_depth < 8)
4210       {
4211          switch (row_info->bit_depth)
4212          {
4213             case 1:
4214             {
4215                sp = row + (png_size_t)((row_width - 1) >> 3);
4216                dp = row + (png_size_t)row_width - 1;
4217                shift = 7 - (int)((row_width + 7) & 0x07);
4218                for (i = 0; i < row_width; i++)
4219                {
4220                   if ((*sp >> shift) & 0x01)
4221                      *dp = 1;
4222 
4223                   else
4224                      *dp = 0;
4225 
4226                   if (shift == 7)
4227                   {
4228                      shift = 0;
4229                      sp--;
4230                   }
4231 
4232                   else
4233                      shift++;
4234 
4235                   dp--;
4236                }
4237                break;
4238             }
4239 
4240             case 2:
4241             {
4242                sp = row + (png_size_t)((row_width - 1) >> 2);
4243                dp = row + (png_size_t)row_width - 1;
4244                shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4245                for (i = 0; i < row_width; i++)
4246                {
4247                   value = (*sp >> shift) & 0x03;
4248                   *dp = (png_byte)value;
4249                   if (shift == 6)
4250                   {
4251                      shift = 0;
4252                      sp--;
4253                   }
4254 
4255                   else
4256                      shift += 2;
4257 
4258                   dp--;
4259                }
4260                break;
4261             }
4262 
4263             case 4:
4264             {
4265                sp = row + (png_size_t)((row_width - 1) >> 1);
4266                dp = row + (png_size_t)row_width - 1;
4267                shift = (int)((row_width & 0x01) << 2);
4268                for (i = 0; i < row_width; i++)
4269                {
4270                   value = (*sp >> shift) & 0x0f;
4271                   *dp = (png_byte)value;
4272                   if (shift == 4)
4273                   {
4274                      shift = 0;
4275                      sp--;
4276                   }
4277 
4278                   else
4279                      shift += 4;
4280 
4281                   dp--;
4282                }
4283                break;
4284             }
4285 
4286             default:
4287                break;
4288          }
4289          row_info->bit_depth = 8;
4290          row_info->pixel_depth = 8;
4291          row_info->rowbytes = row_width;
4292       }
4293 
4294       if (row_info->bit_depth == 8)
4295       {
4296          {
4297             if (num_trans > 0)
4298             {
4299                sp = row + (png_size_t)row_width - 1;
4300                dp = row + (png_size_t)(row_width << 2) - 1;
4301 
4302                for (i = 0; i < row_width; i++)
4303                {
4304                   if ((int)(*sp) >= num_trans)
4305                      *dp-- = 0xff;
4306 
4307                   else
4308                      *dp-- = trans_alpha[*sp];
4309 
4310                   *dp-- = palette[*sp].blue;
4311                   *dp-- = palette[*sp].green;
4312                   *dp-- = palette[*sp].red;
4313                   sp--;
4314                }
4315                row_info->bit_depth = 8;
4316                row_info->pixel_depth = 32;
4317                row_info->rowbytes = row_width * 4;
4318                row_info->color_type = 6;
4319                row_info->channels = 4;
4320             }
4321 
4322             else
4323             {
4324                sp = row + (png_size_t)row_width - 1;
4325                dp = row + (png_size_t)(row_width * 3) - 1;
4326 
4327                for (i = 0; i < row_width; i++)
4328                {
4329                   *dp-- = palette[*sp].blue;
4330                   *dp-- = palette[*sp].green;
4331                   *dp-- = palette[*sp].red;
4332                   sp--;
4333                }
4334 
4335                row_info->bit_depth = 8;
4336                row_info->pixel_depth = 24;
4337                row_info->rowbytes = row_width * 3;
4338                row_info->color_type = 2;
4339                row_info->channels = 3;
4340             }
4341          }
4342       }
4343    }
4344 }
4345 
4346 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
4347  * expanded transparency value is supplied, an alpha channel is built.
4348  */
4349 static void
png_do_expand(png_row_infop row_info,png_bytep row,png_const_color_16p trans_color)4350 png_do_expand(png_row_infop row_info, png_bytep row,
4351     png_const_color_16p trans_color)
4352 {
4353    int shift, value;
4354    png_bytep sp, dp;
4355    png_uint_32 i;
4356    png_uint_32 row_width=row_info->width;
4357 
4358    png_debug(1, "in png_do_expand");
4359 
4360    {
4361       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
4362       {
4363          unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
4364 
4365          if (row_info->bit_depth < 8)
4366          {
4367             switch (row_info->bit_depth)
4368             {
4369                case 1:
4370                {
4371                   gray = (gray & 0x01) * 0xff;
4372                   sp = row + (png_size_t)((row_width - 1) >> 3);
4373                   dp = row + (png_size_t)row_width - 1;
4374                   shift = 7 - (int)((row_width + 7) & 0x07);
4375                   for (i = 0; i < row_width; i++)
4376                   {
4377                      if ((*sp >> shift) & 0x01)
4378                         *dp = 0xff;
4379 
4380                      else
4381                         *dp = 0;
4382 
4383                      if (shift == 7)
4384                      {
4385                         shift = 0;
4386                         sp--;
4387                      }
4388 
4389                      else
4390                         shift++;
4391 
4392                      dp--;
4393                   }
4394                   break;
4395                }
4396 
4397                case 2:
4398                {
4399                   gray = (gray & 0x03) * 0x55;
4400                   sp = row + (png_size_t)((row_width - 1) >> 2);
4401                   dp = row + (png_size_t)row_width - 1;
4402                   shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4403                   for (i = 0; i < row_width; i++)
4404                   {
4405                      value = (*sp >> shift) & 0x03;
4406                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
4407                         (value << 6));
4408                      if (shift == 6)
4409                      {
4410                         shift = 0;
4411                         sp--;
4412                      }
4413 
4414                      else
4415                         shift += 2;
4416 
4417                      dp--;
4418                   }
4419                   break;
4420                }
4421 
4422                case 4:
4423                {
4424                   gray = (gray & 0x0f) * 0x11;
4425                   sp = row + (png_size_t)((row_width - 1) >> 1);
4426                   dp = row + (png_size_t)row_width - 1;
4427                   shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
4428                   for (i = 0; i < row_width; i++)
4429                   {
4430                      value = (*sp >> shift) & 0x0f;
4431                      *dp = (png_byte)(value | (value << 4));
4432                      if (shift == 4)
4433                      {
4434                         shift = 0;
4435                         sp--;
4436                      }
4437 
4438                      else
4439                         shift = 4;
4440 
4441                      dp--;
4442                   }
4443                   break;
4444                }
4445 
4446                default:
4447                   break;
4448             }
4449 
4450             row_info->bit_depth = 8;
4451             row_info->pixel_depth = 8;
4452             row_info->rowbytes = row_width;
4453          }
4454 
4455          if (trans_color != NULL)
4456          {
4457             if (row_info->bit_depth == 8)
4458             {
4459                gray = gray & 0xff;
4460                sp = row + (png_size_t)row_width - 1;
4461                dp = row + (png_size_t)(row_width << 1) - 1;
4462 
4463                for (i = 0; i < row_width; i++)
4464                {
4465                   if ((*sp & 0xffU) == gray)
4466                      *dp-- = 0;
4467 
4468                   else
4469                      *dp-- = 0xff;
4470 
4471                   *dp-- = *sp--;
4472                }
4473             }
4474 
4475             else if (row_info->bit_depth == 16)
4476             {
4477                unsigned int gray_high = (gray >> 8) & 0xff;
4478                unsigned int gray_low = gray & 0xff;
4479                sp = row + row_info->rowbytes - 1;
4480                dp = row + (row_info->rowbytes << 1) - 1;
4481                for (i = 0; i < row_width; i++)
4482                {
4483                   if ((*(sp - 1) & 0xffU) == gray_high &&
4484                       (*(sp) & 0xffU) == gray_low)
4485                   {
4486                      *dp-- = 0;
4487                      *dp-- = 0;
4488                   }
4489 
4490                   else
4491                   {
4492                      *dp-- = 0xff;
4493                      *dp-- = 0xff;
4494                   }
4495 
4496                   *dp-- = *sp--;
4497                   *dp-- = *sp--;
4498                }
4499             }
4500 
4501             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
4502             row_info->channels = 2;
4503             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
4504             row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
4505                row_width);
4506          }
4507       }
4508       else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
4509           trans_color != NULL)
4510       {
4511          if (row_info->bit_depth == 8)
4512          {
4513             png_byte red = (png_byte)(trans_color->red & 0xff);
4514             png_byte green = (png_byte)(trans_color->green & 0xff);
4515             png_byte blue = (png_byte)(trans_color->blue & 0xff);
4516             sp = row + (png_size_t)row_info->rowbytes - 1;
4517             dp = row + (png_size_t)(row_width << 2) - 1;
4518             for (i = 0; i < row_width; i++)
4519             {
4520                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
4521                   *dp-- = 0;
4522 
4523                else
4524                   *dp-- = 0xff;
4525 
4526                *dp-- = *sp--;
4527                *dp-- = *sp--;
4528                *dp-- = *sp--;
4529             }
4530          }
4531          else if (row_info->bit_depth == 16)
4532          {
4533             png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
4534             png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
4535             png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
4536             png_byte red_low = (png_byte)(trans_color->red & 0xff);
4537             png_byte green_low = (png_byte)(trans_color->green & 0xff);
4538             png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
4539             sp = row + row_info->rowbytes - 1;
4540             dp = row + (png_size_t)(row_width << 3) - 1;
4541             for (i = 0; i < row_width; i++)
4542             {
4543                if (*(sp - 5) == red_high &&
4544                    *(sp - 4) == red_low &&
4545                    *(sp - 3) == green_high &&
4546                    *(sp - 2) == green_low &&
4547                    *(sp - 1) == blue_high &&
4548                    *(sp    ) == blue_low)
4549                {
4550                   *dp-- = 0;
4551                   *dp-- = 0;
4552                }
4553 
4554                else
4555                {
4556                   *dp-- = 0xff;
4557                   *dp-- = 0xff;
4558                }
4559 
4560                *dp-- = *sp--;
4561                *dp-- = *sp--;
4562                *dp-- = *sp--;
4563                *dp-- = *sp--;
4564                *dp-- = *sp--;
4565                *dp-- = *sp--;
4566             }
4567          }
4568          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
4569          row_info->channels = 4;
4570          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
4571          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4572       }
4573    }
4574 }
4575 #endif
4576 
4577 #ifdef PNG_READ_EXPAND_16_SUPPORTED
4578 /* If the bit depth is 8 and the color type is not a palette type expand the
4579  * whole row to 16 bits.  Has no effect otherwise.
4580  */
4581 static void
png_do_expand_16(png_row_infop row_info,png_bytep row)4582 png_do_expand_16(png_row_infop row_info, png_bytep row)
4583 {
4584    if (row_info->bit_depth == 8 &&
4585       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
4586    {
4587       /* The row have a sequence of bytes containing [0..255] and we need
4588        * to turn it into another row containing [0..65535], to do this we
4589        * calculate:
4590        *
4591        *  (input / 255) * 65535
4592        *
4593        *  Which happens to be exactly input * 257 and this can be achieved
4594        *  simply by byte replication in place (copying backwards).
4595        */
4596       png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
4597       png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
4598       while (dp > sp)
4599          dp[-2] = dp[-1] = *--sp, dp -= 2;
4600 
4601       row_info->rowbytes *= 2;
4602       row_info->bit_depth = 16;
4603       row_info->pixel_depth = (png_byte)(row_info->channels * 16);
4604    }
4605 }
4606 #endif
4607 
4608 #ifdef PNG_READ_QUANTIZE_SUPPORTED
4609 static void
png_do_quantize(png_row_infop row_info,png_bytep row,png_const_bytep palette_lookup,png_const_bytep quantize_lookup)4610 png_do_quantize(png_row_infop row_info, png_bytep row,
4611     png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
4612 {
4613    png_bytep sp, dp;
4614    png_uint_32 i;
4615    png_uint_32 row_width=row_info->width;
4616 
4617    png_debug(1, "in png_do_quantize");
4618 
4619    if (row_info->bit_depth == 8)
4620    {
4621       if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
4622       {
4623          int r, g, b, p;
4624          sp = row;
4625          dp = row;
4626          for (i = 0; i < row_width; i++)
4627          {
4628             r = *sp++;
4629             g = *sp++;
4630             b = *sp++;
4631 
4632             /* This looks real messy, but the compiler will reduce
4633              * it down to a reasonable formula.  For example, with
4634              * 5 bits per color, we get:
4635              * p = (((r >> 3) & 0x1f) << 10) |
4636              *    (((g >> 3) & 0x1f) << 5) |
4637              *    ((b >> 3) & 0x1f);
4638              */
4639             p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4640                 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4641                 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4642                 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4643                 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4644                 (PNG_QUANTIZE_BLUE_BITS)) |
4645                 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4646                 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4647 
4648             *dp++ = palette_lookup[p];
4649          }
4650 
4651          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4652          row_info->channels = 1;
4653          row_info->pixel_depth = row_info->bit_depth;
4654          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4655       }
4656 
4657       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
4658          palette_lookup != NULL)
4659       {
4660          int r, g, b, p;
4661          sp = row;
4662          dp = row;
4663          for (i = 0; i < row_width; i++)
4664          {
4665             r = *sp++;
4666             g = *sp++;
4667             b = *sp++;
4668             sp++;
4669 
4670             p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4671                 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4672                 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4673                 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4674                 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4675                 (PNG_QUANTIZE_BLUE_BITS)) |
4676                 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4677                 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4678 
4679             *dp++ = palette_lookup[p];
4680          }
4681 
4682          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4683          row_info->channels = 1;
4684          row_info->pixel_depth = row_info->bit_depth;
4685          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4686       }
4687 
4688       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4689          quantize_lookup)
4690       {
4691          sp = row;
4692 
4693          for (i = 0; i < row_width; i++, sp++)
4694          {
4695             *sp = quantize_lookup[*sp];
4696          }
4697       }
4698    }
4699 }
4700 #endif /* READ_QUANTIZE */
4701 
4702 /* Transform the row.  The order of transformations is significant,
4703  * and is very touchy.  If you add a transformation, take care to
4704  * decide how it fits in with the other transformations here.
4705  */
4706 void /* PRIVATE */
png_do_read_transformations(png_structrp png_ptr,png_row_infop row_info)4707 png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
4708 {
4709    png_debug(1, "in png_do_read_transformations");
4710 
4711    if (png_ptr->row_buf == NULL)
4712    {
4713       /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
4714        * error is incredibly rare and incredibly easy to debug without this
4715        * information.
4716        */
4717       png_error(png_ptr, "NULL row buffer");
4718    }
4719 
4720    /* The following is debugging; prior to 1.5.4 the code was never compiled in;
4721     * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
4722     * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
4723     * all transformations, however in practice the ROW_INIT always gets done on
4724     * demand, if necessary.
4725     */
4726    if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
4727        (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
4728    {
4729       /* Application has failed to call either png_read_start_image() or
4730        * png_read_update_info() after setting transforms that expand pixels.
4731        * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
4732        */
4733       png_error(png_ptr, "Uninitialized row");
4734    }
4735 
4736 #ifdef PNG_READ_EXPAND_SUPPORTED
4737    if ((png_ptr->transformations & PNG_EXPAND) != 0)
4738    {
4739       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4740       {
4741          png_do_expand_palette(row_info, png_ptr->row_buf + 1,
4742              png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
4743       }
4744 
4745       else
4746       {
4747          if (png_ptr->num_trans != 0 &&
4748              (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
4749             png_do_expand(row_info, png_ptr->row_buf + 1,
4750                 &(png_ptr->trans_color));
4751 
4752          else
4753             png_do_expand(row_info, png_ptr->row_buf + 1,
4754                 NULL);
4755       }
4756    }
4757 #endif
4758 
4759 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4760    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4761        (png_ptr->transformations & PNG_COMPOSE) == 0 &&
4762        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
4763        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
4764       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
4765          0 /* at_start == false, because SWAP_ALPHA happens later */);
4766 #endif
4767 
4768 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
4769    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
4770    {
4771       int rgb_error =
4772           png_do_rgb_to_gray(png_ptr, row_info,
4773               png_ptr->row_buf + 1);
4774 
4775       if (rgb_error != 0)
4776       {
4777          png_ptr->rgb_to_gray_status=1;
4778          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4779              PNG_RGB_TO_GRAY_WARN)
4780             png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
4781 
4782          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4783              PNG_RGB_TO_GRAY_ERR)
4784             png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
4785       }
4786    }
4787 #endif
4788 
4789 /* From Andreas Dilger e-mail to png-implement, 26 March 1998:
4790  *
4791  *   In most cases, the "simple transparency" should be done prior to doing
4792  *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
4793  *   pixel is transparent.  You would also need to make sure that the
4794  *   transparency information is upgraded to RGB.
4795  *
4796  *   To summarize, the current flow is:
4797  *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
4798  *                                   with background "in place" if transparent,
4799  *                                   convert to RGB if necessary
4800  *   - Gray + alpha -> composite with gray background and remove alpha bytes,
4801  *                                   convert to RGB if necessary
4802  *
4803  *   To support RGB backgrounds for gray images we need:
4804  *   - Gray + simple transparency -> convert to RGB + simple transparency,
4805  *                                   compare 3 or 6 bytes and composite with
4806  *                                   background "in place" if transparent
4807  *                                   (3x compare/pixel compared to doing
4808  *                                   composite with gray bkgrnd)
4809  *   - Gray + alpha -> convert to RGB + alpha, composite with background and
4810  *                                   remove alpha bytes (3x float
4811  *                                   operations/pixel compared with composite
4812  *                                   on gray background)
4813  *
4814  *  Greg's change will do this.  The reason it wasn't done before is for
4815  *  performance, as this increases the per-pixel operations.  If we would check
4816  *  in advance if the background was gray or RGB, and position the gray-to-RGB
4817  *  transform appropriately, then it would save a lot of work/time.
4818  */
4819 
4820 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4821    /* If gray -> RGB, do so now only if background is non-gray; else do later
4822     * for performance reasons
4823     */
4824    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
4825        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
4826       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
4827 #endif
4828 
4829 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
4830    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
4831    if ((png_ptr->transformations & PNG_COMPOSE) != 0)
4832       png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
4833 #endif
4834 
4835 #ifdef PNG_READ_GAMMA_SUPPORTED
4836    if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
4837 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
4838       /* Because RGB_TO_GRAY does the gamma transform. */
4839       (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
4840 #endif
4841 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
4842    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
4843       /* Because PNG_COMPOSE does the gamma transform if there is something to
4844        * do (if there is an alpha channel or transparency.)
4845        */
4846        !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
4847        ((png_ptr->num_trans != 0) ||
4848        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
4849 #endif
4850       /* Because png_init_read_transformations transforms the palette, unless
4851        * RGB_TO_GRAY will do the transform.
4852        */
4853        (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
4854       png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
4855 #endif
4856 
4857 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4858    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4859        (png_ptr->transformations & PNG_COMPOSE) != 0 &&
4860        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
4861        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
4862       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
4863           0 /* at_start == false, because SWAP_ALPHA happens later */);
4864 #endif
4865 
4866 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4867    if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
4868        (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4869       png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
4870 #endif
4871 
4872 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
4873    if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
4874       png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
4875 #endif
4876 
4877 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
4878    /* There is no harm in doing both of these because only one has any effect,
4879     * by putting the 'scale' option first if the app asks for scale (either by
4880     * calling the API or in a TRANSFORM flag) this is what happens.
4881     */
4882    if ((png_ptr->transformations & PNG_16_TO_8) != 0)
4883       png_do_chop(row_info, png_ptr->row_buf + 1);
4884 #endif
4885 
4886 #ifdef PNG_READ_QUANTIZE_SUPPORTED
4887    if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
4888    {
4889       png_do_quantize(row_info, png_ptr->row_buf + 1,
4890           png_ptr->palette_lookup, png_ptr->quantize_index);
4891 
4892       if (row_info->rowbytes == 0)
4893          png_error(png_ptr, "png_do_quantize returned rowbytes=0");
4894    }
4895 #endif /* READ_QUANTIZE */
4896 
4897 #ifdef PNG_READ_EXPAND_16_SUPPORTED
4898    /* Do the expansion now, after all the arithmetic has been done.  Notice
4899     * that previous transformations can handle the PNG_EXPAND_16 flag if this
4900     * is efficient (particularly true in the case of gamma correction, where
4901     * better accuracy results faster!)
4902     */
4903    if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
4904       png_do_expand_16(row_info, png_ptr->row_buf + 1);
4905 #endif
4906 
4907 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4908    /* NOTE: moved here in 1.5.4 (from much later in this list.) */
4909    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
4910        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
4911       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
4912 #endif
4913 
4914 #ifdef PNG_READ_INVERT_SUPPORTED
4915    if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
4916       png_do_invert(row_info, png_ptr->row_buf + 1);
4917 #endif
4918 
4919 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
4920    if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
4921       png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
4922 #endif
4923 
4924 #ifdef PNG_READ_SHIFT_SUPPORTED
4925    if ((png_ptr->transformations & PNG_SHIFT) != 0)
4926       png_do_unshift(row_info, png_ptr->row_buf + 1,
4927           &(png_ptr->shift));
4928 #endif
4929 
4930 #ifdef PNG_READ_PACK_SUPPORTED
4931    if ((png_ptr->transformations & PNG_PACK) != 0)
4932       png_do_unpack(row_info, png_ptr->row_buf + 1);
4933 #endif
4934 
4935 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
4936    /* Added at libpng-1.5.10 */
4937    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4938        png_ptr->num_palette_max >= 0)
4939       png_do_check_palette_indexes(png_ptr, row_info);
4940 #endif
4941 
4942 #ifdef PNG_READ_BGR_SUPPORTED
4943    if ((png_ptr->transformations & PNG_BGR) != 0)
4944       png_do_bgr(row_info, png_ptr->row_buf + 1);
4945 #endif
4946 
4947 #ifdef PNG_READ_PACKSWAP_SUPPORTED
4948    if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
4949       png_do_packswap(row_info, png_ptr->row_buf + 1);
4950 #endif
4951 
4952 #ifdef PNG_READ_FILLER_SUPPORTED
4953    if ((png_ptr->transformations & PNG_FILLER) != 0)
4954       png_do_read_filler(row_info, png_ptr->row_buf + 1,
4955           (png_uint_32)png_ptr->filler, png_ptr->flags);
4956 #endif
4957 
4958 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
4959    if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
4960       png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
4961 #endif
4962 
4963 #ifdef PNG_READ_16BIT_SUPPORTED
4964 #ifdef PNG_READ_SWAP_SUPPORTED
4965    if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
4966       png_do_swap(row_info, png_ptr->row_buf + 1);
4967 #endif
4968 #endif
4969 
4970 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
4971    if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
4972    {
4973       if (png_ptr->read_user_transform_fn != NULL)
4974          (*(png_ptr->read_user_transform_fn)) /* User read transform function */
4975              (png_ptr,     /* png_ptr */
4976              row_info,     /* row_info: */
4977                 /*  png_uint_32 width;       width of row */
4978                 /*  png_size_t rowbytes;     number of bytes in row */
4979                 /*  png_byte color_type;     color type of pixels */
4980                 /*  png_byte bit_depth;      bit depth of samples */
4981                 /*  png_byte channels;       number of channels (1-4) */
4982                 /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
4983              png_ptr->row_buf + 1);    /* start of pixel data for row */
4984 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
4985       if (png_ptr->user_transform_depth != 0)
4986          row_info->bit_depth = png_ptr->user_transform_depth;
4987 
4988       if (png_ptr->user_transform_channels != 0)
4989          row_info->channels = png_ptr->user_transform_channels;
4990 #endif
4991       row_info->pixel_depth = (png_byte)(row_info->bit_depth *
4992           row_info->channels);
4993 
4994       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
4995    }
4996 #endif
4997 }
4998 
4999 #endif /* READ_TRANSFORMS */
5000 #endif /* READ */
5001