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