]> git.saurik.com Git - wxWidgets.git/blame - src/png/pngtrans.c
fixed new charset detection code (langinfo.h not included in intl.cpp; langinfo.h...
[wxWidgets.git] / src / png / pngtrans.c
CommitLineData
c801d85f
KB
1
2/* pngtrans.c - transforms the data in a row (used by both readers and writers)
3 *
a626cc03 4 * libpng 1.0.3 - January 14, 1999
c801d85f
KB
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
a626cc03 8 * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
c801d85f
KB
9 */
10
11#define PNG_INTERNAL
a626cc03 12#include "png.h"
c801d85f
KB
13
14#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
15/* turn on bgr to rgb mapping */
16void
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 */
26void
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 */
37void
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 */
51void
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)
61void
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)
72int
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
a626cc03
RR
89 * for 48-bit input data, as well as to avoid problems with some compilers
90 * that don't like bytes as parameters.
c801d85f
KB
91 */
92void
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
a626cc03
RR
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)
c801d85f
KB
109 {
110 png_ptr->usr_channels = 4;
111 }
a626cc03
RR
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 }
c801d85f
KB
120}
121#endif
122
123#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
124 defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
125void
126png_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)
135void
136png_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)
144void
145png_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
a626cc03 151/* invert monochrome grayscale data */
c801d85f
KB
152void
153png_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 {
a626cc03 162 png_bytep rp = row;
c801d85f 163 png_uint_32 i;
a626cc03 164 png_uint_32 istop = row_info->rowbytes;
c801d85f 165
a626cc03 166 for (i = 0; i < istop; i++)
c801d85f
KB
167 {
168 *rp = (png_byte)(~(*rp));
a626cc03 169 rp++;
c801d85f
KB
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 */
177void
178png_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 {
a626cc03 187 png_bytep rp = row;
c801d85f 188 png_uint_32 i;
a626cc03 189 png_uint_32 istop= row_info->width * row_info->channels;
c801d85f 190
a626cc03 191 for (i = 0; i < istop; i++, rp += 2)
c801d85f 192 {
a626cc03 193 png_byte t = *rp;
c801d85f
KB
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)
202static 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
237static 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
272static 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 */
308void
309png_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) */
340void
341png_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*/
a626cc03
RR
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
c801d85f
KB
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 {
a626cc03
RR
364 dp+=3; sp+=4;
365 for (i = 1; i < row_width; i++)
c801d85f
KB
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 {
a626cc03 376 for (i = 0; i < row_width; i++)
c801d85f
KB
377 {
378 sp++;
379 *dp++ = *sp++;
380 *dp++ = *sp++;
381 *dp++ = *sp++;
382 }
383 }
384 row_info->pixel_depth = 24;
a626cc03 385 row_info->rowbytes = row_width * 3;
c801d85f
KB
386 }
387 else /* if (row_info->bit_depth == 16) */
388 {
389 if (flags & PNG_FLAG_FILLER_AFTER)
390 {
c801d85f 391 /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
a626cc03
RR
392 sp += 8; dp += 6;
393 for (i = 1; i < row_width; i++)
c801d85f
KB
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 {
c801d85f 411 /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
a626cc03 412 for (i = 0; i < row_width; i++)
c801d85f
KB
413 {
414 /* This could be (although memcpy is probably slower):
415 png_memcpy(dp, sp, 6);
416 sp += 8;
417 dp += 6;
418 */
a626cc03 419 sp+=2;
c801d85f
KB
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;
a626cc03 429 row_info->rowbytes = row_width * 6;
c801d85f
KB
430 }
431 row_info->channels = 3;
a626cc03 432 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
c801d85f
KB
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 {
a626cc03 445 for (i = 0; i < row_width; i++)
c801d85f
KB
446 {
447 *dp++ = *sp++;
448 sp++;
449 }
450 }
451 /* This converts from XG or AG to G */
452 else
453 {
a626cc03 454 for (i = 0; i < row_width; i++)
c801d85f
KB
455 {
456 sp++;
457 *dp++ = *sp++;
458 }
459 }
460 row_info->pixel_depth = 8;
a626cc03 461 row_info->rowbytes = row_width;
c801d85f
KB
462 }
463 else /* if (row_info->bit_depth == 16) */
464 {
465 if (flags & PNG_FLAG_FILLER_AFTER)
466 {
c801d85f 467 /* This converts from GGXX or GGAA to GG */
a626cc03
RR
468 sp += 4; dp += 2;
469 for (i = 1; i < row_width; i++)
c801d85f
KB
470 {
471 *dp++ = *sp++;
472 *dp++ = *sp++;
473 sp += 2;
474 }
475 }
476 else
477 {
c801d85f 478 /* This converts from XXGG or AAGG to GG */
a626cc03 479 for (i = 0; i < row_width; i++)
c801d85f
KB
480 {
481 sp += 2;
482 *dp++ = *sp++;
483 *dp++ = *sp++;
484 }
485 }
486 row_info->pixel_depth = 16;
a626cc03 487 row_info->rowbytes = row_width * 2;
c801d85f
KB
488 }
489 row_info->channels = 1;
a626cc03 490 row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
c801d85f
KB
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 */
498void
499png_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 {
a626cc03 508 png_uint_32 row_width = row_info->width;
c801d85f
KB
509 if (row_info->bit_depth == 8)
510 {
511 if (row_info->color_type == PNG_COLOR_TYPE_RGB)
512 {
513 png_bytep rp;
c801d85f
KB
514 png_uint_32 i;
515
a626cc03 516 for (i = 0, rp = row; i < row_width; i++, rp += 3)
c801d85f 517 {
a626cc03 518 png_byte save = *rp;
c801d85f
KB
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;
c801d85f
KB
526 png_uint_32 i;
527
a626cc03 528 for (i = 0, rp = row; i < row_width; i++, rp += 4)
c801d85f 529 {
a626cc03 530 png_byte save = *rp;
c801d85f
KB
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;
c801d85f
KB
541 png_uint_32 i;
542
a626cc03 543 for (i = 0, rp = row; i < row_width; i++, rp += 6)
c801d85f 544 {
a626cc03 545 png_byte save = *rp;
c801d85f 546 *rp = *(rp + 4);
a626cc03
RR
547 *(rp + 4) = save;
548 save = *(rp + 1);
c801d85f 549 *(rp + 1) = *(rp + 5);
a626cc03 550 *(rp + 5) = save;
c801d85f
KB
551 }
552 }
553 else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
554 {
555 png_bytep rp;
c801d85f
KB
556 png_uint_32 i;
557
a626cc03 558 for (i = 0, rp = row; i < row_width; i++, rp += 8)
c801d85f 559 {
a626cc03 560 png_byte save = *rp;
c801d85f 561 *rp = *(rp + 4);
a626cc03
RR
562 *(rp + 4) = save;
563 save = *(rp + 1);
c801d85f 564 *(rp + 1) = *(rp + 5);
a626cc03 565 *(rp + 5) = save;
c801d85f
KB
566 }
567 }
568 }
569 }
570}
571#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
572