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