f08fb4ecfe9a14ca0ec7c9f5335d8d3365572a66
[synfig.git] / gtkmm-osx / trunk / libpng-1.2.5 / pngtrans.c
1
2 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
3  *
4  * libpng 1.2.5 - October 3, 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 }