blob: 6e1870c596105e4312a8580da072dac60e4ea89d [file] [log] [blame]
The Android Open Source Project893912b2009-03-03 19:30:05 -08001
2/* pngtrans.c - transforms the data in a row (used by both readers and writers)
3 *
Patrick Scotta0bb96c2009-07-22 11:50:02 -04004 * Last changed in libpng 1.2.36 [May 14, 2009]
5 * Copyright (c) 1998-2009 Glenn Randers-Pehrson
The Android Open Source Project893912b2009-03-03 19:30:05 -08006 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
Patrick Scotta0bb96c2009-07-22 11:50:02 -04008 *
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
The Android Open Source Project893912b2009-03-03 19:30:05 -080012 */
13
14#define PNG_INTERNAL
15#include "png.h"
The Android Open Source Project893912b2009-03-03 19:30:05 -080016#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -070017
The Android Open Source Project893912b2009-03-03 19:30:05 -080018#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040019/* Turn on BGR-to-RGB mapping */
The Android Open Source Project893912b2009-03-03 19:30:05 -080020void PNGAPI
21png_set_bgr(png_structp png_ptr)
22{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070023 png_debug(1, "in png_set_bgr");
Patrick Scotta0bb96c2009-07-22 11:50:02 -040024 if (png_ptr == NULL)
25 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080026 png_ptr->transformations |= PNG_BGR;
27}
28#endif
29
30#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040031/* Turn on 16 bit byte swapping */
The Android Open Source Project893912b2009-03-03 19:30:05 -080032void PNGAPI
33png_set_swap(png_structp png_ptr)
34{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070035 png_debug(1, "in png_set_swap");
Patrick Scotta0bb96c2009-07-22 11:50:02 -040036 if (png_ptr == NULL)
37 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080038 if (png_ptr->bit_depth == 16)
39 png_ptr->transformations |= PNG_SWAP_BYTES;
40}
41#endif
42
43#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040044/* Turn on pixel packing */
The Android Open Source Project893912b2009-03-03 19:30:05 -080045void PNGAPI
46png_set_packing(png_structp png_ptr)
47{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070048 png_debug(1, "in png_set_packing");
Patrick Scotta0bb96c2009-07-22 11:50:02 -040049 if (png_ptr == NULL)
50 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080051 if (png_ptr->bit_depth < 8)
52 {
53 png_ptr->transformations |= PNG_PACK;
54 png_ptr->usr_bit_depth = 8;
55 }
56}
57#endif
58
59#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040060/* Turn on packed pixel swapping */
The Android Open Source Project893912b2009-03-03 19:30:05 -080061void PNGAPI
62png_set_packswap(png_structp png_ptr)
63{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070064 png_debug(1, "in png_set_packswap");
Patrick Scotta0bb96c2009-07-22 11:50:02 -040065 if (png_ptr == NULL)
66 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080067 if (png_ptr->bit_depth < 8)
68 png_ptr->transformations |= PNG_PACKSWAP;
69}
70#endif
71
72#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
73void PNGAPI
74png_set_shift(png_structp png_ptr, png_color_8p true_bits)
75{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070076 png_debug(1, "in png_set_shift");
Patrick Scotta0bb96c2009-07-22 11:50:02 -040077 if (png_ptr == NULL)
78 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080079 png_ptr->transformations |= PNG_SHIFT;
80 png_ptr->shift = *true_bits;
81}
82#endif
83
84#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
85 defined(PNG_WRITE_INTERLACING_SUPPORTED)
86int PNGAPI
87png_set_interlace_handling(png_structp png_ptr)
88{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070089 png_debug(1, "in png_set_interlace handling");
The Android Open Source Project893912b2009-03-03 19:30:05 -080090 if (png_ptr && png_ptr->interlaced)
91 {
92 png_ptr->transformations |= PNG_INTERLACE;
93 return (7);
94 }
95
96 return (1);
97}
98#endif
99
100#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
101/* Add a filler byte on read, or remove a filler or alpha byte on write.
102 * The filler type has changed in v0.95 to allow future 2-byte fillers
103 * for 48-bit input data, as well as to avoid problems with some compilers
104 * that don't like bytes as parameters.
105 */
106void PNGAPI
107png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
108{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700109 png_debug(1, "in png_set_filler");
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400110 if (png_ptr == NULL)
111 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800112 png_ptr->transformations |= PNG_FILLER;
113 png_ptr->filler = (png_byte)filler;
114 if (filler_loc == PNG_FILLER_AFTER)
115 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
116 else
117 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
118
119 /* This should probably go in the "do_read_filler" routine.
120 * I attempted to do that in libpng-1.0.1a but that caused problems
121 * so I restored it in libpng-1.0.2a
122 */
123
124 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
125 {
126 png_ptr->usr_channels = 4;
127 }
128
129 /* Also I added this in libpng-1.0.2a (what happens when we expand
130 * a less-than-8-bit grayscale to GA? */
131
132 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
133 {
134 png_ptr->usr_channels = 2;
135 }
136}
137
138#if !defined(PNG_1_0_X)
139/* Added to libpng-1.2.7 */
140void PNGAPI
141png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
142{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700143 png_debug(1, "in png_set_add_alpha");
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400144 if (png_ptr == NULL)
145 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800146 png_set_filler(png_ptr, filler, filler_loc);
147 png_ptr->transformations |= PNG_ADD_ALPHA;
148}
149#endif
150
151#endif
152
153#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
154 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
155void PNGAPI
156png_set_swap_alpha(png_structp png_ptr)
157{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700158 png_debug(1, "in png_set_swap_alpha");
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400159 if (png_ptr == NULL)
160 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800161 png_ptr->transformations |= PNG_SWAP_ALPHA;
162}
163#endif
164
165#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
166 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
167void PNGAPI
168png_set_invert_alpha(png_structp png_ptr)
169{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700170 png_debug(1, "in png_set_invert_alpha");
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400171 if (png_ptr == NULL)
172 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800173 png_ptr->transformations |= PNG_INVERT_ALPHA;
174}
175#endif
176
177#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
178void PNGAPI
179png_set_invert_mono(png_structp png_ptr)
180{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700181 png_debug(1, "in png_set_invert_mono");
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400182 if (png_ptr == NULL)
183 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800184 png_ptr->transformations |= PNG_INVERT_MONO;
185}
186
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400187/* Invert monochrome grayscale data */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800188void /* PRIVATE */
189png_do_invert(png_row_infop row_info, png_bytep row)
190{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700191 png_debug(1, "in png_do_invert");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800192 /* This test removed from libpng version 1.0.13 and 1.2.0:
193 * if (row_info->bit_depth == 1 &&
194 */
195#if defined(PNG_USELESS_TESTS_SUPPORTED)
196 if (row == NULL || row_info == NULL)
197 return;
198#endif
199 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
200 {
201 png_bytep rp = row;
202 png_uint_32 i;
203 png_uint_32 istop = row_info->rowbytes;
204
205 for (i = 0; i < istop; i++)
206 {
207 *rp = (png_byte)(~(*rp));
208 rp++;
209 }
210 }
211 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
212 row_info->bit_depth == 8)
213 {
214 png_bytep rp = row;
215 png_uint_32 i;
216 png_uint_32 istop = row_info->rowbytes;
217
218 for (i = 0; i < istop; i+=2)
219 {
220 *rp = (png_byte)(~(*rp));
221 rp+=2;
222 }
223 }
224 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
225 row_info->bit_depth == 16)
226 {
227 png_bytep rp = row;
228 png_uint_32 i;
229 png_uint_32 istop = row_info->rowbytes;
230
231 for (i = 0; i < istop; i+=4)
232 {
233 *rp = (png_byte)(~(*rp));
234 *(rp+1) = (png_byte)(~(*(rp+1)));
235 rp+=4;
236 }
237 }
238}
239#endif
240
241#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400242/* Swaps byte order on 16 bit depth images */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800243void /* PRIVATE */
244png_do_swap(png_row_infop row_info, png_bytep row)
245{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700246 png_debug(1, "in png_do_swap");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800247 if (
248#if defined(PNG_USELESS_TESTS_SUPPORTED)
249 row != NULL && row_info != NULL &&
250#endif
251 row_info->bit_depth == 16)
252 {
253 png_bytep rp = row;
254 png_uint_32 i;
255 png_uint_32 istop= row_info->width * row_info->channels;
256
257 for (i = 0; i < istop; i++, rp += 2)
258 {
259 png_byte t = *rp;
260 *rp = *(rp + 1);
261 *(rp + 1) = t;
262 }
263 }
264}
265#endif
266
267#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
268static PNG_CONST png_byte onebppswaptable[256] = {
269 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
270 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
271 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
272 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
273 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
274 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
275 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
276 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
277 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
278 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
279 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
280 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
281 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
282 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
283 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
284 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
285 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
286 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
287 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
288 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
289 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
290 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
291 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
292 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
293 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
294 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
295 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
296 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
297 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
298 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
299 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
300 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
301};
302
303static PNG_CONST png_byte twobppswaptable[256] = {
304 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
305 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
306 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
307 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
308 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
309 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
310 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
311 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
312 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
313 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
314 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
315 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
316 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
317 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
318 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
319 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
320 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
321 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
322 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
323 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
324 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
325 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
326 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
327 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
328 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
329 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
330 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
331 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
332 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
333 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
334 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
335 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
336};
337
338static PNG_CONST png_byte fourbppswaptable[256] = {
339 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
340 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
341 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
342 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
343 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
344 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
345 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
346 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
347 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
348 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
349 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
350 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
351 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
352 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
353 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
354 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
355 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
356 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
357 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
358 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
359 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
360 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
361 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
362 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
363 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
364 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
365 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
366 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
367 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
368 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
369 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
370 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
371};
372
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400373/* Swaps pixel packing order within bytes */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800374void /* PRIVATE */
375png_do_packswap(png_row_infop row_info, png_bytep row)
376{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700377 png_debug(1, "in png_do_packswap");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800378 if (
379#if defined(PNG_USELESS_TESTS_SUPPORTED)
380 row != NULL && row_info != NULL &&
381#endif
382 row_info->bit_depth < 8)
383 {
384 png_bytep rp, end, table;
385
386 end = row + row_info->rowbytes;
387
388 if (row_info->bit_depth == 1)
389 table = (png_bytep)onebppswaptable;
390 else if (row_info->bit_depth == 2)
391 table = (png_bytep)twobppswaptable;
392 else if (row_info->bit_depth == 4)
393 table = (png_bytep)fourbppswaptable;
394 else
395 return;
396
397 for (rp = row; rp < end; rp++)
398 *rp = table[*rp];
399 }
400}
401#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
402
403#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
404 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400405/* Remove filler or alpha byte(s) */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800406void /* PRIVATE */
407png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
408{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700409 png_debug(1, "in png_do_strip_filler");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800410#if defined(PNG_USELESS_TESTS_SUPPORTED)
411 if (row != NULL && row_info != NULL)
412#endif
413 {
414 png_bytep sp=row;
415 png_bytep dp=row;
416 png_uint_32 row_width=row_info->width;
417 png_uint_32 i;
418
419 if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400420 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
421 (flags & PNG_FLAG_STRIP_ALPHA))) &&
422 row_info->channels == 4)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800423 {
424 if (row_info->bit_depth == 8)
425 {
426 /* This converts from RGBX or RGBA to RGB */
427 if (flags & PNG_FLAG_FILLER_AFTER)
428 {
429 dp+=3; sp+=4;
430 for (i = 1; i < row_width; i++)
431 {
432 *dp++ = *sp++;
433 *dp++ = *sp++;
434 *dp++ = *sp++;
435 sp++;
436 }
437 }
438 /* This converts from XRGB or ARGB to RGB */
439 else
440 {
441 for (i = 0; i < row_width; i++)
442 {
443 sp++;
444 *dp++ = *sp++;
445 *dp++ = *sp++;
446 *dp++ = *sp++;
447 }
448 }
449 row_info->pixel_depth = 24;
450 row_info->rowbytes = row_width * 3;
451 }
452 else /* if (row_info->bit_depth == 16) */
453 {
454 if (flags & PNG_FLAG_FILLER_AFTER)
455 {
456 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
457 sp += 8; dp += 6;
458 for (i = 1; i < row_width; i++)
459 {
460 /* This could be (although png_memcpy is probably slower):
461 png_memcpy(dp, sp, 6);
462 sp += 8;
463 dp += 6;
464 */
465
466 *dp++ = *sp++;
467 *dp++ = *sp++;
468 *dp++ = *sp++;
469 *dp++ = *sp++;
470 *dp++ = *sp++;
471 *dp++ = *sp++;
472 sp += 2;
473 }
474 }
475 else
476 {
477 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
478 for (i = 0; i < row_width; i++)
479 {
480 /* This could be (although png_memcpy is probably slower):
481 png_memcpy(dp, sp, 6);
482 sp += 8;
483 dp += 6;
484 */
485
486 sp+=2;
487 *dp++ = *sp++;
488 *dp++ = *sp++;
489 *dp++ = *sp++;
490 *dp++ = *sp++;
491 *dp++ = *sp++;
492 *dp++ = *sp++;
493 }
494 }
495 row_info->pixel_depth = 48;
496 row_info->rowbytes = row_width * 6;
497 }
498 row_info->channels = 3;
499 }
500 else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
501 (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
502 (flags & PNG_FLAG_STRIP_ALPHA))) &&
503 row_info->channels == 2)
504 {
505 if (row_info->bit_depth == 8)
506 {
507 /* This converts from GX or GA to G */
508 if (flags & PNG_FLAG_FILLER_AFTER)
509 {
510 for (i = 0; i < row_width; i++)
511 {
512 *dp++ = *sp++;
513 sp++;
514 }
515 }
516 /* This converts from XG or AG to G */
517 else
518 {
519 for (i = 0; i < row_width; i++)
520 {
521 sp++;
522 *dp++ = *sp++;
523 }
524 }
525 row_info->pixel_depth = 8;
526 row_info->rowbytes = row_width;
527 }
528 else /* if (row_info->bit_depth == 16) */
529 {
530 if (flags & PNG_FLAG_FILLER_AFTER)
531 {
532 /* This converts from GGXX or GGAA to GG */
533 sp += 4; dp += 2;
534 for (i = 1; i < row_width; i++)
535 {
536 *dp++ = *sp++;
537 *dp++ = *sp++;
538 sp += 2;
539 }
540 }
541 else
542 {
543 /* This converts from XXGG or AAGG to GG */
544 for (i = 0; i < row_width; i++)
545 {
546 sp += 2;
547 *dp++ = *sp++;
548 *dp++ = *sp++;
549 }
550 }
551 row_info->pixel_depth = 16;
552 row_info->rowbytes = row_width * 2;
553 }
554 row_info->channels = 1;
555 }
556 if (flags & PNG_FLAG_STRIP_ALPHA)
557 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
558 }
559}
560#endif
561
562#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400563/* Swaps red and blue bytes within a pixel */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800564void /* PRIVATE */
565png_do_bgr(png_row_infop row_info, png_bytep row)
566{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700567 png_debug(1, "in png_do_bgr");
The Android Open Source Project893912b2009-03-03 19:30:05 -0800568 if (
569#if defined(PNG_USELESS_TESTS_SUPPORTED)
570 row != NULL && row_info != NULL &&
571#endif
572 (row_info->color_type & PNG_COLOR_MASK_COLOR))
573 {
574 png_uint_32 row_width = row_info->width;
575 if (row_info->bit_depth == 8)
576 {
577 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
578 {
579 png_bytep rp;
580 png_uint_32 i;
581
582 for (i = 0, rp = row; i < row_width; i++, rp += 3)
583 {
584 png_byte save = *rp;
585 *rp = *(rp + 2);
586 *(rp + 2) = save;
587 }
588 }
589 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
590 {
591 png_bytep rp;
592 png_uint_32 i;
593
594 for (i = 0, rp = row; i < row_width; i++, rp += 4)
595 {
596 png_byte save = *rp;
597 *rp = *(rp + 2);
598 *(rp + 2) = save;
599 }
600 }
601 }
602 else if (row_info->bit_depth == 16)
603 {
604 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
605 {
606 png_bytep rp;
607 png_uint_32 i;
608
609 for (i = 0, rp = row; i < row_width; i++, rp += 6)
610 {
611 png_byte save = *rp;
612 *rp = *(rp + 4);
613 *(rp + 4) = save;
614 save = *(rp + 1);
615 *(rp + 1) = *(rp + 5);
616 *(rp + 5) = save;
617 }
618 }
619 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
620 {
621 png_bytep rp;
622 png_uint_32 i;
623
624 for (i = 0, rp = row; i < row_width; i++, rp += 8)
625 {
626 png_byte save = *rp;
627 *rp = *(rp + 4);
628 *(rp + 4) = save;
629 save = *(rp + 1);
630 *(rp + 1) = *(rp + 5);
631 *(rp + 5) = save;
632 }
633 }
634 }
635 }
636}
637#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
638
639#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400640 defined(PNG_LEGACY_SUPPORTED) || \
641 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800642void PNGAPI
643png_set_user_transform_info(png_structp png_ptr, png_voidp
644 user_transform_ptr, int user_transform_depth, int user_transform_channels)
645{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700646 png_debug(1, "in png_set_user_transform_info");
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400647 if (png_ptr == NULL)
648 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800649#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
650 png_ptr->user_transform_ptr = user_transform_ptr;
651 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
652 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
653#else
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700654 if (user_transform_ptr || user_transform_depth || user_transform_channels)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800655 png_warning(png_ptr,
656 "This version of libpng does not support user transform info");
657#endif
658}
659#endif
660
661/* This function returns a pointer to the user_transform_ptr associated with
662 * the user transform functions. The application should free any memory
663 * associated with this pointer before png_write_destroy and png_read_destroy
664 * are called.
665 */
666png_voidp PNGAPI
667png_get_user_transform_ptr(png_structp png_ptr)
668{
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400669 if (png_ptr == NULL)
670 return (NULL);
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700671#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800672 return ((png_voidp)png_ptr->user_transform_ptr);
673#else
674 return (NULL);
675#endif
676}
677#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */