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