Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / core / src / fxcodec / fx_lpng / lpng_v163 / fx_pngtrans.c
1 #if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)\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.6.2 [April 25, 2013]\r
5  * Copyright (c) 1998-2013 Glenn Randers-Pehrson\r
6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\r
7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\r
8  *\r
9  * This code is released under the libpng license.\r
10  * For conditions of distribution and use, see the disclaimer\r
11  * and license in png.h\r
12  */\r
13 \r
14 #include "pngpriv.h"\r
15 \r
16 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\r
17 \r
18 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)\r
19 /* Turn on BGR-to-RGB mapping */\r
20 void PNGAPI\r
21 png_set_bgr(png_structrp png_ptr)\r
22 {\r
23    png_debug(1, "in png_set_bgr");\r
24 \r
25    if (png_ptr == NULL)\r
26       return;\r
27 \r
28    png_ptr->transformations |= PNG_BGR;\r
29 }\r
30 #endif\r
31 \r
32 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)\r
33 /* Turn on 16 bit byte swapping */\r
34 void PNGAPI\r
35 png_set_swap(png_structrp png_ptr)\r
36 {\r
37    png_debug(1, "in png_set_swap");\r
38 \r
39    if (png_ptr == NULL)\r
40       return;\r
41 \r
42    if (png_ptr->bit_depth == 16)\r
43       png_ptr->transformations |= PNG_SWAP_BYTES;\r
44 }\r
45 #endif\r
46 \r
47 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)\r
48 /* Turn on pixel packing */\r
49 void PNGAPI\r
50 png_set_packing(png_structrp png_ptr)\r
51 {\r
52    png_debug(1, "in png_set_packing");\r
53 \r
54    if (png_ptr == NULL)\r
55       return;\r
56 \r
57    if (png_ptr->bit_depth < 8)\r
58    {\r
59       png_ptr->transformations |= PNG_PACK;\r
60       png_ptr->usr_bit_depth = 8;\r
61    }\r
62 }\r
63 #endif\r
64 \r
65 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)\r
66 /* Turn on packed pixel swapping */\r
67 void PNGAPI\r
68 png_set_packswap(png_structrp png_ptr)\r
69 {\r
70    png_debug(1, "in png_set_packswap");\r
71 \r
72    if (png_ptr == NULL)\r
73       return;\r
74 \r
75    if (png_ptr->bit_depth < 8)\r
76       png_ptr->transformations |= PNG_PACKSWAP;\r
77 }\r
78 #endif\r
79 \r
80 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)\r
81 void PNGAPI\r
82 png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)\r
83 {\r
84    png_debug(1, "in png_set_shift");\r
85 \r
86    if (png_ptr == NULL)\r
87       return;\r
88 \r
89    png_ptr->transformations |= PNG_SHIFT;\r
90    png_ptr->shift = *true_bits;\r
91 }\r
92 #endif\r
93 \r
94 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \\r
95     defined(PNG_WRITE_INTERLACING_SUPPORTED)\r
96 int PNGAPI\r
97 png_set_interlace_handling(png_structrp png_ptr)\r
98 {\r
99    png_debug(1, "in png_set_interlace handling");\r
100 \r
101    if (png_ptr && png_ptr->interlaced)\r
102    {\r
103       png_ptr->transformations |= PNG_INTERLACE;\r
104       return (7);\r
105    }\r
106 \r
107    return (1);\r
108 }\r
109 #endif\r
110 \r
111 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)\r
112 /* Add a filler byte on read, or remove a filler or alpha byte on write.\r
113  * The filler type has changed in v0.95 to allow future 2-byte fillers\r
114  * for 48-bit input data, as well as to avoid problems with some compilers\r
115  * that don't like bytes as parameters.\r
116  */\r
117 void PNGAPI\r
118 png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)\r
119 {\r
120    png_debug(1, "in png_set_filler");\r
121 \r
122    if (png_ptr == NULL)\r
123       return;\r
124 \r
125    /* In libpng 1.6 it is possible to determine whether this is a read or write\r
126     * operation and therefore to do more checking here for a valid call.\r
127     */\r
128    if (png_ptr->mode & PNG_IS_READ_STRUCT)\r
129    {\r
130 #     ifdef PNG_READ_FILLER_SUPPORTED\r
131          /* On read png_set_filler is always valid, regardless of the base PNG\r
132           * format, because other transformations can give a format where the\r
133           * filler code can execute (basically an 8 or 16-bit component RGB or G\r
134           * format.)\r
135           *\r
136           * NOTE: usr_channels is not used by the read code!  (This has led to\r
137           * confusion in the past.)  The filler is only used in the read code.\r
138           */\r
139          png_ptr->filler = (png_uint_16)filler;\r
140 #     else\r
141          png_app_error(png_ptr, "png_set_filler not supported on read");\r
142          PNG_UNUSED(filler) /* not used in the write case */\r
143          return;\r
144 #     endif\r
145    }\r
146 \r
147    else /* write */\r
148    {\r
149 #     ifdef PNG_WRITE_FILLER_SUPPORTED\r
150          /* On write the usr_channels parameter must be set correctly at the\r
151           * start to record the number of channels in the app-supplied data.\r
152           */\r
153          switch (png_ptr->color_type)\r
154          {\r
155             case PNG_COLOR_TYPE_RGB:\r
156                png_ptr->usr_channels = 4;\r
157                break;\r
158 \r
159             case PNG_COLOR_TYPE_GRAY:\r
160                if (png_ptr->bit_depth >= 8)\r
161                {\r
162                   png_ptr->usr_channels = 2;\r
163                   break;\r
164                }\r
165 \r
166                else\r
167                {\r
168                   /* There simply isn't any code in libpng to strip out bits\r
169                    * from bytes when the components are less than a byte in\r
170                    * size!\r
171                    */\r
172                   png_app_error(png_ptr,\r
173                      "png_set_filler is invalid for low bit depth gray output");\r
174                   return;\r
175                }\r
176 \r
177             default:\r
178                png_app_error(png_ptr,\r
179                   "png_set_filler: inappropriate color type");\r
180                return;\r
181          }\r
182 #     else\r
183          png_app_error(png_ptr, "png_set_filler not supported on write");\r
184          return;\r
185 #     endif\r
186    }\r
187 \r
188    /* Here on success - libpng supports the operation, set the transformation\r
189     * and the flag to say where the filler channel is.\r
190     */\r
191    png_ptr->transformations |= PNG_FILLER;\r
192 \r
193    if (filler_loc == PNG_FILLER_AFTER)\r
194       png_ptr->flags |= PNG_FLAG_FILLER_AFTER;\r
195 \r
196    else\r
197       png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;\r
198 }\r
199 \r
200 /* Added to libpng-1.2.7 */\r
201 void PNGAPI\r
202 png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)\r
203 {\r
204    png_debug(1, "in png_set_add_alpha");\r
205 \r
206    if (png_ptr == NULL)\r
207       return;\r
208 \r
209    png_set_filler(png_ptr, filler, filler_loc);\r
210    /* The above may fail to do anything. */\r
211    if (png_ptr->transformations & PNG_FILLER)\r
212       png_ptr->transformations |= PNG_ADD_ALPHA;\r
213 }\r
214 \r
215 #endif\r
216 \r
217 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \\r
218     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)\r
219 void PNGAPI\r
220 png_set_swap_alpha(png_structrp png_ptr)\r
221 {\r
222    png_debug(1, "in png_set_swap_alpha");\r
223 \r
224    if (png_ptr == NULL)\r
225       return;\r
226 \r
227    png_ptr->transformations |= PNG_SWAP_ALPHA;\r
228 }\r
229 #endif\r
230 \r
231 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \\r
232     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)\r
233 void PNGAPI\r
234 png_set_invert_alpha(png_structrp png_ptr)\r
235 {\r
236    png_debug(1, "in png_set_invert_alpha");\r
237 \r
238    if (png_ptr == NULL)\r
239       return;\r
240 \r
241    png_ptr->transformations |= PNG_INVERT_ALPHA;\r
242 }\r
243 #endif\r
244 \r
245 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)\r
246 void PNGAPI\r
247 png_set_invert_mono(png_structrp png_ptr)\r
248 {\r
249    png_debug(1, "in png_set_invert_mono");\r
250 \r
251    if (png_ptr == NULL)\r
252       return;\r
253 \r
254    png_ptr->transformations |= PNG_INVERT_MONO;\r
255 }\r
256 \r
257 /* Invert monochrome grayscale data */\r
258 void /* PRIVATE */\r
259 png_do_invert(png_row_infop row_info, png_bytep row)\r
260 {\r
261    png_debug(1, "in png_do_invert");\r
262 \r
263   /* This test removed from libpng version 1.0.13 and 1.2.0:\r
264    *   if (row_info->bit_depth == 1 &&\r
265    */\r
266    if (row_info->color_type == PNG_COLOR_TYPE_GRAY)\r
267    {\r
268       png_bytep rp = row;\r
269       png_size_t i;\r
270       png_size_t istop = row_info->rowbytes;\r
271 \r
272       for (i = 0; i < istop; i++)\r
273       {\r
274          *rp = (png_byte)(~(*rp));\r
275          rp++;\r
276       }\r
277    }\r
278 \r
279    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&\r
280       row_info->bit_depth == 8)\r
281    {\r
282       png_bytep rp = row;\r
283       png_size_t i;\r
284       png_size_t istop = row_info->rowbytes;\r
285 \r
286       for (i = 0; i < istop; i += 2)\r
287       {\r
288          *rp = (png_byte)(~(*rp));\r
289          rp += 2;\r
290       }\r
291    }\r
292 \r
293 #ifdef PNG_16BIT_SUPPORTED\r
294    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&\r
295       row_info->bit_depth == 16)\r
296    {\r
297       png_bytep rp = row;\r
298       png_size_t i;\r
299       png_size_t istop = row_info->rowbytes;\r
300 \r
301       for (i = 0; i < istop; i += 4)\r
302       {\r
303          *rp = (png_byte)(~(*rp));\r
304          *(rp + 1) = (png_byte)(~(*(rp + 1)));\r
305          rp += 4;\r
306       }\r
307    }\r
308 #endif\r
309 }\r
310 #endif\r
311 \r
312 #ifdef PNG_16BIT_SUPPORTED\r
313 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)\r
314 /* Swaps byte order on 16 bit depth images */\r
315 void /* PRIVATE */\r
316 png_do_swap(png_row_infop row_info, png_bytep row)\r
317 {\r
318    png_debug(1, "in png_do_swap");\r
319 \r
320    if (row_info->bit_depth == 16)\r
321    {\r
322       png_bytep rp = row;\r
323       png_uint_32 i;\r
324       png_uint_32 istop= row_info->width * row_info->channels;\r
325 \r
326       for (i = 0; i < istop; i++, rp += 2)\r
327       {\r
328          png_byte t = *rp;\r
329          *rp = *(rp + 1);\r
330          *(rp + 1) = t;\r
331       }\r
332    }\r
333 }\r
334 #endif\r
335 #endif\r
336 \r
337 #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)\r
338 static PNG_CONST png_byte onebppswaptable[256] = {\r
339    0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,\r
340    0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,\r
341    0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,\r
342    0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,\r
343    0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,\r
344    0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,\r
345    0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,\r
346    0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,\r
347    0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,\r
348    0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,\r
349    0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,\r
350    0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,\r
351    0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,\r
352    0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,\r
353    0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,\r
354    0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,\r
355    0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,\r
356    0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,\r
357    0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,\r
358    0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,\r
359    0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,\r
360    0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,\r
361    0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,\r
362    0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,\r
363    0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,\r
364    0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,\r
365    0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,\r
366    0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,\r
367    0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,\r
368    0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,\r
369    0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,\r
370    0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF\r
371 };\r
372 \r
373 static PNG_CONST png_byte twobppswaptable[256] = {\r
374    0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,\r
375    0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,\r
376    0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,\r
377    0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,\r
378    0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,\r
379    0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,\r
380    0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,\r
381    0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,\r
382    0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,\r
383    0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,\r
384    0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,\r
385    0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,\r
386    0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,\r
387    0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,\r
388    0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,\r
389    0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,\r
390    0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,\r
391    0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,\r
392    0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,\r
393    0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,\r
394    0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,\r
395    0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,\r
396    0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,\r
397    0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,\r
398    0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,\r
399    0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,\r
400    0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,\r
401    0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,\r
402    0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,\r
403    0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,\r
404    0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,\r
405    0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF\r
406 };\r
407 \r
408 static PNG_CONST png_byte fourbppswaptable[256] = {\r
409    0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,\r
410    0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,\r
411    0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,\r
412    0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,\r
413    0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,\r
414    0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,\r
415    0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,\r
416    0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,\r
417    0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,\r
418    0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,\r
419    0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,\r
420    0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,\r
421    0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,\r
422    0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,\r
423    0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,\r
424    0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,\r
425    0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,\r
426    0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,\r
427    0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,\r
428    0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,\r
429    0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,\r
430    0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,\r
431    0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,\r
432    0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,\r
433    0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,\r
434    0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,\r
435    0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,\r
436    0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,\r
437    0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,\r
438    0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,\r
439    0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,\r
440    0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF\r
441 };\r
442 \r
443 /* Swaps pixel packing order within bytes */\r
444 void /* PRIVATE */\r
445 png_do_packswap(png_row_infop row_info, png_bytep row)\r
446 {\r
447    png_debug(1, "in png_do_packswap");\r
448 \r
449    if (row_info->bit_depth < 8)\r
450    {\r
451       png_bytep rp;\r
452       png_const_bytep end, table;\r
453 \r
454       end = row + row_info->rowbytes;\r
455 \r
456       if (row_info->bit_depth == 1)\r
457          table = onebppswaptable;\r
458 \r
459       else if (row_info->bit_depth == 2)\r
460          table = twobppswaptable;\r
461 \r
462       else if (row_info->bit_depth == 4)\r
463          table = fourbppswaptable;\r
464 \r
465       else\r
466          return;\r
467 \r
468       for (rp = row; rp < end; rp++)\r
469          *rp = table[*rp];\r
470    }\r
471 }\r
472 #endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */\r
473 \r
474 #if defined(PNG_WRITE_FILLER_SUPPORTED) || \\r
475     defined(PNG_READ_STRIP_ALPHA_SUPPORTED)\r
476 /* Remove a channel - this used to be 'png_do_strip_filler' but it used a\r
477  * somewhat weird combination of flags to determine what to do.  All the calls\r
478  * to png_do_strip_filler are changed in 1.5.2 to call this instead with the\r
479  * correct arguments.\r
480  *\r
481  * The routine isn't general - the channel must be the channel at the start or\r
482  * end (not in the middle) of each pixel.\r
483  */\r
484 void /* PRIVATE */\r
485 png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)\r
486 {\r
487    png_bytep sp = row; /* source pointer */\r
488    png_bytep dp = row; /* destination pointer */\r
489    png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */\r
490 \r
491    /* At the start sp will point to the first byte to copy and dp to where\r
492     * it is copied to.  ep always points just beyond the end of the row, so\r
493     * the loop simply copies (channels-1) channels until sp reaches ep.\r
494     *\r
495     * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.\r
496     *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.\r
497     */\r
498 \r
499    /* GA, GX, XG cases */\r
500    if (row_info->channels == 2)\r
501    {\r
502       if (row_info->bit_depth == 8)\r
503       {\r
504          if (at_start) /* Skip initial filler */\r
505             ++sp;\r
506          else          /* Skip initial channel and, for sp, the filler */\r
507             sp += 2, ++dp;\r
508 \r
509          /* For a 1 pixel wide image there is nothing to do */\r
510          while (sp < ep)\r
511             *dp++ = *sp, sp += 2;\r
512 \r
513          row_info->pixel_depth = 8;\r
514       }\r
515 \r
516       else if (row_info->bit_depth == 16)\r
517       {\r
518          if (at_start) /* Skip initial filler */\r
519             sp += 2;\r
520          else          /* Skip initial channel and, for sp, the filler */\r
521             sp += 4, dp += 2;\r
522 \r
523          while (sp < ep)\r
524             *dp++ = *sp++, *dp++ = *sp, sp += 3;\r
525 \r
526          row_info->pixel_depth = 16;\r
527       }\r
528 \r
529       else\r
530          return; /* bad bit depth */\r
531 \r
532       row_info->channels = 1;\r
533 \r
534       /* Finally fix the color type if it records an alpha channel */\r
535       if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\r
536          row_info->color_type = PNG_COLOR_TYPE_GRAY;\r
537    }\r
538 \r
539    /* RGBA, RGBX, XRGB cases */\r
540    else if (row_info->channels == 4)\r
541    {\r
542       if (row_info->bit_depth == 8)\r
543       {\r
544          if (at_start) /* Skip initial filler */\r
545             ++sp;\r
546          else          /* Skip initial channels and, for sp, the filler */\r
547             sp += 4, dp += 3;\r
548 \r
549          /* Note that the loop adds 3 to dp and 4 to sp each time. */\r
550          while (sp < ep)\r
551             *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;\r
552 \r
553          row_info->pixel_depth = 24;\r
554       }\r
555 \r
556       else if (row_info->bit_depth == 16)\r
557       {\r
558          if (at_start) /* Skip initial filler */\r
559             sp += 2;\r
560          else          /* Skip initial channels and, for sp, the filler */\r
561             sp += 8, dp += 6;\r
562 \r
563          while (sp < ep)\r
564          {\r
565             /* Copy 6 bytes, skip 2 */\r
566             *dp++ = *sp++, *dp++ = *sp++;\r
567             *dp++ = *sp++, *dp++ = *sp++;\r
568             *dp++ = *sp++, *dp++ = *sp, sp += 3;\r
569          }\r
570 \r
571          row_info->pixel_depth = 48;\r
572       }\r
573 \r
574       else\r
575          return; /* bad bit depth */\r
576 \r
577       row_info->channels = 3;\r
578 \r
579       /* Finally fix the color type if it records an alpha channel */\r
580       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\r
581          row_info->color_type = PNG_COLOR_TYPE_RGB;\r
582    }\r
583 \r
584    else\r
585       return; /* The filler channel has gone already */\r
586 \r
587    /* Fix the rowbytes value. */\r
588    row_info->rowbytes = dp-row;\r
589 }\r
590 #endif\r
591 \r
592 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)\r
593 /* Swaps red and blue bytes within a pixel */\r
594 void /* PRIVATE */\r
595 png_do_bgr(png_row_infop row_info, png_bytep row)\r
596 {\r
597    png_debug(1, "in png_do_bgr");\r
598 \r
599    if ((row_info->color_type & PNG_COLOR_MASK_COLOR))\r
600    {\r
601       png_uint_32 row_width = row_info->width;\r
602       if (row_info->bit_depth == 8)\r
603       {\r
604          if (row_info->color_type == PNG_COLOR_TYPE_RGB)\r
605          {\r
606             png_bytep rp;\r
607             png_uint_32 i;\r
608 \r
609             for (i = 0, rp = row; i < row_width; i++, rp += 3)\r
610             {\r
611                png_byte save = *rp;\r
612                *rp = *(rp + 2);\r
613                *(rp + 2) = save;\r
614             }\r
615          }\r
616 \r
617          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\r
618          {\r
619             png_bytep rp;\r
620             png_uint_32 i;\r
621 \r
622             for (i = 0, rp = row; i < row_width; i++, rp += 4)\r
623             {\r
624                png_byte save = *rp;\r
625                *rp = *(rp + 2);\r
626                *(rp + 2) = save;\r
627             }\r
628          }\r
629       }\r
630 \r
631 #ifdef PNG_16BIT_SUPPORTED\r
632       else if (row_info->bit_depth == 16)\r
633       {\r
634          if (row_info->color_type == PNG_COLOR_TYPE_RGB)\r
635          {\r
636             png_bytep rp;\r
637             png_uint_32 i;\r
638 \r
639             for (i = 0, rp = row; i < row_width; i++, rp += 6)\r
640             {\r
641                png_byte save = *rp;\r
642                *rp = *(rp + 4);\r
643                *(rp + 4) = save;\r
644                save = *(rp + 1);\r
645                *(rp + 1) = *(rp + 5);\r
646                *(rp + 5) = save;\r
647             }\r
648          }\r
649 \r
650          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)\r
651          {\r
652             png_bytep rp;\r
653             png_uint_32 i;\r
654 \r
655             for (i = 0, rp = row; i < row_width; i++, rp += 8)\r
656             {\r
657                png_byte save = *rp;\r
658                *rp = *(rp + 4);\r
659                *(rp + 4) = save;\r
660                save = *(rp + 1);\r
661                *(rp + 1) = *(rp + 5);\r
662                *(rp + 5) = save;\r
663             }\r
664          }\r
665       }\r
666 #endif\r
667    }\r
668 }\r
669 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */\r
670 \r
671 #if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \\r
672     defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)\r
673 /* Added at libpng-1.5.10 */\r
674 void /* PRIVATE */\r
675 png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)\r
676 {\r
677    if (png_ptr->num_palette < (1 << row_info->bit_depth) &&\r
678       png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */\r
679    {\r
680       /* Calculations moved outside switch in an attempt to stop different\r
681        * compiler warnings.  'padding' is in *bits* within the last byte, it is\r
682        * an 'int' because pixel_depth becomes an 'int' in the expression below,\r
683        * and this calculation is used because it avoids warnings that other\r
684        * forms produced on either GCC or MSVC.\r
685        */\r
686       int padding = (-row_info->pixel_depth * row_info->width) & 7;\r
687       png_bytep rp = png_ptr->row_buf + row_info->rowbytes;\r
688 \r
689       switch (row_info->bit_depth)\r
690       {\r
691          case 1:\r
692          {\r
693             /* in this case, all bytes must be 0 so we don't need\r
694              * to unpack the pixels except for the rightmost one.\r
695              */\r
696             for (; rp > png_ptr->row_buf; rp--)\r
697             {\r
698               if (*rp >> padding != 0)\r
699                  png_ptr->num_palette_max = 1;\r
700               padding = 0;\r
701             }\r
702 \r
703             break;\r
704          }\r
705 \r
706          case 2:\r
707          {\r
708             for (; rp > png_ptr->row_buf; rp--)\r
709             {\r
710               int i = ((*rp >> padding) & 0x03);\r
711 \r
712               if (i > png_ptr->num_palette_max)\r
713                  png_ptr->num_palette_max = i;\r
714 \r
715               i = (((*rp >> padding) >> 2) & 0x03);\r
716 \r
717               if (i > png_ptr->num_palette_max)\r
718                  png_ptr->num_palette_max = i;\r
719 \r
720               i = (((*rp >> padding) >> 4) & 0x03);\r
721 \r
722               if (i > png_ptr->num_palette_max)\r
723                  png_ptr->num_palette_max = i;\r
724 \r
725               i = (((*rp >> padding) >> 6) & 0x03);\r
726 \r
727               if (i > png_ptr->num_palette_max)\r
728                  png_ptr->num_palette_max = i;\r
729 \r
730               padding = 0;\r
731             }\r
732 \r
733             break;\r
734          }\r
735 \r
736          case 4:\r
737          {\r
738             for (; rp > png_ptr->row_buf; rp--)\r
739             {\r
740               int i = ((*rp >> padding) & 0x0f);\r
741 \r
742               if (i > png_ptr->num_palette_max)\r
743                  png_ptr->num_palette_max = i;\r
744 \r
745               i = (((*rp >> padding) >> 4) & 0x0f);\r
746 \r
747               if (i > png_ptr->num_palette_max)\r
748                  png_ptr->num_palette_max = i;\r
749 \r
750               padding = 0;\r
751             }\r
752 \r
753             break;\r
754          }\r
755 \r
756          case 8:\r
757          {\r
758             for (; rp > png_ptr->row_buf; rp--)\r
759             {\r
760                if (*rp > png_ptr->num_palette_max)\r
761                   png_ptr->num_palette_max = (int) *rp;\r
762             }\r
763 \r
764             break;\r
765          }\r
766 \r
767          default:\r
768             break;\r
769       }\r
770    }\r
771 }\r
772 #endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */\r
773 \r
774 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \\r
775     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)\r
776 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\r
777 void PNGAPI\r
778 png_set_user_transform_info(png_structrp png_ptr, png_voidp\r
779    user_transform_ptr, int user_transform_depth, int user_transform_channels)\r
780 {\r
781    png_debug(1, "in png_set_user_transform_info");\r
782 \r
783    if (png_ptr == NULL)\r
784       return;\r
785 \r
786 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED\r
787    if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&\r
788       (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)\r
789    {\r
790       png_app_error(png_ptr,\r
791             "info change after png_start_read_image or png_read_update_info");\r
792       return;\r
793    }\r
794 #endif\r
795 \r
796    png_ptr->user_transform_ptr = user_transform_ptr;\r
797    png_ptr->user_transform_depth = (png_byte)user_transform_depth;\r
798    png_ptr->user_transform_channels = (png_byte)user_transform_channels;\r
799 }\r
800 #endif\r
801 \r
802 /* This function returns a pointer to the user_transform_ptr associated with\r
803  * the user transform functions.  The application should free any memory\r
804  * associated with this pointer before png_write_destroy and png_read_destroy\r
805  * are called.\r
806  */\r
807 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED\r
808 png_voidp PNGAPI\r
809 png_get_user_transform_ptr(png_const_structrp png_ptr)\r
810 {\r
811    if (png_ptr == NULL)\r
812       return (NULL);\r
813 \r
814    return png_ptr->user_transform_ptr;\r
815 }\r
816 #endif\r
817 \r
818 #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED\r
819 png_uint_32 PNGAPI\r
820 png_get_current_row_number(png_const_structrp png_ptr)\r
821 {\r
822    /* See the comments in png.h - this is the sub-image row when reading and\r
823     * interlaced image.\r
824     */\r
825    if (png_ptr != NULL)\r
826       return png_ptr->row_number;\r
827 \r
828    return PNG_UINT_32_MAX; /* help the app not to fail silently */\r
829 }\r
830 \r
831 png_byte PNGAPI\r
832 png_get_current_pass_number(png_const_structrp png_ptr)\r
833 {\r
834    if (png_ptr != NULL)\r
835       return png_ptr->pass;\r
836    return 8; /* invalid */\r
837 }\r
838 #endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */\r
839 #endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||\r
840           PNG_WRITE_USER_TRANSFORM_SUPPORTED */\r
841 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */\r
842 #endif\r