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