blob: 6ad9dcf628cf09506d13a7a187c07c0ab14a173f [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 Scott5f6bd842010-06-28 16:55:16 -04004 * Last changed in libpng 1.2.41 [December 3, 2009]
Patrick Scotta0bb96c2009-07-22 11:50:02 -04005 * 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
Patrick Scott5f6bd842010-06-28 16:55:16 -040015#define PNG_NO_PEDANTIC_WARNINGS
The Android Open Source Project893912b2009-03-03 19:30:05 -080016#include "png.h"
The Android Open Source Project893912b2009-03-03 19:30:05 -080017#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
The Android Open Source Project4215dd12009-03-09 11:52:12 -070018
The Android Open Source Project893912b2009-03-03 19:30:05 -080019#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040020/* Turn on BGR-to-RGB mapping */
The Android Open Source Project893912b2009-03-03 19:30:05 -080021void PNGAPI
22png_set_bgr(png_structp png_ptr)
23{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070024 png_debug(1, "in png_set_bgr");
Patrick Scott5f6bd842010-06-28 16:55:16 -040025
Patrick Scotta0bb96c2009-07-22 11:50:02 -040026 if (png_ptr == NULL)
27 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080028 png_ptr->transformations |= PNG_BGR;
29}
30#endif
31
32#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040033/* Turn on 16 bit byte swapping */
The Android Open Source Project893912b2009-03-03 19:30:05 -080034void PNGAPI
35png_set_swap(png_structp png_ptr)
36{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070037 png_debug(1, "in png_set_swap");
Patrick Scott5f6bd842010-06-28 16:55:16 -040038
Patrick Scotta0bb96c2009-07-22 11:50:02 -040039 if (png_ptr == NULL)
40 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080041 if (png_ptr->bit_depth == 16)
42 png_ptr->transformations |= PNG_SWAP_BYTES;
43}
44#endif
45
46#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040047/* Turn on pixel packing */
The Android Open Source Project893912b2009-03-03 19:30:05 -080048void PNGAPI
49png_set_packing(png_structp png_ptr)
50{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070051 png_debug(1, "in png_set_packing");
Patrick Scott5f6bd842010-06-28 16:55:16 -040052
Patrick Scotta0bb96c2009-07-22 11:50:02 -040053 if (png_ptr == NULL)
54 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080055 if (png_ptr->bit_depth < 8)
56 {
57 png_ptr->transformations |= PNG_PACK;
58 png_ptr->usr_bit_depth = 8;
59 }
60}
61#endif
62
63#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -040064/* Turn on packed pixel swapping */
The Android Open Source Project893912b2009-03-03 19:30:05 -080065void PNGAPI
66png_set_packswap(png_structp png_ptr)
67{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070068 png_debug(1, "in png_set_packswap");
Patrick Scott5f6bd842010-06-28 16:55:16 -040069
Patrick Scotta0bb96c2009-07-22 11:50:02 -040070 if (png_ptr == NULL)
71 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080072 if (png_ptr->bit_depth < 8)
73 png_ptr->transformations |= PNG_PACKSWAP;
74}
75#endif
76
77#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
78void PNGAPI
79png_set_shift(png_structp png_ptr, png_color_8p true_bits)
80{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070081 png_debug(1, "in png_set_shift");
Patrick Scott5f6bd842010-06-28 16:55:16 -040082
Patrick Scotta0bb96c2009-07-22 11:50:02 -040083 if (png_ptr == NULL)
84 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -080085 png_ptr->transformations |= PNG_SHIFT;
86 png_ptr->shift = *true_bits;
87}
88#endif
89
90#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
91 defined(PNG_WRITE_INTERLACING_SUPPORTED)
92int PNGAPI
93png_set_interlace_handling(png_structp png_ptr)
94{
The Android Open Source Project4215dd12009-03-09 11:52:12 -070095 png_debug(1, "in png_set_interlace handling");
Patrick Scott5f6bd842010-06-28 16:55:16 -040096
The Android Open Source Project893912b2009-03-03 19:30:05 -080097 if (png_ptr && png_ptr->interlaced)
98 {
99 png_ptr->transformations |= PNG_INTERLACE;
100 return (7);
101 }
102
103 return (1);
104}
105#endif
106
107#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
108/* Add a filler byte on read, or remove a filler or alpha byte on write.
109 * The filler type has changed in v0.95 to allow future 2-byte fillers
110 * for 48-bit input data, as well as to avoid problems with some compilers
111 * that don't like bytes as parameters.
112 */
113void PNGAPI
114png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
115{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700116 png_debug(1, "in png_set_filler");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400117
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400118 if (png_ptr == NULL)
119 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800120 png_ptr->transformations |= PNG_FILLER;
Patrick Scott5f6bd842010-06-28 16:55:16 -0400121#ifdef PNG_LEGACY_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800122 png_ptr->filler = (png_byte)filler;
Patrick Scott5f6bd842010-06-28 16:55:16 -0400123#else
124 png_ptr->filler = (png_uint_16)filler;
125#endif
The Android Open Source Project893912b2009-03-03 19:30:05 -0800126 if (filler_loc == PNG_FILLER_AFTER)
127 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
128 else
129 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
130
131 /* This should probably go in the "do_read_filler" routine.
132 * I attempted to do that in libpng-1.0.1a but that caused problems
133 * so I restored it in libpng-1.0.2a
134 */
135
136 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
137 {
138 png_ptr->usr_channels = 4;
139 }
140
141 /* Also I added this in libpng-1.0.2a (what happens when we expand
142 * a less-than-8-bit grayscale to GA? */
143
144 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
145 {
146 png_ptr->usr_channels = 2;
147 }
148}
149
Patrick Scott5f6bd842010-06-28 16:55:16 -0400150#ifndef PNG_1_0_X
The Android Open Source Project893912b2009-03-03 19:30:05 -0800151/* Added to libpng-1.2.7 */
152void PNGAPI
153png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
154{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700155 png_debug(1, "in png_set_add_alpha");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400156
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400157 if (png_ptr == NULL)
158 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800159 png_set_filler(png_ptr, filler, filler_loc);
160 png_ptr->transformations |= PNG_ADD_ALPHA;
161}
162#endif
163
164#endif
165
166#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
167 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
168void PNGAPI
169png_set_swap_alpha(png_structp png_ptr)
170{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700171 png_debug(1, "in png_set_swap_alpha");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400172
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400173 if (png_ptr == NULL)
174 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800175 png_ptr->transformations |= PNG_SWAP_ALPHA;
176}
177#endif
178
179#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
180 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
181void PNGAPI
182png_set_invert_alpha(png_structp png_ptr)
183{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700184 png_debug(1, "in png_set_invert_alpha");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400185
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400186 if (png_ptr == NULL)
187 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800188 png_ptr->transformations |= PNG_INVERT_ALPHA;
189}
190#endif
191
192#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
193void PNGAPI
194png_set_invert_mono(png_structp png_ptr)
195{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700196 png_debug(1, "in png_set_invert_mono");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400197
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400198 if (png_ptr == NULL)
199 return;
The Android Open Source Project893912b2009-03-03 19:30:05 -0800200 png_ptr->transformations |= PNG_INVERT_MONO;
201}
202
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400203/* Invert monochrome grayscale data */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800204void /* PRIVATE */
205png_do_invert(png_row_infop row_info, png_bytep row)
206{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700207 png_debug(1, "in png_do_invert");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400208
The Android Open Source Project893912b2009-03-03 19:30:05 -0800209 /* This test removed from libpng version 1.0.13 and 1.2.0:
210 * if (row_info->bit_depth == 1 &&
211 */
Patrick Scott5f6bd842010-06-28 16:55:16 -0400212#ifdef PNG_USELESS_TESTS_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800213 if (row == NULL || row_info == NULL)
214 return;
215#endif
216 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
217 {
218 png_bytep rp = row;
219 png_uint_32 i;
220 png_uint_32 istop = row_info->rowbytes;
221
222 for (i = 0; i < istop; i++)
223 {
224 *rp = (png_byte)(~(*rp));
225 rp++;
226 }
227 }
228 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
229 row_info->bit_depth == 8)
230 {
231 png_bytep rp = row;
232 png_uint_32 i;
233 png_uint_32 istop = row_info->rowbytes;
234
235 for (i = 0; i < istop; i+=2)
236 {
237 *rp = (png_byte)(~(*rp));
238 rp+=2;
239 }
240 }
241 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
242 row_info->bit_depth == 16)
243 {
244 png_bytep rp = row;
245 png_uint_32 i;
246 png_uint_32 istop = row_info->rowbytes;
247
248 for (i = 0; i < istop; i+=4)
249 {
250 *rp = (png_byte)(~(*rp));
251 *(rp+1) = (png_byte)(~(*(rp+1)));
252 rp+=4;
253 }
254 }
255}
256#endif
257
258#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400259/* Swaps byte order on 16 bit depth images */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800260void /* PRIVATE */
261png_do_swap(png_row_infop row_info, png_bytep row)
262{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700263 png_debug(1, "in png_do_swap");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400264
The Android Open Source Project893912b2009-03-03 19:30:05 -0800265 if (
Patrick Scott5f6bd842010-06-28 16:55:16 -0400266#ifdef PNG_USELESS_TESTS_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800267 row != NULL && row_info != NULL &&
268#endif
269 row_info->bit_depth == 16)
270 {
271 png_bytep rp = row;
272 png_uint_32 i;
273 png_uint_32 istop= row_info->width * row_info->channels;
274
275 for (i = 0; i < istop; i++, rp += 2)
276 {
277 png_byte t = *rp;
278 *rp = *(rp + 1);
279 *(rp + 1) = t;
280 }
281 }
282}
283#endif
284
285#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
286static PNG_CONST png_byte onebppswaptable[256] = {
287 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
288 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
289 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
290 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
291 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
292 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
293 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
294 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
295 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
296 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
297 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
298 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
299 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
300 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
301 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
302 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
303 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
304 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
305 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
306 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
307 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
308 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
309 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
310 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
311 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
312 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
313 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
314 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
315 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
316 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
317 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
318 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
319};
320
321static PNG_CONST png_byte twobppswaptable[256] = {
322 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
323 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
324 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
325 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
326 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
327 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
328 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
329 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
330 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
331 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
332 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
333 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
334 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
335 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
336 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
337 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
338 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
339 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
340 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
341 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
342 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
343 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
344 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
345 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
346 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
347 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
348 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
349 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
350 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
351 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
352 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
353 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
354};
355
356static PNG_CONST png_byte fourbppswaptable[256] = {
357 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
358 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
359 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
360 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
361 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
362 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
363 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
364 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
365 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
366 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
367 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
368 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
369 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
370 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
371 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
372 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
373 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
374 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
375 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
376 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
377 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
378 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
379 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
380 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
381 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
382 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
383 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
384 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
385 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
386 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
387 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
388 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
389};
390
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400391/* Swaps pixel packing order within bytes */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800392void /* PRIVATE */
393png_do_packswap(png_row_infop row_info, png_bytep row)
394{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700395 png_debug(1, "in png_do_packswap");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400396
The Android Open Source Project893912b2009-03-03 19:30:05 -0800397 if (
Patrick Scott5f6bd842010-06-28 16:55:16 -0400398#ifdef PNG_USELESS_TESTS_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800399 row != NULL && row_info != NULL &&
400#endif
401 row_info->bit_depth < 8)
402 {
403 png_bytep rp, end, table;
404
405 end = row + row_info->rowbytes;
406
407 if (row_info->bit_depth == 1)
408 table = (png_bytep)onebppswaptable;
409 else if (row_info->bit_depth == 2)
410 table = (png_bytep)twobppswaptable;
411 else if (row_info->bit_depth == 4)
412 table = (png_bytep)fourbppswaptable;
413 else
414 return;
415
416 for (rp = row; rp < end; rp++)
417 *rp = table[*rp];
418 }
419}
420#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
421
422#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
423 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400424/* Remove filler or alpha byte(s) */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800425void /* PRIVATE */
426png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
427{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700428 png_debug(1, "in png_do_strip_filler");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400429
430#ifdef PNG_USELESS_TESTS_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800431 if (row != NULL && row_info != NULL)
432#endif
433 {
434 png_bytep sp=row;
435 png_bytep dp=row;
436 png_uint_32 row_width=row_info->width;
437 png_uint_32 i;
438
439 if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400440 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
441 (flags & PNG_FLAG_STRIP_ALPHA))) &&
442 row_info->channels == 4)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800443 {
444 if (row_info->bit_depth == 8)
445 {
446 /* This converts from RGBX or RGBA to RGB */
447 if (flags & PNG_FLAG_FILLER_AFTER)
448 {
449 dp+=3; sp+=4;
450 for (i = 1; i < row_width; i++)
451 {
452 *dp++ = *sp++;
453 *dp++ = *sp++;
454 *dp++ = *sp++;
455 sp++;
456 }
457 }
458 /* This converts from XRGB or ARGB to RGB */
459 else
460 {
461 for (i = 0; i < row_width; i++)
462 {
463 sp++;
464 *dp++ = *sp++;
465 *dp++ = *sp++;
466 *dp++ = *sp++;
467 }
468 }
469 row_info->pixel_depth = 24;
470 row_info->rowbytes = row_width * 3;
471 }
472 else /* if (row_info->bit_depth == 16) */
473 {
474 if (flags & PNG_FLAG_FILLER_AFTER)
475 {
476 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
477 sp += 8; dp += 6;
478 for (i = 1; 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 *dp++ = *sp++;
487 *dp++ = *sp++;
488 *dp++ = *sp++;
489 *dp++ = *sp++;
490 *dp++ = *sp++;
491 *dp++ = *sp++;
492 sp += 2;
493 }
494 }
495 else
496 {
497 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
498 for (i = 0; i < row_width; i++)
499 {
500 /* This could be (although png_memcpy is probably slower):
501 png_memcpy(dp, sp, 6);
502 sp += 8;
503 dp += 6;
504 */
505
506 sp+=2;
507 *dp++ = *sp++;
508 *dp++ = *sp++;
509 *dp++ = *sp++;
510 *dp++ = *sp++;
511 *dp++ = *sp++;
512 *dp++ = *sp++;
513 }
514 }
515 row_info->pixel_depth = 48;
516 row_info->rowbytes = row_width * 6;
517 }
518 row_info->channels = 3;
519 }
520 else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
521 (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
522 (flags & PNG_FLAG_STRIP_ALPHA))) &&
523 row_info->channels == 2)
524 {
525 if (row_info->bit_depth == 8)
526 {
527 /* This converts from GX or GA to G */
528 if (flags & PNG_FLAG_FILLER_AFTER)
529 {
530 for (i = 0; i < row_width; i++)
531 {
532 *dp++ = *sp++;
533 sp++;
534 }
535 }
536 /* This converts from XG or AG to G */
537 else
538 {
539 for (i = 0; i < row_width; i++)
540 {
541 sp++;
542 *dp++ = *sp++;
543 }
544 }
545 row_info->pixel_depth = 8;
546 row_info->rowbytes = row_width;
547 }
548 else /* if (row_info->bit_depth == 16) */
549 {
550 if (flags & PNG_FLAG_FILLER_AFTER)
551 {
552 /* This converts from GGXX or GGAA to GG */
553 sp += 4; dp += 2;
554 for (i = 1; i < row_width; i++)
555 {
556 *dp++ = *sp++;
557 *dp++ = *sp++;
558 sp += 2;
559 }
560 }
561 else
562 {
563 /* This converts from XXGG or AAGG to GG */
564 for (i = 0; i < row_width; i++)
565 {
566 sp += 2;
567 *dp++ = *sp++;
568 *dp++ = *sp++;
569 }
570 }
571 row_info->pixel_depth = 16;
572 row_info->rowbytes = row_width * 2;
573 }
574 row_info->channels = 1;
575 }
576 if (flags & PNG_FLAG_STRIP_ALPHA)
577 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
578 }
579}
580#endif
581
582#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400583/* Swaps red and blue bytes within a pixel */
The Android Open Source Project893912b2009-03-03 19:30:05 -0800584void /* PRIVATE */
585png_do_bgr(png_row_infop row_info, png_bytep row)
586{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700587 png_debug(1, "in png_do_bgr");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400588
The Android Open Source Project893912b2009-03-03 19:30:05 -0800589 if (
Patrick Scott5f6bd842010-06-28 16:55:16 -0400590#ifdef PNG_USELESS_TESTS_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800591 row != NULL && row_info != NULL &&
592#endif
593 (row_info->color_type & PNG_COLOR_MASK_COLOR))
594 {
595 png_uint_32 row_width = row_info->width;
596 if (row_info->bit_depth == 8)
597 {
598 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
599 {
600 png_bytep rp;
601 png_uint_32 i;
602
603 for (i = 0, rp = row; i < row_width; i++, rp += 3)
604 {
605 png_byte save = *rp;
606 *rp = *(rp + 2);
607 *(rp + 2) = save;
608 }
609 }
610 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
611 {
612 png_bytep rp;
613 png_uint_32 i;
614
615 for (i = 0, rp = row; i < row_width; i++, rp += 4)
616 {
617 png_byte save = *rp;
618 *rp = *(rp + 2);
619 *(rp + 2) = save;
620 }
621 }
622 }
623 else if (row_info->bit_depth == 16)
624 {
625 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
626 {
627 png_bytep rp;
628 png_uint_32 i;
629
630 for (i = 0, rp = row; i < row_width; i++, rp += 6)
631 {
632 png_byte save = *rp;
633 *rp = *(rp + 4);
634 *(rp + 4) = save;
635 save = *(rp + 1);
636 *(rp + 1) = *(rp + 5);
637 *(rp + 5) = save;
638 }
639 }
640 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
641 {
642 png_bytep rp;
643 png_uint_32 i;
644
645 for (i = 0, rp = row; i < row_width; i++, rp += 8)
646 {
647 png_byte save = *rp;
648 *rp = *(rp + 4);
649 *(rp + 4) = save;
650 save = *(rp + 1);
651 *(rp + 1) = *(rp + 5);
652 *(rp + 5) = save;
653 }
654 }
655 }
656 }
657}
658#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
659
660#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400661 defined(PNG_LEGACY_SUPPORTED) || \
662 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800663void PNGAPI
664png_set_user_transform_info(png_structp png_ptr, png_voidp
665 user_transform_ptr, int user_transform_depth, int user_transform_channels)
666{
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700667 png_debug(1, "in png_set_user_transform_info");
Patrick Scott5f6bd842010-06-28 16:55:16 -0400668
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400669 if (png_ptr == NULL)
670 return;
Patrick Scott5f6bd842010-06-28 16:55:16 -0400671#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800672 png_ptr->user_transform_ptr = user_transform_ptr;
673 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
674 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
675#else
The Android Open Source Project4215dd12009-03-09 11:52:12 -0700676 if (user_transform_ptr || user_transform_depth || user_transform_channels)
The Android Open Source Project893912b2009-03-03 19:30:05 -0800677 png_warning(png_ptr,
678 "This version of libpng does not support user transform info");
679#endif
680}
681#endif
682
683/* This function returns a pointer to the user_transform_ptr associated with
684 * the user transform functions. The application should free any memory
685 * associated with this pointer before png_write_destroy and png_read_destroy
686 * are called.
687 */
688png_voidp PNGAPI
689png_get_user_transform_ptr(png_structp png_ptr)
690{
Patrick Scotta0bb96c2009-07-22 11:50:02 -0400691 if (png_ptr == NULL)
692 return (NULL);
Patrick Scott5f6bd842010-06-28 16:55:16 -0400693#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
The Android Open Source Project893912b2009-03-03 19:30:05 -0800694 return ((png_voidp)png_ptr->user_transform_ptr);
695#else
696 return (NULL);
697#endif
698}
699#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */