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