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