xref: /aosp_15_r20/external/libpng/pngtrans.c (revision a67afe4df73cf47866eedc69947994b8ff839aba)
1*a67afe4dSAndroid Build Coastguard Worker 
2*a67afe4dSAndroid Build Coastguard Worker /* pngtrans.c - transforms the data in a row (used by both readers and writers)
3*a67afe4dSAndroid Build Coastguard Worker  *
4*a67afe4dSAndroid Build Coastguard Worker  * Copyright (c) 2018-2024 Cosmin Truta
5*a67afe4dSAndroid Build Coastguard Worker  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
6*a67afe4dSAndroid Build Coastguard Worker  * Copyright (c) 1996-1997 Andreas Dilger
7*a67afe4dSAndroid Build Coastguard Worker  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
8*a67afe4dSAndroid Build Coastguard Worker  *
9*a67afe4dSAndroid Build Coastguard Worker  * This code is released under the libpng license.
10*a67afe4dSAndroid Build Coastguard Worker  * For conditions of distribution and use, see the disclaimer
11*a67afe4dSAndroid Build Coastguard Worker  * and license in png.h
12*a67afe4dSAndroid Build Coastguard Worker  */
13*a67afe4dSAndroid Build Coastguard Worker 
14*a67afe4dSAndroid Build Coastguard Worker #include "pngpriv.h"
15*a67afe4dSAndroid Build Coastguard Worker 
16*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
17*a67afe4dSAndroid Build Coastguard Worker 
18*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
19*a67afe4dSAndroid Build Coastguard Worker /* Turn on BGR-to-RGB mapping */
20*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_bgr(png_structrp png_ptr)21*a67afe4dSAndroid Build Coastguard Worker png_set_bgr(png_structrp png_ptr)
22*a67afe4dSAndroid Build Coastguard Worker {
23*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_bgr");
24*a67afe4dSAndroid Build Coastguard Worker 
25*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
26*a67afe4dSAndroid Build Coastguard Worker       return;
27*a67afe4dSAndroid Build Coastguard Worker 
28*a67afe4dSAndroid Build Coastguard Worker    png_ptr->transformations |= PNG_BGR;
29*a67afe4dSAndroid Build Coastguard Worker }
30*a67afe4dSAndroid Build Coastguard Worker #endif
31*a67afe4dSAndroid Build Coastguard Worker 
32*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
33*a67afe4dSAndroid Build Coastguard Worker /* Turn on 16-bit byte swapping */
34*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_swap(png_structrp png_ptr)35*a67afe4dSAndroid Build Coastguard Worker png_set_swap(png_structrp png_ptr)
36*a67afe4dSAndroid Build Coastguard Worker {
37*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_swap");
38*a67afe4dSAndroid Build Coastguard Worker 
39*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
40*a67afe4dSAndroid Build Coastguard Worker       return;
41*a67afe4dSAndroid Build Coastguard Worker 
42*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr->bit_depth == 16)
43*a67afe4dSAndroid Build Coastguard Worker       png_ptr->transformations |= PNG_SWAP_BYTES;
44*a67afe4dSAndroid Build Coastguard Worker }
45*a67afe4dSAndroid Build Coastguard Worker #endif
46*a67afe4dSAndroid Build Coastguard Worker 
47*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
48*a67afe4dSAndroid Build Coastguard Worker /* Turn on pixel packing */
49*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_packing(png_structrp png_ptr)50*a67afe4dSAndroid Build Coastguard Worker png_set_packing(png_structrp png_ptr)
51*a67afe4dSAndroid Build Coastguard Worker {
52*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_packing");
53*a67afe4dSAndroid Build Coastguard Worker 
54*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
55*a67afe4dSAndroid Build Coastguard Worker       return;
56*a67afe4dSAndroid Build Coastguard Worker 
57*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr->bit_depth < 8)
58*a67afe4dSAndroid Build Coastguard Worker    {
59*a67afe4dSAndroid Build Coastguard Worker       png_ptr->transformations |= PNG_PACK;
60*a67afe4dSAndroid Build Coastguard Worker #     ifdef PNG_WRITE_SUPPORTED
61*a67afe4dSAndroid Build Coastguard Worker          png_ptr->usr_bit_depth = 8;
62*a67afe4dSAndroid Build Coastguard Worker #     endif
63*a67afe4dSAndroid Build Coastguard Worker    }
64*a67afe4dSAndroid Build Coastguard Worker }
65*a67afe4dSAndroid Build Coastguard Worker #endif
66*a67afe4dSAndroid Build Coastguard Worker 
67*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
68*a67afe4dSAndroid Build Coastguard Worker /* Turn on packed pixel swapping */
69*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_packswap(png_structrp png_ptr)70*a67afe4dSAndroid Build Coastguard Worker png_set_packswap(png_structrp png_ptr)
71*a67afe4dSAndroid Build Coastguard Worker {
72*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_packswap");
73*a67afe4dSAndroid Build Coastguard Worker 
74*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
75*a67afe4dSAndroid Build Coastguard Worker       return;
76*a67afe4dSAndroid Build Coastguard Worker 
77*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr->bit_depth < 8)
78*a67afe4dSAndroid Build Coastguard Worker       png_ptr->transformations |= PNG_PACKSWAP;
79*a67afe4dSAndroid Build Coastguard Worker }
80*a67afe4dSAndroid Build Coastguard Worker #endif
81*a67afe4dSAndroid Build Coastguard Worker 
82*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
83*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_shift(png_structrp png_ptr,png_const_color_8p true_bits)84*a67afe4dSAndroid Build Coastguard Worker png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
85*a67afe4dSAndroid Build Coastguard Worker {
86*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_shift");
87*a67afe4dSAndroid Build Coastguard Worker 
88*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
89*a67afe4dSAndroid Build Coastguard Worker       return;
90*a67afe4dSAndroid Build Coastguard Worker 
91*a67afe4dSAndroid Build Coastguard Worker    png_ptr->transformations |= PNG_SHIFT;
92*a67afe4dSAndroid Build Coastguard Worker    png_ptr->shift = *true_bits;
93*a67afe4dSAndroid Build Coastguard Worker }
94*a67afe4dSAndroid Build Coastguard Worker #endif
95*a67afe4dSAndroid Build Coastguard Worker 
96*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
97*a67afe4dSAndroid Build Coastguard Worker     defined(PNG_WRITE_INTERLACING_SUPPORTED)
98*a67afe4dSAndroid Build Coastguard Worker int PNGAPI
png_set_interlace_handling(png_structrp png_ptr)99*a67afe4dSAndroid Build Coastguard Worker png_set_interlace_handling(png_structrp png_ptr)
100*a67afe4dSAndroid Build Coastguard Worker {
101*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_interlace handling");
102*a67afe4dSAndroid Build Coastguard Worker 
103*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr != 0 && png_ptr->interlaced != 0)
104*a67afe4dSAndroid Build Coastguard Worker    {
105*a67afe4dSAndroid Build Coastguard Worker       png_ptr->transformations |= PNG_INTERLACE;
106*a67afe4dSAndroid Build Coastguard Worker       return 7;
107*a67afe4dSAndroid Build Coastguard Worker    }
108*a67afe4dSAndroid Build Coastguard Worker 
109*a67afe4dSAndroid Build Coastguard Worker    return 1;
110*a67afe4dSAndroid Build Coastguard Worker }
111*a67afe4dSAndroid Build Coastguard Worker #endif
112*a67afe4dSAndroid Build Coastguard Worker 
113*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
114*a67afe4dSAndroid Build Coastguard Worker /* Add a filler byte on read, or remove a filler or alpha byte on write.
115*a67afe4dSAndroid Build Coastguard Worker  * The filler type has changed in v0.95 to allow future 2-byte fillers
116*a67afe4dSAndroid Build Coastguard Worker  * for 48-bit input data, as well as to avoid problems with some compilers
117*a67afe4dSAndroid Build Coastguard Worker  * that don't like bytes as parameters.
118*a67afe4dSAndroid Build Coastguard Worker  */
119*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_filler(png_structrp png_ptr,png_uint_32 filler,int filler_loc)120*a67afe4dSAndroid Build Coastguard Worker png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
121*a67afe4dSAndroid Build Coastguard Worker {
122*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_filler");
123*a67afe4dSAndroid Build Coastguard Worker 
124*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
125*a67afe4dSAndroid Build Coastguard Worker       return;
126*a67afe4dSAndroid Build Coastguard Worker 
127*a67afe4dSAndroid Build Coastguard Worker    /* In libpng 1.6 it is possible to determine whether this is a read or write
128*a67afe4dSAndroid Build Coastguard Worker     * operation and therefore to do more checking here for a valid call.
129*a67afe4dSAndroid Build Coastguard Worker     */
130*a67afe4dSAndroid Build Coastguard Worker    if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
131*a67afe4dSAndroid Build Coastguard Worker    {
132*a67afe4dSAndroid Build Coastguard Worker #     ifdef PNG_READ_FILLER_SUPPORTED
133*a67afe4dSAndroid Build Coastguard Worker          /* On read png_set_filler is always valid, regardless of the base PNG
134*a67afe4dSAndroid Build Coastguard Worker           * format, because other transformations can give a format where the
135*a67afe4dSAndroid Build Coastguard Worker           * filler code can execute (basically an 8 or 16-bit component RGB or G
136*a67afe4dSAndroid Build Coastguard Worker           * format.)
137*a67afe4dSAndroid Build Coastguard Worker           *
138*a67afe4dSAndroid Build Coastguard Worker           * NOTE: usr_channels is not used by the read code!  (This has led to
139*a67afe4dSAndroid Build Coastguard Worker           * confusion in the past.)  The filler is only used in the read code.
140*a67afe4dSAndroid Build Coastguard Worker           */
141*a67afe4dSAndroid Build Coastguard Worker          png_ptr->filler = (png_uint_16)filler;
142*a67afe4dSAndroid Build Coastguard Worker #     else
143*a67afe4dSAndroid Build Coastguard Worker          png_app_error(png_ptr, "png_set_filler not supported on read");
144*a67afe4dSAndroid Build Coastguard Worker          PNG_UNUSED(filler) /* not used in the write case */
145*a67afe4dSAndroid Build Coastguard Worker          return;
146*a67afe4dSAndroid Build Coastguard Worker #     endif
147*a67afe4dSAndroid Build Coastguard Worker    }
148*a67afe4dSAndroid Build Coastguard Worker 
149*a67afe4dSAndroid Build Coastguard Worker    else /* write */
150*a67afe4dSAndroid Build Coastguard Worker    {
151*a67afe4dSAndroid Build Coastguard Worker #     ifdef PNG_WRITE_FILLER_SUPPORTED
152*a67afe4dSAndroid Build Coastguard Worker          /* On write the usr_channels parameter must be set correctly at the
153*a67afe4dSAndroid Build Coastguard Worker           * start to record the number of channels in the app-supplied data.
154*a67afe4dSAndroid Build Coastguard Worker           */
155*a67afe4dSAndroid Build Coastguard Worker          switch (png_ptr->color_type)
156*a67afe4dSAndroid Build Coastguard Worker          {
157*a67afe4dSAndroid Build Coastguard Worker             case PNG_COLOR_TYPE_RGB:
158*a67afe4dSAndroid Build Coastguard Worker                png_ptr->usr_channels = 4;
159*a67afe4dSAndroid Build Coastguard Worker                break;
160*a67afe4dSAndroid Build Coastguard Worker 
161*a67afe4dSAndroid Build Coastguard Worker             case PNG_COLOR_TYPE_GRAY:
162*a67afe4dSAndroid Build Coastguard Worker                if (png_ptr->bit_depth >= 8)
163*a67afe4dSAndroid Build Coastguard Worker                {
164*a67afe4dSAndroid Build Coastguard Worker                   png_ptr->usr_channels = 2;
165*a67afe4dSAndroid Build Coastguard Worker                   break;
166*a67afe4dSAndroid Build Coastguard Worker                }
167*a67afe4dSAndroid Build Coastguard Worker 
168*a67afe4dSAndroid Build Coastguard Worker                else
169*a67afe4dSAndroid Build Coastguard Worker                {
170*a67afe4dSAndroid Build Coastguard Worker                   /* There simply isn't any code in libpng to strip out bits
171*a67afe4dSAndroid Build Coastguard Worker                    * from bytes when the components are less than a byte in
172*a67afe4dSAndroid Build Coastguard Worker                    * size!
173*a67afe4dSAndroid Build Coastguard Worker                    */
174*a67afe4dSAndroid Build Coastguard Worker                   png_app_error(png_ptr,
175*a67afe4dSAndroid Build Coastguard Worker                       "png_set_filler is invalid for"
176*a67afe4dSAndroid Build Coastguard Worker                       " low bit depth gray output");
177*a67afe4dSAndroid Build Coastguard Worker                   return;
178*a67afe4dSAndroid Build Coastguard Worker                }
179*a67afe4dSAndroid Build Coastguard Worker 
180*a67afe4dSAndroid Build Coastguard Worker             default:
181*a67afe4dSAndroid Build Coastguard Worker                png_app_error(png_ptr,
182*a67afe4dSAndroid Build Coastguard Worker                    "png_set_filler: inappropriate color type");
183*a67afe4dSAndroid Build Coastguard Worker                return;
184*a67afe4dSAndroid Build Coastguard Worker          }
185*a67afe4dSAndroid Build Coastguard Worker #     else
186*a67afe4dSAndroid Build Coastguard Worker          png_app_error(png_ptr, "png_set_filler not supported on write");
187*a67afe4dSAndroid Build Coastguard Worker          return;
188*a67afe4dSAndroid Build Coastguard Worker #     endif
189*a67afe4dSAndroid Build Coastguard Worker    }
190*a67afe4dSAndroid Build Coastguard Worker 
191*a67afe4dSAndroid Build Coastguard Worker    /* Here on success - libpng supports the operation, set the transformation
192*a67afe4dSAndroid Build Coastguard Worker     * and the flag to say where the filler channel is.
193*a67afe4dSAndroid Build Coastguard Worker     */
194*a67afe4dSAndroid Build Coastguard Worker    png_ptr->transformations |= PNG_FILLER;
195*a67afe4dSAndroid Build Coastguard Worker 
196*a67afe4dSAndroid Build Coastguard Worker    if (filler_loc == PNG_FILLER_AFTER)
197*a67afe4dSAndroid Build Coastguard Worker       png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
198*a67afe4dSAndroid Build Coastguard Worker 
199*a67afe4dSAndroid Build Coastguard Worker    else
200*a67afe4dSAndroid Build Coastguard Worker       png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
201*a67afe4dSAndroid Build Coastguard Worker }
202*a67afe4dSAndroid Build Coastguard Worker 
203*a67afe4dSAndroid Build Coastguard Worker /* Added to libpng-1.2.7 */
204*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_add_alpha(png_structrp png_ptr,png_uint_32 filler,int filler_loc)205*a67afe4dSAndroid Build Coastguard Worker png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
206*a67afe4dSAndroid Build Coastguard Worker {
207*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_add_alpha");
208*a67afe4dSAndroid Build Coastguard Worker 
209*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
210*a67afe4dSAndroid Build Coastguard Worker       return;
211*a67afe4dSAndroid Build Coastguard Worker 
212*a67afe4dSAndroid Build Coastguard Worker    png_set_filler(png_ptr, filler, filler_loc);
213*a67afe4dSAndroid Build Coastguard Worker    /* The above may fail to do anything. */
214*a67afe4dSAndroid Build Coastguard Worker    if ((png_ptr->transformations & PNG_FILLER) != 0)
215*a67afe4dSAndroid Build Coastguard Worker       png_ptr->transformations |= PNG_ADD_ALPHA;
216*a67afe4dSAndroid Build Coastguard Worker }
217*a67afe4dSAndroid Build Coastguard Worker 
218*a67afe4dSAndroid Build Coastguard Worker #endif
219*a67afe4dSAndroid Build Coastguard Worker 
220*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
221*a67afe4dSAndroid Build Coastguard Worker     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
222*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_swap_alpha(png_structrp png_ptr)223*a67afe4dSAndroid Build Coastguard Worker png_set_swap_alpha(png_structrp png_ptr)
224*a67afe4dSAndroid Build Coastguard Worker {
225*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_swap_alpha");
226*a67afe4dSAndroid Build Coastguard Worker 
227*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
228*a67afe4dSAndroid Build Coastguard Worker       return;
229*a67afe4dSAndroid Build Coastguard Worker 
230*a67afe4dSAndroid Build Coastguard Worker    png_ptr->transformations |= PNG_SWAP_ALPHA;
231*a67afe4dSAndroid Build Coastguard Worker }
232*a67afe4dSAndroid Build Coastguard Worker #endif
233*a67afe4dSAndroid Build Coastguard Worker 
234*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
235*a67afe4dSAndroid Build Coastguard Worker     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
236*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_invert_alpha(png_structrp png_ptr)237*a67afe4dSAndroid Build Coastguard Worker png_set_invert_alpha(png_structrp png_ptr)
238*a67afe4dSAndroid Build Coastguard Worker {
239*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_invert_alpha");
240*a67afe4dSAndroid Build Coastguard Worker 
241*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
242*a67afe4dSAndroid Build Coastguard Worker       return;
243*a67afe4dSAndroid Build Coastguard Worker 
244*a67afe4dSAndroid Build Coastguard Worker    png_ptr->transformations |= PNG_INVERT_ALPHA;
245*a67afe4dSAndroid Build Coastguard Worker }
246*a67afe4dSAndroid Build Coastguard Worker #endif
247*a67afe4dSAndroid Build Coastguard Worker 
248*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
249*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_invert_mono(png_structrp png_ptr)250*a67afe4dSAndroid Build Coastguard Worker png_set_invert_mono(png_structrp png_ptr)
251*a67afe4dSAndroid Build Coastguard Worker {
252*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_invert_mono");
253*a67afe4dSAndroid Build Coastguard Worker 
254*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
255*a67afe4dSAndroid Build Coastguard Worker       return;
256*a67afe4dSAndroid Build Coastguard Worker 
257*a67afe4dSAndroid Build Coastguard Worker    png_ptr->transformations |= PNG_INVERT_MONO;
258*a67afe4dSAndroid Build Coastguard Worker }
259*a67afe4dSAndroid Build Coastguard Worker 
260*a67afe4dSAndroid Build Coastguard Worker /* Invert monochrome grayscale data */
261*a67afe4dSAndroid Build Coastguard Worker void /* PRIVATE */
png_do_invert(png_row_infop row_info,png_bytep row)262*a67afe4dSAndroid Build Coastguard Worker png_do_invert(png_row_infop row_info, png_bytep row)
263*a67afe4dSAndroid Build Coastguard Worker {
264*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_do_invert");
265*a67afe4dSAndroid Build Coastguard Worker 
266*a67afe4dSAndroid Build Coastguard Worker   /* This test removed from libpng version 1.0.13 and 1.2.0:
267*a67afe4dSAndroid Build Coastguard Worker    *   if (row_info->bit_depth == 1 &&
268*a67afe4dSAndroid Build Coastguard Worker    */
269*a67afe4dSAndroid Build Coastguard Worker    if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
270*a67afe4dSAndroid Build Coastguard Worker    {
271*a67afe4dSAndroid Build Coastguard Worker       png_bytep rp = row;
272*a67afe4dSAndroid Build Coastguard Worker       size_t i;
273*a67afe4dSAndroid Build Coastguard Worker       size_t istop = row_info->rowbytes;
274*a67afe4dSAndroid Build Coastguard Worker 
275*a67afe4dSAndroid Build Coastguard Worker       for (i = 0; i < istop; i++)
276*a67afe4dSAndroid Build Coastguard Worker       {
277*a67afe4dSAndroid Build Coastguard Worker          *rp = (png_byte)(~(*rp));
278*a67afe4dSAndroid Build Coastguard Worker          rp++;
279*a67afe4dSAndroid Build Coastguard Worker       }
280*a67afe4dSAndroid Build Coastguard Worker    }
281*a67afe4dSAndroid Build Coastguard Worker 
282*a67afe4dSAndroid Build Coastguard Worker    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
283*a67afe4dSAndroid Build Coastguard Worker       row_info->bit_depth == 8)
284*a67afe4dSAndroid Build Coastguard Worker    {
285*a67afe4dSAndroid Build Coastguard Worker       png_bytep rp = row;
286*a67afe4dSAndroid Build Coastguard Worker       size_t i;
287*a67afe4dSAndroid Build Coastguard Worker       size_t istop = row_info->rowbytes;
288*a67afe4dSAndroid Build Coastguard Worker 
289*a67afe4dSAndroid Build Coastguard Worker       for (i = 0; i < istop; i += 2)
290*a67afe4dSAndroid Build Coastguard Worker       {
291*a67afe4dSAndroid Build Coastguard Worker          *rp = (png_byte)(~(*rp));
292*a67afe4dSAndroid Build Coastguard Worker          rp += 2;
293*a67afe4dSAndroid Build Coastguard Worker       }
294*a67afe4dSAndroid Build Coastguard Worker    }
295*a67afe4dSAndroid Build Coastguard Worker 
296*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_16BIT_SUPPORTED
297*a67afe4dSAndroid Build Coastguard Worker    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
298*a67afe4dSAndroid Build Coastguard Worker       row_info->bit_depth == 16)
299*a67afe4dSAndroid Build Coastguard Worker    {
300*a67afe4dSAndroid Build Coastguard Worker       png_bytep rp = row;
301*a67afe4dSAndroid Build Coastguard Worker       size_t i;
302*a67afe4dSAndroid Build Coastguard Worker       size_t istop = row_info->rowbytes;
303*a67afe4dSAndroid Build Coastguard Worker 
304*a67afe4dSAndroid Build Coastguard Worker       for (i = 0; i < istop; i += 4)
305*a67afe4dSAndroid Build Coastguard Worker       {
306*a67afe4dSAndroid Build Coastguard Worker          *rp = (png_byte)(~(*rp));
307*a67afe4dSAndroid Build Coastguard Worker          *(rp + 1) = (png_byte)(~(*(rp + 1)));
308*a67afe4dSAndroid Build Coastguard Worker          rp += 4;
309*a67afe4dSAndroid Build Coastguard Worker       }
310*a67afe4dSAndroid Build Coastguard Worker    }
311*a67afe4dSAndroid Build Coastguard Worker #endif
312*a67afe4dSAndroid Build Coastguard Worker }
313*a67afe4dSAndroid Build Coastguard Worker #endif
314*a67afe4dSAndroid Build Coastguard Worker 
315*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_16BIT_SUPPORTED
316*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
317*a67afe4dSAndroid Build Coastguard Worker /* Swaps byte order on 16-bit depth images */
318*a67afe4dSAndroid Build Coastguard Worker void /* PRIVATE */
png_do_swap(png_row_infop row_info,png_bytep row)319*a67afe4dSAndroid Build Coastguard Worker png_do_swap(png_row_infop row_info, png_bytep row)
320*a67afe4dSAndroid Build Coastguard Worker {
321*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_do_swap");
322*a67afe4dSAndroid Build Coastguard Worker 
323*a67afe4dSAndroid Build Coastguard Worker    if (row_info->bit_depth == 16)
324*a67afe4dSAndroid Build Coastguard Worker    {
325*a67afe4dSAndroid Build Coastguard Worker       png_bytep rp = row;
326*a67afe4dSAndroid Build Coastguard Worker       png_uint_32 i;
327*a67afe4dSAndroid Build Coastguard Worker       png_uint_32 istop= row_info->width * row_info->channels;
328*a67afe4dSAndroid Build Coastguard Worker 
329*a67afe4dSAndroid Build Coastguard Worker       for (i = 0; i < istop; i++, rp += 2)
330*a67afe4dSAndroid Build Coastguard Worker       {
331*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
332*a67afe4dSAndroid Build Coastguard Worker          /* Feature added to libpng-1.6.11 for testing purposes, not
333*a67afe4dSAndroid Build Coastguard Worker           * enabled by default.
334*a67afe4dSAndroid Build Coastguard Worker           */
335*a67afe4dSAndroid Build Coastguard Worker          *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
336*a67afe4dSAndroid Build Coastguard Worker #else
337*a67afe4dSAndroid Build Coastguard Worker          png_byte t = *rp;
338*a67afe4dSAndroid Build Coastguard Worker          *rp = *(rp + 1);
339*a67afe4dSAndroid Build Coastguard Worker          *(rp + 1) = t;
340*a67afe4dSAndroid Build Coastguard Worker #endif
341*a67afe4dSAndroid Build Coastguard Worker       }
342*a67afe4dSAndroid Build Coastguard Worker    }
343*a67afe4dSAndroid Build Coastguard Worker }
344*a67afe4dSAndroid Build Coastguard Worker #endif
345*a67afe4dSAndroid Build Coastguard Worker #endif
346*a67afe4dSAndroid Build Coastguard Worker 
347*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
348*a67afe4dSAndroid Build Coastguard Worker static const png_byte onebppswaptable[256] = {
349*a67afe4dSAndroid Build Coastguard Worker    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
350*a67afe4dSAndroid Build Coastguard Worker    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
351*a67afe4dSAndroid Build Coastguard Worker    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
352*a67afe4dSAndroid Build Coastguard Worker    0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
353*a67afe4dSAndroid Build Coastguard Worker    0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
354*a67afe4dSAndroid Build Coastguard Worker    0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
355*a67afe4dSAndroid Build Coastguard Worker    0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
356*a67afe4dSAndroid Build Coastguard Worker    0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
357*a67afe4dSAndroid Build Coastguard Worker    0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
358*a67afe4dSAndroid Build Coastguard Worker    0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
359*a67afe4dSAndroid Build Coastguard Worker    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
360*a67afe4dSAndroid Build Coastguard Worker    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
361*a67afe4dSAndroid Build Coastguard Worker    0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
362*a67afe4dSAndroid Build Coastguard Worker    0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
363*a67afe4dSAndroid Build Coastguard Worker    0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
364*a67afe4dSAndroid Build Coastguard Worker    0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
365*a67afe4dSAndroid Build Coastguard Worker    0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
366*a67afe4dSAndroid Build Coastguard Worker    0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
367*a67afe4dSAndroid Build Coastguard Worker    0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
368*a67afe4dSAndroid Build Coastguard Worker    0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
369*a67afe4dSAndroid Build Coastguard Worker    0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
370*a67afe4dSAndroid Build Coastguard Worker    0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
371*a67afe4dSAndroid Build Coastguard Worker    0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
372*a67afe4dSAndroid Build Coastguard Worker    0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
373*a67afe4dSAndroid Build Coastguard Worker    0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
374*a67afe4dSAndroid Build Coastguard Worker    0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
375*a67afe4dSAndroid Build Coastguard Worker    0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
376*a67afe4dSAndroid Build Coastguard Worker    0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
377*a67afe4dSAndroid Build Coastguard Worker    0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
378*a67afe4dSAndroid Build Coastguard Worker    0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
379*a67afe4dSAndroid Build Coastguard Worker    0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
380*a67afe4dSAndroid Build Coastguard Worker    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
381*a67afe4dSAndroid Build Coastguard Worker };
382*a67afe4dSAndroid Build Coastguard Worker 
383*a67afe4dSAndroid Build Coastguard Worker static const png_byte twobppswaptable[256] = {
384*a67afe4dSAndroid Build Coastguard Worker    0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
385*a67afe4dSAndroid Build Coastguard Worker    0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
386*a67afe4dSAndroid Build Coastguard Worker    0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
387*a67afe4dSAndroid Build Coastguard Worker    0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
388*a67afe4dSAndroid Build Coastguard Worker    0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
389*a67afe4dSAndroid Build Coastguard Worker    0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
390*a67afe4dSAndroid Build Coastguard Worker    0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
391*a67afe4dSAndroid Build Coastguard Worker    0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
392*a67afe4dSAndroid Build Coastguard Worker    0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
393*a67afe4dSAndroid Build Coastguard Worker    0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
394*a67afe4dSAndroid Build Coastguard Worker    0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
395*a67afe4dSAndroid Build Coastguard Worker    0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
396*a67afe4dSAndroid Build Coastguard Worker    0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
397*a67afe4dSAndroid Build Coastguard Worker    0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
398*a67afe4dSAndroid Build Coastguard Worker    0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
399*a67afe4dSAndroid Build Coastguard Worker    0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
400*a67afe4dSAndroid Build Coastguard Worker    0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
401*a67afe4dSAndroid Build Coastguard Worker    0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
402*a67afe4dSAndroid Build Coastguard Worker    0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
403*a67afe4dSAndroid Build Coastguard Worker    0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
404*a67afe4dSAndroid Build Coastguard Worker    0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
405*a67afe4dSAndroid Build Coastguard Worker    0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
406*a67afe4dSAndroid Build Coastguard Worker    0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
407*a67afe4dSAndroid Build Coastguard Worker    0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
408*a67afe4dSAndroid Build Coastguard Worker    0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
409*a67afe4dSAndroid Build Coastguard Worker    0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
410*a67afe4dSAndroid Build Coastguard Worker    0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
411*a67afe4dSAndroid Build Coastguard Worker    0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
412*a67afe4dSAndroid Build Coastguard Worker    0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
413*a67afe4dSAndroid Build Coastguard Worker    0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
414*a67afe4dSAndroid Build Coastguard Worker    0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
415*a67afe4dSAndroid Build Coastguard Worker    0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
416*a67afe4dSAndroid Build Coastguard Worker };
417*a67afe4dSAndroid Build Coastguard Worker 
418*a67afe4dSAndroid Build Coastguard Worker static const png_byte fourbppswaptable[256] = {
419*a67afe4dSAndroid Build Coastguard Worker    0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
420*a67afe4dSAndroid Build Coastguard Worker    0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
421*a67afe4dSAndroid Build Coastguard Worker    0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
422*a67afe4dSAndroid Build Coastguard Worker    0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
423*a67afe4dSAndroid Build Coastguard Worker    0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
424*a67afe4dSAndroid Build Coastguard Worker    0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
425*a67afe4dSAndroid Build Coastguard Worker    0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
426*a67afe4dSAndroid Build Coastguard Worker    0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
427*a67afe4dSAndroid Build Coastguard Worker    0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
428*a67afe4dSAndroid Build Coastguard Worker    0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
429*a67afe4dSAndroid Build Coastguard Worker    0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
430*a67afe4dSAndroid Build Coastguard Worker    0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
431*a67afe4dSAndroid Build Coastguard Worker    0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
432*a67afe4dSAndroid Build Coastguard Worker    0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
433*a67afe4dSAndroid Build Coastguard Worker    0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
434*a67afe4dSAndroid Build Coastguard Worker    0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
435*a67afe4dSAndroid Build Coastguard Worker    0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
436*a67afe4dSAndroid Build Coastguard Worker    0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
437*a67afe4dSAndroid Build Coastguard Worker    0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
438*a67afe4dSAndroid Build Coastguard Worker    0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
439*a67afe4dSAndroid Build Coastguard Worker    0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
440*a67afe4dSAndroid Build Coastguard Worker    0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
441*a67afe4dSAndroid Build Coastguard Worker    0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
442*a67afe4dSAndroid Build Coastguard Worker    0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
443*a67afe4dSAndroid Build Coastguard Worker    0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
444*a67afe4dSAndroid Build Coastguard Worker    0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
445*a67afe4dSAndroid Build Coastguard Worker    0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
446*a67afe4dSAndroid Build Coastguard Worker    0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
447*a67afe4dSAndroid Build Coastguard Worker    0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
448*a67afe4dSAndroid Build Coastguard Worker    0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
449*a67afe4dSAndroid Build Coastguard Worker    0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
450*a67afe4dSAndroid Build Coastguard Worker    0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
451*a67afe4dSAndroid Build Coastguard Worker };
452*a67afe4dSAndroid Build Coastguard Worker 
453*a67afe4dSAndroid Build Coastguard Worker /* Swaps pixel packing order within bytes */
454*a67afe4dSAndroid Build Coastguard Worker void /* PRIVATE */
png_do_packswap(png_row_infop row_info,png_bytep row)455*a67afe4dSAndroid Build Coastguard Worker png_do_packswap(png_row_infop row_info, png_bytep row)
456*a67afe4dSAndroid Build Coastguard Worker {
457*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_do_packswap");
458*a67afe4dSAndroid Build Coastguard Worker 
459*a67afe4dSAndroid Build Coastguard Worker    if (row_info->bit_depth < 8)
460*a67afe4dSAndroid Build Coastguard Worker    {
461*a67afe4dSAndroid Build Coastguard Worker       png_bytep rp;
462*a67afe4dSAndroid Build Coastguard Worker       png_const_bytep end, table;
463*a67afe4dSAndroid Build Coastguard Worker 
464*a67afe4dSAndroid Build Coastguard Worker       end = row + row_info->rowbytes;
465*a67afe4dSAndroid Build Coastguard Worker 
466*a67afe4dSAndroid Build Coastguard Worker       if (row_info->bit_depth == 1)
467*a67afe4dSAndroid Build Coastguard Worker          table = onebppswaptable;
468*a67afe4dSAndroid Build Coastguard Worker 
469*a67afe4dSAndroid Build Coastguard Worker       else if (row_info->bit_depth == 2)
470*a67afe4dSAndroid Build Coastguard Worker          table = twobppswaptable;
471*a67afe4dSAndroid Build Coastguard Worker 
472*a67afe4dSAndroid Build Coastguard Worker       else if (row_info->bit_depth == 4)
473*a67afe4dSAndroid Build Coastguard Worker          table = fourbppswaptable;
474*a67afe4dSAndroid Build Coastguard Worker 
475*a67afe4dSAndroid Build Coastguard Worker       else
476*a67afe4dSAndroid Build Coastguard Worker          return;
477*a67afe4dSAndroid Build Coastguard Worker 
478*a67afe4dSAndroid Build Coastguard Worker       for (rp = row; rp < end; rp++)
479*a67afe4dSAndroid Build Coastguard Worker          *rp = table[*rp];
480*a67afe4dSAndroid Build Coastguard Worker    }
481*a67afe4dSAndroid Build Coastguard Worker }
482*a67afe4dSAndroid Build Coastguard Worker #endif /* PACKSWAP || WRITE_PACKSWAP */
483*a67afe4dSAndroid Build Coastguard Worker 
484*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_WRITE_FILLER_SUPPORTED) || \
485*a67afe4dSAndroid Build Coastguard Worker     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
486*a67afe4dSAndroid Build Coastguard Worker /* Remove a channel - this used to be 'png_do_strip_filler' but it used a
487*a67afe4dSAndroid Build Coastguard Worker  * somewhat weird combination of flags to determine what to do.  All the calls
488*a67afe4dSAndroid Build Coastguard Worker  * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
489*a67afe4dSAndroid Build Coastguard Worker  * correct arguments.
490*a67afe4dSAndroid Build Coastguard Worker  *
491*a67afe4dSAndroid Build Coastguard Worker  * The routine isn't general - the channel must be the channel at the start or
492*a67afe4dSAndroid Build Coastguard Worker  * end (not in the middle) of each pixel.
493*a67afe4dSAndroid Build Coastguard Worker  */
494*a67afe4dSAndroid Build Coastguard Worker void /* PRIVATE */
png_do_strip_channel(png_row_infop row_info,png_bytep row,int at_start)495*a67afe4dSAndroid Build Coastguard Worker png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
496*a67afe4dSAndroid Build Coastguard Worker {
497*a67afe4dSAndroid Build Coastguard Worker    png_bytep sp = row; /* source pointer */
498*a67afe4dSAndroid Build Coastguard Worker    png_bytep dp = row; /* destination pointer */
499*a67afe4dSAndroid Build Coastguard Worker    png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
500*a67afe4dSAndroid Build Coastguard Worker 
501*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_do_strip_channel");
502*a67afe4dSAndroid Build Coastguard Worker 
503*a67afe4dSAndroid Build Coastguard Worker    /* At the start sp will point to the first byte to copy and dp to where
504*a67afe4dSAndroid Build Coastguard Worker     * it is copied to.  ep always points just beyond the end of the row, so
505*a67afe4dSAndroid Build Coastguard Worker     * the loop simply copies (channels-1) channels until sp reaches ep.
506*a67afe4dSAndroid Build Coastguard Worker     *
507*a67afe4dSAndroid Build Coastguard Worker     * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
508*a67afe4dSAndroid Build Coastguard Worker     *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
509*a67afe4dSAndroid Build Coastguard Worker     */
510*a67afe4dSAndroid Build Coastguard Worker 
511*a67afe4dSAndroid Build Coastguard Worker    /* GA, GX, XG cases */
512*a67afe4dSAndroid Build Coastguard Worker    if (row_info->channels == 2)
513*a67afe4dSAndroid Build Coastguard Worker    {
514*a67afe4dSAndroid Build Coastguard Worker       if (row_info->bit_depth == 8)
515*a67afe4dSAndroid Build Coastguard Worker       {
516*a67afe4dSAndroid Build Coastguard Worker          if (at_start != 0) /* Skip initial filler */
517*a67afe4dSAndroid Build Coastguard Worker             ++sp;
518*a67afe4dSAndroid Build Coastguard Worker          else          /* Skip initial channel and, for sp, the filler */
519*a67afe4dSAndroid Build Coastguard Worker          {
520*a67afe4dSAndroid Build Coastguard Worker             sp += 2; ++dp;
521*a67afe4dSAndroid Build Coastguard Worker          }
522*a67afe4dSAndroid Build Coastguard Worker 
523*a67afe4dSAndroid Build Coastguard Worker          /* For a 1 pixel wide image there is nothing to do */
524*a67afe4dSAndroid Build Coastguard Worker          while (sp < ep)
525*a67afe4dSAndroid Build Coastguard Worker          {
526*a67afe4dSAndroid Build Coastguard Worker             *dp++ = *sp; sp += 2;
527*a67afe4dSAndroid Build Coastguard Worker          }
528*a67afe4dSAndroid Build Coastguard Worker 
529*a67afe4dSAndroid Build Coastguard Worker          row_info->pixel_depth = 8;
530*a67afe4dSAndroid Build Coastguard Worker       }
531*a67afe4dSAndroid Build Coastguard Worker 
532*a67afe4dSAndroid Build Coastguard Worker       else if (row_info->bit_depth == 16)
533*a67afe4dSAndroid Build Coastguard Worker       {
534*a67afe4dSAndroid Build Coastguard Worker          if (at_start != 0) /* Skip initial filler */
535*a67afe4dSAndroid Build Coastguard Worker             sp += 2;
536*a67afe4dSAndroid Build Coastguard Worker          else          /* Skip initial channel and, for sp, the filler */
537*a67afe4dSAndroid Build Coastguard Worker          {
538*a67afe4dSAndroid Build Coastguard Worker             sp += 4; dp += 2;
539*a67afe4dSAndroid Build Coastguard Worker          }
540*a67afe4dSAndroid Build Coastguard Worker 
541*a67afe4dSAndroid Build Coastguard Worker          while (sp < ep)
542*a67afe4dSAndroid Build Coastguard Worker          {
543*a67afe4dSAndroid Build Coastguard Worker             *dp++ = *sp++; *dp++ = *sp; sp += 3;
544*a67afe4dSAndroid Build Coastguard Worker          }
545*a67afe4dSAndroid Build Coastguard Worker 
546*a67afe4dSAndroid Build Coastguard Worker          row_info->pixel_depth = 16;
547*a67afe4dSAndroid Build Coastguard Worker       }
548*a67afe4dSAndroid Build Coastguard Worker 
549*a67afe4dSAndroid Build Coastguard Worker       else
550*a67afe4dSAndroid Build Coastguard Worker          return; /* bad bit depth */
551*a67afe4dSAndroid Build Coastguard Worker 
552*a67afe4dSAndroid Build Coastguard Worker       row_info->channels = 1;
553*a67afe4dSAndroid Build Coastguard Worker 
554*a67afe4dSAndroid Build Coastguard Worker       /* Finally fix the color type if it records an alpha channel */
555*a67afe4dSAndroid Build Coastguard Worker       if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
556*a67afe4dSAndroid Build Coastguard Worker          row_info->color_type = PNG_COLOR_TYPE_GRAY;
557*a67afe4dSAndroid Build Coastguard Worker    }
558*a67afe4dSAndroid Build Coastguard Worker 
559*a67afe4dSAndroid Build Coastguard Worker    /* RGBA, RGBX, XRGB cases */
560*a67afe4dSAndroid Build Coastguard Worker    else if (row_info->channels == 4)
561*a67afe4dSAndroid Build Coastguard Worker    {
562*a67afe4dSAndroid Build Coastguard Worker       if (row_info->bit_depth == 8)
563*a67afe4dSAndroid Build Coastguard Worker       {
564*a67afe4dSAndroid Build Coastguard Worker          if (at_start != 0) /* Skip initial filler */
565*a67afe4dSAndroid Build Coastguard Worker             ++sp;
566*a67afe4dSAndroid Build Coastguard Worker          else          /* Skip initial channels and, for sp, the filler */
567*a67afe4dSAndroid Build Coastguard Worker          {
568*a67afe4dSAndroid Build Coastguard Worker             sp += 4; dp += 3;
569*a67afe4dSAndroid Build Coastguard Worker          }
570*a67afe4dSAndroid Build Coastguard Worker 
571*a67afe4dSAndroid Build Coastguard Worker          /* Note that the loop adds 3 to dp and 4 to sp each time. */
572*a67afe4dSAndroid Build Coastguard Worker          while (sp < ep)
573*a67afe4dSAndroid Build Coastguard Worker          {
574*a67afe4dSAndroid Build Coastguard Worker             *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
575*a67afe4dSAndroid Build Coastguard Worker          }
576*a67afe4dSAndroid Build Coastguard Worker 
577*a67afe4dSAndroid Build Coastguard Worker          row_info->pixel_depth = 24;
578*a67afe4dSAndroid Build Coastguard Worker       }
579*a67afe4dSAndroid Build Coastguard Worker 
580*a67afe4dSAndroid Build Coastguard Worker       else if (row_info->bit_depth == 16)
581*a67afe4dSAndroid Build Coastguard Worker       {
582*a67afe4dSAndroid Build Coastguard Worker          if (at_start != 0) /* Skip initial filler */
583*a67afe4dSAndroid Build Coastguard Worker             sp += 2;
584*a67afe4dSAndroid Build Coastguard Worker          else          /* Skip initial channels and, for sp, the filler */
585*a67afe4dSAndroid Build Coastguard Worker          {
586*a67afe4dSAndroid Build Coastguard Worker             sp += 8; dp += 6;
587*a67afe4dSAndroid Build Coastguard Worker          }
588*a67afe4dSAndroid Build Coastguard Worker 
589*a67afe4dSAndroid Build Coastguard Worker          while (sp < ep)
590*a67afe4dSAndroid Build Coastguard Worker          {
591*a67afe4dSAndroid Build Coastguard Worker             /* Copy 6 bytes, skip 2 */
592*a67afe4dSAndroid Build Coastguard Worker             *dp++ = *sp++; *dp++ = *sp++;
593*a67afe4dSAndroid Build Coastguard Worker             *dp++ = *sp++; *dp++ = *sp++;
594*a67afe4dSAndroid Build Coastguard Worker             *dp++ = *sp++; *dp++ = *sp; sp += 3;
595*a67afe4dSAndroid Build Coastguard Worker          }
596*a67afe4dSAndroid Build Coastguard Worker 
597*a67afe4dSAndroid Build Coastguard Worker          row_info->pixel_depth = 48;
598*a67afe4dSAndroid Build Coastguard Worker       }
599*a67afe4dSAndroid Build Coastguard Worker 
600*a67afe4dSAndroid Build Coastguard Worker       else
601*a67afe4dSAndroid Build Coastguard Worker          return; /* bad bit depth */
602*a67afe4dSAndroid Build Coastguard Worker 
603*a67afe4dSAndroid Build Coastguard Worker       row_info->channels = 3;
604*a67afe4dSAndroid Build Coastguard Worker 
605*a67afe4dSAndroid Build Coastguard Worker       /* Finally fix the color type if it records an alpha channel */
606*a67afe4dSAndroid Build Coastguard Worker       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
607*a67afe4dSAndroid Build Coastguard Worker          row_info->color_type = PNG_COLOR_TYPE_RGB;
608*a67afe4dSAndroid Build Coastguard Worker    }
609*a67afe4dSAndroid Build Coastguard Worker 
610*a67afe4dSAndroid Build Coastguard Worker    else
611*a67afe4dSAndroid Build Coastguard Worker       return; /* The filler channel has gone already */
612*a67afe4dSAndroid Build Coastguard Worker 
613*a67afe4dSAndroid Build Coastguard Worker    /* Fix the rowbytes value. */
614*a67afe4dSAndroid Build Coastguard Worker    row_info->rowbytes = (size_t)(dp-row);
615*a67afe4dSAndroid Build Coastguard Worker }
616*a67afe4dSAndroid Build Coastguard Worker #endif
617*a67afe4dSAndroid Build Coastguard Worker 
618*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
619*a67afe4dSAndroid Build Coastguard Worker /* Swaps red and blue bytes within a pixel */
620*a67afe4dSAndroid Build Coastguard Worker void /* PRIVATE */
png_do_bgr(png_row_infop row_info,png_bytep row)621*a67afe4dSAndroid Build Coastguard Worker png_do_bgr(png_row_infop row_info, png_bytep row)
622*a67afe4dSAndroid Build Coastguard Worker {
623*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_do_bgr");
624*a67afe4dSAndroid Build Coastguard Worker 
625*a67afe4dSAndroid Build Coastguard Worker    if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
626*a67afe4dSAndroid Build Coastguard Worker    {
627*a67afe4dSAndroid Build Coastguard Worker       png_uint_32 row_width = row_info->width;
628*a67afe4dSAndroid Build Coastguard Worker       if (row_info->bit_depth == 8)
629*a67afe4dSAndroid Build Coastguard Worker       {
630*a67afe4dSAndroid Build Coastguard Worker          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
631*a67afe4dSAndroid Build Coastguard Worker          {
632*a67afe4dSAndroid Build Coastguard Worker             png_bytep rp;
633*a67afe4dSAndroid Build Coastguard Worker             png_uint_32 i;
634*a67afe4dSAndroid Build Coastguard Worker 
635*a67afe4dSAndroid Build Coastguard Worker             for (i = 0, rp = row; i < row_width; i++, rp += 3)
636*a67afe4dSAndroid Build Coastguard Worker             {
637*a67afe4dSAndroid Build Coastguard Worker                png_byte save = *rp;
638*a67afe4dSAndroid Build Coastguard Worker                *rp = *(rp + 2);
639*a67afe4dSAndroid Build Coastguard Worker                *(rp + 2) = save;
640*a67afe4dSAndroid Build Coastguard Worker             }
641*a67afe4dSAndroid Build Coastguard Worker          }
642*a67afe4dSAndroid Build Coastguard Worker 
643*a67afe4dSAndroid Build Coastguard Worker          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
644*a67afe4dSAndroid Build Coastguard Worker          {
645*a67afe4dSAndroid Build Coastguard Worker             png_bytep rp;
646*a67afe4dSAndroid Build Coastguard Worker             png_uint_32 i;
647*a67afe4dSAndroid Build Coastguard Worker 
648*a67afe4dSAndroid Build Coastguard Worker             for (i = 0, rp = row; i < row_width; i++, rp += 4)
649*a67afe4dSAndroid Build Coastguard Worker             {
650*a67afe4dSAndroid Build Coastguard Worker                png_byte save = *rp;
651*a67afe4dSAndroid Build Coastguard Worker                *rp = *(rp + 2);
652*a67afe4dSAndroid Build Coastguard Worker                *(rp + 2) = save;
653*a67afe4dSAndroid Build Coastguard Worker             }
654*a67afe4dSAndroid Build Coastguard Worker          }
655*a67afe4dSAndroid Build Coastguard Worker       }
656*a67afe4dSAndroid Build Coastguard Worker 
657*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_16BIT_SUPPORTED
658*a67afe4dSAndroid Build Coastguard Worker       else if (row_info->bit_depth == 16)
659*a67afe4dSAndroid Build Coastguard Worker       {
660*a67afe4dSAndroid Build Coastguard Worker          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
661*a67afe4dSAndroid Build Coastguard Worker          {
662*a67afe4dSAndroid Build Coastguard Worker             png_bytep rp;
663*a67afe4dSAndroid Build Coastguard Worker             png_uint_32 i;
664*a67afe4dSAndroid Build Coastguard Worker 
665*a67afe4dSAndroid Build Coastguard Worker             for (i = 0, rp = row; i < row_width; i++, rp += 6)
666*a67afe4dSAndroid Build Coastguard Worker             {
667*a67afe4dSAndroid Build Coastguard Worker                png_byte save = *rp;
668*a67afe4dSAndroid Build Coastguard Worker                *rp = *(rp + 4);
669*a67afe4dSAndroid Build Coastguard Worker                *(rp + 4) = save;
670*a67afe4dSAndroid Build Coastguard Worker                save = *(rp + 1);
671*a67afe4dSAndroid Build Coastguard Worker                *(rp + 1) = *(rp + 5);
672*a67afe4dSAndroid Build Coastguard Worker                *(rp + 5) = save;
673*a67afe4dSAndroid Build Coastguard Worker             }
674*a67afe4dSAndroid Build Coastguard Worker          }
675*a67afe4dSAndroid Build Coastguard Worker 
676*a67afe4dSAndroid Build Coastguard Worker          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
677*a67afe4dSAndroid Build Coastguard Worker          {
678*a67afe4dSAndroid Build Coastguard Worker             png_bytep rp;
679*a67afe4dSAndroid Build Coastguard Worker             png_uint_32 i;
680*a67afe4dSAndroid Build Coastguard Worker 
681*a67afe4dSAndroid Build Coastguard Worker             for (i = 0, rp = row; i < row_width; i++, rp += 8)
682*a67afe4dSAndroid Build Coastguard Worker             {
683*a67afe4dSAndroid Build Coastguard Worker                png_byte save = *rp;
684*a67afe4dSAndroid Build Coastguard Worker                *rp = *(rp + 4);
685*a67afe4dSAndroid Build Coastguard Worker                *(rp + 4) = save;
686*a67afe4dSAndroid Build Coastguard Worker                save = *(rp + 1);
687*a67afe4dSAndroid Build Coastguard Worker                *(rp + 1) = *(rp + 5);
688*a67afe4dSAndroid Build Coastguard Worker                *(rp + 5) = save;
689*a67afe4dSAndroid Build Coastguard Worker             }
690*a67afe4dSAndroid Build Coastguard Worker          }
691*a67afe4dSAndroid Build Coastguard Worker       }
692*a67afe4dSAndroid Build Coastguard Worker #endif
693*a67afe4dSAndroid Build Coastguard Worker    }
694*a67afe4dSAndroid Build Coastguard Worker }
695*a67afe4dSAndroid Build Coastguard Worker #endif /* READ_BGR || WRITE_BGR */
696*a67afe4dSAndroid Build Coastguard Worker 
697*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
698*a67afe4dSAndroid Build Coastguard Worker     defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
699*a67afe4dSAndroid Build Coastguard Worker /* Added at libpng-1.5.10 */
700*a67afe4dSAndroid Build Coastguard Worker void /* PRIVATE */
png_do_check_palette_indexes(png_structrp png_ptr,png_row_infop row_info)701*a67afe4dSAndroid Build Coastguard Worker png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
702*a67afe4dSAndroid Build Coastguard Worker {
703*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_do_check_palette_indexes");
704*a67afe4dSAndroid Build Coastguard Worker 
705*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
706*a67afe4dSAndroid Build Coastguard Worker       png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
707*a67afe4dSAndroid Build Coastguard Worker    {
708*a67afe4dSAndroid Build Coastguard Worker       /* Calculations moved outside switch in an attempt to stop different
709*a67afe4dSAndroid Build Coastguard Worker        * compiler warnings.  'padding' is in *bits* within the last byte, it is
710*a67afe4dSAndroid Build Coastguard Worker        * an 'int' because pixel_depth becomes an 'int' in the expression below,
711*a67afe4dSAndroid Build Coastguard Worker        * and this calculation is used because it avoids warnings that other
712*a67afe4dSAndroid Build Coastguard Worker        * forms produced on either GCC or MSVC.
713*a67afe4dSAndroid Build Coastguard Worker        */
714*a67afe4dSAndroid Build Coastguard Worker       int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
715*a67afe4dSAndroid Build Coastguard Worker       png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
716*a67afe4dSAndroid Build Coastguard Worker 
717*a67afe4dSAndroid Build Coastguard Worker       switch (row_info->bit_depth)
718*a67afe4dSAndroid Build Coastguard Worker       {
719*a67afe4dSAndroid Build Coastguard Worker          case 1:
720*a67afe4dSAndroid Build Coastguard Worker          {
721*a67afe4dSAndroid Build Coastguard Worker             /* in this case, all bytes must be 0 so we don't need
722*a67afe4dSAndroid Build Coastguard Worker              * to unpack the pixels except for the rightmost one.
723*a67afe4dSAndroid Build Coastguard Worker              */
724*a67afe4dSAndroid Build Coastguard Worker             for (; rp > png_ptr->row_buf; rp--)
725*a67afe4dSAndroid Build Coastguard Worker             {
726*a67afe4dSAndroid Build Coastguard Worker               if ((*rp >> padding) != 0)
727*a67afe4dSAndroid Build Coastguard Worker                  png_ptr->num_palette_max = 1;
728*a67afe4dSAndroid Build Coastguard Worker               padding = 0;
729*a67afe4dSAndroid Build Coastguard Worker             }
730*a67afe4dSAndroid Build Coastguard Worker 
731*a67afe4dSAndroid Build Coastguard Worker             break;
732*a67afe4dSAndroid Build Coastguard Worker          }
733*a67afe4dSAndroid Build Coastguard Worker 
734*a67afe4dSAndroid Build Coastguard Worker          case 2:
735*a67afe4dSAndroid Build Coastguard Worker          {
736*a67afe4dSAndroid Build Coastguard Worker             for (; rp > png_ptr->row_buf; rp--)
737*a67afe4dSAndroid Build Coastguard Worker             {
738*a67afe4dSAndroid Build Coastguard Worker               int i = ((*rp >> padding) & 0x03);
739*a67afe4dSAndroid Build Coastguard Worker 
740*a67afe4dSAndroid Build Coastguard Worker               if (i > png_ptr->num_palette_max)
741*a67afe4dSAndroid Build Coastguard Worker                  png_ptr->num_palette_max = i;
742*a67afe4dSAndroid Build Coastguard Worker 
743*a67afe4dSAndroid Build Coastguard Worker               i = (((*rp >> padding) >> 2) & 0x03);
744*a67afe4dSAndroid Build Coastguard Worker 
745*a67afe4dSAndroid Build Coastguard Worker               if (i > png_ptr->num_palette_max)
746*a67afe4dSAndroid Build Coastguard Worker                  png_ptr->num_palette_max = i;
747*a67afe4dSAndroid Build Coastguard Worker 
748*a67afe4dSAndroid Build Coastguard Worker               i = (((*rp >> padding) >> 4) & 0x03);
749*a67afe4dSAndroid Build Coastguard Worker 
750*a67afe4dSAndroid Build Coastguard Worker               if (i > png_ptr->num_palette_max)
751*a67afe4dSAndroid Build Coastguard Worker                  png_ptr->num_palette_max = i;
752*a67afe4dSAndroid Build Coastguard Worker 
753*a67afe4dSAndroid Build Coastguard Worker               i = (((*rp >> padding) >> 6) & 0x03);
754*a67afe4dSAndroid Build Coastguard Worker 
755*a67afe4dSAndroid Build Coastguard Worker               if (i > png_ptr->num_palette_max)
756*a67afe4dSAndroid Build Coastguard Worker                  png_ptr->num_palette_max = i;
757*a67afe4dSAndroid Build Coastguard Worker 
758*a67afe4dSAndroid Build Coastguard Worker               padding = 0;
759*a67afe4dSAndroid Build Coastguard Worker             }
760*a67afe4dSAndroid Build Coastguard Worker 
761*a67afe4dSAndroid Build Coastguard Worker             break;
762*a67afe4dSAndroid Build Coastguard Worker          }
763*a67afe4dSAndroid Build Coastguard Worker 
764*a67afe4dSAndroid Build Coastguard Worker          case 4:
765*a67afe4dSAndroid Build Coastguard Worker          {
766*a67afe4dSAndroid Build Coastguard Worker             for (; rp > png_ptr->row_buf; rp--)
767*a67afe4dSAndroid Build Coastguard Worker             {
768*a67afe4dSAndroid Build Coastguard Worker               int i = ((*rp >> padding) & 0x0f);
769*a67afe4dSAndroid Build Coastguard Worker 
770*a67afe4dSAndroid Build Coastguard Worker               if (i > png_ptr->num_palette_max)
771*a67afe4dSAndroid Build Coastguard Worker                  png_ptr->num_palette_max = i;
772*a67afe4dSAndroid Build Coastguard Worker 
773*a67afe4dSAndroid Build Coastguard Worker               i = (((*rp >> padding) >> 4) & 0x0f);
774*a67afe4dSAndroid Build Coastguard Worker 
775*a67afe4dSAndroid Build Coastguard Worker               if (i > png_ptr->num_palette_max)
776*a67afe4dSAndroid Build Coastguard Worker                  png_ptr->num_palette_max = i;
777*a67afe4dSAndroid Build Coastguard Worker 
778*a67afe4dSAndroid Build Coastguard Worker               padding = 0;
779*a67afe4dSAndroid Build Coastguard Worker             }
780*a67afe4dSAndroid Build Coastguard Worker 
781*a67afe4dSAndroid Build Coastguard Worker             break;
782*a67afe4dSAndroid Build Coastguard Worker          }
783*a67afe4dSAndroid Build Coastguard Worker 
784*a67afe4dSAndroid Build Coastguard Worker          case 8:
785*a67afe4dSAndroid Build Coastguard Worker          {
786*a67afe4dSAndroid Build Coastguard Worker             for (; rp > png_ptr->row_buf; rp--)
787*a67afe4dSAndroid Build Coastguard Worker             {
788*a67afe4dSAndroid Build Coastguard Worker                if (*rp > png_ptr->num_palette_max)
789*a67afe4dSAndroid Build Coastguard Worker                   png_ptr->num_palette_max = (int) *rp;
790*a67afe4dSAndroid Build Coastguard Worker             }
791*a67afe4dSAndroid Build Coastguard Worker 
792*a67afe4dSAndroid Build Coastguard Worker             break;
793*a67afe4dSAndroid Build Coastguard Worker          }
794*a67afe4dSAndroid Build Coastguard Worker 
795*a67afe4dSAndroid Build Coastguard Worker          default:
796*a67afe4dSAndroid Build Coastguard Worker             break;
797*a67afe4dSAndroid Build Coastguard Worker       }
798*a67afe4dSAndroid Build Coastguard Worker    }
799*a67afe4dSAndroid Build Coastguard Worker }
800*a67afe4dSAndroid Build Coastguard Worker #endif /* CHECK_FOR_INVALID_INDEX */
801*a67afe4dSAndroid Build Coastguard Worker 
802*a67afe4dSAndroid Build Coastguard Worker #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
803*a67afe4dSAndroid Build Coastguard Worker     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
804*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
805*a67afe4dSAndroid Build Coastguard Worker void PNGAPI
png_set_user_transform_info(png_structrp png_ptr,png_voidp user_transform_ptr,int user_transform_depth,int user_transform_channels)806*a67afe4dSAndroid Build Coastguard Worker png_set_user_transform_info(png_structrp png_ptr, png_voidp
807*a67afe4dSAndroid Build Coastguard Worker    user_transform_ptr, int user_transform_depth, int user_transform_channels)
808*a67afe4dSAndroid Build Coastguard Worker {
809*a67afe4dSAndroid Build Coastguard Worker    png_debug(1, "in png_set_user_transform_info");
810*a67afe4dSAndroid Build Coastguard Worker 
811*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
812*a67afe4dSAndroid Build Coastguard Worker       return;
813*a67afe4dSAndroid Build Coastguard Worker 
814*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
815*a67afe4dSAndroid Build Coastguard Worker    if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
816*a67afe4dSAndroid Build Coastguard Worker       (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
817*a67afe4dSAndroid Build Coastguard Worker    {
818*a67afe4dSAndroid Build Coastguard Worker       png_app_error(png_ptr,
819*a67afe4dSAndroid Build Coastguard Worker           "info change after png_start_read_image or png_read_update_info");
820*a67afe4dSAndroid Build Coastguard Worker       return;
821*a67afe4dSAndroid Build Coastguard Worker    }
822*a67afe4dSAndroid Build Coastguard Worker #endif
823*a67afe4dSAndroid Build Coastguard Worker 
824*a67afe4dSAndroid Build Coastguard Worker    png_ptr->user_transform_ptr = user_transform_ptr;
825*a67afe4dSAndroid Build Coastguard Worker    png_ptr->user_transform_depth = (png_byte)user_transform_depth;
826*a67afe4dSAndroid Build Coastguard Worker    png_ptr->user_transform_channels = (png_byte)user_transform_channels;
827*a67afe4dSAndroid Build Coastguard Worker }
828*a67afe4dSAndroid Build Coastguard Worker #endif
829*a67afe4dSAndroid Build Coastguard Worker 
830*a67afe4dSAndroid Build Coastguard Worker /* This function returns a pointer to the user_transform_ptr associated with
831*a67afe4dSAndroid Build Coastguard Worker  * the user transform functions.  The application should free any memory
832*a67afe4dSAndroid Build Coastguard Worker  * associated with this pointer before png_write_destroy and png_read_destroy
833*a67afe4dSAndroid Build Coastguard Worker  * are called.
834*a67afe4dSAndroid Build Coastguard Worker  */
835*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
836*a67afe4dSAndroid Build Coastguard Worker png_voidp PNGAPI
png_get_user_transform_ptr(png_const_structrp png_ptr)837*a67afe4dSAndroid Build Coastguard Worker png_get_user_transform_ptr(png_const_structrp png_ptr)
838*a67afe4dSAndroid Build Coastguard Worker {
839*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr == NULL)
840*a67afe4dSAndroid Build Coastguard Worker       return NULL;
841*a67afe4dSAndroid Build Coastguard Worker 
842*a67afe4dSAndroid Build Coastguard Worker    return png_ptr->user_transform_ptr;
843*a67afe4dSAndroid Build Coastguard Worker }
844*a67afe4dSAndroid Build Coastguard Worker #endif
845*a67afe4dSAndroid Build Coastguard Worker 
846*a67afe4dSAndroid Build Coastguard Worker #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
847*a67afe4dSAndroid Build Coastguard Worker png_uint_32 PNGAPI
png_get_current_row_number(png_const_structrp png_ptr)848*a67afe4dSAndroid Build Coastguard Worker png_get_current_row_number(png_const_structrp png_ptr)
849*a67afe4dSAndroid Build Coastguard Worker {
850*a67afe4dSAndroid Build Coastguard Worker    /* See the comments in png.h - this is the sub-image row when reading an
851*a67afe4dSAndroid Build Coastguard Worker     * interlaced image.
852*a67afe4dSAndroid Build Coastguard Worker     */
853*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr != NULL)
854*a67afe4dSAndroid Build Coastguard Worker       return png_ptr->row_number;
855*a67afe4dSAndroid Build Coastguard Worker 
856*a67afe4dSAndroid Build Coastguard Worker    return PNG_UINT_32_MAX; /* help the app not to fail silently */
857*a67afe4dSAndroid Build Coastguard Worker }
858*a67afe4dSAndroid Build Coastguard Worker 
859*a67afe4dSAndroid Build Coastguard Worker png_byte PNGAPI
png_get_current_pass_number(png_const_structrp png_ptr)860*a67afe4dSAndroid Build Coastguard Worker png_get_current_pass_number(png_const_structrp png_ptr)
861*a67afe4dSAndroid Build Coastguard Worker {
862*a67afe4dSAndroid Build Coastguard Worker    if (png_ptr != NULL)
863*a67afe4dSAndroid Build Coastguard Worker       return png_ptr->pass;
864*a67afe4dSAndroid Build Coastguard Worker    return 8; /* invalid */
865*a67afe4dSAndroid Build Coastguard Worker }
866*a67afe4dSAndroid Build Coastguard Worker #endif /* USER_TRANSFORM_INFO */
867*a67afe4dSAndroid Build Coastguard Worker #endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
868*a67afe4dSAndroid Build Coastguard Worker #endif /* READ || WRITE */
869