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