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