pngrtran.c revision 4215dd1533c56e1a89ae6f1d6ea68677fac27fda
1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* pngrtran.c - transforms the data in a row for PNG readers
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
44215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * Last changed in libpng 1.2.35 [February 14, 2009]
5893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * For conditions of distribution and use, see copyright notice in png.h
64215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * Copyright (c) 1998-2009 Glenn Randers-Pehrson
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * This file contains functions optionally called by an application
11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in order to tell libpng how to handle data when reading a PNG.
12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * Transformations that are used in both reading and writing are
13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in pngtrans.c.
14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_INTERNAL
17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "png.h"
18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SUPPORTED)
19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Set the action on getting a CRC error for an ancillary or critical chunk. */
21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_crc_action");
25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Tell libpng how we react to CRC errors in critical chunks */
264215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (crit_action)
28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_NO_CHANGE:                        /* leave setting as is */
30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_WARN_USE:                               /* warn/use data */
32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_QUIET_USE:                             /* quiet/use data */
36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           PNG_FLAG_CRC_CRITICAL_IGNORE;
39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_WARN_DISCARD:    /* not a valid action for critical data */
414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_warning(png_ptr,
424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            "Can't discard critical data on CRC error.");
43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_ERROR_QUIT:                                /* error/quit */
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_DEFAULT:
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      default:
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (ancil_action)
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_NO_CHANGE:                       /* leave setting as is */
53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_WARN_USE:                              /* warn/use data */
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_QUIET_USE:                            /* quiet/use data */
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_ERROR_QUIT:                               /* error/quit */
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_WARN_DISCARD:                      /* warn/discard data */
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_DEFAULT:
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      default:
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defined(PNG_FLOATING_POINT_SUPPORTED)
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* handle alpha and tRNS via a background color */
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_background(png_structp png_ptr,
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_color_16p background_color, int background_gamma_code,
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int need_expand, double background_gamma)
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
834215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_background");
844215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Application must supply a known background gamma");
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_BACKGROUND;
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_memcpy(&(png_ptr->background), background_color,
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_sizeof(png_color_16));
94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->background_gamma = (float)background_gamma;
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_16_TO_8_SUPPORTED)
101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* strip 16 bit depth files to 8 bit depth */
102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_strip_16(png_structp png_ptr)
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_strip_16");
1064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_16_TO_8;
108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_strip_alpha(png_structp png_ptr)
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_strip_alpha");
1164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_DITHER_SUPPORTED)
122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Dither file to 8 bit.  Supply a palette, the current number
123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of elements in the palette, the maximum number of elements
124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * allowed, and a histogram if possible.  If the current number
125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of colors is greater then the maximum number, the palette will be
126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * modified to fit in the maximum number.  "full_dither" indicates
127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * whether we need a dithering cube set up for RGB images, or if we
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * simply are reducing the number of colors in a paletted image.
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef struct png_dsort_struct
132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   struct png_dsort_struct FAR * next;
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte left;
135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte right;
136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} png_dsort;
137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef png_dsort FAR *       png_dsortp;
138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef png_dsort FAR * FAR * png_dsortpp;
139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_dither(png_structp png_ptr, png_colorp palette,
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int num_palette, int maximum_colors, png_uint_16p histogram,
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int full_dither)
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_dither");
1464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_DITHER;
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!full_dither)
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
1544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         (png_uint_32)(num_palette * png_sizeof(png_byte)));
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < num_palette; i++)
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->dither_index[i] = (png_byte)i;
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (num_palette > maximum_colors)
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (histogram != NULL)
162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This is easy enough, just throw out the least used colors.
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            Perhaps not the best solution, but good enough. */
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* initialize an array to sort colors */
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
1704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            (png_uint_32)(num_palette * png_sizeof(png_byte)));
171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* initialize the dither_sort array */
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->dither_sort[i] = (png_byte)i;
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* Find the least used palette entries by starting a
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bubble sort, and running it until we have sorted
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            out enough colors.  Note that we don't care about
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sorting all the colors, just finding which are
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            least used. */
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = num_palette - 1; i >= maximum_colors; i--)
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int done; /* to stop early if the list is pre-sorted */
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int j;
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            done = 1;
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (j = 0; j < i; j++)
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (histogram[png_ptr->dither_sort[j]]
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   < histogram[png_ptr->dither_sort[j + 1]])
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte t;
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  t = png_ptr->dither_sort[j];
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_sort[j + 1] = t;
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  done = 0;
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (done)
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* swap the palette around, and set up a table, if necessary */
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (full_dither)
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int j = num_palette;
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* put all the useful colors within the max, but don't
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               move the others */
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < maximum_colors; i++)
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  do
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     j--;
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i] = palette[j];
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int j = num_palette;
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* move all the used colors inside the max limit, and
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               develop a translation table */
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < maximum_colors; i++)
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               /* only move the colors we need to */
232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_color tmp_color;
235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  do
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     j--;
238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  tmp_color = palette[j];
241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[j] = palette[i];
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i] = tmp_color;
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  /* indicate where the color went */
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_index[j] = (png_byte)i;
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_index[i] = (png_byte)j;
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* find closest color for those colors we are not using */
250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < num_palette; i++)
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ((int)png_ptr->dither_index[i] >= maximum_colors)
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int min_d, k, min_k, d_index;
255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  /* find the closest color to one we threw out */
257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  d_index = png_ptr->dither_index[i];
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (k = 1, min_k = 0; k < maximum_colors; k++)
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     int d;
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (d < min_d)
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        min_d = d;
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        min_k = k;
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  /* point to closest color */
272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_index[i] = (png_byte)min_k;
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, png_ptr->dither_sort);
2774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_ptr->dither_sort = NULL;
278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This is much harder to do simply (and quickly).  Perhaps
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            we need to go through a median cut routine, but those
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            don't always behave themselves with only a few colors
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            as input.  So we will just find the closest two colors,
285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            and throw out one of them (chosen somewhat randomly).
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            [We don't understand this at all, so if someone wants to
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             work on improving it, be our guest - AED, GRP]
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            */
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int max_d;
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int num_new_palette;
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_dsortp t;
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_dsortpp hash;
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2954215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         t = NULL;
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* initialize palette index arrays */
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
2994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            (png_uint_32)(num_palette * png_sizeof(png_byte)));
300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
3014215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            (png_uint_32)(num_palette * png_sizeof(png_byte)));
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* initialize the sort array */
304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->index_to_palette[i] = (png_byte)i;
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette_to_index[i] = (png_byte)i;
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
3114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_sizeof(png_dsortp)));
3124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_memset(hash, 0, 769 * png_sizeof(png_dsortp));
313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_new_palette = num_palette;
315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* initial wild guess at how far apart the farthest pixel
317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pair we will be eliminating will be.  Larger
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            numbers mean more areas will be allocated, Smaller
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            numbers run the risk of not saving enough data, and
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            having to do this all over again.
321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            I have not done extensive checking on this number.
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            */
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         max_d = 96;
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         while (num_new_palette > maximum_colors)
327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < num_new_palette - 1; i++)
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int j;
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (j = i + 1; j < num_new_palette; j++)
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d;
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  d = PNG_COLOR_DIST(palette[i], palette[j]);
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (d <= max_d)
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t = (png_dsortp)png_malloc_warn(png_ptr,
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         (png_uint_32)(png_sizeof(png_dsort)));
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (t == NULL)
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         break;
345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t->next = hash[d];
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t->left = (png_byte)i;
347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t->right = (png_byte)j;
348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     hash[d] = t;
349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (t == NULL)
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (t != NULL)
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i <= max_d; i++)
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (hash[i] != NULL)
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_dsortp p;
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (p = hash[i]; p; p = p->next)
363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if ((int)png_ptr->index_to_palette[p->left]
365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        < num_new_palette &&
366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (int)png_ptr->index_to_palette[p->right]
367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        < num_new_palette)
368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        int j, next_j;
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (num_new_palette & 0x01)
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           j = p->left;
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           next_j = p->right;
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           j = p->right;
379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           next_j = p->left;
380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        num_new_palette--;
383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        palette[png_ptr->index_to_palette[j]]
384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          = palette[num_new_palette];
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!full_dither)
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           int k;
388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           for (k = 0; k < num_palette; k++)
390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           {
391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                              if (png_ptr->dither_index[k] ==
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->index_to_palette[j])
393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->dither_index[k] =
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    png_ptr->index_to_palette[next_j];
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                              if ((int)png_ptr->dither_index[k] ==
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 num_new_palette)
397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->dither_index[k] =
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    png_ptr->index_to_palette[j];
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           }
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_ptr->index_to_palette[png_ptr->palette_to_index
403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           [num_new_palette]] = png_ptr->index_to_palette[j];
404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           = png_ptr->palette_to_index[num_new_palette];
406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (num_new_palette <= maximum_colors)
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        break;
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (num_new_palette <= maximum_colors)
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < 769; i++)
419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (hash[i] != NULL)
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_dsortp p = hash[i];
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  while (p)
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t = p->next;
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_free(png_ptr, p);
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     p = t;
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               hash[i] = 0;
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_d += 96;
433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, hash);
435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, png_ptr->palette_to_index);
436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, png_ptr->index_to_palette);
4374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_ptr->palette_to_index = NULL;
4384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_ptr->index_to_palette = NULL;
439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      num_palette = maximum_colors;
441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->palette == NULL)
443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->palette = palette;
445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->num_palette = (png_uint_16)num_palette;
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (full_dither)
449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_bytep distance;
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         PNG_DITHER_BLUE_BITS;
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int num_red = (1 << PNG_DITHER_RED_BITS);
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int num_green = (1 << PNG_DITHER_GREEN_BITS);
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int num_blue = (1 << PNG_DITHER_BLUE_BITS);
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_size_t num_entries = ((png_size_t)1 << total_bits);
458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
4604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         (png_uint_32)(num_entries * png_sizeof(png_byte)));
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_memset(png_ptr->palette_lookup, 0, num_entries *
4634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_sizeof(png_byte));
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_sizeof(png_byte)));
467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < num_palette; i++)
471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int ir, ig, ib;
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (ir = 0; ir < num_red; ir++)
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* int dr = abs(ir - r); */
480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int dr = ((ir > r) ? ir - r : r - ir);
481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (ig = 0; ig < num_green; ig++)
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               /* int dg = abs(ig - g); */
486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int dg = ((ig > g) ? ig - g : g - ig);
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int dt = dr + dg;
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int dm = ((dr > dg) ? dr : dg);
489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (ib = 0; ib < num_blue; ib++)
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d_index = index_g | ib;
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  /* int db = abs(ib - b); */
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int db = ((ib > b) ? ib - b : b - ib);
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int dmax = ((dm > db) ? dm : db);
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d = dmax + dt + db;
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (d < (int)distance[d_index])
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     distance[d_index] = (png_byte)d;
502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_ptr->palette_lookup[d_index] = (png_byte)i;
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_free(png_ptr, distance);
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Transform the image from the file_gamma to the screen_gamma.  We
516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * only do transformations on images where the file_gamma and screen_gamma
517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * are not close reciprocals, otherwise it slows things down slightly, and
518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * also needlessly introduces small errors.
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * We will turn off gamma transformation later if no semitransparent entries
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * are present in the tRNS array for palette images.  We can't do it here
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * because we don't necessarily have the tRNS chunk yet.
523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_gamma");
5284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->transformations |= PNG_GAMMA;
533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->gamma = (float)file_gamma;
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->screen_gamma = (float)scrn_gamma;
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB, expand grayscale images of
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * to alpha channels.
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_expand(png_structp png_ptr)
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_expand");
5474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR 19990627:  the following three functions currently are identical
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  to png_set_expand().  However, it is entirely reasonable that someone
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  might wish to expand an indexed image to RGB but *not* expand a single,
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  fully transparent palette entry to a full alpha channel--perhaps instead
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  the transparent color with a particular RGB value, or drop tRNS entirely.
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  IOW, a future version of the library may make the transformations flag
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  a bit more fine-grained, with separate bits for each of these three
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  functions.
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  More to the point, these functions make it obvious what libpng will be
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  doing, whereas "expand" can (and does) mean any number of things.
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  to expand only the sample depth but not to expand the tRNS to alpha.
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB. */
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_palette_to_rgb(png_structp png_ptr)
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_palette_to_rgb");
5744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_1_0_X)
580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand grayscale images of less than 8-bit depth to 8 bits. */
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5844215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
5854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_EXPAND;
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand grayscale images of less than 8-bit depth to 8 bits. */
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Deprecated as of libpng-1.2.9 */
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_gray_1_2_4_to_8(png_structp png_ptr)
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_gray_1_2_4_to_8");
5984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand tRNS chunks to alpha channels. */
605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_tRNS_to_alpha(png_structp png_ptr)
607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_tRNS_to_alpha");
609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_gray_to_rgb(png_structp png_ptr)
617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_gray_to_rgb");
619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_GRAY_TO_RGB;
620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_FLOATING_POINT_SUPPORTED)
626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Convert a RGB image to a grayscale of the same width.  This allows us,
627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   double green)
633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int red_fixed = (int)((float)red*100000.0 + 0.5);
635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int green_fixed = (int)((float)green*100000.0 + 0.5);
6364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr == NULL) return;
637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_fixed_point red, png_fixed_point green)
644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_rgb_to_gray");
6464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch(error_action)
648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              break;
651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              break;
653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations |= PNG_EXPAND;
658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
6604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr,
6614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 red_int, green_int;
6674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (red < 0 || green < 0)
668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         red_int   =  6968; /* .212671 * 32768 + .5 */
670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         green_int = 23434; /* .715160 * 32768 + .5 */
671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
6724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      else if (red + green < 100000L)
673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         red_int   =  6968;
681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         green_int = 23434;
682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->rgb_to_gray_red_coeff   = red_int;
684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->rgb_to_gray_green_coeff = green_int;
6854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->rgb_to_gray_blue_coeff  =
6864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         (png_uint_16)(32768 - red_int - green_int);
687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defined(PNG_LEGACY_SUPPORTED)
694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   read_user_transform_fn)
697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_read_user_transform_fn");
6994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr == NULL) return;
700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_USER_TRANSFORM;
702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->read_user_transform_fn = read_user_transform_fn;
703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_LEGACY_SUPPORTED
7054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (read_user_transform_fn)
706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr,
707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        "This version of libpng does not support user transforms");
708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Initialize everything needed for the read.  This includes modifying
713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the palette.
714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_init_read_transformations(png_structp png_ptr)
717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
7184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_init_read_transformations");
719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
7204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr != NULL)
721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project || defined(PNG_READ_GAMMA_SUPPORTED)
725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int color_type = png_ptr->color_type;
726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Detect gray background and attempt to enable optimization
732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * for gray --> RGB case */
733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * background color might actually be gray yet not be flagged as such.
736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * This is not a problem for the current code, which uses
737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * png_do_gray_to_rgb() transformation.
739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    */
740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       !(color_type & PNG_COLOR_MASK_COLOR))
742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->background.red == png_ptr->background.green &&
748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->background.red == png_ptr->background.blue)
749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->background.gray = png_ptr->background.red;
752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->transformations & PNG_EXPAND))
757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* expand background and tRNS chunks */
761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         switch (png_ptr->bit_depth)
762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 1:
764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.gray *= (png_uint_16)0xff;
765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 =  png_ptr->background.blue = png_ptr->background.gray;
767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.gray *= (png_uint_16)0xff;
770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.red = png_ptr->trans_values.green
771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 2:
775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.gray *= (png_uint_16)0x55;
776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.gray *= (png_uint_16)0x55;
781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.red = png_ptr->trans_values.green
782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 4:
786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.gray *= (png_uint_16)0x11;
787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.gray *= (png_uint_16)0x11;
792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.red = png_ptr->trans_values.green
793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 8:
797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 16:
798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (color_type == PNG_COLOR_TYPE_PALETTE)
804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->background.red   =
806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette[png_ptr->background.index].red;
807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->background.green =
808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette[png_ptr->background.index].green;
809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->background.blue  =
810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette[png_ptr->background.index].blue;
811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (png_ptr->transformations & PNG_INVERT_ALPHA)
814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           /* invert the alpha channel (in tRNS) unless the pixels are
820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              going to be expanded, in which case leave it for later */
8214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              int i, istop;
822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              istop=(int)png_ptr->num_trans;
823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              for (i=0; i<istop; i++)
824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->background_1 = png_ptr->background;
835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         < PNG_GAMMA_THRESHOLD))
841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
8424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    int i, k;
843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    k=0;
844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i=0; i<png_ptr->num_trans; i++)
845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        k=1; /* partial transparency is present */
848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (k == 0)
850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations &= ~PNG_GAMMA;
851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma != 0.0)
855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_build_gamma_table(png_ptr);
857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->transformations & PNG_BACKGROUND)
859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (color_type == PNG_COLOR_TYPE_PALETTE)
861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           /* could skip if no transparency and
863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           */
864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_color back, back_1;
865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_colorp palette = png_ptr->palette;
866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int num_palette = png_ptr->num_palette;
867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int i;
868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back.red = png_ptr->gamma_table[png_ptr->background.red];
871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back.green = png_ptr->gamma_table[png_ptr->background.green];
872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               double g, gs;
881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               switch (png_ptr->background_gamma_type)
883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  case PNG_BACKGROUND_GAMMA_SCREEN:
885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = (png_ptr->screen_gamma);
886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0;
887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  case PNG_BACKGROUND_GAMMA_FILE:
889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = 1.0 / (png_ptr->gamma);
890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  case PNG_BACKGROUND_GAMMA_UNIQUE:
893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = 1.0 / (png_ptr->background_gamma);
894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0 / (png_ptr->background_gamma *
895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->screen_gamma);
896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  default:
898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = 1.0;    /* back_1 */
899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0;   /* back */
900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.red   = (png_byte)png_ptr->background.red;
905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.green = (png_byte)png_ptr->background.green;
906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.blue  = (png_byte)png_ptr->background.blue;
907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.red = (png_byte)(pow(
911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     (double)png_ptr->background.red/255, gs) * 255.0 + .5);
912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.green = (png_byte)(pow(
913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     (double)png_ptr->background.green/255, gs) * 255.0 + .5);
914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.blue = (png_byte)(pow(
915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.red = (png_byte)(pow(
919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.red/255, g) * 255.0 + .5);
920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.green = (png_byte)(pow(
921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.green/255, g) * 255.0 + .5);
922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.blue = (png_byte)(pow(
923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < num_palette; i++)
926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (png_ptr->trans[i] == 0)
930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i] = back;
932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else /* if (png_ptr->trans[i] != 0xff) */
934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte v, w;
936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     v = png_ptr->gamma_to_1[palette[i].red];
938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_composite(w, v, png_ptr->trans[i], back_1.red);
939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i].red = png_ptr->gamma_from_1[w];
940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     v = png_ptr->gamma_to_1[palette[i].green];
942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_composite(w, v, png_ptr->trans[i], back_1.green);
943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i].green = png_ptr->gamma_from_1[w];
944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     v = png_ptr->gamma_to_1[palette[i].blue];
946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_composite(w, v, png_ptr->trans[i], back_1.blue);
947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i].blue = png_ptr->gamma_from_1[w];
948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i].red = png_ptr->gamma_table[palette[i].red];
953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i].green = png_ptr->gamma_table[palette[i].green];
954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	    /* Prevent the transformations being done again, and make sure
958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	     * that the now spurious alpha channel is stripped - the code
959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	     * has just reduced background composition and gamma correction
960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	     * to a simple alpha channel strip.
961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	     */
962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	    png_ptr->transformations &= ~PNG_BACKGROUND;
963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	    png_ptr->transformations &= ~PNG_GAMMA;
964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	    png_ptr->transformations |= PNG_STRIP_ALPHA;
965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* color_type != PNG_COLOR_TYPE_PALETTE */
969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            double g = 1.0;
972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            double gs = 1.0;
973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (png_ptr->background_gamma_type)
975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case PNG_BACKGROUND_GAMMA_SCREEN:
977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  g = (png_ptr->screen_gamma);
978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gs = 1.0;
979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case PNG_BACKGROUND_GAMMA_FILE:
981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  g = 1.0 / (png_ptr->gamma);
982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case PNG_BACKGROUND_GAMMA_UNIQUE:
985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  g = 1.0 / (png_ptr->background_gamma);
986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gs = 1.0 / (png_ptr->background_gamma *
987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_ptr->screen_gamma);
988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->background_1.gray = (png_uint_16)(pow(
992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (double)png_ptr->background.gray / m, g) * m + .5);
993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->background.gray = (png_uint_16)(pow(
994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (double)png_ptr->background.gray / m, gs) * m + .5);
995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if ((png_ptr->background.red != png_ptr->background.green) ||
997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                (png_ptr->background.red != png_ptr->background.blue) ||
998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                (png_ptr->background.red != png_ptr->background.gray))
999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               /* RGB or RGBA with color background */
1001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.red = (png_uint_16)(pow(
1002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.red / m, g) * m + .5);
1003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.green = (png_uint_16)(pow(
1004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.green / m, g) * m + .5);
1005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.blue = (png_uint_16)(pow(
1006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.blue / m, g) * m + .5);
1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = (png_uint_16)(pow(
1008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.red / m, gs) * m + .5);
1009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.green = (png_uint_16)(pow(
1010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.green / m, gs) * m + .5);
1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.blue = (png_uint_16)(pow(
1012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.blue / m, gs) * m + .5);
1013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
1015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.red = png_ptr->background_1.green
1018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background_1.blue = png_ptr->background_1.gray;
1019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
1020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
1021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* transformation does not include PNG_BACKGROUND */
1026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (color_type == PNG_COLOR_TYPE_PALETTE)
1028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_colorp palette = png_ptr->palette;
1030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int num_palette = png_ptr->num_palette;
1031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
1034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i].red = png_ptr->gamma_table[palette[i].red];
1036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i].green = png_ptr->gamma_table[palette[i].green];
1037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	 /* Done the gamma correction. */
1041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project	 png_ptr->transformations &= ~PNG_GAMMA;
1042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
1046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
1048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* No GAMMA transformation */
1050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND) &&
1051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (color_type == PNG_COLOR_TYPE_PALETTE))
1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
1054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int istop = (int)png_ptr->num_trans;
1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_color back;
1056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_colorp palette = png_ptr->palette;
1057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      back.red   = (png_byte)png_ptr->background.red;
1059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      back.green = (png_byte)png_ptr->background.green;
1060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      back.blue  = (png_byte)png_ptr->background.blue;
1061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < istop; i++)
1063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->trans[i] == 0)
1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i] = back;
1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (png_ptr->trans[i] != 0xff)
1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* The png_composite() macro is defined in png.h */
1071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_composite(palette[i].red, palette[i].red,
1072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->trans[i], back.red);
1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_composite(palette[i].green, palette[i].green,
1074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->trans[i], back.green);
1075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_composite(palette[i].blue, palette[i].blue,
1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->trans[i], back.blue);
1077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Handled alpha, still need to strip the channel. */
1081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations &= ~PNG_BACKGROUND;
1082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations |= PNG_STRIP_ALPHA;
1083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SHIFT_SUPPORTED)
1087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_SHIFT) &&
1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (color_type == PNG_COLOR_TYPE_PALETTE))
1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 i;
1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 istop = png_ptr->num_palette;
1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int sr = 8 - png_ptr->sig_bit.red;
1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int sg = 8 - png_ptr->sig_bit.green;
1094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int sb = 8 - png_ptr->sig_bit.blue;
1095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (sr < 0 || sr > 8)
1097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sr = 0;
1098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (sg < 0 || sg > 8)
1099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sg = 0;
1100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (sb < 0 || sb > 8)
1101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sb = 0;
1102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < istop; i++)
1103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette[i].red >>= sr;
1105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette[i].green >>= sg;
1106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette[i].blue >>= sb;
1107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif  /* PNG_READ_SHIFT_SUPPORTED */
1110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project }
1111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project && !defined(PNG_READ_BACKGROUND_SUPPORTED)
11134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr)
1114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Modify the info structure to reflect the transformations.  The
1119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * info should be updated so a PNG file could be written with it,
1120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * assuming the transformations result in valid PNG data.
1121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_transform_info(png_structp png_ptr, png_infop info_ptr)
1124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
11254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_read_transform_info");
1126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
1127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_EXPAND)
1128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans &&
1132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (png_ptr->transformations & PNG_EXPAND_tRNS))
1133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->bit_depth = 8;
1137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->num_trans = 0;
1138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans)
1142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->transformations & PNG_EXPAND_tRNS)
1144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if 0 /* Removed from libpng-1.2.27 */
1146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
1147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
1148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (info_ptr->bit_depth < 8)
1151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            info_ptr->bit_depth = 8;
1152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->num_trans = 0;
1153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_BACKGROUND)
1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->num_trans = 0;
1162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->background = png_ptr->background;
1163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
1167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_GAMMA)
1168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
1170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->gamma = png_ptr->gamma;
1171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->int_gamma = png_ptr->int_gamma;
1174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_16_TO_8_SUPPORTED)
1179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
1180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->bit_depth = 8;
1181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
1185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
1186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
1191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_DITHER_SUPPORTED)
1194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_DITHER)
1195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
1198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette_lookup && info_ptr->bit_depth == 8)
1199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
1201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_PACK_SUPPORTED)
1206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
1207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->bit_depth = 8;
1208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 1;
1212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
1213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 3;
1214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
1215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 1;
1216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
1219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
1223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels++;
1224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_FILLER_SUPPORTED)
1226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
1227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_FILLER) &&
1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
1230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels++;
1232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* if adding a true alpha channel not just filler */
1233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_1_0_X)
1234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->transformations & PNG_ADD_ALPHA)
1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefined(PNG_READ_USER_TRANSFORM_SUPPORTED)
12424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->transformations & PNG_USER_TRANSFORM)
1243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
12444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       if (info_ptr->bit_depth < png_ptr->user_transform_depth)
1245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->bit_depth = png_ptr->user_transform_depth;
12464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       if (info_ptr->channels < png_ptr->user_transform_channels)
1247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->channels = png_ptr->user_transform_channels;
1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
1249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
1252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->bit_depth);
1253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
1255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_READ_EXPAND_SUPPORTED)
12574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr)
1258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Transform the row.  The order of transformations is significant,
1263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * and is very touchy.  If you add a transformation, take care to
1264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * decide how it fits in with the other transformations here.
1265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_transformations(png_structp png_ptr)
1268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
12694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_transformations");
1270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->row_buf == NULL)
1271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
1273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      char msg[50];
1274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_snprintf2(msg, 50,
12764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
1277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->pass);
1278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, msg);
1279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "NULL row buffer");
1281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_WARN_UNINITIALIZED_ROW
1284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
1285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Application has failed to call either png_read_start_image()
1286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * or png_read_update_info() after setting transforms that expand
1287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * pixels.  This check added to libpng-1.2.19 */
1288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if (PNG_WARN_UNINITIALIZED_ROW==1)
1289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Uninitialized row");
1290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Uninitialized row");
1292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
1296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_EXPAND)
1297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
1299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
1301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
1302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans &&
1306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             (png_ptr->transformations & PNG_EXPAND_tRNS))
1307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               &(png_ptr->trans_values));
1309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               NULL);
1312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
1317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
1318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
1320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
1323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int rgb_error =
1326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
13274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (rgb_error)
1328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->rgb_to_gray_status=1;
13304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
1331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             PNG_RGB_TO_GRAY_WARN)
1332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
13334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
1334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             PNG_RGB_TO_GRAY_ERR)
1335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
1336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
1341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectFrom Andreas Dilger e-mail to png-implement, 26 March 1998:
1342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  In most cases, the "simple transparency" should be done prior to doing
1344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  gray-to-RGB, or you will have to test 3x as many bytes to check if a
1345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  pixel is transparent.  You would also need to make sure that the
1346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  transparency information is upgraded to RGB.
1347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  To summarize, the current flow is:
1349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  with background "in place" if transparent,
1351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  convert to RGB if necessary
1352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  - Gray + alpha -> composite with gray background and remove alpha bytes,
1353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  convert to RGB if necessary
1354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  To support RGB backgrounds for gray images we need:
1356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  - Gray + simple transparency -> convert to RGB + simple transparency, compare
1357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  3 or 6 bytes and composite with background
1358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  "in place" if transparent (3x compare/pixel
1359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  compared to doing composite with gray bkgrnd)
1360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  - Gray + alpha -> convert to RGB + alpha, composite with background and
1361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  remove alpha bytes (3x float operations/pixel
1362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  compared with composite on gray background)
1363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  Greg's change will do this.  The reason it wasn't done before is for
1365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  performance, as this increases the per-pixel operations.  If we would check
1366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  in advance if the background was gray or RGB, and position the gray-to-RGB
1367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  transform appropriately, then it would save a lot of work/time.
1368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* if gray -> RGB, do so now only if background is non-gray; else do later
1372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * for performance reasons */
1373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND) &&
1380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      ((png_ptr->num_trans != 0 ) ||
1381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
1382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
1383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         &(png_ptr->trans_values), &(png_ptr->background)
1384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
1385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         , &(png_ptr->background_1),
1386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_table, png_ptr->gamma_from_1,
1387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_to_1, png_ptr->gamma_16_table,
1388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
1389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_shift
1390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project);
1392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
1395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_GAMMA) &&
1396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
1397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      !((png_ptr->transformations & PNG_BACKGROUND) &&
1398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      ((png_ptr->num_trans != 0) ||
1399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
1400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
1402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
1403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_table, png_ptr->gamma_16_table,
1404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_shift);
1405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_16_TO_8_SUPPORTED)
1408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_16_TO_8)
1409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
1410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_DITHER_SUPPORTED)
1413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_DITHER)
1414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
1416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette_lookup, png_ptr->dither_index);
14174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->row_info.rowbytes == (png_uint_32)0)
1418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_error(png_ptr, "png_do_dither returned rowbytes=0");
1419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_INVERT_SUPPORTED)
1423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_INVERT_MONO)
1424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
1425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SHIFT_SUPPORTED)
1428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_SHIFT)
1429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
1430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         &(png_ptr->shift));
1431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_PACK_SUPPORTED)
1434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_PACK)
1435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
1436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BGR_SUPPORTED)
1439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_BGR)
1440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
1441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
1444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_PACKSWAP)
1445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
1449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* if gray -> RGB, do so now only if we did not do so above */
1450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_FILLER_SUPPORTED)
1456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_FILLER)
1457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         (png_uint_32)png_ptr->filler, png_ptr->flags);
1459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_INVERT_ALPHA)
1463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_SWAP_ALPHA)
1468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SWAP_SUPPORTED)
1472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_SWAP_BYTES)
1473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
1477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_USER_TRANSFORM)
1478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
14794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->read_user_transform_fn != NULL)
1480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        (*(png_ptr->read_user_transform_fn)) /* user read transform function */
1481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          (png_ptr,                    /* png_ptr */
1482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           &(png_ptr->row_info),       /* row_info:     */
1483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             /*  png_uint_32 width;          width of row */
1484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             /*  png_uint_32 rowbytes;       number of bytes in row */
1485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             /*  png_byte color_type;        color type of pixels */
1486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             /*  png_byte bit_depth;         bit depth of samples */
1487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             /*  png_byte channels;          number of channels (1-4) */
1488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
1489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->row_buf + 1);      /* start of pixel data for row */
1490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
14914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->user_transform_depth)
1492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
14934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->user_transform_channels)
1494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.channels = png_ptr->user_transform_channels;
1495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
1497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.channels);
1498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
1499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.width);
1500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_PACK_SUPPORTED)
1506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * without changing the actual values.  Thus, if you had a row with
1508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * a bit depth of 1, you would end up with bytes that only contained
1509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
1510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * png_do_shift() after this.
1511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_unpack(png_row_infop row_info, png_bytep row)
1514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
15154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_unpack");
1516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
1517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
1518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row_info->bit_depth < 8)
1520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 i;
1523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width=row_info->width;
1524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->bit_depth)
1526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 1:
1528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
1530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)row_width - 1;
1531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
1532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp = (png_byte)((*sp >> shift) & 0x01);
1535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == 7)
1536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 0;
1538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
1539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
1541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift++;
1542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp--;
1544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 2:
1548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
1551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)row_width - 1;
1552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
1553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp = (png_byte)((*sp >> shift) & 0x03);
1556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == 6)
1557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 0;
1559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
1560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
1562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift += 2;
1563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp--;
1565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 4:
1569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
1571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)row_width - 1;
1572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
1573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp = (png_byte)((*sp >> shift) & 0x0f);
1576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == 4)
1577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 0;
1579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
1580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
1582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 4;
1583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp--;
1585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->bit_depth = 8;
1590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->rowbytes = row_width * row_info->channels;
1592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SHIFT_SUPPORTED)
1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Reverse the effects of png_do_shift.  This routine merely shifts the
1598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * pixels back to their significant bits values.  Thus, if you have
1599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * a row of bit depth 8, but only 5 are significant, this will shift
1600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the values back to 0 through 31.
1601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
1604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
16054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_unshift");
1606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
1607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
1608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL && sig_bits != NULL &&
1609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
1611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int shift[4];
1613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int channels = 0;
1614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int c;
1615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 value = 0;
1616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
1617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
1619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->red;
1621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->green;
1622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->blue;
1623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->gray;
1627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
1629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
1631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (c = 0; c < channels; c++)
1634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (shift[c] <= 0)
1636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            shift[c] = 0;
1637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            value = 1;
1639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!value)
1642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
1643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->bit_depth)
1645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 2:
1647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp;
1649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = row_info->rowbytes;
1651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (bp = row, i = 0; i < istop; i++)
1653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp >>= 1;
1655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ &= 0x55;
1656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 4:
1660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp = row;
1662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = row_info->rowbytes;
1664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
1665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)((int)0xf >> shift[0]));
1666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < istop; i++)
1668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp >>= shift[0];
1670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ &= mask;
1671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 8:
1675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp = row;
1677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = row_width * channels;
1679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < istop; i++)
1681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ >>= shift[i%channels];
1683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 16:
1687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp = row;
1689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = channels * row_width;
1691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < istop; i++)
1693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               value = (png_uint_16)((*bp << 8) + *(bp + 1));
1695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               value >>= shift[i%channels];
1696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ = (png_byte)(value >> 8);
1697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ = (png_byte)(value & 0xff);
1698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_16_TO_8_SUPPORTED)
1707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* chop rows of bit depth 16 down to 8 */
1708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_chop(png_row_infop row_info, png_bytep row)
1710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
17114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_chop");
1712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
1713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
1714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row_info->bit_depth == 16)
1716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_bytep sp = row;
1719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_bytep dp = row;
1720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 i;
1721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 istop = row_info->width * row_info->channels;
1722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i<istop; i++, sp += 2, dp++)
1724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
1726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* This does a more accurate scaling of the 16-bit color
1727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * value, rather than a simple low-byte truncation.
1728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * What the ideal calculation should be:
1730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = (((((png_uint_32)(*sp) << 8) |
1731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *          (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
1732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * GRR: no, I think this is what it really should be:
1734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = (((((png_uint_32)(*sp) << 8) |
1735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *           (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
1736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * GRR: here's the exact calculation with shifts:
1738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
1739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = (temp - (temp >> 8)) >> 8;
1740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * Approximate calculation with shift/add instead of multiply/divide:
1742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = ((((png_uint_32)(*sp) << 8) |
1743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * What we actually do to avoid extra shifting and conversion:
1746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       */
1747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
1749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       /* Simply discard the low order byte */
1751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *dp = *sp;
1752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->bit_depth = 8;
1755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->rowbytes = row_info->width * row_info->channels;
1757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
1762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
1764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
17654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_swap_alpha");
1766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
1767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
1768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
1771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from RGBA to ARGB */
1774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
1775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save;
1779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save = *(--sp);
1784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save;
1788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from RRGGBBAA to AARRGGBB */
1791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save[2];
1796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[0] = *(--sp);
1801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[1] = *(--sp);
1802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[0];
1809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[1];
1810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from GA to AG */
1816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
1817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save;
1821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save = *(--sp);
1826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save;
1828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from GGAA to AAGG */
1831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save[2];
1836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[0] = *(--sp);
1841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[1] = *(--sp);
1842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[0];
1845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[1];
1846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
1854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
1856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
18574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_invert_alpha");
1858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
1859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
1860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
1863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in RGBA */
1866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
1867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*             This does nothing:
1877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               We can replace it with:
1881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/
1882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp-=3;
1883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp=sp;
1884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in RRGGBBAA */
1887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*             This does nothing:
1899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               We can replace it with:
1906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/
1907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp-=6;
1908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp=sp;
1909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in GA */
1915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
1916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in GGAA */
1928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp  = row + row_info->rowbytes;
1931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
1939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/
1942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp-=2;
1943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp=sp;
1944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_FILLER_SUPPORTED)
1952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Add filler channel if we have RGB color */
1953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_filler(png_row_infop row_info, png_bytep row,
1955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 filler, png_uint_32 flags)
1956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
1958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width = row_info->width;
1959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
1961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte lo_filler = (png_byte)(filler & 0xff);
1962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_filler");
1964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
1965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
1966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL  && row_info != NULL &&
1967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row_info->color_type == PNG_COLOR_TYPE_GRAY)
1969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
19704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (row_info->bit_depth == 8)
1971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from G to GX */
1973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
1974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width;
1976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp =  sp + (png_size_t)row_width;
1977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
1978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
1980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
1983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
1984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 16;
1985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 2;
1986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* This changes the data from G to XG */
1988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width;
1991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width;
1992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
1996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
1998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 16;
1999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 2;
2000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
20024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      else if (row_info->bit_depth == 16)
2003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from GG to GGXX */
2005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
2006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2;
2008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
2010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = hi_filler;
2017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
2018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
2019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from GG to XXGG */
2023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2;
2026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
2035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   } /* COLOR_TYPE == GRAY */
2040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
20424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (row_info->bit_depth == 8)
2043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from RGB to RGBX */
2045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
2046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 3;
2048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width;
2049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
2050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
2057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* This changes the data from RGB to XRGB */
2062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 3;
2065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp + (png_size_t)row_width;
2066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
20784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      else if (row_info->bit_depth == 16)
2079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from RRGGBB to RRGGBBXX */
2081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
2082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 6;
2084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
2086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = hi_filler;
2097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
2098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 64;
2100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 8;
2101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from RRGGBB to XXRRGGBB */
2103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 6;
2106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 64;
2120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 8;
2121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   } /* COLOR_TYPE == RGB */
2124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* expand grayscale files to RGB, with or without alpha */
2129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
2131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
2133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width = row_info->width;
2134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_gray_to_rgb");
2136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row_info->bit_depth >= 8 &&
2137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
2138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
2139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      !(row_info->color_type & PNG_COLOR_MASK_COLOR))
2141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width - 1;
2147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 4;
2159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
2187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 4;
2188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->channels += (png_byte)2;
2202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->color_type |= PNG_COLOR_MASK_COLOR;
2203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(row_info->channels *
2204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->bit_depth);
22054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
2211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* reduce RGB files to grayscale, with or without alpha
2212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * using the equation given in Poynton's ColorFAQ at
22134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008)
22144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * New link:
22154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * <http://www.poynton.com/notes/colour_and_gamma/>
22164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * Charles Poynton poynton at poynton.com
2217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  We approximate this with
2221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
2223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  which can be expressed with integers as
2225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
2227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  The calculation is to be done in a linear colorspace.
2229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  Other integer coefficents can be used via png_set_rgb_to_gray().
2231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
2232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint /* PRIVATE */
2233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
2234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
2237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width = row_info->width;
2239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int rgb_error = 0;
2240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_rgb_to_gray");
2242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
2243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
2244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
2245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (row_info->color_type & PNG_COLOR_MASK_COLOR))
2247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
2249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
2250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
2251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
2265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
2266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
22674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *(dp++) = png_ptr->gamma_from_1[
22714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                       (rc*red + gc*green + bc*blue)>>15];
2272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
22744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                     *(dp++) = *(sp - 1);
2275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = *(sp++);
2285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = *(sp++);
2286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = *(sp++);
22874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
22904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                     *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
2291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
22934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                     *(dp++) = *(sp - 1);
2294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else /* RGB bit_depth == 16 */
2299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_16_to_1 != NULL &&
2302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                png_ptr->gamma_16_from_1 != NULL)
2303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, w;
2309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red == green && red == blue)
2315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = red;
2316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
2319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][red>>8];
2320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
2321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][green>>8];
2322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
2323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][blue>>8];
2324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
2325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  + bc*blue_1)>>15);
2326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         png_ptr->gamma_shift][gray16 >> 8];
2328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((w>>8) & 0xff);
2332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(w & 0xff);
2333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, gray16;
2343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
2352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(gray16 & 0xff);
2353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
2369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
2370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
23714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) =  png_ptr->gamma_from_1
2374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             [(rc*red + gc*green + bc*blue)>>15];
2375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = *(sp++);
2386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = *(sp++);
2387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = *(sp++);
23884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
2391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else /* RGBA bit_depth == 16 */
2396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_16_to_1 != NULL &&
2399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                png_ptr->gamma_16_from_1 != NULL)
2400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, w;
2406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
24114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red == green && red == blue)
2412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = red;
2413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
2416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][red>>8];
2417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
2418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][green>>8];
2419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
2420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][blue>>8];
2421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 gray16  = (png_uint_16)((rc * red_1
2422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  + gc * green_1 + bc * blue_1)>>15);
2423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         png_ptr->gamma_shift][gray16 >> 8];
2425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((w>>8) & 0xff);
2429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(w & 0xff);
2430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);
2432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, gray16;
2442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
24454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
2449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(gray16 & 0xff);
2450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);
2452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   row_info->channels -= (png_byte)2;
2457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
2458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(row_info->channels *
2459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->bit_depth);
24604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   return rgb_error;
2463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
2467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * large of png_color.  This lets grayscale images be treated as
2468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * paletted.  Most useful for gamma correction and simplification
2469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of code.
2470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
2471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
2472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_build_grayscale_palette(int bit_depth, png_colorp palette)
2473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int num_palette;
2475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int color_inc;
2476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int i;
2477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int v;
2478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
24794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_build_grayscale_palette");
2480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (palette == NULL)
2481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (bit_depth)
2484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 1:
2486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 2;
2487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0xff;
2488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 2:
2490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 4;
2491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0x55;
2492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 4:
2494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 16;
2495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0x11;
2496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 8:
2498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 256;
2499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 1;
2500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      default:
2502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 0;
2503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0;
2504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
2508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].red = (png_byte)v;
2510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].green = (png_byte)v;
2511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].blue = (png_byte)v;
2512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* This function is currently unused.  Do we really need it? */
2516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
2517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_correct_palette(png_structp png_ptr, png_colorp palette,
2519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int num_palette)
2520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
25214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_correct_palette");
2522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
2523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
2524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
2525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_color back, back_1;
2527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
2529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.red = png_ptr->gamma_table[png_ptr->background.red];
2531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.green = png_ptr->gamma_table[png_ptr->background.green];
2532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.blue = png_ptr->gamma_table[png_ptr->background.blue];
2533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
2535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
2536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
2537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
2539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         double g;
2541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
2543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
2545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
2546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.red = png_ptr->background.red;
2548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.green = png_ptr->background.green;
2549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.blue = png_ptr->background.blue;
2550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.red =
2554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)(pow((double)png_ptr->background.red/255, g) *
2555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                255.0 + 0.5);
2556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.green =
2557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)(pow((double)png_ptr->background.green/255, g) *
2558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                255.0 + 0.5);
2559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.blue =
2560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)(pow((double)png_ptr->background.blue/255, g) *
2561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                255.0 + 0.5);
2562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         g = 1.0 / png_ptr->background_gamma;
2565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.red =
2567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            (png_byte)(pow((double)png_ptr->background.red/255, g) *
2568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             255.0 + 0.5);
2569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.green =
2570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            (png_byte)(pow((double)png_ptr->background.green/255, g) *
2571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             255.0 + 0.5);
2572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.blue =
2573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            (png_byte)(pow((double)png_ptr->background.blue/255, g) *
2574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             255.0 + 0.5);
2575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
2580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < (png_uint_32)num_palette; i++)
2582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
2584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i] = back;
2586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
2588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte v, w;
2590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
2592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(w, v, png_ptr->trans[i], back_1.red);
2593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = png_ptr->gamma_from_1[w];
2594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
2596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(w, v, png_ptr->trans[i], back_1.green);
2597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = png_ptr->gamma_from_1[w];
2598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
2600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(w, v, png_ptr->trans[i], back_1.blue);
2601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = png_ptr->gamma_from_1[w];
2602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = png_ptr->gamma_table[palette[i].red];
2606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = png_ptr->gamma_table[palette[i].green];
2607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
2612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
2614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
2616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
2618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i] = back;
2620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = png_ptr->gamma_table[palette[i].red];
2624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = png_ptr->gamma_table[palette[i].green];
2625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
2631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_GAMMA)
2634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
2636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < num_palette; i++)
2638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette[i].red = png_ptr->gamma_table[palette[i].red];
2640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette[i].green = png_ptr->gamma_table[palette[i].green];
2641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
2645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
2646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
2649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_BACKGROUND)
2650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_color back;
2654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.red   = (png_byte)png_ptr->background.red;
2656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.green = (png_byte)png_ptr->background.green;
2657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.blue  = (png_byte)png_ptr->background.blue;
2658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < (int)png_ptr->num_trans; i++)
2660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->trans[i] == 0)
2662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = back.red;
2664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = back.green;
2665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = back.blue;
2666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (png_ptr->trans[i] != 0xff)
2668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(palette[i].red, png_ptr->palette[i].red,
2670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->trans[i], back.red);
2671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(palette[i].green, png_ptr->palette[i].green,
2672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->trans[i], back.green);
2673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(palette[i].blue, png_ptr->palette[i].blue,
2674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->trans[i], back.blue);
2675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else /* assume grayscale palette (what else could it be?) */
2679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
2681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
2683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (i == (png_byte)png_ptr->trans_values.gray)
2685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = (png_byte)png_ptr->background.red;
2687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = (png_byte)png_ptr->background.green;
2688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = (png_byte)png_ptr->background.blue;
2689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED)
2698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Replace any alpha or transparency with the supplied background color.
2699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "background" is already in the screen gamma, while "background_1" is
2700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * at a gamma of 1.0.  Paletted files have already been taken care of.
2701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
2702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_background(png_row_infop row_info, png_bytep row,
2704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_color_16p trans_values, png_color_16p background
2705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   , png_color_16p background_1,
2707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
2708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
2709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_16pp gamma_16_to_1, int gamma_shift
2710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   )
2712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
2714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
2715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
2716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int shift;
2717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
27184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_background");
2719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (background != NULL &&
2720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
2721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
2722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
2724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
2725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->color_type)
2727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY:
2729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (row_info->bit_depth)
2731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 1:
2733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
2735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 7;
2736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
2737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if ((png_uint_16)((*sp >> shift) & 0x01)
2739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        == trans_values->gray)
2740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp |= (png_byte)(background->gray << shift);
2743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (!shift)
2745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 7;
2747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp++;
2748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
2750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift--;
2751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 2:
2755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_table != NULL)
2758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 6;
2761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x03)
2764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
2772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
2773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                               (p << 4) | (p << 6)] >> 6) & 0x03);
2774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(g << shift);
2776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 6;
2780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 2;
2784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 6;
2791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x03)
2794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 6;
2802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 2;
2806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 4:
2811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_table != NULL)
2814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 4;
2817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x0f)
2820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
2828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte g = (png_byte)((gamma_table[p |
2829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             (p << 4)] >> 4) & 0x0f);
2830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(g << shift);
2832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 4;
2836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 4;
2840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 4;
2847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x0f)
2850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 4;
2858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 4;
2862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 8:
2867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_table != NULL)
2870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp++)
2873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (*sp == trans_values->gray)
2875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)background->gray;
2877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = gamma_table[*sp];
2881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp++)
2889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (*sp == trans_values->gray)
2891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)background->gray;
2893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 16:
2899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_16 != NULL)
2902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp += 2)
2905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
2907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (v == trans_values->gray)
2910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           /* background is already in screen gamma */
2912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)((background->gray >> 8) & 0xff);
2913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *(sp + 1) = (png_byte)(background->gray & 0xff);
2914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
2918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)((v >> 8) & 0xff);
2919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *(sp + 1) = (png_byte)(v & 0xff);
2920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp += 2)
2928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
2930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (v == trans_values->gray)
2933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)((background->gray >> 8) & 0xff);
2935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *(sp + 1) = (png_byte)(background->gray & 0xff);
2936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB:
2945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
2947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_table != NULL)
2950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
2952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 3)
2953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (*sp == trans_values->red &&
2955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) == trans_values->green &&
2956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) == trans_values->blue)
2957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)background->red;
2959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)background->green;
2960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)background->blue;
2961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
2963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = gamma_table[*sp];
2965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = gamma_table[*(sp + 1)];
2966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = gamma_table[*(sp + 2)];
2967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
2974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 3)
2975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (*sp == trans_values->red &&
2977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) == trans_values->green &&
2978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) == trans_values->blue)
2979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)background->red;
2981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)background->green;
2982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)background->blue;
2983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
2988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
2990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_16 != NULL)
2991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
2993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 6)
2994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
2996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
2997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
2998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (r == trans_values->red && g == trans_values->green &&
2999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        b == trans_values->blue)
3000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* background is already in screen gamma */
3002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)((background->red >> 8) & 0xff);
3003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)(background->red & 0xff);
3004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
3005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 3) = (png_byte)(background->green & 0xff);
3006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 5) = (png_byte)(background->blue & 0xff);
3008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)((v >> 8) & 0xff);
3013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)(v & 0xff);
3014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 3) = (png_byte)(v & 0xff);
3017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 5) = (png_byte)(v & 0xff);
3020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 6)
3028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
3030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
3032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (r == trans_values->red && g == trans_values->green &&
3034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        b == trans_values->blue)
3035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)((background->red >> 8) & 0xff);
3037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)(background->red & 0xff);
3038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
3039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 3) = (png_byte)(background->green & 0xff);
3040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 5) = (png_byte)(background->blue & 0xff);
3042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY_ALPHA:
3049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_table != NULL)
3055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 2, dp++)
3059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = *(sp + 1);
3061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_table[*sp];
3065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* background is already in screen gamma */
3069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->gray;
3070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_byte v, w;
3074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*sp];
3076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->gray);
3077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_from_1[w];
3078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 2, dp++)
3087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte a = *(sp + 1);
3089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = *sp;
3093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->gray;
3098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*dp, *sp, a, background_1->gray);
3102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
3104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = (png_byte)background->gray;
3105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (png_ptr->bit_depth == 16) */
3110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_16_to_1 != NULL)
3114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
3118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
3132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* background is already in screen gamma */
3136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->gray >> 8) & 0xff);
3137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->gray & 0xff);
3138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 g, v, w;
3143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, g, a, background_1->gray);
3146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
3147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((w >> 8) & 0xff);
3148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(w & 0xff);
3149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
3159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_memcpy(dp, sp, 2);
3164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
3168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->gray >> 8) & 0xff);
3172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->gray & 0xff);
3173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 g, v;
3178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, g, a, background_1->gray);
3181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB_ALPHA:
3191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_table != NULL)
3197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte a = *(sp + 3);
3203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_table[*sp];
3207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = gamma_table[*(sp + 1)];
3208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = gamma_table[*(sp + 2)];
3209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* background is already in screen gamma */
3213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->red;
3214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)background->green;
3215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)background->blue;
3216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_byte v, w;
3220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*sp];
3222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->red);
3223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_from_1[w];
3224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*(sp + 1)];
3225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->green);
3226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = gamma_from_1[w];
3227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*(sp + 2)];
3228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->blue);
3229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = gamma_from_1[w];
3230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte a = *(sp + 3);
3241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = *sp;
3245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = *(sp + 1);
3246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = *(sp + 2);
3247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->red;
3251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)background->green;
3252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)background->blue;
3253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*dp, *sp, a, background->red);
3257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*(dp + 1), *(sp + 1), a,
3258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           background->green);
3259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*(dp + 2), *(sp + 2), a,
3260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           background->blue);
3261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_16_to_1 != NULL)
3270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         << 8) + (png_uint_16)(*(sp + 7)));
3277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
3286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(v & 0xff);
3287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
3289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(v & 0xff);
3290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        /* background is already in screen gamma */
3294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->red >> 8) & 0xff);
3295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->red & 0xff);
3296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(background->green & 0xff);
3298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(background->blue & 0xff);
3300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v, w, x;
3304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(w, v, a, background_1->red);
3307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((x >> 8) & 0xff);
3309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(x & 0xff);
3310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(w, v, a, background_1->green);
3312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((x >> 8) & 0xff);
3314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(x & 0xff);
3315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(w, v, a, background_1->blue);
3317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
3318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((x >> 8) & 0xff);
3319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(x & 0xff);
3320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        << 8) + (png_uint_16)(*(sp + 7)));
3332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_memcpy(dp, sp, 6);
3335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->red >> 8) & 0xff);
3339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->red & 0xff);
3340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(background->green & 0xff);
3342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(background->blue & 0xff);
3344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            + *(sp + 3));
3352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            + *(sp + 5));
3354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, r, a, background->red);
3356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, g, a, background->green);
3359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
3360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(v & 0xff);
3361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, b, a, background->blue);
3362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
3363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(v & 0xff);
3364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
3373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
3375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels--;
3376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = (png_byte)(row_info->channels *
3377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->bit_depth);
33784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
3385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Gamma correct the image, avoiding the alpha channel.  Make sure
3386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * you do this after you deal with the transparency issue on grayscale
3387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * or RGB images. If your bit depth is 8, use gamma_table, if it
3388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * is 16, use gamma_16_table and gamma_shift.  Build these with
3389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * build_gamma_table().
3390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
3391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_gamma(png_row_infop row_info, png_bytep row,
3393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep gamma_table, png_uint_16pp gamma_16_table,
3394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int gamma_shift)
3395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp;
3397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
3398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
3399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
34004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_gamma");
3401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
3402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
3403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
3404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
3406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
3407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->color_type)
3409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB:
3411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v;
3431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB_ALPHA:
3449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 4;
3481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY_ALPHA:
3486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 4;
3505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY:
3510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 2)
3512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i += 4)
3515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int a = *sp & 0xc0;
3517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int b = *sp & 0x30;
3518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int c = *sp & 0x0c;
3519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d = *sp & 0x03;
3520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)(
3522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
3523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
3524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
3525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
3526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 4)
3530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i += 2)
3533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int msb = *sp & 0xf0;
3535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int lsb = *sp & 0x0f;
3536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
3538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
3539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (row_info->bit_depth == 8)
3543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (row_info->bit_depth == 16)
3552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
3570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expands a palette row to an RGB or RGBA row depending
3571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * upon whether you supply trans and num_trans.
3572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
3573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand_palette(png_row_infop row_info, png_bytep row,
3575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_colorp palette, png_bytep trans, int num_trans)
3576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int shift, value;
3578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
3579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
3580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
3581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
35824215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_expand_palette");
3583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
3584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
3585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
3586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row_info->color_type == PNG_COLOR_TYPE_PALETTE)
3588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->bit_depth < 8)
3590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         switch (row_info->bit_depth)
3592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 1:
3594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)((row_width - 1) >> 3);
3596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)row_width - 1;
3597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               shift = 7 - (int)((row_width + 7) & 0x07);
3598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if ((*sp >> shift) & 0x01)
3601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = 1;
3602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = 0;
3604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (shift == 7)
3605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 0;
3607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp--;
3608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift++;
3611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp--;
3613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
3615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 2:
3617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)((row_width - 1) >> 2);
3619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)row_width - 1;
3620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  value = (*sp >> shift) & 0x03;
3624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp = (png_byte)value;
3625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (shift == 6)
3626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 0;
3628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp--;
3629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift += 2;
3632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp--;
3634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
3636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 4:
3638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)((row_width - 1) >> 1);
3640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)row_width - 1;
3641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               shift = (int)((row_width & 0x01) << 2);
3642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  value = (*sp >> shift) & 0x0f;
3645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp = (png_byte)value;
3646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (shift == 4)
3647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 0;
3649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp--;
3650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift += 4;
3653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp--;
3655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
3657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->bit_depth = 8;
3660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = 8;
3661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->rowbytes = row_width;
3662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->bit_depth)
3664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 8:
3666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (trans != NULL)
3668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)row_width - 1;
3670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)(row_width << 2) - 1;
3671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if ((int)(*sp) >= num_trans)
3675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = trans[*sp];
3678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].blue;
3679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].green;
3680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].red;
3681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
3682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->bit_depth = 8;
3684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->pixel_depth = 32;
3685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->rowbytes = row_width * 4;
3686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->color_type = 6;
3687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->channels = 4;
3688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
3690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)row_width - 1;
3692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)(row_width * 3) - 1;
3693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].blue;
3697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].green;
3698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].red;
3699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
3700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->bit_depth = 8;
3702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->pixel_depth = 24;
3703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->rowbytes = row_width * 3;
3704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->color_type = 2;
3705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->channels = 3;
3706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* If the bit depth < 8, it is expanded to 8.  Also, if the already
3714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * expanded transparency value is supplied, an alpha channel is built.
3715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
3716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand(png_row_infop row_info, png_bytep row,
3718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_color_16p trans_value)
3719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int shift, value;
3721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
3722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
3723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
3724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
37254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_expand");
3726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
3727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
3728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
3731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
3733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth < 8)
3735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (row_info->bit_depth)
3737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 1:
3739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray = (png_uint_16)((gray&0x01)*0xff);
3741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row + (png_size_t)((row_width - 1) >> 3);
3742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row + (png_size_t)row_width - 1;
3743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 7 - (int)((row_width + 7) & 0x07);
3744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
3745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if ((*sp >> shift) & 0x01)
3747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = 0xff;
3748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = 0;
3750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (shift == 7)
3751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 0;
3753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp--;
3754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift++;
3757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
3759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 2:
3763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray = (png_uint_16)((gray&0x03)*0x55);
3765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row + (png_size_t)((row_width - 1) >> 2);
3766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row + (png_size_t)row_width - 1;
3767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
3769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     value = (*sp >> shift) & 0x03;
3771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
3772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (value << 6));
3773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (shift == 6)
3774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 0;
3776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp--;
3777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift += 2;
3780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
3782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 4:
3786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray = (png_uint_16)((gray&0x0f)*0x11);
3788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row + (png_size_t)((row_width - 1) >> 1);
3789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row + (png_size_t)row_width - 1;
3790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
3791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
3792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     value = (*sp >> shift) & 0x0f;
3794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = (png_byte)(value | (value << 4));
3795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (shift == 4)
3796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 0;
3798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp--;
3799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 4;
3802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
3804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->bit_depth = 8;
3809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 8;
3810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width;
3811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (trans_value != NULL)
3814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               gray = gray & 0xff;
3818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)row_width - 1;
3819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)(row_width << 1) - 1;
3820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (*sp == gray)
3823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0;
3824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = *sp--;
3827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (row_info->bit_depth == 16)
3830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte gray_high = (gray >> 8) & 0xff;
3832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte gray_low = gray & 0xff;
3833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + row_info->rowbytes - 1;
3834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (row_info->rowbytes << 1) - 1;
3835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
38374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
3838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0;
3840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0;
3841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = *sp--;
3848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = *sp--;
3849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
3852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
3853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
3854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
3855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_width);
3856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
3859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
3861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte red = trans_value->red & 0xff;
3863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte green = trans_value->green & 0xff;
3864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte blue = trans_value->blue & 0xff;
3865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sp = row + (png_size_t)row_info->rowbytes - 1;
3866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dp = row + (png_size_t)(row_width << 2) - 1;
3867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
3868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
3870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0;
3871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0xff;
3873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (row_info->bit_depth == 16)
3879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte red_high = (trans_value->red >> 8) & 0xff;
3881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte green_high = (trans_value->green >> 8) & 0xff;
3882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte blue_high = (trans_value->blue >> 8) & 0xff;
3883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte red_low = trans_value->red & 0xff;
3884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte green_low = trans_value->green & 0xff;
3885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte blue_low = trans_value->blue & 0xff;
3886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sp = row + row_info->rowbytes - 1;
3887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dp = row + (png_size_t)(row_width << 3) - 1;
3888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
3889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (*(sp - 5) == red_high &&
3891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 4) == red_low &&
3892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 3) == green_high &&
3893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 2) == green_low &&
3894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 1) == blue_high &&
3895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp    ) == blue_low)
3896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0;
3898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0;
3899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0xff;
3903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0xff;
3904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
3911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
3914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels = 4;
3915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
39164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_DITHER_SUPPORTED)
3923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_dither(png_row_infop row_info, png_bytep row,
3925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_bytep palette_lookup, png_bytep dither_lookup)
3926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
3928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
3929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
3930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
39314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_dither");
3932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
3933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
3934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
3937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette_lookup && row_info->bit_depth == 8)
3938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int r, g, b, p;
3940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sp = row;
3941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         dp = row;
3942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < row_width; i++)
3943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r = *sp++;
3945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g = *sp++;
3946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b = *sp++;
3947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* this looks real messy, but the compiler will reduce
3949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               it down to a reasonable formula.  For example, with
3950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               5 bits per color, we get:
3951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               p = (((r >> 3) & 0x1f) << 10) |
3952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (((g >> 3) & 0x1f) << 5) |
3953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  ((b >> 3) & 0x1f);
3954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               */
3955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
3956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
3957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
3958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
3959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
3960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_BLUE_BITS)) |
3961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
3962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_BLUE_BITS) - 1));
3963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dp++ = palette_lookup[p];
3965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
3967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels = 1;
3968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = row_info->bit_depth;
39694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
3972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette_lookup != NULL && row_info->bit_depth == 8)
3973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int r, g, b, p;
3975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sp = row;
3976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         dp = row;
3977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < row_width; i++)
3978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r = *sp++;
3980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g = *sp++;
3981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b = *sp++;
3982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sp++;
3983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
3985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
3986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
3987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
3988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
3989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_BLUE_BITS)) |
3990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
3991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_BLUE_BITS) - 1));
3992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dp++ = palette_lookup[p];
3994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
3996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels = 1;
3997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = row_info->bit_depth;
39984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         dither_lookup && row_info->bit_depth == 8)
4002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sp = row;
4004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < row_width; i++, sp++)
4005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
4006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *sp = dither_lookup[*sp];
4007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
4010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
4011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
4014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED)
4015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic PNG_CONST int png_gamma_shift[] =
4016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
4017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
4019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * tables, we don't make a full table if we are reducing to 8-bit in
4020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the future.  Note also how the gamma_16 tables are segmented so that
4021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * we don't need to allocate > 64K chunks for a full 16-bit table.
4022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
4023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
4024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_build_gamma_table(png_structp png_ptr)
4025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
40264215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project  png_debug(1, "in png_build_gamma_table");
4027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (png_ptr->bit_depth <= 8)
4029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
4030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     int i;
4031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     double g;
4032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->screen_gamma > .000001)
4034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
4035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0;
4037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
4039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        (png_uint_32)256);
4040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     for (i = 0; i < 256; i++)
4042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
4044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g) * 255.0 + .5);
4045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
4050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma);
4053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
4055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           (png_uint_32)256);
4056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < 256; i++)
4058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
4060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              g) * 255.0 + .5);
4061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
4065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           (png_uint_32)256);
4066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
40674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        if (png_ptr->screen_gamma > 0.000001)
4068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g = 1.0 / png_ptr->screen_gamma;
4069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else
4070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g = png_ptr->gamma;   /* probably doing rgb_to_gray */
4071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < 256; i++)
4073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
4075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              g) * 255.0 + .5);
4076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
4081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else
4082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
4083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     double g;
4084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     int i, j, shift, num;
4085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     int sig_bit;
4086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_uint_32 ig;
4087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
4089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sig_bit = (int)png_ptr->sig_bit.red;
4091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if ((int)png_ptr->sig_bit.green > sig_bit)
4092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           sig_bit = png_ptr->sig_bit.green;
4093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if ((int)png_ptr->sig_bit.blue > sig_bit)
4094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           sig_bit = png_ptr->sig_bit.blue;
4095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sig_bit = (int)png_ptr->sig_bit.gray;
4099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (sig_bit > 0)
4102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 16 - sig_bit;
4103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 0;
4105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & PNG_16_TO_8)
4107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (shift < (16 - PNG_MAX_GAMMA_8))
4109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           shift = (16 - PNG_MAX_GAMMA_8);
4110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (shift > 8)
4113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 8;
4114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (shift < 0)
4115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 0;
4116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->gamma_shift = (png_byte)shift;
4118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     num = (1 << (8 - shift));
4120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->screen_gamma > .000001)
4122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
4123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0;
4125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
41274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        (png_uint_32)(num * png_sizeof(png_uint_16p)));
4128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
4130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double fin, fout;
4132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_uint_32 last, max;
4133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
41344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        png_memset(png_ptr->gamma_16_table, 0, num * png_sizeof(png_uint_16p));
41354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
4136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
41394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / g;
4143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        last = 0;
4144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < 256; i++)
4145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           fout = ((double)i + 0.5) / 256.0;
4147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           fin = pow(fout, g);
4148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
4149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           while (last <= max)
4150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
4152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 [(int)(last >> (8 - shift))] = (png_uint_16)(
4153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)i | ((png_uint_16)i << 8));
4154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              last++;
4155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        while (last < ((png_uint_32)num << 8))
4158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
4160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
4161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           last++;
4162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
41694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
4172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           for (j = 0; j < 256; j++)
4173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_table[i][j] =
4175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    65535.0, g) * 65535.0 + .5);
4177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
4184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma);
4187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
41894215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project           (png_uint_32)(num * png_sizeof(png_uint_16p )));
41904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
41914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        png_memset(png_ptr->gamma_16_to_1, 0, num * png_sizeof(png_uint_16p));
4192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
41964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           ig = (((png_uint_32)i *
4199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (png_uint_32)png_gamma_shift[shift]) >> 4);
4200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           for (j = 0; j < 256; j++)
4201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_to_1[i][j] =
4203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    65535.0, g) * 65535.0 + .5);
4205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
42084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        if (png_ptr->screen_gamma > 0.000001)
4209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g = 1.0 / png_ptr->screen_gamma;
4210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else
4211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g = png_ptr->gamma;   /* probably doing rgb_to_gray */
4212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
42144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project           (png_uint_32)(num * png_sizeof(png_uint_16p)));
42154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
42164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        png_memset(png_ptr->gamma_16_from_1, 0,
42174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project           num * png_sizeof(png_uint_16p));
4218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
42224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           ig = (((png_uint_32)i *
4225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (png_uint_32)png_gamma_shift[shift]) >> 4);
4226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           for (j = 0; j < 256; j++)
4227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_from_1[i][j] =
4229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    65535.0, g) * 65535.0 + .5);
4231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
4236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
4237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* To do: install integer version of png_build_gamma_table here */
4239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_MNG_FEATURES_SUPPORTED)
4242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* undoes intrapixel differencing  */
4243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
4244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_intrapixel(png_row_infop row_info, png_bytep row)
4245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
42464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_intrapixel");
4247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
4248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USELESS_TESTS_SUPPORTED)
4249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
4250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (row_info->color_type & PNG_COLOR_MASK_COLOR))
4252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
4253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int bytes_per_pixel;
4254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
4255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->bit_depth == 8)
4256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp;
4258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
4259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
4261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 3;
4262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 4;
4264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
4265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return;
4266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
4268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
4269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
4270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
4271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->bit_depth == 16)
4274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp;
4276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
4277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
4279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 6;
4280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 8;
4282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
4283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return;
4284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
4286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
42874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
42884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
42894215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
42904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 red  = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
42914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
4292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp  ) = (png_byte)((red >> 8) & 0xff);
4293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+1) = (png_byte)(red & 0xff);
4294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
4295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+5) = (png_byte)(blue & 0xff);
4296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
4299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
4300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_MNG_FEATURES_SUPPORTED */
4301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_SUPPORTED */
4302