]> git.saurik.com Git - wxWidgets.git/blame - src/png/pngtrans.c
Update wxWebFileHandler to handle paths with fragments correctly, some backends pass...
[wxWidgets.git] / src / png / pngtrans.c
CommitLineData
0272a10d
VZ
1
2/* pngtrans.c - transforms the data in a row (used by both readers and writers)
3 *
b61cc19c
PC
4 * Last changed in libpng 1.4.2 [April 29, 2010]
5 * Copyright (c) 1998-2010 Glenn Randers-Pehrson
0272a10d
VZ
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
b61cc19c
PC
8 *
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
0272a10d
VZ
12 */
13
b61cc19c 14#define PNG_NO_PEDANTIC_WARNINGS
0272a10d 15#include "png.h"
0272a10d 16#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
b61cc19c 17#include "pngpriv.h"
970f6abe 18
0272a10d 19#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
b61cc19c 20/* Turn on BGR-to-RGB mapping */
0272a10d
VZ
21void PNGAPI
22png_set_bgr(png_structp png_ptr)
23{
970f6abe 24 png_debug(1, "in png_set_bgr");
b61cc19c
PC
25
26 if (png_ptr == NULL)
27 return;
0272a10d
VZ
28 png_ptr->transformations |= PNG_BGR;
29}
30#endif
31
32#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
b61cc19c 33/* Turn on 16 bit byte swapping */
0272a10d
VZ
34void PNGAPI
35png_set_swap(png_structp png_ptr)
36{
970f6abe 37 png_debug(1, "in png_set_swap");
b61cc19c
PC
38
39 if (png_ptr == NULL)
40 return;
0272a10d
VZ
41 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)
b61cc19c 47/* Turn on pixel packing */
0272a10d
VZ
48void PNGAPI
49png_set_packing(png_structp png_ptr)
50{
970f6abe 51 png_debug(1, "in png_set_packing");
b61cc19c
PC
52
53 if (png_ptr == NULL)
54 return;
0272a10d
VZ
55 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)
b61cc19c 64/* Turn on packed pixel swapping */
0272a10d
VZ
65void PNGAPI
66png_set_packswap(png_structp png_ptr)
67{
970f6abe 68 png_debug(1, "in png_set_packswap");
b61cc19c
PC
69
70 if (png_ptr == NULL)
71 return;
0272a10d
VZ
72 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{
970f6abe 81 png_debug(1, "in png_set_shift");
b61cc19c
PC
82
83 if (png_ptr == NULL)
84 return;
0272a10d
VZ
85 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{
970f6abe 95 png_debug(1, "in png_set_interlace handling");
b61cc19c 96
0272a10d
VZ
97 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{
970f6abe 116 png_debug(1, "in png_set_filler");
b61cc19c
PC
117
118 if (png_ptr == NULL)
119 return;
0272a10d 120 png_ptr->transformations |= PNG_FILLER;
b61cc19c 121 png_ptr->filler = (png_uint_16)filler;
0272a10d
VZ
122 if (filler_loc == PNG_FILLER_AFTER)
123 png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
124 else
125 png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
126
127 /* This should probably go in the "do_read_filler" routine.
128 * I attempted to do that in libpng-1.0.1a but that caused problems
129 * so I restored it in libpng-1.0.2a
130 */
131
132 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
133 {
134 png_ptr->usr_channels = 4;
135 }
136
137 /* Also I added this in libpng-1.0.2a (what happens when we expand
138 * a less-than-8-bit grayscale to GA? */
139
140 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
141 {
142 png_ptr->usr_channels = 2;
143 }
144}
145
0272a10d
VZ
146/* Added to libpng-1.2.7 */
147void PNGAPI
148png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
149{
970f6abe 150 png_debug(1, "in png_set_add_alpha");
b61cc19c
PC
151
152 if (png_ptr == NULL)
153 return;
0272a10d
VZ
154 png_set_filler(png_ptr, filler, filler_loc);
155 png_ptr->transformations |= PNG_ADD_ALPHA;
156}
0272a10d
VZ
157
158#endif
159
160#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
161 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
162void PNGAPI
163png_set_swap_alpha(png_structp png_ptr)
164{
970f6abe 165 png_debug(1, "in png_set_swap_alpha");
b61cc19c
PC
166
167 if (png_ptr == NULL)
168 return;
0272a10d
VZ
169 png_ptr->transformations |= PNG_SWAP_ALPHA;
170}
171#endif
172
173#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
174 defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
175void PNGAPI
176png_set_invert_alpha(png_structp png_ptr)
177{
970f6abe 178 png_debug(1, "in png_set_invert_alpha");
b61cc19c
PC
179
180 if (png_ptr == NULL)
181 return;
0272a10d
VZ
182 png_ptr->transformations |= PNG_INVERT_ALPHA;
183}
184#endif
185
186#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
187void PNGAPI
188png_set_invert_mono(png_structp png_ptr)
189{
970f6abe 190 png_debug(1, "in png_set_invert_mono");
b61cc19c
PC
191
192 if (png_ptr == NULL)
193 return;
0272a10d
VZ
194 png_ptr->transformations |= PNG_INVERT_MONO;
195}
196
b61cc19c 197/* Invert monochrome grayscale data */
0272a10d
VZ
198void /* PRIVATE */
199png_do_invert(png_row_infop row_info, png_bytep row)
200{
970f6abe 201 png_debug(1, "in png_do_invert");
b61cc19c 202
0272a10d
VZ
203 /* This test removed from libpng version 1.0.13 and 1.2.0:
204 * if (row_info->bit_depth == 1 &&
205 */
0272a10d
VZ
206 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
207 {
208 png_bytep rp = row;
209 png_uint_32 i;
210 png_uint_32 istop = row_info->rowbytes;
211
212 for (i = 0; i < istop; i++)
213 {
214 *rp = (png_byte)(~(*rp));
215 rp++;
216 }
217 }
218 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
219 row_info->bit_depth == 8)
220 {
221 png_bytep rp = row;
222 png_uint_32 i;
223 png_uint_32 istop = row_info->rowbytes;
224
225 for (i = 0; i < istop; i+=2)
226 {
227 *rp = (png_byte)(~(*rp));
228 rp+=2;
229 }
230 }
231 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
232 row_info->bit_depth == 16)
233 {
234 png_bytep rp = row;
235 png_uint_32 i;
236 png_uint_32 istop = row_info->rowbytes;
237
238 for (i = 0; i < istop; i+=4)
239 {
240 *rp = (png_byte)(~(*rp));
241 *(rp+1) = (png_byte)(~(*(rp+1)));
242 rp+=4;
243 }
244 }
245}
246#endif
247
248#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
b61cc19c 249/* Swaps byte order on 16 bit depth images */
0272a10d
VZ
250void /* PRIVATE */
251png_do_swap(png_row_infop row_info, png_bytep row)
252{
970f6abe 253 png_debug(1, "in png_do_swap");
b61cc19c 254
0272a10d 255 if (
0272a10d
VZ
256 row_info->bit_depth == 16)
257 {
258 png_bytep rp = row;
259 png_uint_32 i;
260 png_uint_32 istop= row_info->width * row_info->channels;
261
262 for (i = 0; i < istop; i++, rp += 2)
263 {
264 png_byte t = *rp;
265 *rp = *(rp + 1);
266 *(rp + 1) = t;
267 }
268 }
269}
270#endif
271
272#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
273static PNG_CONST png_byte onebppswaptable[256] = {
274 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
275 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
276 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
277 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
278 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
279 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
280 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
281 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
282 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
283 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
284 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
285 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
286 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
287 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
288 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
289 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
290 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
291 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
292 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
293 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
294 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
295 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
296 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
297 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
298 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
299 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
300 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
301 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
302 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
303 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
304 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
305 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
306};
307
308static PNG_CONST png_byte twobppswaptable[256] = {
309 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
310 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
311 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
312 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
313 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
314 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
315 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
316 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
317 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
318 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
319 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
320 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
321 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
322 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
323 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
324 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
325 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
326 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
327 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
328 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
329 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
330 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
331 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
332 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
333 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
334 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
335 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
336 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
337 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
338 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
339 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
340 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
341};
342
343static PNG_CONST png_byte fourbppswaptable[256] = {
344 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
345 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
346 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
347 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
348 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
349 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
350 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
351 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
352 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
353 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
354 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
355 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
356 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
357 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
358 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
359 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
360 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
361 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
362 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
363 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
364 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
365 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
366 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
367 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
368 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
369 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
370 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
371 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
372 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
373 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
374 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
375 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
376};
377
b61cc19c 378/* Swaps pixel packing order within bytes */
0272a10d
VZ
379void /* PRIVATE */
380png_do_packswap(png_row_infop row_info, png_bytep row)
381{
970f6abe 382 png_debug(1, "in png_do_packswap");
b61cc19c 383
0272a10d 384 if (
0272a10d
VZ
385 row_info->bit_depth < 8)
386 {
387 png_bytep rp, end, table;
388
389 end = row + row_info->rowbytes;
390
391 if (row_info->bit_depth == 1)
392 table = (png_bytep)onebppswaptable;
393 else if (row_info->bit_depth == 2)
394 table = (png_bytep)twobppswaptable;
395 else if (row_info->bit_depth == 4)
396 table = (png_bytep)fourbppswaptable;
397 else
398 return;
399
400 for (rp = row; rp < end; rp++)
401 *rp = table[*rp];
402 }
403}
404#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
405
406#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
407 defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
b61cc19c 408/* Remove filler or alpha byte(s) */
0272a10d
VZ
409void /* PRIVATE */
410png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
411{
970f6abe 412 png_debug(1, "in png_do_strip_filler");
b61cc19c 413
0272a10d
VZ
414 {
415 png_bytep sp=row;
416 png_bytep dp=row;
417 png_uint_32 row_width=row_info->width;
418 png_uint_32 i;
419
420 if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
b61cc19c
PC
421 (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
422 (flags & PNG_FLAG_STRIP_ALPHA))) &&
423 row_info->channels == 4)
0272a10d
VZ
424 {
425 if (row_info->bit_depth == 8)
426 {
427 /* This converts from RGBX or RGBA to RGB */
428 if (flags & PNG_FLAG_FILLER_AFTER)
429 {
430 dp+=3; sp+=4;
431 for (i = 1; i < row_width; i++)
432 {
433 *dp++ = *sp++;
434 *dp++ = *sp++;
435 *dp++ = *sp++;
436 sp++;
437 }
438 }
439 /* This converts from XRGB or ARGB to RGB */
440 else
441 {
442 for (i = 0; i < row_width; i++)
443 {
444 sp++;
445 *dp++ = *sp++;
446 *dp++ = *sp++;
447 *dp++ = *sp++;
448 }
449 }
450 row_info->pixel_depth = 24;
451 row_info->rowbytes = row_width * 3;
452 }
453 else /* if (row_info->bit_depth == 16) */
454 {
455 if (flags & PNG_FLAG_FILLER_AFTER)
456 {
457 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
458 sp += 8; dp += 6;
459 for (i = 1; i < row_width; i++)
460 {
461 /* This could be (although png_memcpy is probably slower):
462 png_memcpy(dp, sp, 6);
463 sp += 8;
464 dp += 6;
465 */
466
467 *dp++ = *sp++;
468 *dp++ = *sp++;
469 *dp++ = *sp++;
470 *dp++ = *sp++;
471 *dp++ = *sp++;
472 *dp++ = *sp++;
473 sp += 2;
474 }
475 }
476 else
477 {
478 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
479 for (i = 0; i < row_width; i++)
480 {
481 /* This could be (although png_memcpy is probably slower):
482 png_memcpy(dp, sp, 6);
483 sp += 8;
484 dp += 6;
485 */
486
487 sp+=2;
488 *dp++ = *sp++;
489 *dp++ = *sp++;
490 *dp++ = *sp++;
491 *dp++ = *sp++;
492 *dp++ = *sp++;
493 *dp++ = *sp++;
494 }
495 }
496 row_info->pixel_depth = 48;
497 row_info->rowbytes = row_width * 6;
498 }
499 row_info->channels = 3;
500 }
501 else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
502 (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
503 (flags & PNG_FLAG_STRIP_ALPHA))) &&
504 row_info->channels == 2)
505 {
506 if (row_info->bit_depth == 8)
507 {
508 /* This converts from GX or GA to G */
509 if (flags & PNG_FLAG_FILLER_AFTER)
510 {
511 for (i = 0; i < row_width; i++)
512 {
513 *dp++ = *sp++;
514 sp++;
515 }
516 }
517 /* This converts from XG or AG to G */
518 else
519 {
520 for (i = 0; i < row_width; i++)
521 {
522 sp++;
523 *dp++ = *sp++;
524 }
525 }
526 row_info->pixel_depth = 8;
527 row_info->rowbytes = row_width;
528 }
529 else /* if (row_info->bit_depth == 16) */
530 {
531 if (flags & PNG_FLAG_FILLER_AFTER)
532 {
533 /* This converts from GGXX or GGAA to GG */
534 sp += 4; dp += 2;
535 for (i = 1; i < row_width; i++)
536 {
537 *dp++ = *sp++;
538 *dp++ = *sp++;
539 sp += 2;
540 }
541 }
542 else
543 {
544 /* This converts from XXGG or AAGG to GG */
545 for (i = 0; i < row_width; i++)
546 {
547 sp += 2;
548 *dp++ = *sp++;
549 *dp++ = *sp++;
550 }
551 }
552 row_info->pixel_depth = 16;
553 row_info->rowbytes = row_width * 2;
554 }
555 row_info->channels = 1;
556 }
557 if (flags & PNG_FLAG_STRIP_ALPHA)
558 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
559 }
560}
561#endif
562
563#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
b61cc19c 564/* Swaps red and blue bytes within a pixel */
0272a10d
VZ
565void /* PRIVATE */
566png_do_bgr(png_row_infop row_info, png_bytep row)
567{
970f6abe 568 png_debug(1, "in png_do_bgr");
b61cc19c 569
0272a10d 570 if (
0272a10d
VZ
571 (row_info->color_type & PNG_COLOR_MASK_COLOR))
572 {
573 png_uint_32 row_width = row_info->width;
574 if (row_info->bit_depth == 8)
575 {
576 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
577 {
578 png_bytep rp;
579 png_uint_32 i;
580
581 for (i = 0, rp = row; i < row_width; i++, rp += 3)
582 {
583 png_byte save = *rp;
584 *rp = *(rp + 2);
585 *(rp + 2) = save;
586 }
587 }
588 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
589 {
590 png_bytep rp;
591 png_uint_32 i;
592
593 for (i = 0, rp = row; i < row_width; i++, rp += 4)
594 {
595 png_byte save = *rp;
596 *rp = *(rp + 2);
597 *(rp + 2) = save;
598 }
599 }
600 }
601 else if (row_info->bit_depth == 16)
602 {
603 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
604 {
605 png_bytep rp;
606 png_uint_32 i;
607
608 for (i = 0, rp = row; i < row_width; i++, rp += 6)
609 {
610 png_byte save = *rp;
611 *rp = *(rp + 4);
612 *(rp + 4) = save;
613 save = *(rp + 1);
614 *(rp + 1) = *(rp + 5);
615 *(rp + 5) = save;
616 }
617 }
618 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
619 {
620 png_bytep rp;
621 png_uint_32 i;
622
623 for (i = 0, rp = row; i < row_width; i++, rp += 8)
624 {
625 png_byte save = *rp;
626 *rp = *(rp + 4);
627 *(rp + 4) = save;
628 save = *(rp + 1);
629 *(rp + 1) = *(rp + 5);
630 *(rp + 5) = save;
631 }
632 }
633 }
634 }
635}
636#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
637
638#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
b61cc19c 639 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
0272a10d
VZ
640void PNGAPI
641png_set_user_transform_info(png_structp png_ptr, png_voidp
642 user_transform_ptr, int user_transform_depth, int user_transform_channels)
643{
970f6abe 644 png_debug(1, "in png_set_user_transform_info");
b61cc19c
PC
645
646 if (png_ptr == NULL)
647 return;
648#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
0272a10d
VZ
649 png_ptr->user_transform_ptr = user_transform_ptr;
650 png_ptr->user_transform_depth = (png_byte)user_transform_depth;
651 png_ptr->user_transform_channels = (png_byte)user_transform_channels;
652#else
970f6abe 653 if (user_transform_ptr || user_transform_depth || user_transform_channels)
0272a10d
VZ
654 png_warning(png_ptr,
655 "This version of libpng does not support user transform info");
656#endif
657}
0272a10d
VZ
658
659/* This function returns a pointer to the user_transform_ptr associated with
660 * the user transform functions. The application should free any memory
661 * associated with this pointer before png_write_destroy and png_read_destroy
662 * are called.
663 */
664png_voidp PNGAPI
665png_get_user_transform_ptr(png_structp png_ptr)
666{
b61cc19c
PC
667 if (png_ptr == NULL)
668 return (NULL);
669#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
0272a10d
VZ
670 return ((png_voidp)png_ptr->user_transform_ptr);
671#else
672 return (NULL);
673#endif
674}
b61cc19c
PC
675#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
676 PNG_WRITE_USER_TRANSFORM_SUPPORTED */
0272a10d 677#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */