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