pngrtran.c revision b50c217251b086440efcdb273c22f86a06c80cba
1
2/* pngrtran.c - transforms the data in a row for PNG readers
3 *
4 * Last changed in libpng 1.6.2 [April 25, 2013]
5 * Copyright (c) 1998-2013 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         if (png_ptr->trans_alpha[i] == 255)
1120            continue;
1121         else if (png_ptr->trans_alpha[i] == 0)
1122            input_has_transparency = 1;
1123         else
1124            input_has_alpha = 1;
1125   }
1126
1127   /* If no alpha we can optimize. */
1128   if (!input_has_alpha)
1129   {
1130      /* Any alpha means background and associative alpha processing is
1131       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
1132       * and ENCODE_ALPHA are irrelevant.
1133       */
1134      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1135      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1136
1137      if (!input_has_transparency)
1138         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1139   }
1140
1141#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1142   /* png_set_background handling - deals with the complexity of whether the
1143    * background color is in the file format or the screen format in the case
1144    * where an 'expand' will happen.
1145    */
1146
1147   /* The following code cannot be entered in the alpha pre-multiplication case
1148    * because PNG_BACKGROUND_EXPAND is cancelled below.
1149    */
1150   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1151       (png_ptr->transformations & PNG_EXPAND))
1152   {
1153      {
1154         png_ptr->background.red   =
1155             png_ptr->palette[png_ptr->background.index].red;
1156         png_ptr->background.green =
1157             png_ptr->palette[png_ptr->background.index].green;
1158         png_ptr->background.blue  =
1159             png_ptr->palette[png_ptr->background.index].blue;
1160
1161#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1162        if (png_ptr->transformations & PNG_INVERT_ALPHA)
1163        {
1164           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
1165           {
1166              /* Invert the alpha channel (in tRNS) unless the pixels are
1167               * going to be expanded, in which case leave it for later
1168               */
1169              int i, istop = png_ptr->num_trans;
1170
1171              for (i=0; i<istop; i++)
1172                 png_ptr->trans_alpha[i] = (png_byte)(255 -
1173                    png_ptr->trans_alpha[i]);
1174           }
1175        }
1176#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
1177      }
1178   } /* background expand and (therefore) no alpha association. */
1179#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1180}
1181
1182static void /* PRIVATE */
1183png_init_rgb_transformations(png_structrp png_ptr)
1184{
1185   /* Added to libpng-1.5.4: check the color type to determine whether there
1186    * is any alpha or transparency in the image and simply cancel the
1187    * background and alpha mode stuff if there isn't.
1188    */
1189   int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
1190   int input_has_transparency = png_ptr->num_trans > 0;
1191
1192   /* If no alpha we can optimize. */
1193   if (!input_has_alpha)
1194   {
1195      /* Any alpha means background and associative alpha processing is
1196       * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
1197       * and ENCODE_ALPHA are irrelevant.
1198       */
1199#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1200         png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1201         png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1202#     endif
1203
1204      if (!input_has_transparency)
1205         png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
1206   }
1207
1208#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1209   /* png_set_background handling - deals with the complexity of whether the
1210    * background color is in the file format or the screen format in the case
1211    * where an 'expand' will happen.
1212    */
1213
1214   /* The following code cannot be entered in the alpha pre-multiplication case
1215    * because PNG_BACKGROUND_EXPAND is cancelled below.
1216    */
1217   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1218       (png_ptr->transformations & PNG_EXPAND) &&
1219       !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
1220       /* i.e., GRAY or GRAY_ALPHA */
1221   {
1222      {
1223         /* Expand background and tRNS chunks */
1224         int gray = png_ptr->background.gray;
1225         int trans_gray = png_ptr->trans_color.gray;
1226
1227         switch (png_ptr->bit_depth)
1228         {
1229            case 1:
1230               gray *= 0xff;
1231               trans_gray *= 0xff;
1232               break;
1233
1234            case 2:
1235               gray *= 0x55;
1236               trans_gray *= 0x55;
1237               break;
1238
1239            case 4:
1240               gray *= 0x11;
1241               trans_gray *= 0x11;
1242               break;
1243
1244            default:
1245
1246            case 8:
1247               /* FALL THROUGH (Already 8 bits) */
1248
1249            case 16:
1250               /* Already a full 16 bits */
1251               break;
1252         }
1253
1254         png_ptr->background.red = png_ptr->background.green =
1255            png_ptr->background.blue = (png_uint_16)gray;
1256
1257         if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
1258         {
1259            png_ptr->trans_color.red = png_ptr->trans_color.green =
1260               png_ptr->trans_color.blue = (png_uint_16)trans_gray;
1261         }
1262      }
1263   } /* background expand and (therefore) no alpha association. */
1264#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1265}
1266
1267void /* PRIVATE */
1268png_init_read_transformations(png_structrp png_ptr)
1269{
1270   png_debug(1, "in png_init_read_transformations");
1271
1272   /* This internal function is called from png_read_start_row in pngrutil.c
1273    * and it is called before the 'rowbytes' calculation is done, so the code
1274    * in here can change or update the transformations flags.
1275    *
1276    * First do updates that do not depend on the details of the PNG image data
1277    * being processed.
1278    */
1279
1280#ifdef PNG_READ_GAMMA_SUPPORTED
1281   /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
1282    * png_set_alpha_mode and this is another source for a default file gamma so
1283    * the test needs to be performed later - here.  In addition prior to 1.5.4
1284    * the tests were repeated for the PALETTE color type here - this is no
1285    * longer necessary (and doesn't seem to have been necessary before.)
1286    */
1287   {
1288      /* The following temporary indicates if overall gamma correction is
1289       * required.
1290       */
1291      int gamma_correction = 0;
1292
1293      if (png_ptr->colorspace.gamma != 0) /* has been set */
1294      {
1295         if (png_ptr->screen_gamma != 0) /* screen set too */
1296            gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
1297               png_ptr->screen_gamma);
1298
1299         else
1300            /* Assume the output matches the input; a long time default behavior
1301             * of libpng, although the standard has nothing to say about this.
1302             */
1303            png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
1304      }
1305
1306      else if (png_ptr->screen_gamma != 0)
1307         /* The converse - assume the file matches the screen, note that this
1308          * perhaps undesireable default can (from 1.5.4) be changed by calling
1309          * png_set_alpha_mode (even if the alpha handling mode isn't required
1310          * or isn't changed from the default.)
1311          */
1312         png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
1313
1314      else /* neither are set */
1315         /* Just in case the following prevents any processing - file and screen
1316          * are both assumed to be linear and there is no way to introduce a
1317          * third gamma value other than png_set_background with 'UNIQUE', and,
1318          * prior to 1.5.4
1319          */
1320         png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
1321
1322      /* We have a gamma value now. */
1323      png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
1324
1325      /* Now turn the gamma transformation on or off as appropriate.  Notice
1326       * that PNG_GAMMA just refers to the file->screen correction.  Alpha
1327       * composition may independently cause gamma correction because it needs
1328       * linear data (e.g. if the file has a gAMA chunk but the screen gamma
1329       * hasn't been specified.)  In any case this flag may get turned off in
1330       * the code immediately below if the transform can be handled outside the
1331       * row loop.
1332       */
1333      if (gamma_correction)
1334         png_ptr->transformations |= PNG_GAMMA;
1335
1336      else
1337         png_ptr->transformations &= ~PNG_GAMMA;
1338   }
1339#endif
1340
1341   /* Certain transformations have the effect of preventing other
1342    * transformations that happen afterward in png_do_read_transformations,
1343    * resolve the interdependencies here.  From the code of
1344    * png_do_read_transformations the order is:
1345    *
1346    *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
1347    *  2) PNG_STRIP_ALPHA (if no compose)
1348    *  3) PNG_RGB_TO_GRAY
1349    *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
1350    *  5) PNG_COMPOSE
1351    *  6) PNG_GAMMA
1352    *  7) PNG_STRIP_ALPHA (if compose)
1353    *  8) PNG_ENCODE_ALPHA
1354    *  9) PNG_SCALE_16_TO_8
1355    * 10) PNG_16_TO_8
1356    * 11) PNG_QUANTIZE (converts to palette)
1357    * 12) PNG_EXPAND_16
1358    * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
1359    * 14) PNG_INVERT_MONO
1360    * 15) PNG_SHIFT
1361    * 16) PNG_PACK
1362    * 17) PNG_BGR
1363    * 18) PNG_PACKSWAP
1364    * 19) PNG_FILLER (includes PNG_ADD_ALPHA)
1365    * 20) PNG_INVERT_ALPHA
1366    * 21) PNG_SWAP_ALPHA
1367    * 22) PNG_SWAP_BYTES
1368    * 23) PNG_USER_TRANSFORM [must be last]
1369    */
1370#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1371   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
1372      !(png_ptr->transformations & PNG_COMPOSE))
1373   {
1374      /* Stripping the alpha channel happens immediately after the 'expand'
1375       * transformations, before all other transformation, so it cancels out
1376       * the alpha handling.  It has the side effect negating the effect of
1377       * PNG_EXPAND_tRNS too:
1378       */
1379      png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
1380         PNG_EXPAND_tRNS);
1381      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1382
1383      /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
1384       * so transparency information would remain just so long as it wasn't
1385       * expanded.  This produces unexpected API changes if the set of things
1386       * that do PNG_EXPAND_tRNS changes (perfectly possible given the
1387       * documentation - which says ask for what you want, accept what you
1388       * get.)  This makes the behavior consistent from 1.5.4:
1389       */
1390      png_ptr->num_trans = 0;
1391   }
1392#endif /* STRIP_ALPHA supported, no COMPOSE */
1393
1394#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
1395   /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
1396    * settings will have no effect.
1397    */
1398   if (!png_gamma_significant(png_ptr->screen_gamma))
1399   {
1400      png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
1401      png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
1402   }
1403#endif
1404
1405#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1406   /* Make sure the coefficients for the rgb to gray conversion are set
1407    * appropriately.
1408    */
1409   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1410      png_colorspace_set_rgb_coefficients(png_ptr);
1411#endif
1412
1413#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1414#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
1415   /* Detect gray background and attempt to enable optimization for
1416    * gray --> RGB case.
1417    *
1418    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
1419    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
1420    * background color might actually be gray yet not be flagged as such.
1421    * This is not a problem for the current code, which uses
1422    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
1423    * png_do_gray_to_rgb() transformation.
1424    *
1425    * TODO: this code needs to be revised to avoid the complexity and
1426    * interdependencies.  The color type of the background should be recorded in
1427    * png_set_background, along with the bit depth, then the code has a record
1428    * of exactly what color space the background is currently in.
1429    */
1430   if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
1431   {
1432      /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
1433       * the file was grayscale the background value is gray.
1434       */
1435      if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
1436         png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1437   }
1438
1439   else if (png_ptr->transformations & PNG_COMPOSE)
1440   {
1441      /* PNG_COMPOSE: png_set_background was called with need_expand false,
1442       * so the color is in the color space of the output or png_set_alpha_mode
1443       * was called and the color is black.  Ignore RGB_TO_GRAY because that
1444       * happens before GRAY_TO_RGB.
1445       */
1446      if (png_ptr->transformations & PNG_GRAY_TO_RGB)
1447      {
1448         if (png_ptr->background.red == png_ptr->background.green &&
1449             png_ptr->background.red == png_ptr->background.blue)
1450         {
1451            png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
1452            png_ptr->background.gray = png_ptr->background.red;
1453         }
1454      }
1455   }
1456#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
1457#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
1458
1459   /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
1460    * can be performed directly on the palette, and some (such as rgb to gray)
1461    * can be optimized inside the palette.  This is particularly true of the
1462    * composite (background and alpha) stuff, which can be pretty much all done
1463    * in the palette even if the result is expanded to RGB or gray afterward.
1464    *
1465    * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
1466    * earlier and the palette stuff is actually handled on the first row.  This
1467    * leads to the reported bug that the palette returned by png_get_PLTE is not
1468    * updated.
1469    */
1470   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1471      png_init_palette_transformations(png_ptr);
1472
1473   else
1474      png_init_rgb_transformations(png_ptr);
1475
1476#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1477   defined(PNG_READ_EXPAND_16_SUPPORTED)
1478   if ((png_ptr->transformations & PNG_EXPAND_16) &&
1479      (png_ptr->transformations & PNG_COMPOSE) &&
1480      !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1481      png_ptr->bit_depth != 16)
1482   {
1483      /* TODO: fix this.  Because the expand_16 operation is after the compose
1484       * handling the background color must be 8, not 16, bits deep, but the
1485       * application will supply a 16-bit value so reduce it here.
1486       *
1487       * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
1488       * present, so that case is ok (until do_expand_16 is moved.)
1489       *
1490       * NOTE: this discards the low 16 bits of the user supplied background
1491       * color, but until expand_16 works properly there is no choice!
1492       */
1493#     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
1494      CHOP(png_ptr->background.red);
1495      CHOP(png_ptr->background.green);
1496      CHOP(png_ptr->background.blue);
1497      CHOP(png_ptr->background.gray);
1498#     undef CHOP
1499   }
1500#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */
1501
1502#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
1503   (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
1504   defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
1505   if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) &&
1506      (png_ptr->transformations & PNG_COMPOSE) &&
1507      !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
1508      png_ptr->bit_depth == 16)
1509   {
1510      /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
1511       * component this will also happen after PNG_COMPOSE and so the background
1512       * color must be pre-expanded here.
1513       *
1514       * TODO: fix this too.
1515       */
1516      png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
1517      png_ptr->background.green =
1518         (png_uint_16)(png_ptr->background.green * 257);
1519      png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
1520      png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
1521   }
1522#endif
1523
1524   /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
1525    * background support (see the comments in scripts/pnglibconf.dfa), this
1526    * allows pre-multiplication of the alpha channel to be implemented as
1527    * compositing on black.  This is probably sub-optimal and has been done in
1528    * 1.5.4 betas simply to enable external critique and testing (i.e. to
1529    * implement the new API quickly, without lots of internal changes.)
1530    */
1531
1532#ifdef PNG_READ_GAMMA_SUPPORTED
1533#  ifdef PNG_READ_BACKGROUND_SUPPORTED
1534      /* Includes ALPHA_MODE */
1535      png_ptr->background_1 = png_ptr->background;
1536#  endif
1537
1538   /* This needs to change - in the palette image case a whole set of tables are
1539    * built when it would be quicker to just calculate the correct value for
1540    * each palette entry directly.  Also, the test is too tricky - why check
1541    * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
1542    * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
1543    * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
1544    * the gamma tables will not be built even if composition is required on a
1545    * gamma encoded value.
1546    *
1547    * In 1.5.4 this is addressed below by an additional check on the individual
1548    * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
1549    * tables.
1550    */
1551   if ((png_ptr->transformations & PNG_GAMMA)
1552      || ((png_ptr->transformations & PNG_RGB_TO_GRAY)
1553         && (png_gamma_significant(png_ptr->colorspace.gamma) ||
1554            png_gamma_significant(png_ptr->screen_gamma)))
1555      || ((png_ptr->transformations & PNG_COMPOSE)
1556         && (png_gamma_significant(png_ptr->colorspace.gamma)
1557            || png_gamma_significant(png_ptr->screen_gamma)
1558#  ifdef PNG_READ_BACKGROUND_SUPPORTED
1559            || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE
1560               && png_gamma_significant(png_ptr->background_gamma))
1561#  endif
1562      )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA)
1563         && png_gamma_significant(png_ptr->screen_gamma))
1564      )
1565   {
1566      png_build_gamma_table(png_ptr, png_ptr->bit_depth);
1567
1568#ifdef PNG_READ_BACKGROUND_SUPPORTED
1569      if (png_ptr->transformations & PNG_COMPOSE)
1570      {
1571         /* Issue a warning about this combination: because RGB_TO_GRAY is
1572          * optimized to do the gamma transform if present yet do_background has
1573          * to do the same thing if both options are set a
1574          * double-gamma-correction happens.  This is true in all versions of
1575          * libpng to date.
1576          */
1577         if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1578            png_warning(png_ptr,
1579               "libpng does not support gamma+background+rgb_to_gray");
1580
1581         if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1582         {
1583            /* We don't get to here unless there is a tRNS chunk with non-opaque
1584             * entries - see the checking code at the start of this function.
1585             */
1586            png_color back, back_1;
1587            png_colorp palette = png_ptr->palette;
1588            int num_palette = png_ptr->num_palette;
1589            int i;
1590            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
1591            {
1592
1593               back.red = png_ptr->gamma_table[png_ptr->background.red];
1594               back.green = png_ptr->gamma_table[png_ptr->background.green];
1595               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
1596
1597               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
1598               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
1599               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
1600            }
1601            else
1602            {
1603               png_fixed_point g, gs;
1604
1605               switch (png_ptr->background_gamma_type)
1606               {
1607                  case PNG_BACKGROUND_GAMMA_SCREEN:
1608                     g = (png_ptr->screen_gamma);
1609                     gs = PNG_FP_1;
1610                     break;
1611
1612                  case PNG_BACKGROUND_GAMMA_FILE:
1613                     g = png_reciprocal(png_ptr->colorspace.gamma);
1614                     gs = png_reciprocal2(png_ptr->colorspace.gamma,
1615                        png_ptr->screen_gamma);
1616                     break;
1617
1618                  case PNG_BACKGROUND_GAMMA_UNIQUE:
1619                     g = png_reciprocal(png_ptr->background_gamma);
1620                     gs = png_reciprocal2(png_ptr->background_gamma,
1621                        png_ptr->screen_gamma);
1622                     break;
1623                  default:
1624                     g = PNG_FP_1;    /* back_1 */
1625                     gs = PNG_FP_1;   /* back */
1626                     break;
1627               }
1628
1629               if (png_gamma_significant(gs))
1630               {
1631                  back.red = png_gamma_8bit_correct(png_ptr->background.red,
1632                      gs);
1633                  back.green = png_gamma_8bit_correct(png_ptr->background.green,
1634                      gs);
1635                  back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1636                      gs);
1637               }
1638
1639               else
1640               {
1641                  back.red   = (png_byte)png_ptr->background.red;
1642                  back.green = (png_byte)png_ptr->background.green;
1643                  back.blue  = (png_byte)png_ptr->background.blue;
1644               }
1645
1646               if (png_gamma_significant(g))
1647               {
1648                  back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
1649                     g);
1650                  back_1.green = png_gamma_8bit_correct(
1651                     png_ptr->background.green, g);
1652                  back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
1653                     g);
1654               }
1655
1656               else
1657               {
1658                  back_1.red   = (png_byte)png_ptr->background.red;
1659                  back_1.green = (png_byte)png_ptr->background.green;
1660                  back_1.blue  = (png_byte)png_ptr->background.blue;
1661               }
1662            }
1663
1664            for (i = 0; i < num_palette; i++)
1665            {
1666               if (i < (int)png_ptr->num_trans &&
1667                   png_ptr->trans_alpha[i] != 0xff)
1668               {
1669                  if (png_ptr->trans_alpha[i] == 0)
1670                  {
1671                     palette[i] = back;
1672                  }
1673                  else /* if (png_ptr->trans_alpha[i] != 0xff) */
1674                  {
1675                     png_byte v, w;
1676
1677                     v = png_ptr->gamma_to_1[palette[i].red];
1678                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
1679                     palette[i].red = png_ptr->gamma_from_1[w];
1680
1681                     v = png_ptr->gamma_to_1[palette[i].green];
1682                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
1683                     palette[i].green = png_ptr->gamma_from_1[w];
1684
1685                     v = png_ptr->gamma_to_1[palette[i].blue];
1686                     png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
1687                     palette[i].blue = png_ptr->gamma_from_1[w];
1688                  }
1689               }
1690               else
1691               {
1692                  palette[i].red = png_ptr->gamma_table[palette[i].red];
1693                  palette[i].green = png_ptr->gamma_table[palette[i].green];
1694                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1695               }
1696            }
1697
1698            /* Prevent the transformations being done again.
1699             *
1700             * NOTE: this is highly dubious; it removes the transformations in
1701             * place.  This seems inconsistent with the general treatment of the
1702             * transformations elsewhere.
1703             */
1704            png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
1705         } /* color_type == PNG_COLOR_TYPE_PALETTE */
1706
1707         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
1708         else /* color_type != PNG_COLOR_TYPE_PALETTE */
1709         {
1710            int gs_sig, g_sig;
1711            png_fixed_point g = PNG_FP_1;  /* Correction to linear */
1712            png_fixed_point gs = PNG_FP_1; /* Correction to screen */
1713
1714            switch (png_ptr->background_gamma_type)
1715            {
1716               case PNG_BACKGROUND_GAMMA_SCREEN:
1717                  g = png_ptr->screen_gamma;
1718                  /* gs = PNG_FP_1; */
1719                  break;
1720
1721               case PNG_BACKGROUND_GAMMA_FILE:
1722                  g = png_reciprocal(png_ptr->colorspace.gamma);
1723                  gs = png_reciprocal2(png_ptr->colorspace.gamma,
1724                     png_ptr->screen_gamma);
1725                  break;
1726
1727               case PNG_BACKGROUND_GAMMA_UNIQUE:
1728                  g = png_reciprocal(png_ptr->background_gamma);
1729                  gs = png_reciprocal2(png_ptr->background_gamma,
1730                      png_ptr->screen_gamma);
1731                  break;
1732
1733               default:
1734                  png_error(png_ptr, "invalid background gamma type");
1735            }
1736
1737            g_sig = png_gamma_significant(g);
1738            gs_sig = png_gamma_significant(gs);
1739
1740            if (g_sig)
1741               png_ptr->background_1.gray = png_gamma_correct(png_ptr,
1742                   png_ptr->background.gray, g);
1743
1744            if (gs_sig)
1745               png_ptr->background.gray = png_gamma_correct(png_ptr,
1746                   png_ptr->background.gray, gs);
1747
1748            if ((png_ptr->background.red != png_ptr->background.green) ||
1749                (png_ptr->background.red != png_ptr->background.blue) ||
1750                (png_ptr->background.red != png_ptr->background.gray))
1751            {
1752               /* RGB or RGBA with color background */
1753               if (g_sig)
1754               {
1755                  png_ptr->background_1.red = png_gamma_correct(png_ptr,
1756                      png_ptr->background.red, g);
1757
1758                  png_ptr->background_1.green = png_gamma_correct(png_ptr,
1759                      png_ptr->background.green, g);
1760
1761                  png_ptr->background_1.blue = png_gamma_correct(png_ptr,
1762                      png_ptr->background.blue, g);
1763               }
1764
1765               if (gs_sig)
1766               {
1767                  png_ptr->background.red = png_gamma_correct(png_ptr,
1768                      png_ptr->background.red, gs);
1769
1770                  png_ptr->background.green = png_gamma_correct(png_ptr,
1771                      png_ptr->background.green, gs);
1772
1773                  png_ptr->background.blue = png_gamma_correct(png_ptr,
1774                      png_ptr->background.blue, gs);
1775               }
1776            }
1777
1778            else
1779            {
1780               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1781               png_ptr->background_1.red = png_ptr->background_1.green
1782                   = png_ptr->background_1.blue = png_ptr->background_1.gray;
1783
1784               png_ptr->background.red = png_ptr->background.green
1785                   = png_ptr->background.blue = png_ptr->background.gray;
1786            }
1787
1788            /* The background is now in screen gamma: */
1789            png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
1790         } /* color_type != PNG_COLOR_TYPE_PALETTE */
1791      }/* png_ptr->transformations & PNG_BACKGROUND */
1792
1793      else
1794      /* Transformation does not include PNG_BACKGROUND */
1795#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1796      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
1797#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1798         /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
1799         && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
1800         (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
1801#endif
1802         )
1803      {
1804         png_colorp palette = png_ptr->palette;
1805         int num_palette = png_ptr->num_palette;
1806         int i;
1807
1808         /* NOTE: there are other transformations that should probably be in
1809          * here too.
1810          */
1811         for (i = 0; i < num_palette; i++)
1812         {
1813            palette[i].red = png_ptr->gamma_table[palette[i].red];
1814            palette[i].green = png_ptr->gamma_table[palette[i].green];
1815            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1816         }
1817
1818         /* Done the gamma correction. */
1819         png_ptr->transformations &= ~PNG_GAMMA;
1820      } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
1821   }
1822#ifdef PNG_READ_BACKGROUND_SUPPORTED
1823   else
1824#endif
1825#endif /* PNG_READ_GAMMA_SUPPORTED */
1826
1827#ifdef PNG_READ_BACKGROUND_SUPPORTED
1828   /* No GAMMA transformation (see the hanging else 4 lines above) */
1829   if ((png_ptr->transformations & PNG_COMPOSE) &&
1830       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1831   {
1832      int i;
1833      int istop = (int)png_ptr->num_trans;
1834      png_color back;
1835      png_colorp palette = png_ptr->palette;
1836
1837      back.red   = (png_byte)png_ptr->background.red;
1838      back.green = (png_byte)png_ptr->background.green;
1839      back.blue  = (png_byte)png_ptr->background.blue;
1840
1841      for (i = 0; i < istop; i++)
1842      {
1843         if (png_ptr->trans_alpha[i] == 0)
1844         {
1845            palette[i] = back;
1846         }
1847
1848         else if (png_ptr->trans_alpha[i] != 0xff)
1849         {
1850            /* The png_composite() macro is defined in png.h */
1851            png_composite(palette[i].red, palette[i].red,
1852                png_ptr->trans_alpha[i], back.red);
1853
1854            png_composite(palette[i].green, palette[i].green,
1855                png_ptr->trans_alpha[i], back.green);
1856
1857            png_composite(palette[i].blue, palette[i].blue,
1858                png_ptr->trans_alpha[i], back.blue);
1859         }
1860      }
1861
1862      png_ptr->transformations &= ~PNG_COMPOSE;
1863   }
1864#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1865
1866#ifdef PNG_READ_SHIFT_SUPPORTED
1867   if ((png_ptr->transformations & PNG_SHIFT) &&
1868      !(png_ptr->transformations & PNG_EXPAND) &&
1869       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
1870   {
1871      int i;
1872      int istop = png_ptr->num_palette;
1873      int shift = 8 - png_ptr->sig_bit.red;
1874
1875      png_ptr->transformations &= ~PNG_SHIFT;
1876
1877      /* significant bits can be in the range 1 to 7 for a meaninful result, if
1878       * the number of significant bits is 0 then no shift is done (this is an
1879       * error condition which is silently ignored.)
1880       */
1881      if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
1882      {
1883         int component = png_ptr->palette[i].red;
1884
1885         component >>= shift;
1886         png_ptr->palette[i].red = (png_byte)component;
1887      }
1888
1889      shift = 8 - png_ptr->sig_bit.green;
1890      if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
1891      {
1892         int component = png_ptr->palette[i].green;
1893
1894         component >>= shift;
1895         png_ptr->palette[i].green = (png_byte)component;
1896      }
1897
1898      shift = 8 - png_ptr->sig_bit.blue;
1899      if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
1900      {
1901         int component = png_ptr->palette[i].blue;
1902
1903         component >>= shift;
1904         png_ptr->palette[i].blue = (png_byte)component;
1905      }
1906   }
1907#endif  /* PNG_READ_SHIFT_SUPPORTED */
1908}
1909
1910/* Modify the info structure to reflect the transformations.  The
1911 * info should be updated so a PNG file could be written with it,
1912 * assuming the transformations result in valid PNG data.
1913 */
1914void /* PRIVATE */
1915png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
1916{
1917   png_debug(1, "in png_read_transform_info");
1918
1919#ifdef PNG_READ_EXPAND_SUPPORTED
1920   if (png_ptr->transformations & PNG_EXPAND)
1921   {
1922      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1923      {
1924         /* This check must match what actually happens in
1925          * png_do_expand_palette; if it ever checks the tRNS chunk to see if
1926          * it is all opaque we must do the same (at present it does not.)
1927          */
1928         if (png_ptr->num_trans > 0)
1929            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1930
1931         else
1932            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1933
1934         info_ptr->bit_depth = 8;
1935         info_ptr->num_trans = 0;
1936      }
1937      else
1938      {
1939         if (png_ptr->num_trans)
1940         {
1941            if (png_ptr->transformations & PNG_EXPAND_tRNS)
1942               info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1943         }
1944         if (info_ptr->bit_depth < 8)
1945            info_ptr->bit_depth = 8;
1946
1947         info_ptr->num_trans = 0;
1948      }
1949   }
1950#endif
1951
1952#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
1953   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
1954   /* The following is almost certainly wrong unless the background value is in
1955    * the screen space!
1956    */
1957   if (png_ptr->transformations & PNG_COMPOSE)
1958      info_ptr->background = png_ptr->background;
1959#endif
1960
1961#ifdef PNG_READ_GAMMA_SUPPORTED
1962   /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
1963    * however it seems that the code in png_init_read_transformations, which has
1964    * been called before this from png_read_update_info->png_read_start_row
1965    * sometimes does the gamma transform and cancels the flag.
1966    *
1967    * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
1968    * the screen_gamma value.  The following probably results in weirdness if
1969    * the info_ptr is used by the app after the rows have been read.
1970    */
1971   info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
1972#endif
1973
1974   if (info_ptr->bit_depth == 16)
1975   {
1976#  ifdef PNG_READ_16BIT_SUPPORTED
1977#     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1978         if (png_ptr->transformations & PNG_SCALE_16_TO_8)
1979            info_ptr->bit_depth = 8;
1980#     endif
1981
1982#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1983         if (png_ptr->transformations & PNG_16_TO_8)
1984            info_ptr->bit_depth = 8;
1985#     endif
1986
1987#  else
1988      /* No 16 bit support: force chopping 16-bit input down to 8, in this case
1989       * the app program can chose if both APIs are available by setting the
1990       * correct scaling to use.
1991       */
1992#     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1993         /* For compatibility with previous versions use the strip method by
1994          * default.  This code works because if PNG_SCALE_16_TO_8 is already
1995          * set the code below will do that in preference to the chop.
1996          */
1997         png_ptr->transformations |= PNG_16_TO_8;
1998         info_ptr->bit_depth = 8;
1999#     else
2000
2001#        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2002            png_ptr->transformations |= PNG_SCALE_16_TO_8;
2003            info_ptr->bit_depth = 8;
2004#        else
2005
2006            CONFIGURATION ERROR: you must enable at least one 16 to 8 method
2007#        endif
2008#    endif
2009#endif /* !READ_16BIT_SUPPORTED */
2010   }
2011
2012#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2013   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
2014      info_ptr->color_type = (png_byte)(info_ptr->color_type |
2015         PNG_COLOR_MASK_COLOR);
2016#endif
2017
2018#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2019   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
2020      info_ptr->color_type = (png_byte)(info_ptr->color_type &
2021         ~PNG_COLOR_MASK_COLOR);
2022#endif
2023
2024#ifdef PNG_READ_QUANTIZE_SUPPORTED
2025   if (png_ptr->transformations & PNG_QUANTIZE)
2026   {
2027      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
2028          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
2029          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
2030      {
2031         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
2032      }
2033   }
2034#endif
2035
2036#ifdef PNG_READ_EXPAND_16_SUPPORTED
2037   if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 &&
2038      info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
2039   {
2040      info_ptr->bit_depth = 16;
2041   }
2042#endif
2043
2044#ifdef PNG_READ_PACK_SUPPORTED
2045   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
2046      info_ptr->bit_depth = 8;
2047#endif
2048
2049   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2050      info_ptr->channels = 1;
2051
2052   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
2053      info_ptr->channels = 3;
2054
2055   else
2056      info_ptr->channels = 1;
2057
2058#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
2059   if (png_ptr->transformations & PNG_STRIP_ALPHA)
2060   {
2061      info_ptr->color_type = (png_byte)(info_ptr->color_type &
2062         ~PNG_COLOR_MASK_ALPHA);
2063      info_ptr->num_trans = 0;
2064   }
2065#endif
2066
2067   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
2068      info_ptr->channels++;
2069
2070#ifdef PNG_READ_FILLER_SUPPORTED
2071   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
2072   if ((png_ptr->transformations & PNG_FILLER) &&
2073       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
2074       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
2075   {
2076      info_ptr->channels++;
2077      /* If adding a true alpha channel not just filler */
2078      if (png_ptr->transformations & PNG_ADD_ALPHA)
2079         info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
2080   }
2081#endif
2082
2083#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
2084defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
2085   if (png_ptr->transformations & PNG_USER_TRANSFORM)
2086   {
2087      if (info_ptr->bit_depth < png_ptr->user_transform_depth)
2088         info_ptr->bit_depth = png_ptr->user_transform_depth;
2089
2090      if (info_ptr->channels < png_ptr->user_transform_channels)
2091         info_ptr->channels = png_ptr->user_transform_channels;
2092   }
2093#endif
2094
2095   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
2096       info_ptr->bit_depth);
2097
2098   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
2099
2100   /* Adding in 1.5.4: cache the above value in png_struct so that we can later
2101    * check in png_rowbytes that the user buffer won't get overwritten.  Note
2102    * that the field is not always set - if png_read_update_info isn't called
2103    * the application has to either not do any transforms or get the calculation
2104    * right itself.
2105    */
2106   png_ptr->info_rowbytes = info_ptr->rowbytes;
2107
2108#ifndef PNG_READ_EXPAND_SUPPORTED
2109   if (png_ptr)
2110      return;
2111#endif
2112}
2113
2114/* Transform the row.  The order of transformations is significant,
2115 * and is very touchy.  If you add a transformation, take care to
2116 * decide how it fits in with the other transformations here.
2117 */
2118void /* PRIVATE */
2119png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
2120{
2121   png_debug(1, "in png_do_read_transformations");
2122
2123   if (png_ptr->row_buf == NULL)
2124   {
2125      /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
2126       * error is incredibly rare and incredibly easy to debug without this
2127       * information.
2128       */
2129      png_error(png_ptr, "NULL row buffer");
2130   }
2131
2132   /* The following is debugging; prior to 1.5.4 the code was never compiled in;
2133    * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
2134    * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
2135    * all transformations, however in practice the ROW_INIT always gets done on
2136    * demand, if necessary.
2137    */
2138   if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
2139      !(png_ptr->flags & PNG_FLAG_ROW_INIT))
2140   {
2141      /* Application has failed to call either png_read_start_image() or
2142       * png_read_update_info() after setting transforms that expand pixels.
2143       * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
2144       */
2145      png_error(png_ptr, "Uninitialized row");
2146   }
2147
2148#ifdef PNG_READ_EXPAND_SUPPORTED
2149   if (png_ptr->transformations & PNG_EXPAND)
2150   {
2151      if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
2152      {
2153         png_do_expand_palette(row_info, png_ptr->row_buf + 1,
2154             png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
2155      }
2156
2157      else
2158      {
2159         if (png_ptr->num_trans &&
2160             (png_ptr->transformations & PNG_EXPAND_tRNS))
2161            png_do_expand(row_info, png_ptr->row_buf + 1,
2162                &(png_ptr->trans_color));
2163
2164         else
2165            png_do_expand(row_info, png_ptr->row_buf + 1,
2166                NULL);
2167      }
2168   }
2169#endif
2170
2171#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
2172   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
2173      !(png_ptr->transformations & PNG_COMPOSE) &&
2174      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2175      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2176      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
2177         0 /* at_start == false, because SWAP_ALPHA happens later */);
2178#endif
2179
2180#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2181   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
2182   {
2183      int rgb_error =
2184          png_do_rgb_to_gray(png_ptr, row_info,
2185              png_ptr->row_buf + 1);
2186
2187      if (rgb_error)
2188      {
2189         png_ptr->rgb_to_gray_status=1;
2190         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
2191             PNG_RGB_TO_GRAY_WARN)
2192            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
2193
2194         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
2195             PNG_RGB_TO_GRAY_ERR)
2196            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
2197      }
2198   }
2199#endif
2200
2201/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
2202 *
2203 *   In most cases, the "simple transparency" should be done prior to doing
2204 *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
2205 *   pixel is transparent.  You would also need to make sure that the
2206 *   transparency information is upgraded to RGB.
2207 *
2208 *   To summarize, the current flow is:
2209 *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
2210 *                                   with background "in place" if transparent,
2211 *                                   convert to RGB if necessary
2212 *   - Gray + alpha -> composite with gray background and remove alpha bytes,
2213 *                                   convert to RGB if necessary
2214 *
2215 *   To support RGB backgrounds for gray images we need:
2216 *   - Gray + simple transparency -> convert to RGB + simple transparency,
2217 *                                   compare 3 or 6 bytes and composite with
2218 *                                   background "in place" if transparent
2219 *                                   (3x compare/pixel compared to doing
2220 *                                   composite with gray bkgrnd)
2221 *   - Gray + alpha -> convert to RGB + alpha, composite with background and
2222 *                                   remove alpha bytes (3x float
2223 *                                   operations/pixel compared with composite
2224 *                                   on gray background)
2225 *
2226 *  Greg's change will do this.  The reason it wasn't done before is for
2227 *  performance, as this increases the per-pixel operations.  If we would check
2228 *  in advance if the background was gray or RGB, and position the gray-to-RGB
2229 *  transform appropriately, then it would save a lot of work/time.
2230 */
2231
2232#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2233   /* If gray -> RGB, do so now only if background is non-gray; else do later
2234    * for performance reasons
2235    */
2236   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
2237       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
2238      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
2239#endif
2240
2241#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
2242   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
2243   if (png_ptr->transformations & PNG_COMPOSE)
2244      png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
2245#endif
2246
2247#ifdef PNG_READ_GAMMA_SUPPORTED
2248   if ((png_ptr->transformations & PNG_GAMMA) &&
2249#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2250      /* Because RGB_TO_GRAY does the gamma transform. */
2251      !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&
2252#endif
2253#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
2254   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
2255      /* Because PNG_COMPOSE does the gamma transform if there is something to
2256       * do (if there is an alpha channel or transparency.)
2257       */
2258       !((png_ptr->transformations & PNG_COMPOSE) &&
2259       ((png_ptr->num_trans != 0) ||
2260       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
2261#endif
2262      /* Because png_init_read_transformations transforms the palette, unless
2263       * RGB_TO_GRAY will do the transform.
2264       */
2265       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
2266      png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
2267#endif
2268
2269#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
2270   if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
2271      (png_ptr->transformations & PNG_COMPOSE) &&
2272      (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2273      row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2274      png_do_strip_channel(row_info, png_ptr->row_buf + 1,
2275         0 /* at_start == false, because SWAP_ALPHA happens later */);
2276#endif
2277
2278#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
2279   if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
2280      (row_info->color_type & PNG_COLOR_MASK_ALPHA))
2281      png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
2282#endif
2283
2284#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2285   if (png_ptr->transformations & PNG_SCALE_16_TO_8)
2286      png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
2287#endif
2288
2289#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2290   /* There is no harm in doing both of these because only one has any effect,
2291    * by putting the 'scale' option first if the app asks for scale (either by
2292    * calling the API or in a TRANSFORM flag) this is what happens.
2293    */
2294   if (png_ptr->transformations & PNG_16_TO_8)
2295      png_do_chop(row_info, png_ptr->row_buf + 1);
2296#endif
2297
2298#ifdef PNG_READ_QUANTIZE_SUPPORTED
2299   if (png_ptr->transformations & PNG_QUANTIZE)
2300   {
2301      png_do_quantize(row_info, png_ptr->row_buf + 1,
2302          png_ptr->palette_lookup, png_ptr->quantize_index);
2303
2304      if (row_info->rowbytes == 0)
2305         png_error(png_ptr, "png_do_quantize returned rowbytes=0");
2306   }
2307#endif /* PNG_READ_QUANTIZE_SUPPORTED */
2308
2309#ifdef PNG_READ_EXPAND_16_SUPPORTED
2310   /* Do the expansion now, after all the arithmetic has been done.  Notice
2311    * that previous transformations can handle the PNG_EXPAND_16 flag if this
2312    * is efficient (particularly true in the case of gamma correction, where
2313    * better accuracy results faster!)
2314    */
2315   if (png_ptr->transformations & PNG_EXPAND_16)
2316      png_do_expand_16(row_info, png_ptr->row_buf + 1);
2317#endif
2318
2319#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2320   /* NOTE: moved here in 1.5.4 (from much later in this list.) */
2321   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
2322       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
2323      png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
2324#endif
2325
2326#ifdef PNG_READ_INVERT_SUPPORTED
2327   if (png_ptr->transformations & PNG_INVERT_MONO)
2328      png_do_invert(row_info, png_ptr->row_buf + 1);
2329#endif
2330
2331#ifdef PNG_READ_SHIFT_SUPPORTED
2332   if (png_ptr->transformations & PNG_SHIFT)
2333      png_do_unshift(row_info, png_ptr->row_buf + 1,
2334          &(png_ptr->shift));
2335#endif
2336
2337#ifdef PNG_READ_PACK_SUPPORTED
2338   if (png_ptr->transformations & PNG_PACK)
2339      png_do_unpack(row_info, png_ptr->row_buf + 1);
2340#endif
2341
2342#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
2343   /* Added at libpng-1.5.10 */
2344   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
2345       png_ptr->num_palette_max >= 0)
2346      png_do_check_palette_indexes(png_ptr, row_info);
2347#endif
2348
2349#ifdef PNG_READ_BGR_SUPPORTED
2350   if (png_ptr->transformations & PNG_BGR)
2351      png_do_bgr(row_info, png_ptr->row_buf + 1);
2352#endif
2353
2354#ifdef PNG_READ_PACKSWAP_SUPPORTED
2355   if (png_ptr->transformations & PNG_PACKSWAP)
2356      png_do_packswap(row_info, png_ptr->row_buf + 1);
2357#endif
2358
2359#ifdef PNG_READ_FILLER_SUPPORTED
2360   if (png_ptr->transformations & PNG_FILLER)
2361      png_do_read_filler(row_info, png_ptr->row_buf + 1,
2362          (png_uint_32)png_ptr->filler, png_ptr->flags);
2363#endif
2364
2365#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
2366   if (png_ptr->transformations & PNG_INVERT_ALPHA)
2367      png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
2368#endif
2369
2370#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
2371   if (png_ptr->transformations & PNG_SWAP_ALPHA)
2372      png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
2373#endif
2374
2375#ifdef PNG_READ_16BIT_SUPPORTED
2376#ifdef PNG_READ_SWAP_SUPPORTED
2377   if (png_ptr->transformations & PNG_SWAP_BYTES)
2378      png_do_swap(row_info, png_ptr->row_buf + 1);
2379#endif
2380#endif
2381
2382#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
2383   if (png_ptr->transformations & PNG_USER_TRANSFORM)
2384    {
2385      if (png_ptr->read_user_transform_fn != NULL)
2386         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
2387             (png_ptr,     /* png_ptr */
2388             row_info,     /* row_info: */
2389                /*  png_uint_32 width;       width of row */
2390                /*  png_size_t rowbytes;     number of bytes in row */
2391                /*  png_byte color_type;     color type of pixels */
2392                /*  png_byte bit_depth;      bit depth of samples */
2393                /*  png_byte channels;       number of channels (1-4) */
2394                /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
2395             png_ptr->row_buf + 1);    /* start of pixel data for row */
2396#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
2397      if (png_ptr->user_transform_depth)
2398         row_info->bit_depth = png_ptr->user_transform_depth;
2399
2400      if (png_ptr->user_transform_channels)
2401         row_info->channels = png_ptr->user_transform_channels;
2402#endif
2403      row_info->pixel_depth = (png_byte)(row_info->bit_depth *
2404          row_info->channels);
2405
2406      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
2407   }
2408#endif
2409}
2410
2411#ifdef PNG_READ_PACK_SUPPORTED
2412/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
2413 * without changing the actual values.  Thus, if you had a row with
2414 * a bit depth of 1, you would end up with bytes that only contained
2415 * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
2416 * png_do_shift() after this.
2417 */
2418void /* PRIVATE */
2419png_do_unpack(png_row_infop row_info, png_bytep row)
2420{
2421   png_debug(1, "in png_do_unpack");
2422
2423   if (row_info->bit_depth < 8)
2424   {
2425      png_uint_32 i;
2426      png_uint_32 row_width=row_info->width;
2427
2428      switch (row_info->bit_depth)
2429      {
2430         case 1:
2431         {
2432            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
2433            png_bytep dp = row + (png_size_t)row_width - 1;
2434            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
2435            for (i = 0; i < row_width; i++)
2436            {
2437               *dp = (png_byte)((*sp >> shift) & 0x01);
2438
2439               if (shift == 7)
2440               {
2441                  shift = 0;
2442                  sp--;
2443               }
2444
2445               else
2446                  shift++;
2447
2448               dp--;
2449            }
2450            break;
2451         }
2452
2453         case 2:
2454         {
2455
2456            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
2457            png_bytep dp = row + (png_size_t)row_width - 1;
2458            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
2459            for (i = 0; i < row_width; i++)
2460            {
2461               *dp = (png_byte)((*sp >> shift) & 0x03);
2462
2463               if (shift == 6)
2464               {
2465                  shift = 0;
2466                  sp--;
2467               }
2468
2469               else
2470                  shift += 2;
2471
2472               dp--;
2473            }
2474            break;
2475         }
2476
2477         case 4:
2478         {
2479            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
2480            png_bytep dp = row + (png_size_t)row_width - 1;
2481            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
2482            for (i = 0; i < row_width; i++)
2483            {
2484               *dp = (png_byte)((*sp >> shift) & 0x0f);
2485
2486               if (shift == 4)
2487               {
2488                  shift = 0;
2489                  sp--;
2490               }
2491
2492               else
2493                  shift = 4;
2494
2495               dp--;
2496            }
2497            break;
2498         }
2499
2500         default:
2501            break;
2502      }
2503      row_info->bit_depth = 8;
2504      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2505      row_info->rowbytes = row_width * row_info->channels;
2506   }
2507}
2508#endif
2509
2510#ifdef PNG_READ_SHIFT_SUPPORTED
2511/* Reverse the effects of png_do_shift.  This routine merely shifts the
2512 * pixels back to their significant bits values.  Thus, if you have
2513 * a row of bit depth 8, but only 5 are significant, this will shift
2514 * the values back to 0 through 31.
2515 */
2516void /* PRIVATE */
2517png_do_unshift(png_row_infop row_info, png_bytep row,
2518    png_const_color_8p sig_bits)
2519{
2520   int color_type;
2521
2522   png_debug(1, "in png_do_unshift");
2523
2524   /* The palette case has already been handled in the _init routine. */
2525   color_type = row_info->color_type;
2526
2527   if (color_type != PNG_COLOR_TYPE_PALETTE)
2528   {
2529      int shift[4];
2530      int channels = 0;
2531      int bit_depth = row_info->bit_depth;
2532
2533      if (color_type & PNG_COLOR_MASK_COLOR)
2534      {
2535         shift[channels++] = bit_depth - sig_bits->red;
2536         shift[channels++] = bit_depth - sig_bits->green;
2537         shift[channels++] = bit_depth - sig_bits->blue;
2538      }
2539
2540      else
2541      {
2542         shift[channels++] = bit_depth - sig_bits->gray;
2543      }
2544
2545      if (color_type & PNG_COLOR_MASK_ALPHA)
2546      {
2547         shift[channels++] = bit_depth - sig_bits->alpha;
2548      }
2549
2550      {
2551         int c, have_shift;
2552
2553         for (c = have_shift = 0; c < channels; ++c)
2554         {
2555            /* A shift of more than the bit depth is an error condition but it
2556             * gets ignored here.
2557             */
2558            if (shift[c] <= 0 || shift[c] >= bit_depth)
2559               shift[c] = 0;
2560
2561            else
2562               have_shift = 1;
2563         }
2564
2565         if (!have_shift)
2566            return;
2567      }
2568
2569      switch (bit_depth)
2570      {
2571         default:
2572         /* Must be 1bpp gray: should not be here! */
2573            /* NOTREACHED */
2574            break;
2575
2576         case 2:
2577         /* Must be 2bpp gray */
2578         /* assert(channels == 1 && shift[0] == 1) */
2579         {
2580            png_bytep bp = row;
2581            png_bytep bp_end = bp + row_info->rowbytes;
2582
2583            while (bp < bp_end)
2584            {
2585               int b = (*bp >> 1) & 0x55;
2586               *bp++ = (png_byte)b;
2587            }
2588            break;
2589         }
2590
2591         case 4:
2592         /* Must be 4bpp gray */
2593         /* assert(channels == 1) */
2594         {
2595            png_bytep bp = row;
2596            png_bytep bp_end = bp + row_info->rowbytes;
2597            int gray_shift = shift[0];
2598            int mask =  0xf >> gray_shift;
2599
2600            mask |= mask << 4;
2601
2602            while (bp < bp_end)
2603            {
2604               int b = (*bp >> gray_shift) & mask;
2605               *bp++ = (png_byte)b;
2606            }
2607            break;
2608         }
2609
2610         case 8:
2611         /* Single byte components, G, GA, RGB, RGBA */
2612         {
2613            png_bytep bp = row;
2614            png_bytep bp_end = bp + row_info->rowbytes;
2615            int channel = 0;
2616
2617            while (bp < bp_end)
2618            {
2619               int b = *bp >> shift[channel];
2620               if (++channel >= channels)
2621                  channel = 0;
2622               *bp++ = (png_byte)b;
2623            }
2624            break;
2625         }
2626
2627#ifdef PNG_READ_16BIT_SUPPORTED
2628         case 16:
2629         /* Double byte components, G, GA, RGB, RGBA */
2630         {
2631            png_bytep bp = row;
2632            png_bytep bp_end = bp + row_info->rowbytes;
2633            int channel = 0;
2634
2635            while (bp < bp_end)
2636            {
2637               int value = (bp[0] << 8) + bp[1];
2638
2639               value >>= shift[channel];
2640               if (++channel >= channels)
2641                  channel = 0;
2642               *bp++ = (png_byte)(value >> 8);
2643               *bp++ = (png_byte)(value & 0xff);
2644            }
2645            break;
2646         }
2647#endif
2648      }
2649   }
2650}
2651#endif
2652
2653#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
2654/* Scale rows of bit depth 16 down to 8 accurately */
2655void /* PRIVATE */
2656png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
2657{
2658   png_debug(1, "in png_do_scale_16_to_8");
2659
2660   if (row_info->bit_depth == 16)
2661   {
2662      png_bytep sp = row; /* source */
2663      png_bytep dp = row; /* destination */
2664      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2665
2666      while (sp < ep)
2667      {
2668         /* The input is an array of 16 bit components, these must be scaled to
2669          * 8 bits each.  For a 16 bit value V the required value (from the PNG
2670          * specification) is:
2671          *
2672          *    (V * 255) / 65535
2673          *
2674          * This reduces to round(V / 257), or floor((V + 128.5)/257)
2675          *
2676          * Represent V as the two byte value vhi.vlo.  Make a guess that the
2677          * result is the top byte of V, vhi, then the correction to this value
2678          * is:
2679          *
2680          *    error = floor(((V-vhi.vhi) + 128.5) / 257)
2681          *          = floor(((vlo-vhi) + 128.5) / 257)
2682          *
2683          * This can be approximated using integer arithmetic (and a signed
2684          * shift):
2685          *
2686          *    error = (vlo-vhi+128) >> 8;
2687          *
2688          * The approximate differs from the exact answer only when (vlo-vhi) is
2689          * 128; it then gives a correction of +1 when the exact correction is
2690          * 0.  This gives 128 errors.  The exact answer (correct for all 16 bit
2691          * input values) is:
2692          *
2693          *    error = (vlo-vhi+128)*65535 >> 24;
2694          *
2695          * An alternative arithmetic calculation which also gives no errors is:
2696          *
2697          *    (V * 255 + 32895) >> 16
2698          */
2699
2700         png_int_32 tmp = *sp++; /* must be signed! */
2701         tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
2702         *dp++ = (png_byte)tmp;
2703      }
2704
2705      row_info->bit_depth = 8;
2706      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2707      row_info->rowbytes = row_info->width * row_info->channels;
2708   }
2709}
2710#endif
2711
2712#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
2713void /* PRIVATE */
2714/* Simply discard the low byte.  This was the default behavior prior
2715 * to libpng-1.5.4.
2716 */
2717png_do_chop(png_row_infop row_info, png_bytep row)
2718{
2719   png_debug(1, "in png_do_chop");
2720
2721   if (row_info->bit_depth == 16)
2722   {
2723      png_bytep sp = row; /* source */
2724      png_bytep dp = row; /* destination */
2725      png_bytep ep = sp + row_info->rowbytes; /* end+1 */
2726
2727      while (sp < ep)
2728      {
2729         *dp++ = *sp;
2730         sp += 2; /* skip low byte */
2731      }
2732
2733      row_info->bit_depth = 8;
2734      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
2735      row_info->rowbytes = row_info->width * row_info->channels;
2736   }
2737}
2738#endif
2739
2740#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
2741void /* PRIVATE */
2742png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
2743{
2744   png_debug(1, "in png_do_read_swap_alpha");
2745
2746   {
2747      png_uint_32 row_width = row_info->width;
2748      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2749      {
2750         /* This converts from RGBA to ARGB */
2751         if (row_info->bit_depth == 8)
2752         {
2753            png_bytep sp = row + row_info->rowbytes;
2754            png_bytep dp = sp;
2755            png_byte save;
2756            png_uint_32 i;
2757
2758            for (i = 0; i < row_width; i++)
2759            {
2760               save = *(--sp);
2761               *(--dp) = *(--sp);
2762               *(--dp) = *(--sp);
2763               *(--dp) = *(--sp);
2764               *(--dp) = save;
2765            }
2766         }
2767
2768#ifdef PNG_READ_16BIT_SUPPORTED
2769         /* This converts from RRGGBBAA to AARRGGBB */
2770         else
2771         {
2772            png_bytep sp = row + row_info->rowbytes;
2773            png_bytep dp = sp;
2774            png_byte save[2];
2775            png_uint_32 i;
2776
2777            for (i = 0; i < row_width; i++)
2778            {
2779               save[0] = *(--sp);
2780               save[1] = *(--sp);
2781               *(--dp) = *(--sp);
2782               *(--dp) = *(--sp);
2783               *(--dp) = *(--sp);
2784               *(--dp) = *(--sp);
2785               *(--dp) = *(--sp);
2786               *(--dp) = *(--sp);
2787               *(--dp) = save[0];
2788               *(--dp) = save[1];
2789            }
2790         }
2791#endif
2792      }
2793
2794      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2795      {
2796         /* This converts from GA to AG */
2797         if (row_info->bit_depth == 8)
2798         {
2799            png_bytep sp = row + row_info->rowbytes;
2800            png_bytep dp = sp;
2801            png_byte save;
2802            png_uint_32 i;
2803
2804            for (i = 0; i < row_width; i++)
2805            {
2806               save = *(--sp);
2807               *(--dp) = *(--sp);
2808               *(--dp) = save;
2809            }
2810         }
2811
2812#ifdef PNG_READ_16BIT_SUPPORTED
2813         /* This converts from GGAA to AAGG */
2814         else
2815         {
2816            png_bytep sp = row + row_info->rowbytes;
2817            png_bytep dp = sp;
2818            png_byte save[2];
2819            png_uint_32 i;
2820
2821            for (i = 0; i < row_width; i++)
2822            {
2823               save[0] = *(--sp);
2824               save[1] = *(--sp);
2825               *(--dp) = *(--sp);
2826               *(--dp) = *(--sp);
2827               *(--dp) = save[0];
2828               *(--dp) = save[1];
2829            }
2830         }
2831#endif
2832      }
2833   }
2834}
2835#endif
2836
2837#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
2838void /* PRIVATE */
2839png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
2840{
2841   png_uint_32 row_width;
2842   png_debug(1, "in png_do_read_invert_alpha");
2843
2844   row_width = row_info->width;
2845   if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2846   {
2847      if (row_info->bit_depth == 8)
2848      {
2849         /* This inverts the alpha channel in RGBA */
2850         png_bytep sp = row + row_info->rowbytes;
2851         png_bytep dp = sp;
2852         png_uint_32 i;
2853
2854         for (i = 0; i < row_width; i++)
2855         {
2856            *(--dp) = (png_byte)(255 - *(--sp));
2857
2858/*          This does nothing:
2859            *(--dp) = *(--sp);
2860            *(--dp) = *(--sp);
2861            *(--dp) = *(--sp);
2862            We can replace it with:
2863*/
2864            sp-=3;
2865            dp=sp;
2866         }
2867      }
2868
2869#ifdef PNG_READ_16BIT_SUPPORTED
2870      /* This inverts the alpha channel in RRGGBBAA */
2871      else
2872      {
2873         png_bytep sp = row + row_info->rowbytes;
2874         png_bytep dp = sp;
2875         png_uint_32 i;
2876
2877         for (i = 0; i < row_width; i++)
2878         {
2879            *(--dp) = (png_byte)(255 - *(--sp));
2880            *(--dp) = (png_byte)(255 - *(--sp));
2881
2882/*          This does nothing:
2883            *(--dp) = *(--sp);
2884            *(--dp) = *(--sp);
2885            *(--dp) = *(--sp);
2886            *(--dp) = *(--sp);
2887            *(--dp) = *(--sp);
2888            *(--dp) = *(--sp);
2889            We can replace it with:
2890*/
2891            sp-=6;
2892            dp=sp;
2893         }
2894      }
2895#endif
2896   }
2897   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2898   {
2899      if (row_info->bit_depth == 8)
2900      {
2901         /* This inverts the alpha channel in GA */
2902         png_bytep sp = row + row_info->rowbytes;
2903         png_bytep dp = sp;
2904         png_uint_32 i;
2905
2906         for (i = 0; i < row_width; i++)
2907         {
2908            *(--dp) = (png_byte)(255 - *(--sp));
2909            *(--dp) = *(--sp);
2910         }
2911      }
2912
2913#ifdef PNG_READ_16BIT_SUPPORTED
2914      else
2915      {
2916         /* This inverts the alpha channel in GGAA */
2917         png_bytep sp  = row + row_info->rowbytes;
2918         png_bytep dp = sp;
2919         png_uint_32 i;
2920
2921         for (i = 0; i < row_width; i++)
2922         {
2923            *(--dp) = (png_byte)(255 - *(--sp));
2924            *(--dp) = (png_byte)(255 - *(--sp));
2925/*
2926            *(--dp) = *(--sp);
2927            *(--dp) = *(--sp);
2928*/
2929            sp-=2;
2930            dp=sp;
2931         }
2932      }
2933#endif
2934   }
2935}
2936#endif
2937
2938#ifdef PNG_READ_FILLER_SUPPORTED
2939/* Add filler channel if we have RGB color */
2940void /* PRIVATE */
2941png_do_read_filler(png_row_infop row_info, png_bytep row,
2942    png_uint_32 filler, png_uint_32 flags)
2943{
2944   png_uint_32 i;
2945   png_uint_32 row_width = row_info->width;
2946
2947#ifdef PNG_READ_16BIT_SUPPORTED
2948   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
2949#endif
2950   png_byte lo_filler = (png_byte)(filler & 0xff);
2951
2952   png_debug(1, "in png_do_read_filler");
2953
2954   if (
2955       row_info->color_type == PNG_COLOR_TYPE_GRAY)
2956   {
2957      if (row_info->bit_depth == 8)
2958      {
2959         if (flags & PNG_FLAG_FILLER_AFTER)
2960         {
2961            /* This changes the data from G to GX */
2962            png_bytep sp = row + (png_size_t)row_width;
2963            png_bytep dp =  sp + (png_size_t)row_width;
2964            for (i = 1; i < row_width; i++)
2965            {
2966               *(--dp) = lo_filler;
2967               *(--dp) = *(--sp);
2968            }
2969            *(--dp) = lo_filler;
2970            row_info->channels = 2;
2971            row_info->pixel_depth = 16;
2972            row_info->rowbytes = row_width * 2;
2973         }
2974
2975         else
2976         {
2977            /* This changes the data from G to XG */
2978            png_bytep sp = row + (png_size_t)row_width;
2979            png_bytep dp = sp  + (png_size_t)row_width;
2980            for (i = 0; i < row_width; i++)
2981            {
2982               *(--dp) = *(--sp);
2983               *(--dp) = lo_filler;
2984            }
2985            row_info->channels = 2;
2986            row_info->pixel_depth = 16;
2987            row_info->rowbytes = row_width * 2;
2988         }
2989      }
2990
2991#ifdef PNG_READ_16BIT_SUPPORTED
2992      else if (row_info->bit_depth == 16)
2993      {
2994         if (flags & PNG_FLAG_FILLER_AFTER)
2995         {
2996            /* This changes the data from GG to GGXX */
2997            png_bytep sp = row + (png_size_t)row_width * 2;
2998            png_bytep dp = sp  + (png_size_t)row_width * 2;
2999            for (i = 1; i < row_width; i++)
3000            {
3001               *(--dp) = hi_filler;
3002               *(--dp) = lo_filler;
3003               *(--dp) = *(--sp);
3004               *(--dp) = *(--sp);
3005            }
3006            *(--dp) = hi_filler;
3007            *(--dp) = lo_filler;
3008            row_info->channels = 2;
3009            row_info->pixel_depth = 32;
3010            row_info->rowbytes = row_width * 4;
3011         }
3012
3013         else
3014         {
3015            /* This changes the data from GG to XXGG */
3016            png_bytep sp = row + (png_size_t)row_width * 2;
3017            png_bytep dp = sp  + (png_size_t)row_width * 2;
3018            for (i = 0; i < row_width; i++)
3019            {
3020               *(--dp) = *(--sp);
3021               *(--dp) = *(--sp);
3022               *(--dp) = hi_filler;
3023               *(--dp) = lo_filler;
3024            }
3025            row_info->channels = 2;
3026            row_info->pixel_depth = 32;
3027            row_info->rowbytes = row_width * 4;
3028         }
3029      }
3030#endif
3031   } /* COLOR_TYPE == GRAY */
3032   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
3033   {
3034      if (row_info->bit_depth == 8)
3035      {
3036         if (flags & PNG_FLAG_FILLER_AFTER)
3037         {
3038            /* This changes the data from RGB to RGBX */
3039            png_bytep sp = row + (png_size_t)row_width * 3;
3040            png_bytep dp = sp  + (png_size_t)row_width;
3041            for (i = 1; i < row_width; i++)
3042            {
3043               *(--dp) = lo_filler;
3044               *(--dp) = *(--sp);
3045               *(--dp) = *(--sp);
3046               *(--dp) = *(--sp);
3047            }
3048            *(--dp) = lo_filler;
3049            row_info->channels = 4;
3050            row_info->pixel_depth = 32;
3051            row_info->rowbytes = row_width * 4;
3052         }
3053
3054         else
3055         {
3056            /* This changes the data from RGB to XRGB */
3057            png_bytep sp = row + (png_size_t)row_width * 3;
3058            png_bytep dp = sp + (png_size_t)row_width;
3059            for (i = 0; i < row_width; i++)
3060            {
3061               *(--dp) = *(--sp);
3062               *(--dp) = *(--sp);
3063               *(--dp) = *(--sp);
3064               *(--dp) = lo_filler;
3065            }
3066            row_info->channels = 4;
3067            row_info->pixel_depth = 32;
3068            row_info->rowbytes = row_width * 4;
3069         }
3070      }
3071
3072#ifdef PNG_READ_16BIT_SUPPORTED
3073      else if (row_info->bit_depth == 16)
3074      {
3075         if (flags & PNG_FLAG_FILLER_AFTER)
3076         {
3077            /* This changes the data from RRGGBB to RRGGBBXX */
3078            png_bytep sp = row + (png_size_t)row_width * 6;
3079            png_bytep dp = sp  + (png_size_t)row_width * 2;
3080            for (i = 1; i < row_width; i++)
3081            {
3082               *(--dp) = hi_filler;
3083               *(--dp) = lo_filler;
3084               *(--dp) = *(--sp);
3085               *(--dp) = *(--sp);
3086               *(--dp) = *(--sp);
3087               *(--dp) = *(--sp);
3088               *(--dp) = *(--sp);
3089               *(--dp) = *(--sp);
3090            }
3091            *(--dp) = hi_filler;
3092            *(--dp) = lo_filler;
3093            row_info->channels = 4;
3094            row_info->pixel_depth = 64;
3095            row_info->rowbytes = row_width * 8;
3096         }
3097
3098         else
3099         {
3100            /* This changes the data from RRGGBB to XXRRGGBB */
3101            png_bytep sp = row + (png_size_t)row_width * 6;
3102            png_bytep dp = sp  + (png_size_t)row_width * 2;
3103            for (i = 0; i < row_width; i++)
3104            {
3105               *(--dp) = *(--sp);
3106               *(--dp) = *(--sp);
3107               *(--dp) = *(--sp);
3108               *(--dp) = *(--sp);
3109               *(--dp) = *(--sp);
3110               *(--dp) = *(--sp);
3111               *(--dp) = hi_filler;
3112               *(--dp) = lo_filler;
3113            }
3114
3115            row_info->channels = 4;
3116            row_info->pixel_depth = 64;
3117            row_info->rowbytes = row_width * 8;
3118         }
3119      }
3120#endif
3121   } /* COLOR_TYPE == RGB */
3122}
3123#endif
3124
3125#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3126/* Expand grayscale files to RGB, with or without alpha */
3127void /* PRIVATE */
3128png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
3129{
3130   png_uint_32 i;
3131   png_uint_32 row_width = row_info->width;
3132
3133   png_debug(1, "in png_do_gray_to_rgb");
3134
3135   if (row_info->bit_depth >= 8 &&
3136       !(row_info->color_type & PNG_COLOR_MASK_COLOR))
3137   {
3138      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
3139      {
3140         if (row_info->bit_depth == 8)
3141         {
3142            /* This changes G to RGB */
3143            png_bytep sp = row + (png_size_t)row_width - 1;
3144            png_bytep dp = sp  + (png_size_t)row_width * 2;
3145            for (i = 0; i < row_width; i++)
3146            {
3147               *(dp--) = *sp;
3148               *(dp--) = *sp;
3149               *(dp--) = *(sp--);
3150            }
3151         }
3152
3153         else
3154         {
3155            /* This changes GG to RRGGBB */
3156            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
3157            png_bytep dp = sp  + (png_size_t)row_width * 4;
3158            for (i = 0; i < row_width; i++)
3159            {
3160               *(dp--) = *sp;
3161               *(dp--) = *(sp - 1);
3162               *(dp--) = *sp;
3163               *(dp--) = *(sp - 1);
3164               *(dp--) = *(sp--);
3165               *(dp--) = *(sp--);
3166            }
3167         }
3168      }
3169
3170      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3171      {
3172         if (row_info->bit_depth == 8)
3173         {
3174            /* This changes GA to RGBA */
3175            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
3176            png_bytep dp = sp  + (png_size_t)row_width * 2;
3177            for (i = 0; i < row_width; i++)
3178            {
3179               *(dp--) = *(sp--);
3180               *(dp--) = *sp;
3181               *(dp--) = *sp;
3182               *(dp--) = *(sp--);
3183            }
3184         }
3185
3186         else
3187         {
3188            /* This changes GGAA to RRGGBBAA */
3189            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
3190            png_bytep dp = sp  + (png_size_t)row_width * 4;
3191            for (i = 0; i < row_width; i++)
3192            {
3193               *(dp--) = *(sp--);
3194               *(dp--) = *(sp--);
3195               *(dp--) = *sp;
3196               *(dp--) = *(sp - 1);
3197               *(dp--) = *sp;
3198               *(dp--) = *(sp - 1);
3199               *(dp--) = *(sp--);
3200               *(dp--) = *(sp--);
3201            }
3202         }
3203      }
3204      row_info->channels = (png_byte)(row_info->channels + 2);
3205      row_info->color_type |= PNG_COLOR_MASK_COLOR;
3206      row_info->pixel_depth = (png_byte)(row_info->channels *
3207          row_info->bit_depth);
3208      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3209   }
3210}
3211#endif
3212
3213#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
3214/* Reduce RGB files to grayscale, with or without alpha
3215 * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
3216 * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
3217 * versions dated 1998 through November 2002 have been archived at
3218 * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
3219 * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
3220 * Charles Poynton poynton at poynton.com
3221 *
3222 *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
3223 *
3224 *  which can be expressed with integers as
3225 *
3226 *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
3227 *
3228 * Poynton's current link (as of January 2003 through July 2011):
3229 * <http://www.poynton.com/notes/colour_and_gamma/>
3230 * has changed the numbers slightly:
3231 *
3232 *     Y = 0.2126*R + 0.7152*G + 0.0722*B
3233 *
3234 *  which can be expressed with integers as
3235 *
3236 *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
3237 *
3238 *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
3239 *  end point chromaticities and the D65 white point.  Depending on the
3240 *  precision used for the D65 white point this produces a variety of different
3241 *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
3242 *  used (0.3127,0.3290) the Y calculation would be:
3243 *
3244 *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
3245 *
3246 *  While this is correct the rounding results in an overflow for white, because
3247 *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
3248 *  libpng uses, instead, the closest non-overflowing approximation:
3249 *
3250 *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
3251 *
3252 *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
3253 *  (including an sRGB chunk) then the chromaticities are used to calculate the
3254 *  coefficients.  See the chunk handling in pngrutil.c for more information.
3255 *
3256 *  In all cases the calculation is to be done in a linear colorspace.  If no
3257 *  gamma information is available to correct the encoding of the original RGB
3258 *  values this results in an implicit assumption that the original PNG RGB
3259 *  values were linear.
3260 *
3261 *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
3262 *  the API takes just red and green coefficients the blue coefficient is
3263 *  calculated to make the sum 32768.  This will result in different rounding
3264 *  to that used above.
3265 */
3266int /* PRIVATE */
3267png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
3268
3269{
3270   int rgb_error = 0;
3271
3272   png_debug(1, "in png_do_rgb_to_gray");
3273
3274   if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&
3275       (row_info->color_type & PNG_COLOR_MASK_COLOR))
3276   {
3277      PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
3278      PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
3279      PNG_CONST png_uint_32 bc = 32768 - rc - gc;
3280      PNG_CONST png_uint_32 row_width = row_info->width;
3281      PNG_CONST int have_alpha =
3282         (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
3283
3284      if (row_info->bit_depth == 8)
3285      {
3286#ifdef PNG_READ_GAMMA_SUPPORTED
3287         /* Notice that gamma to/from 1 are not necessarily inverses (if
3288          * there is an overall gamma correction).  Prior to 1.5.5 this code
3289          * checked the linearized values for equality; this doesn't match
3290          * the documentation, the original values must be checked.
3291          */
3292         if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3293         {
3294            png_bytep sp = row;
3295            png_bytep dp = row;
3296            png_uint_32 i;
3297
3298            for (i = 0; i < row_width; i++)
3299            {
3300               png_byte red   = *(sp++);
3301               png_byte green = *(sp++);
3302               png_byte blue  = *(sp++);
3303
3304               if (red != green || red != blue)
3305               {
3306                  red = png_ptr->gamma_to_1[red];
3307                  green = png_ptr->gamma_to_1[green];
3308                  blue = png_ptr->gamma_to_1[blue];
3309
3310                  rgb_error |= 1;
3311                  *(dp++) = png_ptr->gamma_from_1[
3312                      (rc*red + gc*green + bc*blue + 16384)>>15];
3313               }
3314
3315               else
3316               {
3317                  /* If there is no overall correction the table will not be
3318                   * set.
3319                   */
3320                  if (png_ptr->gamma_table != NULL)
3321                     red = png_ptr->gamma_table[red];
3322
3323                  *(dp++) = red;
3324               }
3325
3326               if (have_alpha)
3327                  *(dp++) = *(sp++);
3328            }
3329         }
3330         else
3331#endif
3332         {
3333            png_bytep sp = row;
3334            png_bytep dp = row;
3335            png_uint_32 i;
3336
3337            for (i = 0; i < row_width; i++)
3338            {
3339               png_byte red   = *(sp++);
3340               png_byte green = *(sp++);
3341               png_byte blue  = *(sp++);
3342
3343               if (red != green || red != blue)
3344               {
3345                  rgb_error |= 1;
3346                  /* NOTE: this is the historical approach which simply
3347                   * truncates the results.
3348                   */
3349                  *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
3350               }
3351
3352               else
3353                  *(dp++) = red;
3354
3355               if (have_alpha)
3356                  *(dp++) = *(sp++);
3357            }
3358         }
3359      }
3360
3361      else /* RGB bit_depth == 16 */
3362      {
3363#ifdef PNG_READ_GAMMA_SUPPORTED
3364         if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
3365         {
3366            png_bytep sp = row;
3367            png_bytep dp = row;
3368            png_uint_32 i;
3369
3370            for (i = 0; i < row_width; i++)
3371            {
3372               png_uint_16 red, green, blue, w;
3373
3374               red   = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3375               green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3376               blue  = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3377
3378               if (red == green && red == blue)
3379               {
3380                  if (png_ptr->gamma_16_table != NULL)
3381                     w = png_ptr->gamma_16_table[(red&0xff)
3382                         >> png_ptr->gamma_shift][red>>8];
3383
3384                  else
3385                     w = red;
3386               }
3387
3388               else
3389               {
3390                  png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff)
3391                      >> png_ptr->gamma_shift][red>>8];
3392                  png_uint_16 green_1 =
3393                      png_ptr->gamma_16_to_1[(green&0xff) >>
3394                      png_ptr->gamma_shift][green>>8];
3395                  png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff)
3396                      >> png_ptr->gamma_shift][blue>>8];
3397                  png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
3398                      + bc*blue_1 + 16384)>>15);
3399                  w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
3400                      png_ptr->gamma_shift][gray16 >> 8];
3401                  rgb_error |= 1;
3402               }
3403
3404               *(dp++) = (png_byte)((w>>8) & 0xff);
3405               *(dp++) = (png_byte)(w & 0xff);
3406
3407               if (have_alpha)
3408               {
3409                  *(dp++) = *(sp++);
3410                  *(dp++) = *(sp++);
3411               }
3412            }
3413         }
3414         else
3415#endif
3416         {
3417            png_bytep sp = row;
3418            png_bytep dp = row;
3419            png_uint_32 i;
3420
3421            for (i = 0; i < row_width; i++)
3422            {
3423               png_uint_16 red, green, blue, gray16;
3424
3425               red   = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3426               green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3427               blue  = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
3428
3429               if (red != green || red != blue)
3430                  rgb_error |= 1;
3431
3432               /* From 1.5.5 in the 16 bit case do the accurate conversion even
3433                * in the 'fast' case - this is because this is where the code
3434                * ends up when handling linear 16 bit data.
3435                */
3436               gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
3437                  15);
3438               *(dp++) = (png_byte)((gray16>>8) & 0xff);
3439               *(dp++) = (png_byte)(gray16 & 0xff);
3440
3441               if (have_alpha)
3442               {
3443                  *(dp++) = *(sp++);
3444                  *(dp++) = *(sp++);
3445               }
3446            }
3447         }
3448      }
3449
3450      row_info->channels = (png_byte)(row_info->channels - 2);
3451      row_info->color_type = (png_byte)(row_info->color_type &
3452          ~PNG_COLOR_MASK_COLOR);
3453      row_info->pixel_depth = (png_byte)(row_info->channels *
3454          row_info->bit_depth);
3455      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3456   }
3457   return rgb_error;
3458}
3459#endif
3460#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
3461
3462#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
3463/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
3464 * large of png_color.  This lets grayscale images be treated as
3465 * paletted.  Most useful for gamma correction and simplification
3466 * of code.  This API is not used internally.
3467 */
3468void PNGAPI
3469png_build_grayscale_palette(int bit_depth, png_colorp palette)
3470{
3471   int num_palette;
3472   int color_inc;
3473   int i;
3474   int v;
3475
3476   png_debug(1, "in png_do_build_grayscale_palette");
3477
3478   if (palette == NULL)
3479      return;
3480
3481   switch (bit_depth)
3482   {
3483      case 1:
3484         num_palette = 2;
3485         color_inc = 0xff;
3486         break;
3487
3488      case 2:
3489         num_palette = 4;
3490         color_inc = 0x55;
3491         break;
3492
3493      case 4:
3494         num_palette = 16;
3495         color_inc = 0x11;
3496         break;
3497
3498      case 8:
3499         num_palette = 256;
3500         color_inc = 1;
3501         break;
3502
3503      default:
3504         num_palette = 0;
3505         color_inc = 0;
3506         break;
3507   }
3508
3509   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
3510   {
3511      palette[i].red = (png_byte)v;
3512      palette[i].green = (png_byte)v;
3513      palette[i].blue = (png_byte)v;
3514   }
3515}
3516#endif
3517
3518
3519#ifdef PNG_READ_TRANSFORMS_SUPPORTED
3520#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
3521   defined(PNG_READ_ALPHA_MODE_SUPPORTED)
3522/* Replace any alpha or transparency with the supplied background color.
3523 * "background" is already in the screen gamma, while "background_1" is
3524 * at a gamma of 1.0.  Paletted files have already been taken care of.
3525 */
3526void /* PRIVATE */
3527png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3528{
3529#ifdef PNG_READ_GAMMA_SUPPORTED
3530   png_const_bytep gamma_table = png_ptr->gamma_table;
3531   png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
3532   png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
3533   png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
3534   png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
3535   png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
3536   int gamma_shift = png_ptr->gamma_shift;
3537   int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
3538#endif
3539
3540   png_bytep sp;
3541   png_uint_32 i;
3542   png_uint_32 row_width = row_info->width;
3543   int shift;
3544
3545   png_debug(1, "in png_do_compose");
3546
3547   {
3548      switch (row_info->color_type)
3549      {
3550         case PNG_COLOR_TYPE_GRAY:
3551         {
3552            switch (row_info->bit_depth)
3553            {
3554               case 1:
3555               {
3556                  sp = row;
3557                  shift = 7;
3558                  for (i = 0; i < row_width; i++)
3559                  {
3560                     if ((png_uint_16)((*sp >> shift) & 0x01)
3561                        == png_ptr->trans_color.gray)
3562                     {
3563                        unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
3564                        tmp |= png_ptr->background.gray << shift;
3565                        *sp = (png_byte)(tmp & 0xff);
3566                     }
3567
3568                     if (!shift)
3569                     {
3570                        shift = 7;
3571                        sp++;
3572                     }
3573
3574                     else
3575                        shift--;
3576                  }
3577                  break;
3578               }
3579
3580               case 2:
3581               {
3582#ifdef PNG_READ_GAMMA_SUPPORTED
3583                  if (gamma_table != NULL)
3584                  {
3585                     sp = row;
3586                     shift = 6;
3587                     for (i = 0; i < row_width; i++)
3588                     {
3589                        if ((png_uint_16)((*sp >> shift) & 0x03)
3590                            == png_ptr->trans_color.gray)
3591                        {
3592                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3593                           tmp |= png_ptr->background.gray << shift;
3594                           *sp = (png_byte)(tmp & 0xff);
3595                        }
3596
3597                        else
3598                        {
3599                           unsigned int p = (*sp >> shift) & 0x03;
3600                           unsigned int g = (gamma_table [p | (p << 2) |
3601                               (p << 4) | (p << 6)] >> 6) & 0x03;
3602                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3603                           tmp |= g << shift;
3604                           *sp = (png_byte)(tmp & 0xff);
3605                        }
3606
3607                        if (!shift)
3608                        {
3609                           shift = 6;
3610                           sp++;
3611                        }
3612
3613                        else
3614                           shift -= 2;
3615                     }
3616                  }
3617
3618                  else
3619#endif
3620                  {
3621                     sp = row;
3622                     shift = 6;
3623                     for (i = 0; i < row_width; i++)
3624                     {
3625                        if ((png_uint_16)((*sp >> shift) & 0x03)
3626                            == png_ptr->trans_color.gray)
3627                        {
3628                           unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3629                           tmp |= png_ptr->background.gray << shift;
3630                           *sp = (png_byte)(tmp & 0xff);
3631                        }
3632
3633                        if (!shift)
3634                        {
3635                           shift = 6;
3636                           sp++;
3637                        }
3638
3639                        else
3640                           shift -= 2;
3641                     }
3642                  }
3643                  break;
3644               }
3645
3646               case 4:
3647               {
3648#ifdef PNG_READ_GAMMA_SUPPORTED
3649                  if (gamma_table != NULL)
3650                  {
3651                     sp = row;
3652                     shift = 4;
3653                     for (i = 0; i < row_width; i++)
3654                     {
3655                        if ((png_uint_16)((*sp >> shift) & 0x0f)
3656                            == png_ptr->trans_color.gray)
3657                        {
3658                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
3659                           tmp |= png_ptr->background.gray << shift;
3660                           *sp = (png_byte)(tmp & 0xff);
3661                        }
3662
3663                        else
3664                        {
3665                           unsigned int p = (*sp >> shift) & 0x0f;
3666                           unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
3667                              0x0f;
3668                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
3669                           tmp |= g << shift;
3670                           *sp = (png_byte)(tmp & 0xff);
3671                        }
3672
3673                        if (!shift)
3674                        {
3675                           shift = 4;
3676                           sp++;
3677                        }
3678
3679                        else
3680                           shift -= 4;
3681                     }
3682                  }
3683
3684                  else
3685#endif
3686                  {
3687                     sp = row;
3688                     shift = 4;
3689                     for (i = 0; i < row_width; i++)
3690                     {
3691                        if ((png_uint_16)((*sp >> shift) & 0x0f)
3692                            == png_ptr->trans_color.gray)
3693                        {
3694                           unsigned int tmp = *sp & (0xf0f >> (4 - shift));
3695                           tmp |= png_ptr->background.gray << shift;
3696                           *sp = (png_byte)(tmp & 0xff);
3697                        }
3698
3699                        if (!shift)
3700                        {
3701                           shift = 4;
3702                           sp++;
3703                        }
3704
3705                        else
3706                           shift -= 4;
3707                     }
3708                  }
3709                  break;
3710               }
3711
3712               case 8:
3713               {
3714#ifdef PNG_READ_GAMMA_SUPPORTED
3715                  if (gamma_table != NULL)
3716                  {
3717                     sp = row;
3718                     for (i = 0; i < row_width; i++, sp++)
3719                     {
3720                        if (*sp == png_ptr->trans_color.gray)
3721                           *sp = (png_byte)png_ptr->background.gray;
3722
3723                        else
3724                           *sp = gamma_table[*sp];
3725                     }
3726                  }
3727                  else
3728#endif
3729                  {
3730                     sp = row;
3731                     for (i = 0; i < row_width; i++, sp++)
3732                     {
3733                        if (*sp == png_ptr->trans_color.gray)
3734                           *sp = (png_byte)png_ptr->background.gray;
3735                     }
3736                  }
3737                  break;
3738               }
3739
3740               case 16:
3741               {
3742#ifdef PNG_READ_GAMMA_SUPPORTED
3743                  if (gamma_16 != NULL)
3744                  {
3745                     sp = row;
3746                     for (i = 0; i < row_width; i++, sp += 2)
3747                     {
3748                        png_uint_16 v;
3749
3750                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3751
3752                        if (v == png_ptr->trans_color.gray)
3753                        {
3754                           /* Background is already in screen gamma */
3755                           *sp = (png_byte)((png_ptr->background.gray >> 8)
3756                                & 0xff);
3757                           *(sp + 1) = (png_byte)(png_ptr->background.gray
3758                                & 0xff);
3759                        }
3760
3761                        else
3762                        {
3763                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3764                           *sp = (png_byte)((v >> 8) & 0xff);
3765                           *(sp + 1) = (png_byte)(v & 0xff);
3766                        }
3767                     }
3768                  }
3769                  else
3770#endif
3771                  {
3772                     sp = row;
3773                     for (i = 0; i < row_width; i++, sp += 2)
3774                     {
3775                        png_uint_16 v;
3776
3777                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3778
3779                        if (v == png_ptr->trans_color.gray)
3780                        {
3781                           *sp = (png_byte)((png_ptr->background.gray >> 8)
3782                                & 0xff);
3783                           *(sp + 1) = (png_byte)(png_ptr->background.gray
3784                                & 0xff);
3785                        }
3786                     }
3787                  }
3788                  break;
3789               }
3790
3791               default:
3792                  break;
3793            }
3794            break;
3795         }
3796
3797         case PNG_COLOR_TYPE_RGB:
3798         {
3799            if (row_info->bit_depth == 8)
3800            {
3801#ifdef PNG_READ_GAMMA_SUPPORTED
3802               if (gamma_table != NULL)
3803               {
3804                  sp = row;
3805                  for (i = 0; i < row_width; i++, sp += 3)
3806                  {
3807                     if (*sp == png_ptr->trans_color.red &&
3808                         *(sp + 1) == png_ptr->trans_color.green &&
3809                         *(sp + 2) == png_ptr->trans_color.blue)
3810                     {
3811                        *sp = (png_byte)png_ptr->background.red;
3812                        *(sp + 1) = (png_byte)png_ptr->background.green;
3813                        *(sp + 2) = (png_byte)png_ptr->background.blue;
3814                     }
3815
3816                     else
3817                     {
3818                        *sp = gamma_table[*sp];
3819                        *(sp + 1) = gamma_table[*(sp + 1)];
3820                        *(sp + 2) = gamma_table[*(sp + 2)];
3821                     }
3822                  }
3823               }
3824               else
3825#endif
3826               {
3827                  sp = row;
3828                  for (i = 0; i < row_width; i++, sp += 3)
3829                  {
3830                     if (*sp == png_ptr->trans_color.red &&
3831                         *(sp + 1) == png_ptr->trans_color.green &&
3832                         *(sp + 2) == png_ptr->trans_color.blue)
3833                     {
3834                        *sp = (png_byte)png_ptr->background.red;
3835                        *(sp + 1) = (png_byte)png_ptr->background.green;
3836                        *(sp + 2) = (png_byte)png_ptr->background.blue;
3837                     }
3838                  }
3839               }
3840            }
3841            else /* if (row_info->bit_depth == 16) */
3842            {
3843#ifdef PNG_READ_GAMMA_SUPPORTED
3844               if (gamma_16 != NULL)
3845               {
3846                  sp = row;
3847                  for (i = 0; i < row_width; i++, sp += 6)
3848                  {
3849                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3850
3851                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3852                         + *(sp + 3));
3853
3854                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3855                         + *(sp + 5));
3856
3857                     if (r == png_ptr->trans_color.red &&
3858                         g == png_ptr->trans_color.green &&
3859                         b == png_ptr->trans_color.blue)
3860                     {
3861                        /* Background is already in screen gamma */
3862                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3863                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3864                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3865                                & 0xff);
3866                        *(sp + 3) = (png_byte)(png_ptr->background.green
3867                                & 0xff);
3868                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3869                                & 0xff);
3870                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3871                     }
3872
3873                     else
3874                     {
3875                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3876                        *sp = (png_byte)((v >> 8) & 0xff);
3877                        *(sp + 1) = (png_byte)(v & 0xff);
3878
3879                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3880                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3881                        *(sp + 3) = (png_byte)(v & 0xff);
3882
3883                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3884                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3885                        *(sp + 5) = (png_byte)(v & 0xff);
3886                     }
3887                  }
3888               }
3889
3890               else
3891#endif
3892               {
3893                  sp = row;
3894                  for (i = 0; i < row_width; i++, sp += 6)
3895                  {
3896                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3897
3898                     png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3899                         + *(sp + 3));
3900
3901                     png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3902                         + *(sp + 5));
3903
3904                     if (r == png_ptr->trans_color.red &&
3905                         g == png_ptr->trans_color.green &&
3906                         b == png_ptr->trans_color.blue)
3907                     {
3908                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3909                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3910                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3911                                & 0xff);
3912                        *(sp + 3) = (png_byte)(png_ptr->background.green
3913                                & 0xff);
3914                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3915                                & 0xff);
3916                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3917                     }
3918                  }
3919               }
3920            }
3921            break;
3922         }
3923
3924         case PNG_COLOR_TYPE_GRAY_ALPHA:
3925         {
3926            if (row_info->bit_depth == 8)
3927            {
3928#ifdef PNG_READ_GAMMA_SUPPORTED
3929               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3930                   gamma_table != NULL)
3931               {
3932                  sp = row;
3933                  for (i = 0; i < row_width; i++, sp += 2)
3934                  {
3935                     png_uint_16 a = *(sp + 1);
3936
3937                     if (a == 0xff)
3938                        *sp = gamma_table[*sp];
3939
3940                     else if (a == 0)
3941                     {
3942                        /* Background is already in screen gamma */
3943                        *sp = (png_byte)png_ptr->background.gray;
3944                     }
3945
3946                     else
3947                     {
3948                        png_byte v, w;
3949
3950                        v = gamma_to_1[*sp];
3951                        png_composite(w, v, a, png_ptr->background_1.gray);
3952                        if (!optimize)
3953                           w = gamma_from_1[w];
3954                        *sp = w;
3955                     }
3956                  }
3957               }
3958               else
3959#endif
3960               {
3961                  sp = row;
3962                  for (i = 0; i < row_width; i++, sp += 2)
3963                  {
3964                     png_byte a = *(sp + 1);
3965
3966                     if (a == 0)
3967                        *sp = (png_byte)png_ptr->background.gray;
3968
3969                     else if (a < 0xff)
3970                        png_composite(*sp, *sp, a, png_ptr->background.gray);
3971                  }
3972               }
3973            }
3974            else /* if (png_ptr->bit_depth == 16) */
3975            {
3976#ifdef PNG_READ_GAMMA_SUPPORTED
3977               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3978                   gamma_16_to_1 != NULL)
3979               {
3980                  sp = row;
3981                  for (i = 0; i < row_width; i++, sp += 4)
3982                  {
3983                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3984                         + *(sp + 3));
3985
3986                     if (a == (png_uint_16)0xffff)
3987                     {
3988                        png_uint_16 v;
3989
3990                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3991                        *sp = (png_byte)((v >> 8) & 0xff);
3992                        *(sp + 1) = (png_byte)(v & 0xff);
3993                     }
3994
3995                     else if (a == 0)
3996                     {
3997                        /* Background is already in screen gamma */
3998                        *sp = (png_byte)((png_ptr->background.gray >> 8)
3999                                & 0xff);
4000                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
4001                     }
4002
4003                     else
4004                     {
4005                        png_uint_16 g, v, w;
4006
4007                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
4008                        png_composite_16(v, g, a, png_ptr->background_1.gray);
4009                        if (optimize)
4010                           w = v;
4011                        else
4012                           w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
4013                        *sp = (png_byte)((w >> 8) & 0xff);
4014                        *(sp + 1) = (png_byte)(w & 0xff);
4015                     }
4016                  }
4017               }
4018               else
4019#endif
4020               {
4021                  sp = row;
4022                  for (i = 0; i < row_width; i++, sp += 4)
4023                  {
4024                     png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
4025                         + *(sp + 3));
4026
4027                     if (a == 0)
4028                     {
4029                        *sp = (png_byte)((png_ptr->background.gray >> 8)
4030                                & 0xff);
4031                        *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
4032                     }
4033
4034                     else if (a < 0xffff)
4035                     {
4036                        png_uint_16 g, v;
4037
4038                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
4039                        png_composite_16(v, g, a, png_ptr->background.gray);
4040                        *sp = (png_byte)((v >> 8) & 0xff);
4041                        *(sp + 1) = (png_byte)(v & 0xff);
4042                     }
4043                  }
4044               }
4045            }
4046            break;
4047         }
4048
4049         case PNG_COLOR_TYPE_RGB_ALPHA:
4050         {
4051            if (row_info->bit_depth == 8)
4052            {
4053#ifdef PNG_READ_GAMMA_SUPPORTED
4054               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
4055                   gamma_table != NULL)
4056               {
4057                  sp = row;
4058                  for (i = 0; i < row_width; i++, sp += 4)
4059                  {
4060                     png_byte a = *(sp + 3);
4061
4062                     if (a == 0xff)
4063                     {
4064                        *sp = gamma_table[*sp];
4065                        *(sp + 1) = gamma_table[*(sp + 1)];
4066                        *(sp + 2) = gamma_table[*(sp + 2)];
4067                     }
4068
4069                     else if (a == 0)
4070                     {
4071                        /* Background is already in screen gamma */
4072                        *sp = (png_byte)png_ptr->background.red;
4073                        *(sp + 1) = (png_byte)png_ptr->background.green;
4074                        *(sp + 2) = (png_byte)png_ptr->background.blue;
4075                     }
4076
4077                     else
4078                     {
4079                        png_byte v, w;
4080
4081                        v = gamma_to_1[*sp];
4082                        png_composite(w, v, a, png_ptr->background_1.red);
4083                        if (!optimize) w = gamma_from_1[w];
4084                        *sp = w;
4085
4086                        v = gamma_to_1[*(sp + 1)];
4087                        png_composite(w, v, a, png_ptr->background_1.green);
4088                        if (!optimize) w = gamma_from_1[w];
4089                        *(sp + 1) = w;
4090
4091                        v = gamma_to_1[*(sp + 2)];
4092                        png_composite(w, v, a, png_ptr->background_1.blue);
4093                        if (!optimize) w = gamma_from_1[w];
4094                        *(sp + 2) = w;
4095                     }
4096                  }
4097               }
4098               else
4099#endif
4100               {
4101                  sp = row;
4102                  for (i = 0; i < row_width; i++, sp += 4)
4103                  {
4104                     png_byte a = *(sp + 3);
4105
4106                     if (a == 0)
4107                     {
4108                        *sp = (png_byte)png_ptr->background.red;
4109                        *(sp + 1) = (png_byte)png_ptr->background.green;
4110                        *(sp + 2) = (png_byte)png_ptr->background.blue;
4111                     }
4112
4113                     else if (a < 0xff)
4114                     {
4115                        png_composite(*sp, *sp, a, png_ptr->background.red);
4116
4117                        png_composite(*(sp + 1), *(sp + 1), a,
4118                            png_ptr->background.green);
4119
4120                        png_composite(*(sp + 2), *(sp + 2), a,
4121                            png_ptr->background.blue);
4122                     }
4123                  }
4124               }
4125            }
4126            else /* if (row_info->bit_depth == 16) */
4127            {
4128#ifdef PNG_READ_GAMMA_SUPPORTED
4129               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
4130                   gamma_16_to_1 != NULL)
4131               {
4132                  sp = row;
4133                  for (i = 0; i < row_width; i++, sp += 8)
4134                  {
4135                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
4136                         << 8) + (png_uint_16)(*(sp + 7)));
4137
4138                     if (a == (png_uint_16)0xffff)
4139                     {
4140                        png_uint_16 v;
4141
4142                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
4143                        *sp = (png_byte)((v >> 8) & 0xff);
4144                        *(sp + 1) = (png_byte)(v & 0xff);
4145
4146                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
4147                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
4148                        *(sp + 3) = (png_byte)(v & 0xff);
4149
4150                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
4151                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
4152                        *(sp + 5) = (png_byte)(v & 0xff);
4153                     }
4154
4155                     else if (a == 0)
4156                     {
4157                        /* Background is already in screen gamma */
4158                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
4159                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
4160                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
4161                                & 0xff);
4162                        *(sp + 3) = (png_byte)(png_ptr->background.green
4163                                & 0xff);
4164                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
4165                                & 0xff);
4166                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
4167                     }
4168
4169                     else
4170                     {
4171                        png_uint_16 v, w;
4172
4173                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
4174                        png_composite_16(w, v, a, png_ptr->background_1.red);
4175                        if (!optimize)
4176                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
4177                                8];
4178                        *sp = (png_byte)((w >> 8) & 0xff);
4179                        *(sp + 1) = (png_byte)(w & 0xff);
4180
4181                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
4182                        png_composite_16(w, v, a, png_ptr->background_1.green);
4183                        if (!optimize)
4184                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
4185                                8];
4186
4187                        *(sp + 2) = (png_byte)((w >> 8) & 0xff);
4188                        *(sp + 3) = (png_byte)(w & 0xff);
4189
4190                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
4191                        png_composite_16(w, v, a, png_ptr->background_1.blue);
4192                        if (!optimize)
4193                           w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
4194                                8];
4195
4196                        *(sp + 4) = (png_byte)((w >> 8) & 0xff);
4197                        *(sp + 5) = (png_byte)(w & 0xff);
4198                     }
4199                  }
4200               }
4201
4202               else
4203#endif
4204               {
4205                  sp = row;
4206                  for (i = 0; i < row_width; i++, sp += 8)
4207                  {
4208                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
4209                         << 8) + (png_uint_16)(*(sp + 7)));
4210
4211                     if (a == 0)
4212                     {
4213                        *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
4214                        *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
4215                        *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
4216                                & 0xff);
4217                        *(sp + 3) = (png_byte)(png_ptr->background.green
4218                                & 0xff);
4219                        *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
4220                                & 0xff);
4221                        *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
4222                     }
4223
4224                     else if (a < 0xffff)
4225                     {
4226                        png_uint_16 v;
4227
4228                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
4229                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
4230                            + *(sp + 3));
4231                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
4232                            + *(sp + 5));
4233
4234                        png_composite_16(v, r, a, png_ptr->background.red);
4235                        *sp = (png_byte)((v >> 8) & 0xff);
4236                        *(sp + 1) = (png_byte)(v & 0xff);
4237
4238                        png_composite_16(v, g, a, png_ptr->background.green);
4239                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
4240                        *(sp + 3) = (png_byte)(v & 0xff);
4241
4242                        png_composite_16(v, b, a, png_ptr->background.blue);
4243                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
4244                        *(sp + 5) = (png_byte)(v & 0xff);
4245                     }
4246                  }
4247               }
4248            }
4249            break;
4250         }
4251
4252         default:
4253            break;
4254      }
4255   }
4256}
4257#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */
4258
4259#ifdef PNG_READ_GAMMA_SUPPORTED
4260/* Gamma correct the image, avoiding the alpha channel.  Make sure
4261 * you do this after you deal with the transparency issue on grayscale
4262 * or RGB images. If your bit depth is 8, use gamma_table, if it
4263 * is 16, use gamma_16_table and gamma_shift.  Build these with
4264 * build_gamma_table().
4265 */
4266void /* PRIVATE */
4267png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4268{
4269   png_const_bytep gamma_table = png_ptr->gamma_table;
4270   png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
4271   int gamma_shift = png_ptr->gamma_shift;
4272
4273   png_bytep sp;
4274   png_uint_32 i;
4275   png_uint_32 row_width=row_info->width;
4276
4277   png_debug(1, "in png_do_gamma");
4278
4279   if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
4280       (row_info->bit_depth == 16 && gamma_16_table != NULL)))
4281   {
4282      switch (row_info->color_type)
4283      {
4284         case PNG_COLOR_TYPE_RGB:
4285         {
4286            if (row_info->bit_depth == 8)
4287            {
4288               sp = row;
4289               for (i = 0; i < row_width; i++)
4290               {
4291                  *sp = gamma_table[*sp];
4292                  sp++;
4293                  *sp = gamma_table[*sp];
4294                  sp++;
4295                  *sp = gamma_table[*sp];
4296                  sp++;
4297               }
4298            }
4299
4300            else /* if (row_info->bit_depth == 16) */
4301            {
4302               sp = row;
4303               for (i = 0; i < row_width; i++)
4304               {
4305                  png_uint_16 v;
4306
4307                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4308                  *sp = (png_byte)((v >> 8) & 0xff);
4309                  *(sp + 1) = (png_byte)(v & 0xff);
4310                  sp += 2;
4311
4312                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4313                  *sp = (png_byte)((v >> 8) & 0xff);
4314                  *(sp + 1) = (png_byte)(v & 0xff);
4315                  sp += 2;
4316
4317                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4318                  *sp = (png_byte)((v >> 8) & 0xff);
4319                  *(sp + 1) = (png_byte)(v & 0xff);
4320                  sp += 2;
4321               }
4322            }
4323            break;
4324         }
4325
4326         case PNG_COLOR_TYPE_RGB_ALPHA:
4327         {
4328            if (row_info->bit_depth == 8)
4329            {
4330               sp = row;
4331               for (i = 0; i < row_width; i++)
4332               {
4333                  *sp = gamma_table[*sp];
4334                  sp++;
4335
4336                  *sp = gamma_table[*sp];
4337                  sp++;
4338
4339                  *sp = gamma_table[*sp];
4340                  sp++;
4341
4342                  sp++;
4343               }
4344            }
4345
4346            else /* if (row_info->bit_depth == 16) */
4347            {
4348               sp = row;
4349               for (i = 0; i < row_width; i++)
4350               {
4351                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4352                  *sp = (png_byte)((v >> 8) & 0xff);
4353                  *(sp + 1) = (png_byte)(v & 0xff);
4354                  sp += 2;
4355
4356                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4357                  *sp = (png_byte)((v >> 8) & 0xff);
4358                  *(sp + 1) = (png_byte)(v & 0xff);
4359                  sp += 2;
4360
4361                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4362                  *sp = (png_byte)((v >> 8) & 0xff);
4363                  *(sp + 1) = (png_byte)(v & 0xff);
4364                  sp += 4;
4365               }
4366            }
4367            break;
4368         }
4369
4370         case PNG_COLOR_TYPE_GRAY_ALPHA:
4371         {
4372            if (row_info->bit_depth == 8)
4373            {
4374               sp = row;
4375               for (i = 0; i < row_width; i++)
4376               {
4377                  *sp = gamma_table[*sp];
4378                  sp += 2;
4379               }
4380            }
4381
4382            else /* if (row_info->bit_depth == 16) */
4383            {
4384               sp = row;
4385               for (i = 0; i < row_width; i++)
4386               {
4387                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4388                  *sp = (png_byte)((v >> 8) & 0xff);
4389                  *(sp + 1) = (png_byte)(v & 0xff);
4390                  sp += 4;
4391               }
4392            }
4393            break;
4394         }
4395
4396         case PNG_COLOR_TYPE_GRAY:
4397         {
4398            if (row_info->bit_depth == 2)
4399            {
4400               sp = row;
4401               for (i = 0; i < row_width; i += 4)
4402               {
4403                  int a = *sp & 0xc0;
4404                  int b = *sp & 0x30;
4405                  int c = *sp & 0x0c;
4406                  int d = *sp & 0x03;
4407
4408                  *sp = (png_byte)(
4409                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
4410                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
4411                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
4412                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
4413                  sp++;
4414               }
4415            }
4416
4417            if (row_info->bit_depth == 4)
4418            {
4419               sp = row;
4420               for (i = 0; i < row_width; i += 2)
4421               {
4422                  int msb = *sp & 0xf0;
4423                  int lsb = *sp & 0x0f;
4424
4425                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
4426                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
4427                  sp++;
4428               }
4429            }
4430
4431            else if (row_info->bit_depth == 8)
4432            {
4433               sp = row;
4434               for (i = 0; i < row_width; i++)
4435               {
4436                  *sp = gamma_table[*sp];
4437                  sp++;
4438               }
4439            }
4440
4441            else if (row_info->bit_depth == 16)
4442            {
4443               sp = row;
4444               for (i = 0; i < row_width; i++)
4445               {
4446                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4447                  *sp = (png_byte)((v >> 8) & 0xff);
4448                  *(sp + 1) = (png_byte)(v & 0xff);
4449                  sp += 2;
4450               }
4451            }
4452            break;
4453         }
4454
4455         default:
4456            break;
4457      }
4458   }
4459}
4460#endif
4461
4462#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4463/* Encode the alpha channel to the output gamma (the input channel is always
4464 * linear.)  Called only with color types that have an alpha channel.  Needs the
4465 * from_1 tables.
4466 */
4467void /* PRIVATE */
4468png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4469{
4470   png_uint_32 row_width = row_info->width;
4471
4472   png_debug(1, "in png_do_encode_alpha");
4473
4474   if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
4475   {
4476      if (row_info->bit_depth == 8)
4477      {
4478         PNG_CONST png_bytep table = png_ptr->gamma_from_1;
4479
4480         if (table != NULL)
4481         {
4482            PNG_CONST int step =
4483               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
4484
4485            /* The alpha channel is the last component: */
4486            row += step - 1;
4487
4488            for (; row_width > 0; --row_width, row += step)
4489               *row = table[*row];
4490
4491            return;
4492         }
4493      }
4494
4495      else if (row_info->bit_depth == 16)
4496      {
4497         PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
4498         PNG_CONST int gamma_shift = png_ptr->gamma_shift;
4499
4500         if (table != NULL)
4501         {
4502            PNG_CONST int step =
4503               (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
4504
4505            /* The alpha channel is the last component: */
4506            row += step - 2;
4507
4508            for (; row_width > 0; --row_width, row += step)
4509            {
4510               png_uint_16 v;
4511
4512               v = table[*(row + 1) >> gamma_shift][*row];
4513               *row = (png_byte)((v >> 8) & 0xff);
4514               *(row + 1) = (png_byte)(v & 0xff);
4515            }
4516
4517            return;
4518         }
4519      }
4520   }
4521
4522   /* Only get to here if called with a weird row_info; no harm has been done,
4523    * so just issue a warning.
4524    */
4525   png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
4526}
4527#endif
4528
4529#ifdef PNG_READ_EXPAND_SUPPORTED
4530/* Expands a palette row to an RGB or RGBA row depending
4531 * upon whether you supply trans and num_trans.
4532 */
4533void /* PRIVATE */
4534png_do_expand_palette(png_row_infop row_info, png_bytep row,
4535   png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
4536{
4537   int shift, value;
4538   png_bytep sp, dp;
4539   png_uint_32 i;
4540   png_uint_32 row_width=row_info->width;
4541
4542   png_debug(1, "in png_do_expand_palette");
4543
4544   if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4545   {
4546      if (row_info->bit_depth < 8)
4547      {
4548         switch (row_info->bit_depth)
4549         {
4550            case 1:
4551            {
4552               sp = row + (png_size_t)((row_width - 1) >> 3);
4553               dp = row + (png_size_t)row_width - 1;
4554               shift = 7 - (int)((row_width + 7) & 0x07);
4555               for (i = 0; i < row_width; i++)
4556               {
4557                  if ((*sp >> shift) & 0x01)
4558                     *dp = 1;
4559
4560                  else
4561                     *dp = 0;
4562
4563                  if (shift == 7)
4564                  {
4565                     shift = 0;
4566                     sp--;
4567                  }
4568
4569                  else
4570                     shift++;
4571
4572                  dp--;
4573               }
4574               break;
4575            }
4576
4577            case 2:
4578            {
4579               sp = row + (png_size_t)((row_width - 1) >> 2);
4580               dp = row + (png_size_t)row_width - 1;
4581               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4582               for (i = 0; i < row_width; i++)
4583               {
4584                  value = (*sp >> shift) & 0x03;
4585                  *dp = (png_byte)value;
4586                  if (shift == 6)
4587                  {
4588                     shift = 0;
4589                     sp--;
4590                  }
4591
4592                  else
4593                     shift += 2;
4594
4595                  dp--;
4596               }
4597               break;
4598            }
4599
4600            case 4:
4601            {
4602               sp = row + (png_size_t)((row_width - 1) >> 1);
4603               dp = row + (png_size_t)row_width - 1;
4604               shift = (int)((row_width & 0x01) << 2);
4605               for (i = 0; i < row_width; i++)
4606               {
4607                  value = (*sp >> shift) & 0x0f;
4608                  *dp = (png_byte)value;
4609                  if (shift == 4)
4610                  {
4611                     shift = 0;
4612                     sp--;
4613                  }
4614
4615                  else
4616                     shift += 4;
4617
4618                  dp--;
4619               }
4620               break;
4621            }
4622
4623            default:
4624               break;
4625         }
4626         row_info->bit_depth = 8;
4627         row_info->pixel_depth = 8;
4628         row_info->rowbytes = row_width;
4629      }
4630
4631      if (row_info->bit_depth == 8)
4632      {
4633         {
4634            if (num_trans > 0)
4635            {
4636               sp = row + (png_size_t)row_width - 1;
4637               dp = row + (png_size_t)(row_width << 2) - 1;
4638
4639               for (i = 0; i < row_width; i++)
4640               {
4641                  if ((int)(*sp) >= num_trans)
4642                     *dp-- = 0xff;
4643
4644                  else
4645                     *dp-- = trans_alpha[*sp];
4646
4647                  *dp-- = palette[*sp].blue;
4648                  *dp-- = palette[*sp].green;
4649                  *dp-- = palette[*sp].red;
4650                  sp--;
4651               }
4652               row_info->bit_depth = 8;
4653               row_info->pixel_depth = 32;
4654               row_info->rowbytes = row_width * 4;
4655               row_info->color_type = 6;
4656               row_info->channels = 4;
4657            }
4658
4659            else
4660            {
4661               sp = row + (png_size_t)row_width - 1;
4662               dp = row + (png_size_t)(row_width * 3) - 1;
4663
4664               for (i = 0; i < row_width; i++)
4665               {
4666                  *dp-- = palette[*sp].blue;
4667                  *dp-- = palette[*sp].green;
4668                  *dp-- = palette[*sp].red;
4669                  sp--;
4670               }
4671
4672               row_info->bit_depth = 8;
4673               row_info->pixel_depth = 24;
4674               row_info->rowbytes = row_width * 3;
4675               row_info->color_type = 2;
4676               row_info->channels = 3;
4677            }
4678         }
4679      }
4680   }
4681}
4682
4683/* If the bit depth < 8, it is expanded to 8.  Also, if the already
4684 * expanded transparency value is supplied, an alpha channel is built.
4685 */
4686void /* PRIVATE */
4687png_do_expand(png_row_infop row_info, png_bytep row,
4688    png_const_color_16p trans_color)
4689{
4690   int shift, value;
4691   png_bytep sp, dp;
4692   png_uint_32 i;
4693   png_uint_32 row_width=row_info->width;
4694
4695   png_debug(1, "in png_do_expand");
4696
4697   {
4698      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
4699      {
4700         unsigned int gray = trans_color ? trans_color->gray : 0;
4701
4702         if (row_info->bit_depth < 8)
4703         {
4704            switch (row_info->bit_depth)
4705            {
4706               case 1:
4707               {
4708                  gray = (gray & 0x01) * 0xff;
4709                  sp = row + (png_size_t)((row_width - 1) >> 3);
4710                  dp = row + (png_size_t)row_width - 1;
4711                  shift = 7 - (int)((row_width + 7) & 0x07);
4712                  for (i = 0; i < row_width; i++)
4713                  {
4714                     if ((*sp >> shift) & 0x01)
4715                        *dp = 0xff;
4716
4717                     else
4718                        *dp = 0;
4719
4720                     if (shift == 7)
4721                     {
4722                        shift = 0;
4723                        sp--;
4724                     }
4725
4726                     else
4727                        shift++;
4728
4729                     dp--;
4730                  }
4731                  break;
4732               }
4733
4734               case 2:
4735               {
4736                  gray = (gray & 0x03) * 0x55;
4737                  sp = row + (png_size_t)((row_width - 1) >> 2);
4738                  dp = row + (png_size_t)row_width - 1;
4739                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4740                  for (i = 0; i < row_width; i++)
4741                  {
4742                     value = (*sp >> shift) & 0x03;
4743                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
4744                        (value << 6));
4745                     if (shift == 6)
4746                     {
4747                        shift = 0;
4748                        sp--;
4749                     }
4750
4751                     else
4752                        shift += 2;
4753
4754                     dp--;
4755                  }
4756                  break;
4757               }
4758
4759               case 4:
4760               {
4761                  gray = (gray & 0x0f) * 0x11;
4762                  sp = row + (png_size_t)((row_width - 1) >> 1);
4763                  dp = row + (png_size_t)row_width - 1;
4764                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
4765                  for (i = 0; i < row_width; i++)
4766                  {
4767                     value = (*sp >> shift) & 0x0f;
4768                     *dp = (png_byte)(value | (value << 4));
4769                     if (shift == 4)
4770                     {
4771                        shift = 0;
4772                        sp--;
4773                     }
4774
4775                     else
4776                        shift = 4;
4777
4778                     dp--;
4779                  }
4780                  break;
4781               }
4782
4783               default:
4784                  break;
4785            }
4786
4787            row_info->bit_depth = 8;
4788            row_info->pixel_depth = 8;
4789            row_info->rowbytes = row_width;
4790         }
4791
4792         if (trans_color != NULL)
4793         {
4794            if (row_info->bit_depth == 8)
4795            {
4796               gray = gray & 0xff;
4797               sp = row + (png_size_t)row_width - 1;
4798               dp = row + (png_size_t)(row_width << 1) - 1;
4799
4800               for (i = 0; i < row_width; i++)
4801               {
4802                  if (*sp == gray)
4803                     *dp-- = 0;
4804
4805                  else
4806                     *dp-- = 0xff;
4807
4808                  *dp-- = *sp--;
4809               }
4810            }
4811
4812            else if (row_info->bit_depth == 16)
4813            {
4814               unsigned int gray_high = (gray >> 8) & 0xff;
4815               unsigned int gray_low = gray & 0xff;
4816               sp = row + row_info->rowbytes - 1;
4817               dp = row + (row_info->rowbytes << 1) - 1;
4818               for (i = 0; i < row_width; i++)
4819               {
4820                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
4821                  {
4822                     *dp-- = 0;
4823                     *dp-- = 0;
4824                  }
4825
4826                  else
4827                  {
4828                     *dp-- = 0xff;
4829                     *dp-- = 0xff;
4830                  }
4831
4832                  *dp-- = *sp--;
4833                  *dp-- = *sp--;
4834               }
4835            }
4836
4837            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
4838            row_info->channels = 2;
4839            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
4840            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
4841               row_width);
4842         }
4843      }
4844      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color)
4845      {
4846         if (row_info->bit_depth == 8)
4847         {
4848            png_byte red = (png_byte)(trans_color->red & 0xff);
4849            png_byte green = (png_byte)(trans_color->green & 0xff);
4850            png_byte blue = (png_byte)(trans_color->blue & 0xff);
4851            sp = row + (png_size_t)row_info->rowbytes - 1;
4852            dp = row + (png_size_t)(row_width << 2) - 1;
4853            for (i = 0; i < row_width; i++)
4854            {
4855               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
4856                  *dp-- = 0;
4857
4858               else
4859                  *dp-- = 0xff;
4860
4861               *dp-- = *sp--;
4862               *dp-- = *sp--;
4863               *dp-- = *sp--;
4864            }
4865         }
4866         else if (row_info->bit_depth == 16)
4867         {
4868            png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
4869            png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
4870            png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
4871            png_byte red_low = (png_byte)(trans_color->red & 0xff);
4872            png_byte green_low = (png_byte)(trans_color->green & 0xff);
4873            png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
4874            sp = row + row_info->rowbytes - 1;
4875            dp = row + (png_size_t)(row_width << 3) - 1;
4876            for (i = 0; i < row_width; i++)
4877            {
4878               if (*(sp - 5) == red_high &&
4879                   *(sp - 4) == red_low &&
4880                   *(sp - 3) == green_high &&
4881                   *(sp - 2) == green_low &&
4882                   *(sp - 1) == blue_high &&
4883                   *(sp    ) == blue_low)
4884               {
4885                  *dp-- = 0;
4886                  *dp-- = 0;
4887               }
4888
4889               else
4890               {
4891                  *dp-- = 0xff;
4892                  *dp-- = 0xff;
4893               }
4894
4895               *dp-- = *sp--;
4896               *dp-- = *sp--;
4897               *dp-- = *sp--;
4898               *dp-- = *sp--;
4899               *dp-- = *sp--;
4900               *dp-- = *sp--;
4901            }
4902         }
4903         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
4904         row_info->channels = 4;
4905         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
4906         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4907      }
4908   }
4909}
4910#endif
4911
4912#ifdef PNG_READ_EXPAND_16_SUPPORTED
4913/* If the bit depth is 8 and the color type is not a palette type expand the
4914 * whole row to 16 bits.  Has no effect otherwise.
4915 */
4916void /* PRIVATE */
4917png_do_expand_16(png_row_infop row_info, png_bytep row)
4918{
4919   if (row_info->bit_depth == 8 &&
4920      row_info->color_type != PNG_COLOR_TYPE_PALETTE)
4921   {
4922      /* The row have a sequence of bytes containing [0..255] and we need
4923       * to turn it into another row containing [0..65535], to do this we
4924       * calculate:
4925       *
4926       *  (input / 255) * 65535
4927       *
4928       *  Which happens to be exactly input * 257 and this can be achieved
4929       *  simply by byte replication in place (copying backwards).
4930       */
4931      png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
4932      png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
4933      while (dp > sp)
4934         dp[-2] = dp[-1] = *--sp, dp -= 2;
4935
4936      row_info->rowbytes *= 2;
4937      row_info->bit_depth = 16;
4938      row_info->pixel_depth = (png_byte)(row_info->channels * 16);
4939   }
4940}
4941#endif
4942
4943#ifdef PNG_READ_QUANTIZE_SUPPORTED
4944void /* PRIVATE */
4945png_do_quantize(png_row_infop row_info, png_bytep row,
4946    png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
4947{
4948   png_bytep sp, dp;
4949   png_uint_32 i;
4950   png_uint_32 row_width=row_info->width;
4951
4952   png_debug(1, "in png_do_quantize");
4953
4954   if (row_info->bit_depth == 8)
4955   {
4956      if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
4957      {
4958         int r, g, b, p;
4959         sp = row;
4960         dp = row;
4961         for (i = 0; i < row_width; i++)
4962         {
4963            r = *sp++;
4964            g = *sp++;
4965            b = *sp++;
4966
4967            /* This looks real messy, but the compiler will reduce
4968             * it down to a reasonable formula.  For example, with
4969             * 5 bits per color, we get:
4970             * p = (((r >> 3) & 0x1f) << 10) |
4971             *    (((g >> 3) & 0x1f) << 5) |
4972             *    ((b >> 3) & 0x1f);
4973             */
4974            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4975                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4976                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4977                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4978                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4979                (PNG_QUANTIZE_BLUE_BITS)) |
4980                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4981                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4982
4983            *dp++ = palette_lookup[p];
4984         }
4985
4986         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4987         row_info->channels = 1;
4988         row_info->pixel_depth = row_info->bit_depth;
4989         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4990      }
4991
4992      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
4993         palette_lookup != NULL)
4994      {
4995         int r, g, b, p;
4996         sp = row;
4997         dp = row;
4998         for (i = 0; i < row_width; i++)
4999         {
5000            r = *sp++;
5001            g = *sp++;
5002            b = *sp++;
5003            sp++;
5004
5005            p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
5006                ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
5007                (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
5008                (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
5009                ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
5010                (PNG_QUANTIZE_BLUE_BITS)) |
5011                ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
5012                ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
5013
5014            *dp++ = palette_lookup[p];
5015         }
5016
5017         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
5018         row_info->channels = 1;
5019         row_info->pixel_depth = row_info->bit_depth;
5020         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
5021      }
5022
5023      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
5024         quantize_lookup)
5025      {
5026         sp = row;
5027
5028         for (i = 0; i < row_width; i++, sp++)
5029         {
5030            *sp = quantize_lookup[*sp];
5031         }
5032      }
5033   }
5034}
5035#endif /* PNG_READ_QUANTIZE_SUPPORTED */
5036#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
5037
5038#ifdef PNG_MNG_FEATURES_SUPPORTED
5039/* Undoes intrapixel differencing  */
5040void /* PRIVATE */
5041png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
5042{
5043   png_debug(1, "in png_do_read_intrapixel");
5044
5045   if (
5046       (row_info->color_type & PNG_COLOR_MASK_COLOR))
5047   {
5048      int bytes_per_pixel;
5049      png_uint_32 row_width = row_info->width;
5050
5051      if (row_info->bit_depth == 8)
5052      {
5053         png_bytep rp;
5054         png_uint_32 i;
5055
5056         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
5057            bytes_per_pixel = 3;
5058
5059         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
5060            bytes_per_pixel = 4;
5061
5062         else
5063            return;
5064
5065         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
5066         {
5067            *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
5068            *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
5069         }
5070      }
5071      else if (row_info->bit_depth == 16)
5072      {
5073         png_bytep rp;
5074         png_uint_32 i;
5075
5076         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
5077            bytes_per_pixel = 6;
5078
5079         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
5080            bytes_per_pixel = 8;
5081
5082         else
5083            return;
5084
5085         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
5086         {
5087            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
5088            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
5089            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
5090            png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
5091            png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
5092            *(rp    ) = (png_byte)((red >> 8) & 0xff);
5093            *(rp + 1) = (png_byte)(red & 0xff);
5094            *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
5095            *(rp + 5) = (png_byte)(blue & 0xff);
5096         }
5097      }
5098   }
5099}
5100#endif /* PNG_MNG_FEATURES_SUPPORTED */
5101#endif /* PNG_READ_SUPPORTED */
5102