merged libpng-1.2.7 to HEAD (1.2.6 contained serious bug that caused it to produce...
[wxWidgets.git] / src / png / pngtrans.c
1
2 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
3 *
4 * libpng 1.2.7 - September 12, 2004
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2004 Glenn Randers-Pehrson
7 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
9 */
10
11 #define PNG_INTERNAL
12 #include "png.h"
13
14 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
15 /* turn on BGR-to-RGB mapping */
16 void PNGAPI
17 png_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 */
26 void PNGAPI
27 png_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 */
37 void PNGAPI
38 png_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 */
51 void PNGAPI
52 png_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)
61 void PNGAPI
62 png_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)
72 int PNGAPI
73 png_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 */
92 void PNGAPI
93 png_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
103 /* This should probably go in the "do_read_filler" routine.
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 }
121
122 #if !defined(PNG_1_0_X)
123 /* Added to libpng-1.2.7 */
124 void PNGAPI
125 png_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
133 #endif
134
135 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
136 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
137 void PNGAPI
138 png_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)
147 void PNGAPI
148 png_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)
156 void PNGAPI
157 png_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 */
164 void /* PRIVATE */
165 png_do_invert(png_row_infop row_info, png_bytep row)
166 {
167 png_debug(1, "in png_do_invert\n");
168 /* This test removed from libpng version 1.0.13 and 1.2.0:
169 * if (row_info->bit_depth == 1 &&
170 */
171 #if defined(PNG_USELESS_TESTS_SUPPORTED)
172 if (row == NULL || row_info == NULL)
173 return;
174 #endif
175 if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
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 }
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 }
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 */
219 void /* PRIVATE */
220 png_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)
244 static 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
279 static 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
314 static 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 */
350 void /* PRIVATE */
351 png_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) */
382 void /* PRIVATE */
383 png_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 {
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
395 if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
396 row_info->channels == 4)
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 {
434 /* This could be (although png_memcpy is probably slower):
435 png_memcpy(dp, sp, 6);
436 sp += 8;
437 dp += 6;
438 */
439
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 {
454 /* This could be (although png_memcpy is probably slower):
455 png_memcpy(dp, sp, 6);
456 sp += 8;
457 dp += 6;
458 */
459
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;
473 }
474 else if (row_info->color_type == PNG_COLOR_TYPE_GRAY &&
475 row_info->channels == 2)
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;
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 */
534 void /* PRIVATE */
535 png_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
609 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
610 defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
611 defined(PNG_LEGACY_SUPPORTED)
612 void PNGAPI
613 png_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 */
634 png_voidp PNGAPI
635 png_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 }