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