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