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