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 *
466dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier * Last changed in libpng 1.2.45 [July 7, 2011]
566dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
9a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * This code is released under the libpng license.
10a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * For conditions of distribution and use, see the disclaimer
11a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * and license in png.h
12a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *
13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * This file contains functions optionally called by an application
14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in order to tell libpng how to handle data when reading a PNG.
15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * Transformations that are used in both reading and writing are
16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * in pngtrans.c.
17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_INTERNAL
205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#define PNG_NO_PEDANTIC_WARNINGS
21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "png.h"
225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SUPPORTED
23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Set the action on getting a CRC error for an ancillary or critical chunk. */
25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_crc_action");
295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
30a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
31a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   /* Tell libpng how we react to CRC errors in critical chunks */
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (crit_action)
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
36a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
38a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
39a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_WARN_USE:                               /* Warn/use data */
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
43a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
44a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           PNG_FLAG_CRC_CRITICAL_IGNORE;
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
49a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
50a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_warning(png_ptr,
524215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            "Can't discard critical data on CRC error.");
53a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
54a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_DEFAULT:
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      default:
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   /* Tell libpng how we react to CRC errors in ancillary chunks */
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (ancil_action)
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
64a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
66a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
67a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_WARN_USE:                              /* Warn/use data */
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
71a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
72a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           PNG_FLAG_CRC_ANCILLARY_NOWARN;
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
77a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
78a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
82a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
83a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
84a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_CRC_DEFAULT:
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      default:
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    defined(PNG_FLOATING_POINT_SUPPORTED)
94a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Handle alpha and tRNS via a background color */
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_background(png_structp png_ptr,
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_color_16p background_color, int background_gamma_code,
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int need_expand, double background_gamma)
99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_background");
1015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
102a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
103a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Application must supply a known background gamma");
107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_BACKGROUND;
111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_memcpy(&(png_ptr->background), background_color,
112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_sizeof(png_color_16));
113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->background_gamma = (float)background_gamma;
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_16_TO_8_SUPPORTED
120a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Strip 16 bit depth files to 8 bit depth */
121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_strip_16(png_structp png_ptr)
123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_strip_16");
1255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
126a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
127a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_16_TO_8;
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_strip_alpha(png_structp png_ptr)
135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_strip_alpha");
1375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
138a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
139a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags |= PNG_FLAG_STRIP_ALPHA;
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_DITHER_SUPPORTED
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Dither file to 8 bit.  Supply a palette, the current number
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of elements in the palette, the maximum number of elements
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * allowed, and a histogram if possible.  If the current number
148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of colors is greater then the maximum number, the palette will be
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * modified to fit in the maximum number.  "full_dither" indicates
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * whether we need a dithering cube set up for RGB images, or if we
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * simply are reducing the number of colors in a paletted image.
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef struct png_dsort_struct
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   struct png_dsort_struct FAR * next;
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte left;
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte right;
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} png_dsort;
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef png_dsort FAR *       png_dsortp;
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projecttypedef png_dsort FAR * FAR * png_dsortpp;
162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_dither(png_structp png_ptr, png_colorp palette,
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int num_palette, int maximum_colors, png_uint_16p histogram,
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int full_dither)
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1684215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_dither");
1695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
170a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
171a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_DITHER;
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!full_dither)
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
1794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         (png_uint_32)(num_palette * png_sizeof(png_byte)));
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < num_palette; i++)
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->dither_index[i] = (png_byte)i;
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (num_palette > maximum_colors)
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (histogram != NULL)
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This is easy enough, just throw out the least used colors.
189a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * Perhaps not the best solution, but good enough.
190a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          */
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
194a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Initialize an array to sort colors */
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
1964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            (png_uint_32)(num_palette * png_sizeof(png_byte)));
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
198a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Initialize the dither_sort array */
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->dither_sort[i] = (png_byte)i;
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* Find the least used palette entries by starting a
203a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * bubble sort, and running it until we have sorted
204a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * out enough colors.  Note that we don't care about
205a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * sorting all the colors, just finding which are
206a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * least used.
207a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          */
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = num_palette - 1; i >= maximum_colors; i--)
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
211a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            int done; /* To stop early if the list is pre-sorted */
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int j;
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            done = 1;
215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (j = 0; j < i; j++)
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (histogram[png_ptr->dither_sort[j]]
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   < histogram[png_ptr->dither_sort[j + 1]])
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte t;
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  t = png_ptr->dither_sort[j];
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_sort[j + 1] = t;
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  done = 0;
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (done)
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
232a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Swap the palette around, and set up a table, if necessary */
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (full_dither)
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int j = num_palette;
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
237a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            /* Put all the useful colors within the max, but don't
238a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             * move the others.
239a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             */
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < maximum_colors; i++)
241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  do
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     j--;
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i] = palette[j];
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int j = num_palette;
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
255a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            /* Move all the used colors inside the max limit, and
256a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             * develop a translation table.
257a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             */
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < maximum_colors; i++)
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
260a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               /* Only move the colors we need to */
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ((int)png_ptr->dither_sort[i] >= maximum_colors)
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_color tmp_color;
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  do
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     j--;
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  while ((int)png_ptr->dither_sort[j] >= maximum_colors);
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  tmp_color = palette[j];
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[j] = palette[i];
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i] = tmp_color;
272a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                  /* Indicate where the color went */
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_index[j] = (png_byte)i;
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_index[i] = (png_byte)j;
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
278a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            /* Find closest color for those colors we are not using */
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < num_palette; i++)
280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ((int)png_ptr->dither_index[i] >= maximum_colors)
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int min_d, k, min_k, d_index;
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
285a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                  /* Find the closest color to one we threw out */
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  d_index = png_ptr->dither_index[i];
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (k = 1, min_k = 0; k < maximum_colors; k++)
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     int d;
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     d = PNG_COLOR_DIST(palette[d_index], palette[k]);
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (d < min_d)
295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        min_d = d;
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        min_k = k;
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
300a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                  /* Point to closest color */
301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->dither_index[i] = (png_byte)min_k;
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, png_ptr->dither_sort);
3064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_ptr->dither_sort = NULL;
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This is much harder to do simply (and quickly).  Perhaps
311a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * we need to go through a median cut routine, but those
312a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * don't always behave themselves with only a few colors
313a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * as input.  So we will just find the closest two colors,
314a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * and throw out one of them (chosen somewhat randomly).
315a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * [We don't understand this at all, so if someone wants to
316a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          *  work on improving it, be our guest - AED, GRP]
317a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          */
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int max_d;
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int num_new_palette;
321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_dsortp t;
322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_dsortpp hash;
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         t = NULL;
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
326a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Initialize palette index arrays */
327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
3284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            (png_uint_32)(num_palette * png_sizeof(png_byte)));
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
3304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            (png_uint_32)(num_palette * png_sizeof(png_byte)));
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
332a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Initialize the sort array */
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->index_to_palette[i] = (png_byte)i;
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette_to_index[i] = (png_byte)i;
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
3404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_sizeof(png_dsortp)));
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_new_palette = num_palette;
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
344a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Initial wild guess at how far apart the farthest pixel
345a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * pair we will be eliminating will be.  Larger
346a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * numbers mean more areas will be allocated, Smaller
347a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * numbers run the risk of not saving enough data, and
348a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * having to do this all over again.
349a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          *
350a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          * I have not done extensive checking on this number.
351a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          */
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         max_d = 96;
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         while (num_new_palette > maximum_colors)
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < num_new_palette - 1; i++)
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int j;
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (j = i + 1; j < num_new_palette; j++)
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d;
363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  d = PNG_COLOR_DIST(palette[i], palette[j]);
365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (d <= max_d)
367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t = (png_dsortp)png_malloc_warn(png_ptr,
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         (png_uint_32)(png_sizeof(png_dsort)));
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (t == NULL)
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         break;
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t->next = hash[d];
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t->left = (png_byte)i;
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t->right = (png_byte)j;
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     hash[d] = t;
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (t == NULL)
380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (t != NULL)
384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i <= max_d; i++)
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (hash[i] != NULL)
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_dsortp p;
389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (p = hash[i]; p; p = p->next)
391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if ((int)png_ptr->index_to_palette[p->left]
393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        < num_new_palette &&
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (int)png_ptr->index_to_palette[p->right]
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        < num_new_palette)
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        int j, next_j;
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (num_new_palette & 0x01)
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           j = p->left;
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           next_j = p->right;
403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           j = p->right;
407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           next_j = p->left;
408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        num_new_palette--;
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        palette[png_ptr->index_to_palette[j]]
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                          = palette[num_new_palette];
413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!full_dither)
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           int k;
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           for (k = 0; k < num_palette; k++)
418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           {
419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                              if (png_ptr->dither_index[k] ==
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->index_to_palette[j])
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->dither_index[k] =
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    png_ptr->index_to_palette[next_j];
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                              if ((int)png_ptr->dither_index[k] ==
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 num_new_palette)
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->dither_index[k] =
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                    png_ptr->index_to_palette[j];
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           }
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_ptr->index_to_palette[png_ptr->palette_to_index
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           [num_new_palette]] = png_ptr->index_to_palette[j];
432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           = png_ptr->palette_to_index[num_new_palette];
434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                        png_ptr->index_to_palette[j] =
4365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                            (png_byte)num_new_palette;
4375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                        png_ptr->palette_to_index[num_new_palette] =
4385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                            (png_byte)j;
439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (num_new_palette <= maximum_colors)
441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        break;
442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (num_new_palette <= maximum_colors)
444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < 769; i++)
449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (hash[i] != NULL)
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_dsortp p = hash[i];
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  while (p)
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     t = p->next;
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_free(png_ptr, p);
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     p = t;
458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               hash[i] = 0;
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_d += 96;
463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, hash);
465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, png_ptr->palette_to_index);
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, png_ptr->index_to_palette);
4674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_ptr->palette_to_index = NULL;
4684215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_ptr->index_to_palette = NULL;
469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      num_palette = maximum_colors;
471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->palette == NULL)
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->palette = palette;
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->num_palette = (png_uint_16)num_palette;
477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (full_dither)
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_bytep distance;
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         PNG_DITHER_BLUE_BITS;
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int num_red = (1 << PNG_DITHER_RED_BITS);
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int num_green = (1 << PNG_DITHER_GREEN_BITS);
486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int num_blue = (1 << PNG_DITHER_BLUE_BITS);
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_size_t num_entries = ((png_size_t)1 << total_bits);
4885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
4895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr,
4904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         (png_uint_32)(num_entries * png_sizeof(png_byte)));
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_sizeof(png_byte)));
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_memset(distance, 0xff, num_entries * png_sizeof(png_byte));
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < num_palette; i++)
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int ir, ig, ib;
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (ir = 0; ir < num_red; ir++)
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* int dr = abs(ir - r); */
506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int dr = ((ir > r) ? ir - r : r - ir);
5075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            int index_r = (ir << (PNG_DITHER_BLUE_BITS +
5085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                PNG_DITHER_GREEN_BITS));
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (ig = 0; ig < num_green; ig++)
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               /* int dg = abs(ig - g); */
513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int dg = ((ig > g) ? ig - g : g - ig);
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int dt = dr + dg;
515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int dm = ((dr > dg) ? dr : dg);
516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (ib = 0; ib < num_blue; ib++)
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d_index = index_g | ib;
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  /* int db = abs(ib - b); */
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int db = ((ib > b) ? ib - b : b - ib);
523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int dmax = ((dm > db) ? dm : db);
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d = dmax + dt + db;
525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (d < (int)distance[d_index])
527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     distance[d_index] = (png_byte)d;
529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_ptr->palette_lookup[d_index] = (png_byte)i;
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_free(png_ptr, distance);
537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Transform the image from the file_gamma to the screen_gamma.  We
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * only do transformations on images where the file_gamma and screen_gamma
544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * are not close reciprocals, otherwise it slows things down slightly, and
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * also needlessly introduces small errors.
546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * We will turn off gamma transformation later if no semitransparent entries
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * are present in the tRNS array for palette images.  We can't do it here
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * because we don't necessarily have the tRNS chunk yet.
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_gamma");
5555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
556a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
557a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
5585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->transformations |= PNG_GAMMA;
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->gamma = (float)file_gamma;
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->screen_gamma = (float)scrn_gamma;
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB, expand grayscale images of
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * to alpha channels.
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_expand(png_structp png_ptr)
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
5764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_expand");
5775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
578a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
579a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
5805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* GRR 19990627:  the following three functions currently are identical
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  to png_set_expand().  However, it is entirely reasonable that someone
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  might wish to expand an indexed image to RGB but *not* expand a single,
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  fully transparent palette entry to a full alpha channel--perhaps instead
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  the transparent color with a particular RGB value, or drop tRNS entirely.
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  IOW, a future version of the library may make the transformations flag
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  a bit more fine-grained, with separate bits for each of these three
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  functions.
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  More to the point, these functions make it obvious what libpng will be
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  doing, whereas "expand" can (and does) mean any number of things.
597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
5985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
5995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *  to expand only the sample depth but not to expand the tRNS to alpha
6005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand paletted images to RGB. */
604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_palette_to_rgb(png_structp png_ptr)
606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_palette_to_rgb");
6085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
609a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
610a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
6115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_1_0_X
617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand grayscale images of less than 8-bit depth to 8 bits. */
618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
6225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
623a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
624a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
6255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_EXPAND;
627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_1_0_X) || defined(PNG_1_2_X)
632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand grayscale images of less than 8-bit depth to 8 bits. */
633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Deprecated as of libpng-1.2.9 */
634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_gray_1_2_4_to_8(png_structp png_ptr)
636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_gray_1_2_4_to_8");
6385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
639a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
640a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
6415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expand tRNS chunks to alpha channels. */
648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_tRNS_to_alpha(png_structp png_ptr)
650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_tRNS_to_alpha");
6525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_gray_to_rgb(png_structp png_ptr)
661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_gray_to_rgb");
6635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_GRAY_TO_RGB;
665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
6705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_FLOATING_POINT_SUPPORTED
671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Convert a RGB image to a grayscale of the same width.  This allows us,
672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   double green)
678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
67966dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier   int red_fixed, green_fixed;
680a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
681a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
68266dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier   if (red > 21474.83647 || red < -21474.83648 ||
68366dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier       green > 21474.83647 || green < -21474.83648)
68466dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier   {
68566dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier      png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
68666dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier      red_fixed = -1;
68766dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier      green_fixed = -1;
68866dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier   }
68966dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier   else
69066dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier   {
69166dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier      red_fixed = (int)((float)red*100000.0 + 0.5);
69266dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier      green_fixed = (int)((float)green*100000.0 + 0.5);
69366dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier   }
694a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_fixed_point red, png_fixed_point green)
701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
7024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_rgb_to_gray");
7035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
704a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
705a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
7065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch(error_action)
708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              break;
711a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              break;
714a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
7185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations |= PNG_EXPAND;
720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
7224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr,
7234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 red_int, green_int;
7294215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (red < 0 || green < 0)
730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         red_int   =  6968; /* .212671 * 32768 + .5 */
732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         green_int = 23434; /* .715160 * 32768 + .5 */
733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
7344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      else if (red + green < 100000L)
735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
736a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
737a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         red_int   =  6968;
743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         green_int = 23434;
744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->rgb_to_gray_red_coeff   = red_int;
746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->rgb_to_gray_green_coeff = green_int;
7474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->rgb_to_gray_blue_coeff  =
7484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         (png_uint_16)(32768 - red_int - green_int);
749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
754a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    defined(PNG_LEGACY_SUPPORTED) || \
755a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   read_user_transform_fn)
759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
7604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_set_read_user_transform_fn");
7615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
762a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (png_ptr == NULL)
763a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      return;
7645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
7655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->transformations |= PNG_USER_TRANSFORM;
767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->read_user_transform_fn = read_user_transform_fn;
768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_LEGACY_SUPPORTED
7704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (read_user_transform_fn)
771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr,
772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        "This version of libpng does not support user transforms");
773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Initialize everything needed for the read.  This includes modifying
778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the palette.
779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_init_read_transformations(png_structp png_ptr)
782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
7834215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_init_read_transformations");
7845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
7855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
7865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott  if (png_ptr != NULL)
787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
7895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
7905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    defined(PNG_READ_SHIFT_SUPPORTED) || \
7915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    defined(PNG_READ_GAMMA_SUPPORTED)
792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int color_type = png_ptr->color_type;
793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
7975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Detect gray background and attempt to enable optimization
799a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * for gray --> RGB case
800a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    *
801a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * RGB_ALPHA (in which case need_expand is superfluous anyway), the
803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * background color might actually be gray yet not be flagged as such.
804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * This is not a problem for the current code, which uses
805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * PNG_BACKGROUND_IS_GRAY only to decide when to do the
806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * png_do_gray_to_rgb() transformation.
807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    */
808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       !(color_type & PNG_COLOR_MASK_COLOR))
810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   } else if ((png_ptr->transformations & PNG_BACKGROUND) &&
813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (png_ptr->transformations & PNG_GRAY_TO_RGB) &&
815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->background.red == png_ptr->background.green &&
816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->background.red == png_ptr->background.blue)
817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->background.gray = png_ptr->background.red;
820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->transformations & PNG_EXPAND))
825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!(color_type & PNG_COLOR_MASK_COLOR))  /* i.e., GRAY or GRAY_ALPHA */
827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
828a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         /* Expand background and tRNS chunks */
829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         switch (png_ptr->bit_depth)
830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 1:
832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.gray *= (png_uint_16)0xff;
833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 =  png_ptr->background.blue = png_ptr->background.gray;
835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.gray *= (png_uint_16)0xff;
838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.red = png_ptr->trans_values.green
839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
842a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 2:
844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.gray *= (png_uint_16)0x55;
845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.gray *= (png_uint_16)0x55;
850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.red = png_ptr->trans_values.green
851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
854a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 4:
856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.gray *= (png_uint_16)0x11;
857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.gray *= (png_uint_16)0x11;
862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans_values.red = png_ptr->trans_values.green
863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   = png_ptr->trans_values.blue = png_ptr->trans_values.gray;
864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
866a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 8:
868a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 16:
870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (color_type == PNG_COLOR_TYPE_PALETTE)
876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->background.red   =
878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette[png_ptr->background.index].red;
879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->background.green =
880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette[png_ptr->background.index].green;
881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->background.blue  =
882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette[png_ptr->background.index].blue;
883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (png_ptr->transformations & PNG_INVERT_ALPHA)
886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
8875f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
891a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott           /* Invert the alpha channel (in tRNS) unless the pixels are
892a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            * going to be expanded, in which case leave it for later
893a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            */
8944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              int i, istop;
895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              istop=(int)png_ptr->num_trans;
896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              for (i=0; i<istop; i++)
897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->background_1 = png_ptr->background;
908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         < PNG_GAMMA_THRESHOLD))
914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
9154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project    int i, k;
916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    k=0;
917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i=0; i<png_ptr->num_trans; i++)
918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
920a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott        k=1; /* Partial transparency is present */
921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (k == 0)
923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations &= ~PNG_GAMMA;
924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) &&
927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma != 0.0)
928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_build_gamma_table(png_ptr);
9305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
9315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->transformations & PNG_BACKGROUND)
933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (color_type == PNG_COLOR_TYPE_PALETTE)
935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
936a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott           /* Could skip if no transparency */
937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_color back, back_1;
938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_colorp palette = png_ptr->palette;
939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int num_palette = png_ptr->num_palette;
940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int i;
941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back.red = png_ptr->gamma_table[png_ptr->background.red];
944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back.green = png_ptr->gamma_table[png_ptr->background.green];
945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back.blue = png_ptr->gamma_table[png_ptr->background.blue];
946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               double g, gs;
954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               switch (png_ptr->background_gamma_type)
956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  case PNG_BACKGROUND_GAMMA_SCREEN:
958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = (png_ptr->screen_gamma);
959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0;
960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
961a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  case PNG_BACKGROUND_GAMMA_FILE:
963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = 1.0 / (png_ptr->gamma);
964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
966a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  case PNG_BACKGROUND_GAMMA_UNIQUE:
968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = 1.0 / (png_ptr->background_gamma);
969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0 / (png_ptr->background_gamma *
970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 png_ptr->screen_gamma);
971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     break;
972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  default:
973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     g = 1.0;    /* back_1 */
974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     gs = 1.0;   /* back */
975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.red   = (png_byte)png_ptr->background.red;
980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.green = (png_byte)png_ptr->background.green;
981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.blue  = (png_byte)png_ptr->background.blue;
982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.red = (png_byte)(pow(
986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     (double)png_ptr->background.red/255, gs) * 255.0 + .5);
987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.green = (png_byte)(pow(
9885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                     (double)png_ptr->background.green/255, gs) * 255.0
9895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                         + .5);
990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  back.blue = (png_byte)(pow(
991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.red = (png_byte)(pow(
995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.red/255, g) * 255.0 + .5);
996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.green = (png_byte)(pow(
997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.green/255, g) * 255.0 + .5);
998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               back_1.blue = (png_byte)(pow(
999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.blue/255, g) * 255.0 + .5);
1000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < num_palette; i++)
1002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
1004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (png_ptr->trans[i] == 0)
1006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i] = back;
1008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
1009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else /* if (png_ptr->trans[i] != 0xff) */
1010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte v, w;
1012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     v = png_ptr->gamma_to_1[palette[i].red];
1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_composite(w, v, png_ptr->trans[i], back_1.red);
1015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i].red = png_ptr->gamma_from_1[w];
1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     v = png_ptr->gamma_to_1[palette[i].green];
1018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_composite(w, v, png_ptr->trans[i], back_1.green);
1019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i].green = png_ptr->gamma_from_1[w];
1020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     v = png_ptr->gamma_to_1[palette[i].blue];
1022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_composite(w, v, png_ptr->trans[i], back_1.blue);
1023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     palette[i].blue = png_ptr->gamma_from_1[w];
1024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
1025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
1027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i].red = png_ptr->gamma_table[palette[i].red];
1029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i].green = png_ptr->gamma_table[palette[i].green];
1030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
10335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            /* Prevent the transformations being done again, and make sure
10345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott             * that the now spurious alpha channel is stripped - the code
10355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott             * has just reduced background composition and gamma correction
10365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott             * to a simple alpha channel strip.
10375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott             */
10385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            png_ptr->transformations &= ~PNG_BACKGROUND;
10395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            png_ptr->transformations &= ~PNG_GAMMA;
10405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            png_ptr->transformations |= PNG_STRIP_ALPHA;
1041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
1043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* color_type != PNG_COLOR_TYPE_PALETTE */
1045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
1047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            double g = 1.0;
1048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            double gs = 1.0;
1049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (png_ptr->background_gamma_type)
1051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case PNG_BACKGROUND_GAMMA_SCREEN:
1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  g = (png_ptr->screen_gamma);
1054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gs = 1.0;
1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
1056a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case PNG_BACKGROUND_GAMMA_FILE:
1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  g = 1.0 / (png_ptr->gamma);
1059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
1060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
1061a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case PNG_BACKGROUND_GAMMA_UNIQUE:
1063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  g = 1.0 / (png_ptr->background_gamma);
1064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gs = 1.0 / (png_ptr->background_gamma *
1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_ptr->screen_gamma);
1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->background_1.gray = (png_uint_16)(pow(
1070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (double)png_ptr->background.gray / m, g) * m + .5);
1071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->background.gray = (png_uint_16)(pow(
1072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (double)png_ptr->background.gray / m, gs) * m + .5);
1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if ((png_ptr->background.red != png_ptr->background.green) ||
1075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                (png_ptr->background.red != png_ptr->background.blue) ||
1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                (png_ptr->background.red != png_ptr->background.gray))
1077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               /* RGB or RGBA with color background */
1079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.red = (png_uint_16)(pow(
1080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.red / m, g) * m + .5);
1081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.green = (png_uint_16)(pow(
1082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.green / m, g) * m + .5);
1083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.blue = (png_uint_16)(pow(
1084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.blue / m, g) * m + .5);
1085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = (png_uint_16)(pow(
1086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.red / m, gs) * m + .5);
1087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.green = (png_uint_16)(pow(
1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.green / m, gs) * m + .5);
1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.blue = (png_uint_16)(pow(
1090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  (double)png_ptr->background.blue / m, gs) * m + .5);
1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
1095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background_1.red = png_ptr->background_1.green
1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background_1.blue = png_ptr->background_1.gray;
1097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->background.red = png_ptr->background.green
1098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 = png_ptr->background.blue = png_ptr->background.gray;
1099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1103a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Transformation does not include PNG_BACKGROUND */
1104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (color_type == PNG_COLOR_TYPE_PALETTE)
1106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_colorp palette = png_ptr->palette;
1108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int num_palette = png_ptr->num_palette;
1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
1110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
1112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i].red = png_ptr->gamma_table[palette[i].red];
1114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i].green = png_ptr->gamma_table[palette[i].green];
1115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i].blue = png_ptr->gamma_table[palette[i].blue];
1116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         /* Done the gamma correction. */
11195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_ptr->transformations &= ~PNG_GAMMA;
1120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
11225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
1123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
1124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
11265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
1127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* No GAMMA transformation */
1128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND) &&
1129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (color_type == PNG_COLOR_TYPE_PALETTE))
1130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
1132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int istop = (int)png_ptr->num_trans;
1133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_color back;
1134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_colorp palette = png_ptr->palette;
1135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      back.red   = (png_byte)png_ptr->background.red;
1137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      back.green = (png_byte)png_ptr->background.green;
1138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      back.blue  = (png_byte)png_ptr->background.blue;
1139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < istop; i++)
1141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->trans[i] == 0)
1143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            palette[i] = back;
1145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (png_ptr->trans[i] != 0xff)
1147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /* The png_composite() macro is defined in png.h */
1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_composite(palette[i].red, palette[i].red,
1150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->trans[i], back.red);
1151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_composite(palette[i].green, palette[i].green,
1152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->trans[i], back.green);
1153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_composite(palette[i].blue, palette[i].blue,
1154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->trans[i], back.blue);
1155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Handled alpha, still need to strip the channel. */
1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations &= ~PNG_BACKGROUND;
1160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->transformations |= PNG_STRIP_ALPHA;
1161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED */
1163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SHIFT_SUPPORTED
1165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_SHIFT) &&
1166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (color_type == PNG_COLOR_TYPE_PALETTE))
1167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 i;
1169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 istop = png_ptr->num_palette;
1170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int sr = 8 - png_ptr->sig_bit.red;
1171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int sg = 8 - png_ptr->sig_bit.green;
1172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int sb = 8 - png_ptr->sig_bit.blue;
1173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (sr < 0 || sr > 8)
1175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sr = 0;
1176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (sg < 0 || sg > 8)
1177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sg = 0;
1178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (sb < 0 || sb > 8)
1179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sb = 0;
1180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < istop; i++)
1181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette[i].red >>= sr;
1183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette[i].green >>= sg;
1184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette[i].blue >>= sb;
1185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif  /* PNG_READ_SHIFT_SUPPORTED */
1188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project }
1189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
1190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project && !defined(PNG_READ_BACKGROUND_SUPPORTED)
11914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr)
1192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Modify the info structure to reflect the transformations.  The
1197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * info should be updated so a PNG file could be written with it,
1198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * assuming the transformations result in valid PNG data.
1199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_transform_info(png_structp png_ptr, png_infop info_ptr)
1202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
12034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_read_transform_info");
12045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
12055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
1206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_EXPAND)
1207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
121066dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier         if (png_ptr->num_trans)
1211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            info_ptr->color_type = PNG_COLOR_TYPE_RGB;
1214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->bit_depth = 8;
1215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->num_trans = 0;
1216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans)
1220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->transformations & PNG_EXPAND_tRNS)
1222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (info_ptr->bit_depth < 8)
1225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            info_ptr->bit_depth = 8;
1226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->num_trans = 0;
1227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
1232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_BACKGROUND)
1233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->num_trans = 0;
1236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->background = png_ptr->background;
1237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
1241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_GAMMA)
1242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
1244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->gamma = png_ptr->gamma;
1245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->int_gamma = png_ptr->int_gamma;
1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_16_TO_8_SUPPORTED
1253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
1254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->bit_depth = 8;
1255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
1259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
1260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
1265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12675f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_DITHER_SUPPORTED
1268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_DITHER)
1269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1271a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
1272a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          png_ptr->palette_lookup && info_ptr->bit_depth == 8)
1273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
1275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12795f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACK_SUPPORTED
1280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
1281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->bit_depth = 8;
1282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 1;
1286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
1287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 3;
1288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
1289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels = 1;
1290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
1293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
1294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
1297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels++;
1298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED
1300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
1301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_FILLER) &&
1302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
1303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
1304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->channels++;
1306a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* If adding a true alpha channel not just filler */
13075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_1_0_X
1308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->transformations & PNG_ADD_ALPHA)
1309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
1310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
1315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefined(PNG_READ_USER_TRANSFORM_SUPPORTED)
13164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->transformations & PNG_USER_TRANSFORM)
1317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
13184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       if (info_ptr->bit_depth < png_ptr->user_transform_depth)
1319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->bit_depth = png_ptr->user_transform_depth;
13204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       if (info_ptr->channels < png_ptr->user_transform_channels)
1321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         info_ptr->channels = png_ptr->user_transform_channels;
1322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
1323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
1326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      info_ptr->bit_depth);
1327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
1329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_EXPAND_SUPPORTED
13314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr)
1332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Transform the row.  The order of transformations is significant,
1337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * and is very touchy.  If you add a transformation, take care to
1338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * decide how it fits in with the other transformations here.
1339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_transformations(png_structp png_ptr)
1342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
13434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_transformations");
13445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->row_buf == NULL)
1346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
13475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
1348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      char msg[50];
1349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_snprintf2(msg, 50,
13514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number,
1352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->pass);
1353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, msg);
1354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "NULL row buffer");
1356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_WARN_UNINITIALIZED_ROW
1359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
1360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Application has failed to call either png_read_start_image()
1361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * or png_read_update_info() after setting transforms that expand
1362a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       * pixels.  This check added to libpng-1.2.19
1363a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       */
1364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if (PNG_WARN_UNINITIALIZED_ROW==1)
1365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Uninitialized row");
1366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Uninitialized row");
1368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
1372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_EXPAND)
1373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
1375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
1377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
1378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans &&
1382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             (png_ptr->transformations & PNG_EXPAND_tRNS))
1383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               &(png_ptr->trans_values));
1385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
1387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               NULL);
1388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)
1394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA));
1396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_RGB_TO_GRAY)
1400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int rgb_error =
14025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info),
14035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott             png_ptr->row_buf + 1);
14044215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (rgb_error)
1405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->rgb_to_gray_status=1;
14074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
1408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             PNG_RGB_TO_GRAY_WARN)
1409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
14104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
1411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             PNG_RGB_TO_GRAY_ERR)
1412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
1413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1417a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
1418a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *
1419a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   In most cases, the "simple transparency" should be done prior to doing
1420a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
1421a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   pixel is transparent.  You would also need to make sure that the
1422a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   transparency information is upgraded to RGB.
1423a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *
1424a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   To summarize, the current flow is:
1425a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
1426a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   with background "in place" if transparent,
1427a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   convert to RGB if necessary
1428a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   - Gray + alpha -> composite with gray background and remove alpha bytes,
1429a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   convert to RGB if necessary
1430a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *
1431a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   To support RGB backgrounds for gray images we need:
1432a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   - Gray + simple transparency -> convert to RGB + simple transparency,
1433a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   compare 3 or 6 bytes and composite with
1434a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   background "in place" if transparent
1435a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   (3x compare/pixel compared to doing
1436a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   composite with gray bkgrnd)
1437a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *   - Gray + alpha -> convert to RGB + alpha, composite with background and
1438a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   remove alpha bytes (3x float
1439a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   operations/pixel compared with composite
1440a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *                                   on gray background)
1441a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *
1442a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *  Greg's change will do this.  The reason it wasn't done before is for
1443a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *  performance, as this increases the per-pixel operations.  If we would check
1444a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *  in advance if the background was gray or RGB, and position the gray-to-RGB
1445a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott *  transform appropriately, then it would save a lot of work/time.
1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1449a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* If gray -> RGB, do so now only if background is non-gray; else do later
1450a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * for performance reasons
1451a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
1452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
1458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_BACKGROUND) &&
1459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      ((png_ptr->num_trans != 0 ) ||
1460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
1461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
1462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         &(png_ptr->trans_values), &(png_ptr->background)
14635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
1464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         , &(png_ptr->background_1),
1465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_table, png_ptr->gamma_from_1,
1466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_to_1, png_ptr->gamma_16_table,
1467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
1468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->gamma_shift
1469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project);
1471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
1474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_GAMMA) &&
14755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
1476a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       !((png_ptr->transformations & PNG_BACKGROUND) &&
1477a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       ((png_ptr->num_trans != 0) ||
1478a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
1479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1480a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
1481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
1482a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          png_ptr->gamma_table, png_ptr->gamma_16_table,
1483a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          png_ptr->gamma_shift);
1484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_16_TO_8_SUPPORTED
1487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_16_TO_8)
1488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
1489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_DITHER_SUPPORTED
1492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_DITHER)
1493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
1495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->palette_lookup, png_ptr->dither_index);
14964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->row_info.rowbytes == (png_uint_32)0)
1497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_error(png_ptr, "png_do_dither returned rowbytes=0");
1498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INVERT_SUPPORTED
1502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_INVERT_MONO)
1503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
1504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SHIFT_SUPPORTED
1507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_SHIFT)
1508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
1509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         &(png_ptr->shift));
1510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACK_SUPPORTED
1513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_PACK)
1514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
1515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15175f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BGR_SUPPORTED
1518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_BGR)
1519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
1520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED
1523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_PACKSWAP)
1524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1528a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* If gray -> RGB, do so now only if we did not do so above */
1529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
1530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
1531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
1532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED
1535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_FILLER)
1536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
1537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         (png_uint_32)png_ptr->filler, png_ptr->flags);
1538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_INVERT_ALPHA)
1542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_SWAP_ALPHA)
1547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
1548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SWAP_SUPPORTED
1551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_SWAP_BYTES)
1552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
1553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
1556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_USER_TRANSFORM)
1557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
15584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->read_user_transform_fn != NULL)
1559a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         (*(png_ptr->read_user_transform_fn)) /* User read transform function */
1560a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            (png_ptr,                    /* png_ptr */
1561a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               &(png_ptr->row_info),     /* row_info: */
1562a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               /*  png_uint_32 width;       width of row */
1563a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               /*  png_uint_32 rowbytes;    number of bytes in row */
1564a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               /*  png_byte color_type;     color type of pixels */
1565a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               /*  png_byte bit_depth;      bit depth of samples */
1566a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               /*  png_byte channels;       number of channels (1-4) */
1567a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
1568a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott               png_ptr->row_buf + 1);    /* start of pixel data for row */
15695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
15704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->user_transform_depth)
1571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
15724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_ptr->user_transform_channels)
1573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.channels = png_ptr->user_transform_channels;
1574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
1576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.channels);
1577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
1578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->row_info.width);
1579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACK_SUPPORTED
1585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
1586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * without changing the actual values.  Thus, if you had a row with
1587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * a bit depth of 1, you would end up with bytes that only contained
1588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
1589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * png_do_shift() after this.
1590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_unpack(png_row_infop row_info, png_bytep row)
1593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
15944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_unpack");
15955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
15965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
1598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row_info->bit_depth < 8)
1600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 i;
1603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width=row_info->width;
1604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->bit_depth)
1606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 1:
1608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
1610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)row_width - 1;
1611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
1612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp = (png_byte)((*sp >> shift) & 0x01);
1615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == 7)
1616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 0;
1618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
1619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
1621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift++;
1622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp--;
1624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1627a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 2:
1629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
1632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)row_width - 1;
1633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
1634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp = (png_byte)((*sp >> shift) & 0x03);
1637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == 6)
1638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 0;
1640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
1641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
1643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift += 2;
1644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp--;
1646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1649a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 4:
1651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
1653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)row_width - 1;
1654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
1655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp = (png_byte)((*sp >> shift) & 0x0f);
1658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == 4)
1659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
1660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 0;
1661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
1662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
1663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
1664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 4;
1665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp--;
1667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->bit_depth = 8;
1672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->rowbytes = row_width * row_info->channels;
1674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
16785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SHIFT_SUPPORTED
1679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Reverse the effects of png_do_shift.  This routine merely shifts the
1680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * pixels back to their significant bits values.  Thus, if you have
1681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * a row of bit depth 8, but only 5 are significant, this will shift
1682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the values back to 0 through 31.
1683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
1684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
1686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
16874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_unshift");
16885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
1689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
16905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
1691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL && sig_bits != NULL &&
1692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
1694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int shift[4];
1696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int channels = 0;
1697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int c;
1698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_16 value = 0;
1699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
1700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type & PNG_COLOR_MASK_COLOR)
1702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->red;
1704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->green;
1705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->blue;
1706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->gray;
1710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
1712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         shift[channels++] = row_info->bit_depth - sig_bits->alpha;
1714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (c = 0; c < channels; c++)
1717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (shift[c] <= 0)
1719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            shift[c] = 0;
1720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            value = 1;
1722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!value)
1725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
1726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->bit_depth)
1728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 2:
1730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp;
1732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = row_info->rowbytes;
1734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (bp = row, i = 0; i < istop; i++)
1736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp >>= 1;
1738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ &= 0x55;
1739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1742a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 4:
1744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp = row;
1746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = row_info->rowbytes;
1748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
1749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)((int)0xf >> shift[0]));
1750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < istop; i++)
1752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp >>= shift[0];
1754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ &= mask;
1755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1758a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 8:
1760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp = row;
1762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = row_width * channels;
1764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < istop; i++)
1766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ >>= shift[i%channels];
1768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1771a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
1772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 16:
1773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep bp = row;
1775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 istop = channels * row_width;
1777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < istop; i++)
1779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               value = (png_uint_16)((*bp << 8) + *(bp + 1));
1781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               value >>= shift[i%channels];
1782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ = (png_byte)(value >> 8);
1783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *bp++ = (png_byte)(value & 0xff);
1784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
1786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_16_TO_8_SUPPORTED
1793a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Chop rows of bit depth 16 down to 8 */
1794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_chop(png_row_infop row_info, png_bytep row)
1796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
17974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_chop");
17985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
17995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
1800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
1801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row_info->bit_depth == 16)
1803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_bytep sp = row;
1806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_bytep dp = row;
1807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 i;
1808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 istop = row_info->width * row_info->channels;
1809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i<istop; i++, sp += 2, dp++)
1811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
18125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
1813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* This does a more accurate scaling of the 16-bit color
1814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * value, rather than a simple low-byte truncation.
1815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * What the ideal calculation should be:
1817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = (((((png_uint_32)(*sp) << 8) |
1818a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       *          (png_uint_32)(*(sp + 1))) * 255 + 127)
1819a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       *          / (png_uint_32)65535L;
1820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * GRR: no, I think this is what it really should be:
1822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = (((((png_uint_32)(*sp) << 8) |
1823a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       *           (png_uint_32)(*(sp + 1))) + 128L)
1824a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       *           / (png_uint_32)257L;
1825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * GRR: here's the exact calculation with shifts:
1827a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       *   temp = (((png_uint_32)(*sp) << 8) |
1828a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       *           (png_uint_32)(*(sp + 1))) + 128L;
1829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = (temp - (temp >> 8)) >> 8;
1830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * Approximate calculation with shift/add instead of multiply/divide:
1832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *   *dp = ((((png_uint_32)(*sp) << 8) |
1833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *          (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
1834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       *
1835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       * What we actually do to avoid extra shifting and conversion:
1836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       */
1837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
1839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       /* Simply discard the low order byte */
1841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         *dp = *sp;
1842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->bit_depth = 8;
1845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(8 * row_info->channels);
1846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->rowbytes = row_info->width * row_info->channels;
1847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
18515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
1854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
18554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_swap_alpha");
18565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
18575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
1858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
1859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
1862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from RGBA to ARGB */
1865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
1866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save;
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               save = *(--sp);
1875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save;
1879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from RRGGBBAA to AARRGGBB */
1882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save[2];
1887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[0] = *(--sp);
1892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[1] = *(--sp);
1893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[0];
1900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[1];
1901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from GA to AG */
1907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
1908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save;
1912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save = *(--sp);
1917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save;
1919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This converts from GGAA to AAGG */
1922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte save[2];
1927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[0] = *(--sp);
1932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               save[1] = *(--sp);
1933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[0];
1936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = save[1];
1937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
1947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
19484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_invert_alpha");
19495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
19505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
1951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
1952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
1955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
1956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in RGBA */
1958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
1959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*             This does nothing:
1969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               We can replace it with:
1973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/
1974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp-=3;
1975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp=sp;
1976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
1977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in RRGGBBAA */
1979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
1980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
1982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
1983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
1984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
1986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
1987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
1989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*             This does nothing:
1991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
1997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               We can replace it with:
1998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/
1999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp-=6;
2000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp=sp;
2001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in GA */
2007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + row_info->rowbytes;
2010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
2011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
2016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This inverts the alpha channel in GGAA */
2020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp  = row + row_info->rowbytes;
2023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp;
2024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
2029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = (png_byte)(255 - *(--sp));
2030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
2031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project*/
2034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp-=2;
2035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp=sp;
2036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED
2044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Add filler channel if we have RGB color */
2045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_filler(png_row_infop row_info, png_bytep row,
2047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 filler, png_uint_32 flags)
2048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
2050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width = row_info->width;
2051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
2053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte lo_filler = (png_byte)(filler & 0xff);
2054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_filler");
20565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
2057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
20585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
2059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL  && row_info != NULL &&
2060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row_info->color_type == PNG_COLOR_TYPE_GRAY)
2062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
20634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (row_info->bit_depth == 8)
2064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from G to GX */
2066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
2067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width;
2069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp =  sp + (png_size_t)row_width;
2070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
2071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
2076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
2077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 16;
2078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 2;
2079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* This changes the data from G to XG */
2081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width;
2084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width;
2085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
2091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 16;
2092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 2;
2093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
20954215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      else if (row_info->bit_depth == 16)
2096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from GG to GGXX */
2098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
2099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2;
2101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
2103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = hi_filler;
2110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
2111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
2112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from GG to XXGG */
2116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2;
2119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
2128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   } /* COLOR_TYPE == GRAY */
2133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
21354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (row_info->bit_depth == 8)
2136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from RGB to RGBX */
2138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
2139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 3;
2141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width;
2142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
2143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
2150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* This changes the data from RGB to XRGB */
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 * 3;
2158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp + (png_size_t)row_width;
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);
2163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 32;
2168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 4;
2169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
21714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      else if (row_info->bit_depth == 16)
2172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from RRGGBB to RRGGBBXX */
2174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (flags & PNG_FLAG_FILLER_AFTER)
2175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 6;
2177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 1; i < row_width; i++)
2179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = hi_filler;
2190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(--dp) = lo_filler;
2191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 64;
2193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 8;
2194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* This changes the data from RRGGBB to XXRRGGBB */
2196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 6;
2199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = *(--sp);
2208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = hi_filler;
2209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(--dp) = lo_filler;
2210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 4;
2212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 64;
2213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width * 8;
2214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   } /* COLOR_TYPE == RGB */
2217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2221a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Expand grayscale files to RGB, with or without alpha */
2222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
2224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
2226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width = row_info->width;
2227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_gray_to_rgb");
22295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
2230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row_info->bit_depth >= 8 &&
22315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
2232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
2233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      !(row_info->color_type & PNG_COLOR_MASK_COLOR))
2235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width - 1;
2241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 4;
2253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 2;
2270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)row_width * 4 - 1;
2281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = sp  + (png_size_t)row_width * 4;
2282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *sp;
2289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp - 1);
2290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *(dp--) = *(sp--);
2292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->channels += (png_byte)2;
2296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->color_type |= PNG_COLOR_MASK_COLOR;
2297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(row_info->channels *
2298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->bit_depth);
22994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2305a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Reduce RGB files to grayscale, with or without alpha
2306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * using the equation given in Poynton's ColorFAQ at
23074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008)
23084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * New link:
23094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * <http://www.poynton.com/notes/colour_and_gamma/>
23104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * Charles Poynton poynton at poynton.com
2311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  We approximate this with
2315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *     Y = 0.21268 * R    + 0.7151 * G    + 0.07217 * B
2317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  which can be expressed with integers as
2319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
2321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  The calculation is to be done in a linear colorspace.
2323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
2324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  Other integer coefficents can be used via png_set_rgb_to_gray().
2325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
2326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint /* PRIVATE */
2327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
2328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
2331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width = row_info->width;
2333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int rgb_error = 0;
2334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_rgb_to_gray");
23365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
2337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
23385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
2339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
2340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (row_info->color_type & PNG_COLOR_MASK_COLOR))
2342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
2344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
2345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
2346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
2360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
2361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
23624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *(dp++) = png_ptr->gamma_from_1[
23664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                       (rc*red + gc*green + bc*blue)>>15];
2367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
23694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                     *(dp++) = *(sp - 1);
2370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = *(sp++);
2380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = *(sp++);
2381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = *(sp++);
23824215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
23854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                     *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
2386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
23884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                     *(dp++) = *(sp - 1);
2389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else /* RGB bit_depth == 16 */
2394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_16_to_1 != NULL &&
2397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                png_ptr->gamma_16_from_1 != NULL)
2398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, w;
2404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
24094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red == green && red == blue)
2410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = red;
2411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
2414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][red>>8];
24155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                     png_uint_16 green_1 =
24165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                         png_ptr->gamma_16_to_1[(green&0xff) >>
2417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][green>>8];
2418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
2419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  png_ptr->gamma_shift][blue>>8];
2420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
2421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                  + bc*blue_1)>>15);
2422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         png_ptr->gamma_shift][gray16 >> 8];
2424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((w>>8) & 0xff);
2428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(w & 0xff);
2429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, gray16;
2439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
24444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
2448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(gray16 & 0xff);
2449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
2456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
2459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = png_ptr->gamma_to_1[*(sp++)];
2465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = png_ptr->gamma_to_1[*(sp++)];
2466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = png_ptr->gamma_to_1[*(sp++)];
24674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) =  png_ptr->gamma_from_1
2470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             [(rc*red + gc*green + bc*blue)>>15];
2471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte red   = *(sp++);
2482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte green = *(sp++);
2483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_byte blue  = *(sp++);
24844215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) =  (png_byte)((rc*red + gc*green + bc*blue)>>15);
2487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else /* RGBA bit_depth == 16 */
2492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
2494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->gamma_16_to_1 != NULL &&
2495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                png_ptr->gamma_16_from_1 != NULL)
2496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, w;
2502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
2506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
25074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red == green && red == blue)
2508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = red;
2509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red&0xff) >>
25125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                         png_ptr->gamma_shift][red>>8];
25135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                     png_uint_16 green_1 =
25145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                         png_ptr->gamma_16_to_1[(green&0xff) >>
25155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                         png_ptr->gamma_shift][green>>8];
2516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue&0xff) >>
25175f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                         png_ptr->gamma_shift][blue>>8];
2518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 gray16  = (png_uint_16)((rc * red_1
25195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                         + gc * green_1 + bc * blue_1)>>15);
2520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
2521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         png_ptr->gamma_shift][gray16 >> 8];
2522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((w>>8) & 0xff);
2526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(w & 0xff);
2527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);
2529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep sp = row;
2535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_bytep dp = row;
2536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
2537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 red, green, blue, gray16;
2539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  red   = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
2541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  blue  = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
25424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (red != green || red != blue)
2543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     rgb_error |= 1;
2544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray16  = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
2545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)((gray16>>8) & 0xff);
2546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = (png_byte)(gray16 & 0xff);
2547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);  /* alpha */
2548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(dp++) = *(sp++);
2549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   row_info->channels -= (png_byte)2;
2554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
2555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->pixel_depth = (png_byte)(row_info->channels *
2556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->bit_depth);
25574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   return rgb_error;
2560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
2564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * large of png_color.  This lets grayscale images be treated as
2565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * paletted.  Most useful for gamma correction and simplification
2566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * of code.
2567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
2568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI
2569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_build_grayscale_palette(int bit_depth, png_colorp palette)
2570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int num_palette;
2572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int color_inc;
2573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int i;
2574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int v;
2575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
25764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_build_grayscale_palette");
25775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
2578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (palette == NULL)
2579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (bit_depth)
2582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 1:
2584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 2;
2585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0xff;
2586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2587a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
2588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 2:
2589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 4;
2590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0x55;
2591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2592a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
2593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 4:
2594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 16;
2595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0x11;
2596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2597a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
2598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case 8:
2599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 256;
2600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 1;
2601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2602a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
2603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      default:
2604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         num_palette = 0;
2605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         color_inc = 0;
2606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
2610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].red = (png_byte)v;
2612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].green = (png_byte)v;
2613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].blue = (png_byte)v;
2614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* This function is currently unused.  Do we really need it? */
26185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_READ_DITHER_SUPPORTED) && \
26195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott  defined(PNG_CORRECT_PALETTE_SUPPORTED)
2620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_correct_palette(png_structp png_ptr, png_colorp palette,
2622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int num_palette)
2623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
26244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_correct_palette");
26255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
2626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
26275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    defined(PNG_READ_GAMMA_SUPPORTED) && \
26285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott  defined(PNG_FLOATING_POINT_SUPPORTED)
2629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
2630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_color back, back_1;
2632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
2634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.red = png_ptr->gamma_table[png_ptr->background.red];
2636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.green = png_ptr->gamma_table[png_ptr->background.green];
2637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.blue = png_ptr->gamma_table[png_ptr->background.blue];
2638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
2640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
2641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
2642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
2644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         double g;
2646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
2648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
26495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN
26505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott             || fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
2651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.red = png_ptr->background.red;
2653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.green = png_ptr->background.green;
2654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.blue = png_ptr->background.blue;
2655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
2657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.red =
2659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)(pow((double)png_ptr->background.red/255, g) *
2660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                255.0 + 0.5);
2661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.green =
2662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)(pow((double)png_ptr->background.green/255, g) *
2663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                255.0 + 0.5);
2664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            back.blue =
2665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (png_byte)(pow((double)png_ptr->background.blue/255, g) *
2666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                255.0 + 0.5);
2667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         g = 1.0 / png_ptr->background_gamma;
2670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.red =
2672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            (png_byte)(pow((double)png_ptr->background.red/255, g) *
2673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             255.0 + 0.5);
2674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.green =
2675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            (png_byte)(pow((double)png_ptr->background.green/255, g) *
2676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             255.0 + 0.5);
2677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back_1.blue =
2678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            (png_byte)(pow((double)png_ptr->background.blue/255, g) *
2679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             255.0 + 0.5);
2680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
2685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < (png_uint_32)num_palette; i++)
2687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
2689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i] = back;
2691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
2693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte v, w;
2695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
2697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(w, v, png_ptr->trans[i], back_1.red);
2698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = png_ptr->gamma_from_1[w];
2699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
2701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(w, v, png_ptr->trans[i], back_1.green);
2702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = png_ptr->gamma_from_1[w];
2703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
2705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(w, v, png_ptr->trans[i], back_1.blue);
2706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = png_ptr->gamma_from_1[w];
2707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = png_ptr->gamma_table[palette[i].red];
2711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = png_ptr->gamma_table[palette[i].green];
2712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
2717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
2719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
2721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
2723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i] = back;
2725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = png_ptr->gamma_table[palette[i].red];
2729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = png_ptr->gamma_table[palette[i].green];
2730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
2736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
27375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
2738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_GAMMA)
2739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int i;
2741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < num_palette; i++)
2743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette[i].red = png_ptr->gamma_table[palette[i].red];
2745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette[i].green = png_ptr->gamma_table[palette[i].green];
2746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette[i].blue = png_ptr->gamma_table[palette[i].blue];
2747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
27495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
2750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
2751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
27535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
2754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_BACKGROUND)
2755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_color back;
2759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.red   = (png_byte)png_ptr->background.red;
2761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.green = (png_byte)png_ptr->background.green;
2762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         back.blue  = (png_byte)png_ptr->background.blue;
2763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < (int)png_ptr->num_trans; i++)
2765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->trans[i] == 0)
2767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = back.red;
2769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = back.green;
2770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = back.blue;
2771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (png_ptr->trans[i] != 0xff)
2773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(palette[i].red, png_ptr->palette[i].red,
2775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->trans[i], back.red);
2776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(palette[i].green, png_ptr->palette[i].green,
2777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->trans[i], back.green);
2778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_composite(palette[i].blue, png_ptr->palette[i].blue,
2779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_ptr->trans[i], back.blue);
2780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2783a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      else /* Assume grayscale palette (what else could it be?) */
2784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int i;
2786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < num_palette; i++)
2788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (i == (png_byte)png_ptr->trans_values.gray)
2790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].red = (png_byte)png_ptr->background.red;
2792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].green = (png_byte)png_ptr->background.green;
2793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               palette[i].blue = (png_byte)png_ptr->background.blue;
2794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
28025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_BACKGROUND_SUPPORTED
2803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Replace any alpha or transparency with the supplied background color.
2804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * "background" is already in the screen gamma, while "background_1" is
2805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * at a gamma of 1.0.  Paletted files have already been taken care of.
2806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
2807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_background(png_row_infop row_info, png_bytep row,
2809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_color_16p trans_values, png_color_16p background
28105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
2811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   , png_color_16p background_1,
2812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
2813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
2814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_16pp gamma_16_to_1, int gamma_shift
2815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   )
2817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
2819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
2820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
2821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int shift;
2822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
28234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_background");
28245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
2825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (background != NULL &&
28265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
2827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
2828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
2830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
2831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->color_type)
2833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY:
2835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (row_info->bit_depth)
2837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 1:
2839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
2841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 7;
2842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
2843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if ((png_uint_16)((*sp >> shift) & 0x01)
2845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        == trans_values->gray)
2846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp |= (png_byte)(background->gray << shift);
2849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (!shift)
2851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 7;
2853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp++;
2854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
2856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift--;
2857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2860a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
2861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 2:
2862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
28635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
2864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_table != NULL)
2865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 6;
2868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x03)
2871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte p = (png_byte)((*sp >> shift) & 0x03);
2879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte g = (png_byte)((gamma_table [p | (p << 2) |
2880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                               (p << 4) | (p << 6)] >> 6) & 0x03);
2881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(g << shift);
2883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 6;
2887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 2;
2891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 6;
2898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x03)
2901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 6;
2909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 2;
2913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2917a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
2918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 4:
2919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
29205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
2921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_table != NULL)
2922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 4;
2925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x0f)
2928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte p = (png_byte)((*sp >> shift) & 0x0f);
2936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           png_byte g = (png_byte)((gamma_table[p |
2937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                             (p << 4)] >> 4) & 0x0f);
2938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(g << shift);
2940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 4;
2944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 4;
2948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 4;
2955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++)
2956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if ((png_uint_16)((*sp >> shift) & 0x0f)
2958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            == trans_values->gray)
2959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp |= (png_byte)(background->gray << shift);
2962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (!shift)
2964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift = 4;
2966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           sp++;
2967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           shift -= 4;
2970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
2973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2974a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
2975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 8:
2976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
29775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
2978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_table != NULL)
2979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp++)
2982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (*sp == trans_values->gray)
2984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)background->gray;
2986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
2988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
2989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = gamma_table[*sp];
2990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
2991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
2992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
2997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp++)
2998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
2999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (*sp == trans_values->gray)
3000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
3001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)background->gray;
3002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
3003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3007a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 16:
3009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
30105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (gamma_16 != NULL)
3012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
3014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp += 2)
3015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (v == trans_values->gray)
3020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
3021a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                           /* Background is already in screen gamma */
3022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)((background->gray >> 8) & 0xff);
3023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *(sp + 1) = (png_byte)(background->gray & 0xff);
3024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
3025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        else
3026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
3027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)((v >> 8) & 0xff);
3029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *(sp + 1) = (png_byte)(v & 0xff);
3030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
3031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp = row;
3037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     for (i = 0; i < row_width; i++, sp += 2)
3038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        if (v == trans_values->gray)
3043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        {
3044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *sp = (png_byte)((background->gray >> 8) & 0xff);
3045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           *(sp + 1) = (png_byte)(background->gray & 0xff);
3046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        }
3047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3054a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB:
3056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
30595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_table != NULL)
3061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 3)
3064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (*sp == trans_values->red &&
3066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) == trans_values->green &&
3067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) == trans_values->blue)
3068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)background->red;
3070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)background->green;
3071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)background->blue;
3072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = gamma_table[*sp];
3076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = gamma_table[*(sp + 1)];
3077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = gamma_table[*(sp + 2)];
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                  for (i = 0; i < row_width; i++, sp += 3)
3086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (*sp == trans_values->red &&
3088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) == trans_values->green &&
3089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) == trans_values->blue)
3090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)background->red;
3092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)background->green;
3093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)background->blue;
3094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
31005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_16 != NULL)
3102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 6)
3105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
3109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (r == trans_values->red && g == trans_values->green &&
3110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        b == trans_values->blue)
3111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3112a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                        /* Background is already in screen gamma */
3113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)((background->red >> 8) & 0xff);
3114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)(background->red & 0xff);
3115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
3116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 3) = (png_byte)(background->green & 0xff);
3117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 5) = (png_byte)(background->blue & 0xff);
3119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)((v >> 8) & 0xff);
3124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)(v & 0xff);
3125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 3) = (png_byte)(v & 0xff);
3128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 5) = (png_byte)(v & 0xff);
3131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 6)
3139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
3141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
3143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (r == trans_values->red && g == trans_values->green &&
3145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        b == trans_values->blue)
3146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *sp = (png_byte)((background->red >> 8) & 0xff);
3148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 1) = (png_byte)(background->red & 0xff);
3149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
3150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 3) = (png_byte)(background->green & 0xff);
3151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(sp + 5) = (png_byte)(background->blue & 0xff);
3153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3159a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY_ALPHA:
3161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
31645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_table != NULL)
3167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 2, dp++)
3171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = *(sp + 1);
3173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_table[*sp];
3177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3180a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                        /* Background is already in screen gamma */
3181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->gray;
3182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_byte v, w;
3186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*sp];
3188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->gray);
3189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_from_1[w];
3190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 2, dp++)
3199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte a = *(sp + 1);
3201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = *sp;
3205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
32065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->gray;
3210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*dp, *sp, a, background_1->gray);
3214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
3216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = (png_byte)background->gray;
3217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (png_ptr->bit_depth == 16) */
3222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
32235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_16_to_1 != NULL)
3226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
3230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
32415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
3244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3247a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                        /* Background is already in screen gamma */
3248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->gray >> 8) & 0xff);
3249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->gray & 0xff);
3250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
32515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 g, v, w;
3255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, g, a, background_1->gray);
3258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
3259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((w >> 8) & 0xff);
3260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(w & 0xff);
3261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 2)
3271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
3273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_memcpy(dp, sp, 2);
3276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
32775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
3280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->gray >> 8) & 0xff);
3284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->gray & 0xff);
3285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
32865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 g, v;
3290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, g, a, background_1->gray);
3293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3302a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB_ALPHA:
3304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
33075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_table != NULL)
3310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte a = *(sp + 3);
3316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_table[*sp];
3320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = gamma_table[*(sp + 1)];
3321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = gamma_table[*(sp + 2)];
3322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3325a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                        /* Background is already in screen gamma */
3326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->red;
3327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)background->green;
3328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)background->blue;
3329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_byte v, w;
3333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*sp];
3335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->red);
3336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = gamma_from_1[w];
3337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*(sp + 1)];
3338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->green);
3339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = gamma_from_1[w];
3340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_to_1[*(sp + 2)];
3341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(w, v, a, background_1->blue);
3342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = gamma_from_1[w];
3343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 4, dp += 3)
3352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_byte a = *(sp + 3);
3354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == 0xff)
3356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = *sp;
3358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = *(sp + 1);
3359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = *(sp + 2);
3360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)background->red;
3364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)background->green;
3365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)background->blue;
3366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*dp, *sp, a, background->red);
3370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*(dp + 1), *(sp + 1), a,
3371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           background->green);
3372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite(*(dp + 2), *(sp + 2), a,
3373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                           background->blue);
3374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
33805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   gamma_16_to_1 != NULL)
3383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                         << 8) + (png_uint_16)(*(sp + 7)));
3390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
3399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(v & 0xff);
3400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
3402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(v & 0xff);
3403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3406a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                        /* Background is already in screen gamma */
3407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->red >> 8) & 0xff);
3408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->red & 0xff);
3409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(background->green & 0xff);
3411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(background->blue & 0xff);
3413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v, w, x;
3417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(w, v, a, background_1->red);
3420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((x >> 8) & 0xff);
3422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(x & 0xff);
3423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(w, v, a, background_1->green);
3425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
3426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((x >> 8) & 0xff);
3427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(x & 0xff);
3428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(w, v, a, background_1->blue);
3430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
3431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((x >> 8) & 0xff);
3432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(x & 0xff);
3433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row;
3440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row;
3441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++, sp += 8, dp += 6)
3442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        << 8) + (png_uint_16)(*(sp + 7)));
3445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (a == (png_uint_16)0xffff)
3446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_memcpy(dp, sp, 6);
3448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else if (a == 0)
3450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((background->red >> 8) & 0xff);
3452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(background->red & 0xff);
3453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
3454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(background->green & 0xff);
3455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
3456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(background->blue & 0xff);
3457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 v;
3461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            + *(sp + 3));
3465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                            + *(sp + 5));
3467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, r, a, background->red);
3469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = (png_byte)((v >> 8) & 0xff);
3470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 1) = (png_byte)(v & 0xff);
3471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, g, a, background->green);
3472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 2) = (png_byte)((v >> 8) & 0xff);
3473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 3) = (png_byte)(v & 0xff);
3474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        png_composite_16(v, b, a, background->blue);
3475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 4) = (png_byte)((v >> 8) & 0xff);
3476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *(dp + 5) = (png_byte)(v & 0xff);
3477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
3486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
3488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels--;
3489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = (png_byte)(row_info->channels *
3490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->bit_depth);
34914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
34975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
3498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Gamma correct the image, avoiding the alpha channel.  Make sure
3499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * you do this after you deal with the transparency issue on grayscale
3500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * or RGB images. If your bit depth is 8, use gamma_table, if it
3501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * is 16, use gamma_16_table and gamma_shift.  Build these with
3502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * build_gamma_table().
3503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
3504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_gamma(png_row_infop row_info, png_bytep row,
3506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep gamma_table, png_uint_16pp gamma_16_table,
3507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int gamma_shift)
3508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp;
3510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
3511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
3512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
35134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_gamma");
35145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
3515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
35165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
3517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
3518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
3520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
3521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->color_type)
3523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB:
3525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v;
3545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3562a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_RGB_ALPHA:
3564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 4;
3596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3600a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY_ALPHA:
3602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else /* if (row_info->bit_depth == 16) */
3613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 4;
3621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3625a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case PNG_COLOR_TYPE_GRAY:
3627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 2)
3629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i += 4)
3632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int a = *sp & 0xc0;
3634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int b = *sp & 0x30;
3635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int c = *sp & 0x0c;
3636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int d = *sp & 0x03;
3637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)(
36395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                      ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
36405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                      ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
36415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                      ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
36425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                      ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
3643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3646a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 4)
3648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i += 2)
3651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int msb = *sp & 0xf0;
3653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int lsb = *sp & 0x0f;
3654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
36565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                      | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
3657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3660a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (row_info->bit_depth == 8)
3662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = gamma_table[*sp];
3667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
3668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3670a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (row_info->bit_depth == 16)
3672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row;
3674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
3677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *sp = (png_byte)((v >> 8) & 0xff);
3678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp + 1) = (png_byte)(v & 0xff);
3679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp += 2;
3680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
36895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
3690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Expands a palette row to an RGB or RGBA row depending
3691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * upon whether you supply trans and num_trans.
3692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
3693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand_palette(png_row_infop row_info, png_bytep row,
3695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_colorp palette, png_bytep trans, int num_trans)
3696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int shift, value;
3698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
3699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
3700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
3701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
37024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_expand_palette");
37035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
3704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
37055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
3706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
3707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row_info->color_type == PNG_COLOR_TYPE_PALETTE)
3709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->bit_depth < 8)
3711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         switch (row_info->bit_depth)
3713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 1:
3715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)((row_width - 1) >> 3);
3717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)row_width - 1;
3718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               shift = 7 - (int)((row_width + 7) & 0x07);
3719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if ((*sp >> shift) & 0x01)
3722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = 1;
3723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = 0;
3725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (shift == 7)
3726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 0;
3728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp--;
3729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift++;
3732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp--;
3734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
3736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3737a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 2:
3739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)((row_width - 1) >> 2);
3741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)row_width - 1;
3742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  value = (*sp >> shift) & 0x03;
3746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp = (png_byte)value;
3747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (shift == 6)
3748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 0;
3750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp--;
3751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift += 2;
3754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp--;
3756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
3758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3759a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            case 4:
3761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)((row_width - 1) >> 1);
3763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)row_width - 1;
3764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               shift = (int)((row_width & 0x01) << 2);
3765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  value = (*sp >> shift) & 0x0f;
3768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp = (png_byte)value;
3769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (shift == 4)
3770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift = 0;
3772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     sp--;
3773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     shift += 4;
3776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp--;
3778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               break;
3780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->bit_depth = 8;
3783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = 8;
3784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->rowbytes = row_width;
3785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->bit_depth)
3787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 8:
3789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (trans != NULL)
3791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)row_width - 1;
3793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)(row_width << 2) - 1;
3794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if ((int)(*sp) >= num_trans)
3798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = trans[*sp];
3801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].blue;
3802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].green;
3803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].red;
3804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
3805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->bit_depth = 8;
3807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->pixel_depth = 32;
3808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->rowbytes = row_width * 4;
3809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->color_type = 6;
3810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->channels = 4;
3811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
3813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)row_width - 1;
3815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)(row_width * 3) - 1;
3816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].blue;
3820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].green;
3821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = palette[*sp].red;
3822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
3823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3824a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->bit_depth = 8;
3826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->pixel_depth = 24;
3827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->rowbytes = row_width * 3;
3828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->color_type = 2;
3829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_info->channels = 3;
3830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* If the bit depth < 8, it is expanded to 8.  Also, if the already
3838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * expanded transparency value is supplied, an alpha channel is built.
3839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
3840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_expand(png_row_infop row_info, png_bytep row,
3842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_color_16p trans_value)
3843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int shift, value;
3845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
3846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
3847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
3848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
38494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_expand");
38505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
38515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
3852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
3853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
3856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
3858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth < 8)
3860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            switch (row_info->bit_depth)
3862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 1:
3864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray = (png_uint_16)((gray&0x01)*0xff);
3866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row + (png_size_t)((row_width - 1) >> 3);
3867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row + (png_size_t)row_width - 1;
3868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = 7 - (int)((row_width + 7) & 0x07);
3869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
3870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if ((*sp >> shift) & 0x01)
3872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = 0xff;
3873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        *dp = 0;
3875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (shift == 7)
3876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 0;
3878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp--;
3879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift++;
3882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
3884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3887a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 2:
3889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray = (png_uint_16)((gray&0x03)*0x55);
3891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row + (png_size_t)((row_width - 1) >> 2);
3892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row + (png_size_t)row_width - 1;
3893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
3894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
3895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     value = (*sp >> shift) & 0x03;
3897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = (png_byte)(value | (value << 2) | (value << 4) |
3898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        (value << 6));
3899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (shift == 6)
3900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 0;
3902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp--;
3903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift += 2;
3906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
3908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3911a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               case 4:
3913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  gray = (png_uint_16)((gray&0x0f)*0x11);
3915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp = row + (png_size_t)((row_width - 1) >> 1);
3916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp = row + (png_size_t)row_width - 1;
3917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
3918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  for (i = 0; i < row_width; i++)
3919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     value = (*sp >> shift) & 0x0f;
3921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp = (png_byte)(value | (value << 4));
3922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     if (shift == 4)
3923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     {
3924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 0;
3925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        sp--;
3926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     }
3927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     else
3928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                        shift = 4;
3929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
3931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  break;
3933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3935a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->bit_depth = 8;
3937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = 8;
3938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = row_width;
3939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (trans_value != NULL)
3942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (row_info->bit_depth == 8)
3944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               gray = gray & 0xff;
3946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + (png_size_t)row_width - 1;
3947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (png_size_t)(row_width << 1) - 1;
3948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
3950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (*sp == gray)
3951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0;
3952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = *sp--;
3955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3957a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else if (row_info->bit_depth == 16)
3959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte gray_high = (gray >> 8) & 0xff;
3961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte gray_low = gray & 0xff;
3962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp = row + row_info->rowbytes - 1;
3963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp = row + (row_info->rowbytes << 1) - 1;
3964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (i = 0; i < row_width; i++)
3965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
39664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  if (*(sp - 1) == gray_high && *(sp) == gray_low)
3967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0;
3969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0;
3970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
3972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
3973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     *dp-- = 0xff;
3975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
3976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = *sp--;
3977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = *sp--;
3978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
3979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3980a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
3981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
3982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->channels = 2;
3983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
3984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
3985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               row_width);
3986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
3989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->bit_depth == 8)
3991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte red = trans_value->red & 0xff;
3993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte green = trans_value->green & 0xff;
3994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte blue = trans_value->blue & 0xff;
3995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sp = row + (png_size_t)row_info->rowbytes - 1;
3996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dp = row + (png_size_t)(row_width << 2) - 1;
3997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
3998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
4000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0;
4001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
4002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0xff;
4003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
4007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (row_info->bit_depth == 16)
4009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
4010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte red_high = (trans_value->red >> 8) & 0xff;
4011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte green_high = (trans_value->green >> 8) & 0xff;
4012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte blue_high = (trans_value->blue >> 8) & 0xff;
4013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte red_low = trans_value->red & 0xff;
4014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte green_low = trans_value->green & 0xff;
4015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte blue_low = trans_value->blue & 0xff;
4016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sp = row + row_info->rowbytes - 1;
4017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            dp = row + (png_size_t)(row_width << 3) - 1;
4018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
4019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
4020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (*(sp - 5) == red_high &&
4021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 4) == red_low &&
4022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 3) == green_high &&
4023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 2) == green_low &&
4024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp - 1) == blue_high &&
4025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *(sp    ) == blue_low)
4026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
4027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0;
4028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0;
4029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
4030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
4031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
4032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0xff;
4033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp-- = 0xff;
4034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
4035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               *dp-- = *sp--;
4041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
4042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
4044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels = 4;
4045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
40464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
4049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
4050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
40525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_DITHER_SUPPORTED
4053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
4054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_dither(png_row_infop row_info, png_bytep row,
4055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_bytep palette_lookup, png_bytep dither_lookup)
4056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
4057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep sp, dp;
4058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 i;
4059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 row_width=row_info->width;
4060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
40614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_dither");
40625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
40635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
4064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
4065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
4067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
4068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette_lookup && row_info->bit_depth == 8)
4069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int r, g, b, p;
4071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sp = row;
4072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         dp = row;
4073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < row_width; i++)
4074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
4075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r = *sp++;
4076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g = *sp++;
4077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b = *sp++;
4078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4079a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott            /* This looks real messy, but the compiler will reduce
4080a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             * it down to a reasonable formula.  For example, with
4081a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             * 5 bits per color, we get:
4082a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             * p = (((r >> 3) & 0x1f) << 10) |
4083a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             *    (((g >> 3) & 0x1f) << 5) |
4084a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             *    ((b >> 3) & 0x1f);
4085a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott             */
4086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
4087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
4088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
4089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
4090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
4091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_BLUE_BITS)) |
4092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
4093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_BLUE_BITS) - 1));
4094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dp++ = palette_lookup[p];
4096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels = 1;
4099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = row_info->bit_depth;
41004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
4103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         palette_lookup != NULL && row_info->bit_depth == 8)
4104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         int r, g, b, p;
4106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sp = row;
4107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         dp = row;
4108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < row_width; i++)
4109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
4110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            r = *sp++;
4111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            g = *sp++;
4112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b = *sp++;
4113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            sp++;
4114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
4116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_RED_BITS) - 1)) <<
4117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
4118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
4119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
4120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (PNG_DITHER_BLUE_BITS)) |
4121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
4122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((1 << PNG_DITHER_BLUE_BITS) - 1));
4123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *dp++ = palette_lookup[p];
4125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->channels = 1;
4128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         row_info->pixel_depth = row_info->bit_depth;
41294215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         dither_lookup && row_info->bit_depth == 8)
4133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         sp = row;
4135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < row_width; i++, sp++)
4136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
4137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *sp = dither_lookup[*sp];
4138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
4141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
4142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
41455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GAMMA_SUPPORTED
4146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectstatic PNG_CONST int png_gamma_shift[] =
4147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00};
4148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
4150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * tables, we don't make a full table if we are reducing to 8-bit in
4151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the future.  Note also how the gamma_16 tables are segmented so that
4152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * we don't need to allocate > 64K chunks for a full 16-bit table.
41535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41545f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * See the PNG extensions document for an integer algorithm for creating
41555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * the gamma tables.  Maybe we will implement that here someday.
41565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * We should only reach this point if
41585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      the file_gamma is known (i.e., the gAMA or sRGB chunk is present,
41605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      or the application has provided a file_gamma)
41615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *   AND
41635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      {
41645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *         the screen_gamma is known
41655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      OR
41665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41675f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *         RGB_to_gray transformation is being performed
41685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      }
41695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *   AND
41715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      {
41725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *         the screen_gamma is different from the reciprocal of the
41735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *         file_gamma by more than the specified threshold
41745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      OR
41765f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *
41775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *         a background color has been specified and the file_gamma
41785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *         and screen_gamma are not 1.0, within the specified threshold.
41795f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *      }
4180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
41815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
4182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
4183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_build_gamma_table(png_structp png_ptr)
4184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
41854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project  png_debug(1, "in png_build_gamma_table");
4186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (png_ptr->bit_depth <= 8)
4188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
4189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     int i;
4190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     double g;
4191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->screen_gamma > .000001)
4193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
4194a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0;
4197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
4199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        (png_uint_32)256);
4200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     for (i = 0; i < 256; i++)
4202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
4204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g) * 255.0 + .5);
4205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
4210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma);
4213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
4215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           (png_uint_32)256);
4216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < 256; i++)
4218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
4220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              g) * 255.0 + .5);
4221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
4225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           (png_uint_32)256);
4226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
42274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        if (png_ptr->screen_gamma > 0.000001)
4228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g = 1.0 / png_ptr->screen_gamma;
4229a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else
4231a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott           g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
4232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < 256; i++)
4234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
4236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              g) * 255.0 + .5);
4237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
4242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else
4243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
4244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     double g;
4245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     int i, j, shift, num;
4246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     int sig_bit;
4247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_uint_32 ig;
4248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
4250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sig_bit = (int)png_ptr->sig_bit.red;
4252a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if ((int)png_ptr->sig_bit.green > sig_bit)
4254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           sig_bit = png_ptr->sig_bit.green;
4255a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if ((int)png_ptr->sig_bit.blue > sig_bit)
4257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           sig_bit = png_ptr->sig_bit.blue;
4258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        sig_bit = (int)png_ptr->sig_bit.gray;
4262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (sig_bit > 0)
4265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 16 - sig_bit;
4266a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 0;
4269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & PNG_16_TO_8)
4271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (shift < (16 - PNG_MAX_GAMMA_8))
4273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           shift = (16 - PNG_MAX_GAMMA_8);
4274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (shift > 8)
4277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 8;
4278a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (shift < 0)
4280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        shift = 0;
4281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->gamma_shift = (png_byte)shift;
4283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     num = (1 << (8 - shift));
4285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->screen_gamma > .000001)
4287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
4288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0;
4290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
42915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott     png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr,
42924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        (png_uint_32)(num * png_sizeof(png_uint_16p)));
4293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
4295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        double fin, fout;
4297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_uint_32 last, max;
4298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
43024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / g;
4306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        last = 0;
4307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < 256; i++)
4308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           fout = ((double)i + 0.5) / 256.0;
4310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           fin = pow(fout, g);
4311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
4312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           while (last <= max)
4313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
4315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 [(int)(last >> (8 - shift))] = (png_uint_16)(
4316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)i | ((png_uint_16)i << 8));
4317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              last++;
4318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        while (last < ((png_uint_32)num << 8))
4321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
4323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
4324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           last++;
4325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     else
4328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
43324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
4335a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           for (j = 0; j < 256; j++)
4337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_table[i][j] =
4339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    65535.0, g) * 65535.0 + .5);
4341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
4346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
4347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
4348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
4349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        g = 1.0 / (png_ptr->gamma);
4351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
43525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott        png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr,
43534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project           (png_uint_32)(num * png_sizeof(png_uint_16p )));
4354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
43584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           ig = (((png_uint_32)i *
4361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (png_uint_32)png_gamma_shift[shift]) >> 4);
4362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           for (j = 0; j < 256; j++)
4363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_to_1[i][j] =
4365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    65535.0, g) * 65535.0 + .5);
4367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
43704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project        if (png_ptr->screen_gamma > 0.000001)
4371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           g = 1.0 / png_ptr->screen_gamma;
4372a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else
4374a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott           g = png_ptr->gamma;   /* Probably doing rgb_to_gray */
4375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
43765f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott        png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr,
43774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project           (png_uint_32)(num * png_sizeof(png_uint_16p)));
4378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        for (i = 0; i < num; i++)
4380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
4381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
43824215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project              (png_uint_32)(256 * png_sizeof(png_uint_16)));
4383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           ig = (((png_uint_32)i *
4385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              (png_uint_32)png_gamma_shift[shift]) >> 4);
4386a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           for (j = 0; j < 256; j++)
4388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
4389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              png_ptr->gamma_16_from_1[i][j] =
4390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                 (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
4391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                    65535.0, g) * 65535.0 + .5);
4392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
4393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
4394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
4395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
4396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
4397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
4398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* To do: install integer version of png_build_gamma_table here */
4400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
44025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_MNG_FEATURES_SUPPORTED
4403a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Undoes intrapixel differencing  */
4404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
4405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_intrapixel(png_row_infop row_info, png_bytep row)
4406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
44074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_intrapixel");
44085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
4409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (
44105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USELESS_TESTS_SUPPORTED
4411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       row != NULL && row_info != NULL &&
4412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
4413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (row_info->color_type & PNG_COLOR_MASK_COLOR))
4414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
4415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int bytes_per_pixel;
4416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 row_width = row_info->width;
4417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (row_info->bit_depth == 8)
4418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp;
4420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
4421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
4423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 3;
4424a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 4;
4427a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
4429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return;
4430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
4432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
4433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
4434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
4435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (row_info->bit_depth == 16)
4438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
4439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp;
4440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
4441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
4443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 6;
4444a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            bytes_per_pixel = 8;
4447a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
4448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
4449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return;
4450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
4452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
44534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
44544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
44554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
44564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 red  = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL);
44574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL);
4458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp  ) = (png_byte)((red >> 8) & 0xff);
4459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+1) = (png_byte)(red & 0xff);
4460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+4) = (png_byte)((blue >> 8) & 0xff);
4461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *(rp+5) = (png_byte)(blue & 0xff);
4462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
4463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
4464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
4465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
4466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_MNG_FEATURES_SUPPORTED */
4467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_SUPPORTED */
4468