source: svn/newcon3bcm2_21bu/dst/dlib/src/PNG/pngrtran.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

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