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