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