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