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