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