13965825b97a5809454f5810f7e603cbd02daa036scroggo
23965825b97a5809454f5810f7e603cbd02daa036scroggo/* pngtrans.c - transforms the data in a row (used by both readers and writers)
33965825b97a5809454f5810f7e603cbd02daa036scroggo *
43965825b97a5809454f5810f7e603cbd02daa036scroggo * Last changed in libpng 1.6.18 [July 23, 2015]
53965825b97a5809454f5810f7e603cbd02daa036scroggo * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
63965825b97a5809454f5810f7e603cbd02daa036scroggo * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
73965825b97a5809454f5810f7e603cbd02daa036scroggo * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
83965825b97a5809454f5810f7e603cbd02daa036scroggo *
93965825b97a5809454f5810f7e603cbd02daa036scroggo * This code is released under the libpng license.
103965825b97a5809454f5810f7e603cbd02daa036scroggo * For conditions of distribution and use, see the disclaimer
113965825b97a5809454f5810f7e603cbd02daa036scroggo * and license in png.h
123965825b97a5809454f5810f7e603cbd02daa036scroggo */
133965825b97a5809454f5810f7e603cbd02daa036scroggo
143965825b97a5809454f5810f7e603cbd02daa036scroggo#include "pngpriv.h"
153965825b97a5809454f5810f7e603cbd02daa036scroggo
163965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
173965825b97a5809454f5810f7e603cbd02daa036scroggo
183965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
193965825b97a5809454f5810f7e603cbd02daa036scroggo/* Turn on BGR-to-RGB mapping */
203965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
213965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_bgr(png_structrp png_ptr)
223965825b97a5809454f5810f7e603cbd02daa036scroggo{
233965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_bgr");
243965825b97a5809454f5810f7e603cbd02daa036scroggo
253965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
263965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
273965825b97a5809454f5810f7e603cbd02daa036scroggo
283965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->transformations |= PNG_BGR;
293965825b97a5809454f5810f7e603cbd02daa036scroggo}
303965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
313965825b97a5809454f5810f7e603cbd02daa036scroggo
323965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
333965825b97a5809454f5810f7e603cbd02daa036scroggo/* Turn on 16-bit byte swapping */
343965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
353965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_swap(png_structrp png_ptr)
363965825b97a5809454f5810f7e603cbd02daa036scroggo{
373965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_swap");
383965825b97a5809454f5810f7e603cbd02daa036scroggo
393965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
403965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
413965825b97a5809454f5810f7e603cbd02daa036scroggo
423965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr->bit_depth == 16)
433965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->transformations |= PNG_SWAP_BYTES;
443965825b97a5809454f5810f7e603cbd02daa036scroggo}
453965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
463965825b97a5809454f5810f7e603cbd02daa036scroggo
473965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
483965825b97a5809454f5810f7e603cbd02daa036scroggo/* Turn on pixel packing */
493965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
503965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_packing(png_structrp png_ptr)
513965825b97a5809454f5810f7e603cbd02daa036scroggo{
523965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_packing");
533965825b97a5809454f5810f7e603cbd02daa036scroggo
543965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
553965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
563965825b97a5809454f5810f7e603cbd02daa036scroggo
573965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr->bit_depth < 8)
583965825b97a5809454f5810f7e603cbd02daa036scroggo   {
593965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->transformations |= PNG_PACK;
603965825b97a5809454f5810f7e603cbd02daa036scroggo#     ifdef PNG_WRITE_SUPPORTED
613965825b97a5809454f5810f7e603cbd02daa036scroggo         png_ptr->usr_bit_depth = 8;
623965825b97a5809454f5810f7e603cbd02daa036scroggo#     endif
633965825b97a5809454f5810f7e603cbd02daa036scroggo   }
643965825b97a5809454f5810f7e603cbd02daa036scroggo}
653965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
663965825b97a5809454f5810f7e603cbd02daa036scroggo
673965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
683965825b97a5809454f5810f7e603cbd02daa036scroggo/* Turn on packed pixel swapping */
693965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
703965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_packswap(png_structrp png_ptr)
713965825b97a5809454f5810f7e603cbd02daa036scroggo{
723965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_packswap");
733965825b97a5809454f5810f7e603cbd02daa036scroggo
743965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
753965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
763965825b97a5809454f5810f7e603cbd02daa036scroggo
773965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr->bit_depth < 8)
783965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->transformations |= PNG_PACKSWAP;
793965825b97a5809454f5810f7e603cbd02daa036scroggo}
803965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
813965825b97a5809454f5810f7e603cbd02daa036scroggo
823965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
833965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
843965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
853965825b97a5809454f5810f7e603cbd02daa036scroggo{
863965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_shift");
873965825b97a5809454f5810f7e603cbd02daa036scroggo
883965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
893965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
903965825b97a5809454f5810f7e603cbd02daa036scroggo
913965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->transformations |= PNG_SHIFT;
923965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->shift = *true_bits;
933965825b97a5809454f5810f7e603cbd02daa036scroggo}
943965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
953965825b97a5809454f5810f7e603cbd02daa036scroggo
963965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
973965825b97a5809454f5810f7e603cbd02daa036scroggo    defined(PNG_WRITE_INTERLACING_SUPPORTED)
983965825b97a5809454f5810f7e603cbd02daa036scroggoint PNGAPI
993965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_interlace_handling(png_structrp png_ptr)
1003965825b97a5809454f5810f7e603cbd02daa036scroggo{
1013965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_interlace handling");
1023965825b97a5809454f5810f7e603cbd02daa036scroggo
1033965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr != 0 && png_ptr->interlaced != 0)
1043965825b97a5809454f5810f7e603cbd02daa036scroggo   {
1053965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->transformations |= PNG_INTERLACE;
1063965825b97a5809454f5810f7e603cbd02daa036scroggo      return (7);
1073965825b97a5809454f5810f7e603cbd02daa036scroggo   }
1083965825b97a5809454f5810f7e603cbd02daa036scroggo
1093965825b97a5809454f5810f7e603cbd02daa036scroggo   return (1);
1103965825b97a5809454f5810f7e603cbd02daa036scroggo}
1113965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
1123965825b97a5809454f5810f7e603cbd02daa036scroggo
1133965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
1143965825b97a5809454f5810f7e603cbd02daa036scroggo/* Add a filler byte on read, or remove a filler or alpha byte on write.
1153965825b97a5809454f5810f7e603cbd02daa036scroggo * The filler type has changed in v0.95 to allow future 2-byte fillers
1163965825b97a5809454f5810f7e603cbd02daa036scroggo * for 48-bit input data, as well as to avoid problems with some compilers
1173965825b97a5809454f5810f7e603cbd02daa036scroggo * that don't like bytes as parameters.
1183965825b97a5809454f5810f7e603cbd02daa036scroggo */
1193965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
1203965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
1213965825b97a5809454f5810f7e603cbd02daa036scroggo{
1223965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_filler");
1233965825b97a5809454f5810f7e603cbd02daa036scroggo
1243965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
1253965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
1263965825b97a5809454f5810f7e603cbd02daa036scroggo
1273965825b97a5809454f5810f7e603cbd02daa036scroggo   /* In libpng 1.6 it is possible to determine whether this is a read or write
1283965825b97a5809454f5810f7e603cbd02daa036scroggo    * operation and therefore to do more checking here for a valid call.
1293965825b97a5809454f5810f7e603cbd02daa036scroggo    */
1303965825b97a5809454f5810f7e603cbd02daa036scroggo   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1313965825b97a5809454f5810f7e603cbd02daa036scroggo   {
1323965825b97a5809454f5810f7e603cbd02daa036scroggo#     ifdef PNG_READ_FILLER_SUPPORTED
1333965825b97a5809454f5810f7e603cbd02daa036scroggo         /* On read png_set_filler is always valid, regardless of the base PNG
1343965825b97a5809454f5810f7e603cbd02daa036scroggo          * format, because other transformations can give a format where the
1353965825b97a5809454f5810f7e603cbd02daa036scroggo          * filler code can execute (basically an 8 or 16-bit component RGB or G
1363965825b97a5809454f5810f7e603cbd02daa036scroggo          * format.)
1373965825b97a5809454f5810f7e603cbd02daa036scroggo          *
1383965825b97a5809454f5810f7e603cbd02daa036scroggo          * NOTE: usr_channels is not used by the read code!  (This has led to
1393965825b97a5809454f5810f7e603cbd02daa036scroggo          * confusion in the past.)  The filler is only used in the read code.
1403965825b97a5809454f5810f7e603cbd02daa036scroggo          */
1413965825b97a5809454f5810f7e603cbd02daa036scroggo         png_ptr->filler = (png_uint_16)filler;
1423965825b97a5809454f5810f7e603cbd02daa036scroggo#     else
1433965825b97a5809454f5810f7e603cbd02daa036scroggo         png_app_error(png_ptr, "png_set_filler not supported on read");
1443965825b97a5809454f5810f7e603cbd02daa036scroggo         PNG_UNUSED(filler) /* not used in the write case */
1453965825b97a5809454f5810f7e603cbd02daa036scroggo         return;
1463965825b97a5809454f5810f7e603cbd02daa036scroggo#     endif
1473965825b97a5809454f5810f7e603cbd02daa036scroggo   }
1483965825b97a5809454f5810f7e603cbd02daa036scroggo
1493965825b97a5809454f5810f7e603cbd02daa036scroggo   else /* write */
1503965825b97a5809454f5810f7e603cbd02daa036scroggo   {
1513965825b97a5809454f5810f7e603cbd02daa036scroggo#     ifdef PNG_WRITE_FILLER_SUPPORTED
1523965825b97a5809454f5810f7e603cbd02daa036scroggo         /* On write the usr_channels parameter must be set correctly at the
1533965825b97a5809454f5810f7e603cbd02daa036scroggo          * start to record the number of channels in the app-supplied data.
1543965825b97a5809454f5810f7e603cbd02daa036scroggo          */
1553965825b97a5809454f5810f7e603cbd02daa036scroggo         switch (png_ptr->color_type)
1563965825b97a5809454f5810f7e603cbd02daa036scroggo         {
1573965825b97a5809454f5810f7e603cbd02daa036scroggo            case PNG_COLOR_TYPE_RGB:
1583965825b97a5809454f5810f7e603cbd02daa036scroggo               png_ptr->usr_channels = 4;
1593965825b97a5809454f5810f7e603cbd02daa036scroggo               break;
1603965825b97a5809454f5810f7e603cbd02daa036scroggo
1613965825b97a5809454f5810f7e603cbd02daa036scroggo            case PNG_COLOR_TYPE_GRAY:
1623965825b97a5809454f5810f7e603cbd02daa036scroggo               if (png_ptr->bit_depth >= 8)
1633965825b97a5809454f5810f7e603cbd02daa036scroggo               {
1643965825b97a5809454f5810f7e603cbd02daa036scroggo                  png_ptr->usr_channels = 2;
1653965825b97a5809454f5810f7e603cbd02daa036scroggo                  break;
1663965825b97a5809454f5810f7e603cbd02daa036scroggo               }
1673965825b97a5809454f5810f7e603cbd02daa036scroggo
1683965825b97a5809454f5810f7e603cbd02daa036scroggo               else
1693965825b97a5809454f5810f7e603cbd02daa036scroggo               {
1703965825b97a5809454f5810f7e603cbd02daa036scroggo                  /* There simply isn't any code in libpng to strip out bits
1713965825b97a5809454f5810f7e603cbd02daa036scroggo                   * from bytes when the components are less than a byte in
1723965825b97a5809454f5810f7e603cbd02daa036scroggo                   * size!
1733965825b97a5809454f5810f7e603cbd02daa036scroggo                   */
1743965825b97a5809454f5810f7e603cbd02daa036scroggo                  png_app_error(png_ptr,
1753965825b97a5809454f5810f7e603cbd02daa036scroggo                     "png_set_filler is invalid for low bit depth gray output");
1763965825b97a5809454f5810f7e603cbd02daa036scroggo                  return;
1773965825b97a5809454f5810f7e603cbd02daa036scroggo               }
1783965825b97a5809454f5810f7e603cbd02daa036scroggo
1793965825b97a5809454f5810f7e603cbd02daa036scroggo            default:
1803965825b97a5809454f5810f7e603cbd02daa036scroggo               png_app_error(png_ptr,
1813965825b97a5809454f5810f7e603cbd02daa036scroggo                  "png_set_filler: inappropriate color type");
1823965825b97a5809454f5810f7e603cbd02daa036scroggo               return;
1833965825b97a5809454f5810f7e603cbd02daa036scroggo         }
1843965825b97a5809454f5810f7e603cbd02daa036scroggo#     else
1853965825b97a5809454f5810f7e603cbd02daa036scroggo         png_app_error(png_ptr, "png_set_filler not supported on write");
1863965825b97a5809454f5810f7e603cbd02daa036scroggo         return;
1873965825b97a5809454f5810f7e603cbd02daa036scroggo#     endif
1883965825b97a5809454f5810f7e603cbd02daa036scroggo   }
1893965825b97a5809454f5810f7e603cbd02daa036scroggo
1903965825b97a5809454f5810f7e603cbd02daa036scroggo   /* Here on success - libpng supports the operation, set the transformation
1913965825b97a5809454f5810f7e603cbd02daa036scroggo    * and the flag to say where the filler channel is.
1923965825b97a5809454f5810f7e603cbd02daa036scroggo    */
1933965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->transformations |= PNG_FILLER;
1943965825b97a5809454f5810f7e603cbd02daa036scroggo
1953965825b97a5809454f5810f7e603cbd02daa036scroggo   if (filler_loc == PNG_FILLER_AFTER)
1963965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
1973965825b97a5809454f5810f7e603cbd02daa036scroggo
1983965825b97a5809454f5810f7e603cbd02daa036scroggo   else
1993965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
2003965825b97a5809454f5810f7e603cbd02daa036scroggo}
2013965825b97a5809454f5810f7e603cbd02daa036scroggo
2023965825b97a5809454f5810f7e603cbd02daa036scroggo/* Added to libpng-1.2.7 */
2033965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
2043965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
2053965825b97a5809454f5810f7e603cbd02daa036scroggo{
2063965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_add_alpha");
2073965825b97a5809454f5810f7e603cbd02daa036scroggo
2083965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
2093965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
2103965825b97a5809454f5810f7e603cbd02daa036scroggo
2113965825b97a5809454f5810f7e603cbd02daa036scroggo   png_set_filler(png_ptr, filler, filler_loc);
2123965825b97a5809454f5810f7e603cbd02daa036scroggo   /* The above may fail to do anything. */
2133965825b97a5809454f5810f7e603cbd02daa036scroggo   if ((png_ptr->transformations & PNG_FILLER) != 0)
2143965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->transformations |= PNG_ADD_ALPHA;
2153965825b97a5809454f5810f7e603cbd02daa036scroggo}
2163965825b97a5809454f5810f7e603cbd02daa036scroggo
2173965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
2183965825b97a5809454f5810f7e603cbd02daa036scroggo
2193965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
2203965825b97a5809454f5810f7e603cbd02daa036scroggo    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
2213965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
2223965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_swap_alpha(png_structrp png_ptr)
2233965825b97a5809454f5810f7e603cbd02daa036scroggo{
2243965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_swap_alpha");
2253965825b97a5809454f5810f7e603cbd02daa036scroggo
2263965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
2273965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
2283965825b97a5809454f5810f7e603cbd02daa036scroggo
2293965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->transformations |= PNG_SWAP_ALPHA;
2303965825b97a5809454f5810f7e603cbd02daa036scroggo}
2313965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
2323965825b97a5809454f5810f7e603cbd02daa036scroggo
2333965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
2343965825b97a5809454f5810f7e603cbd02daa036scroggo    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
2353965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
2363965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_invert_alpha(png_structrp png_ptr)
2373965825b97a5809454f5810f7e603cbd02daa036scroggo{
2383965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_invert_alpha");
2393965825b97a5809454f5810f7e603cbd02daa036scroggo
2403965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
2413965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
2423965825b97a5809454f5810f7e603cbd02daa036scroggo
2433965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->transformations |= PNG_INVERT_ALPHA;
2443965825b97a5809454f5810f7e603cbd02daa036scroggo}
2453965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
2463965825b97a5809454f5810f7e603cbd02daa036scroggo
2473965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
2483965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
2493965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_invert_mono(png_structrp png_ptr)
2503965825b97a5809454f5810f7e603cbd02daa036scroggo{
2513965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_invert_mono");
2523965825b97a5809454f5810f7e603cbd02daa036scroggo
2533965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
2543965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
2553965825b97a5809454f5810f7e603cbd02daa036scroggo
2563965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->transformations |= PNG_INVERT_MONO;
2573965825b97a5809454f5810f7e603cbd02daa036scroggo}
2583965825b97a5809454f5810f7e603cbd02daa036scroggo
2593965825b97a5809454f5810f7e603cbd02daa036scroggo/* Invert monochrome grayscale data */
2603965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */
2613965825b97a5809454f5810f7e603cbd02daa036scroggopng_do_invert(png_row_infop row_info, png_bytep row)
2623965825b97a5809454f5810f7e603cbd02daa036scroggo{
2633965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_do_invert");
2643965825b97a5809454f5810f7e603cbd02daa036scroggo
2653965825b97a5809454f5810f7e603cbd02daa036scroggo  /* This test removed from libpng version 1.0.13 and 1.2.0:
2663965825b97a5809454f5810f7e603cbd02daa036scroggo   *   if (row_info->bit_depth == 1 &&
2673965825b97a5809454f5810f7e603cbd02daa036scroggo   */
2683965825b97a5809454f5810f7e603cbd02daa036scroggo   if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2693965825b97a5809454f5810f7e603cbd02daa036scroggo   {
2703965825b97a5809454f5810f7e603cbd02daa036scroggo      png_bytep rp = row;
2713965825b97a5809454f5810f7e603cbd02daa036scroggo      png_size_t i;
2723965825b97a5809454f5810f7e603cbd02daa036scroggo      png_size_t istop = row_info->rowbytes;
2733965825b97a5809454f5810f7e603cbd02daa036scroggo
2743965825b97a5809454f5810f7e603cbd02daa036scroggo      for (i = 0; i < istop; i++)
2753965825b97a5809454f5810f7e603cbd02daa036scroggo      {
2763965825b97a5809454f5810f7e603cbd02daa036scroggo         *rp = (png_byte)(~(*rp));
2773965825b97a5809454f5810f7e603cbd02daa036scroggo         rp++;
2783965825b97a5809454f5810f7e603cbd02daa036scroggo      }
2793965825b97a5809454f5810f7e603cbd02daa036scroggo   }
2803965825b97a5809454f5810f7e603cbd02daa036scroggo
2813965825b97a5809454f5810f7e603cbd02daa036scroggo   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
2823965825b97a5809454f5810f7e603cbd02daa036scroggo      row_info->bit_depth == 8)
2833965825b97a5809454f5810f7e603cbd02daa036scroggo   {
2843965825b97a5809454f5810f7e603cbd02daa036scroggo      png_bytep rp = row;
2853965825b97a5809454f5810f7e603cbd02daa036scroggo      png_size_t i;
2863965825b97a5809454f5810f7e603cbd02daa036scroggo      png_size_t istop = row_info->rowbytes;
2873965825b97a5809454f5810f7e603cbd02daa036scroggo
2883965825b97a5809454f5810f7e603cbd02daa036scroggo      for (i = 0; i < istop; i += 2)
2893965825b97a5809454f5810f7e603cbd02daa036scroggo      {
2903965825b97a5809454f5810f7e603cbd02daa036scroggo         *rp = (png_byte)(~(*rp));
2913965825b97a5809454f5810f7e603cbd02daa036scroggo         rp += 2;
2923965825b97a5809454f5810f7e603cbd02daa036scroggo      }
2933965825b97a5809454f5810f7e603cbd02daa036scroggo   }
2943965825b97a5809454f5810f7e603cbd02daa036scroggo
2953965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_16BIT_SUPPORTED
2963965825b97a5809454f5810f7e603cbd02daa036scroggo   else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
2973965825b97a5809454f5810f7e603cbd02daa036scroggo      row_info->bit_depth == 16)
2983965825b97a5809454f5810f7e603cbd02daa036scroggo   {
2993965825b97a5809454f5810f7e603cbd02daa036scroggo      png_bytep rp = row;
3003965825b97a5809454f5810f7e603cbd02daa036scroggo      png_size_t i;
3013965825b97a5809454f5810f7e603cbd02daa036scroggo      png_size_t istop = row_info->rowbytes;
3023965825b97a5809454f5810f7e603cbd02daa036scroggo
3033965825b97a5809454f5810f7e603cbd02daa036scroggo      for (i = 0; i < istop; i += 4)
3043965825b97a5809454f5810f7e603cbd02daa036scroggo      {
3053965825b97a5809454f5810f7e603cbd02daa036scroggo         *rp = (png_byte)(~(*rp));
3063965825b97a5809454f5810f7e603cbd02daa036scroggo         *(rp + 1) = (png_byte)(~(*(rp + 1)));
3073965825b97a5809454f5810f7e603cbd02daa036scroggo         rp += 4;
3083965825b97a5809454f5810f7e603cbd02daa036scroggo      }
3093965825b97a5809454f5810f7e603cbd02daa036scroggo   }
3103965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
3113965825b97a5809454f5810f7e603cbd02daa036scroggo}
3123965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
3133965825b97a5809454f5810f7e603cbd02daa036scroggo
3143965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_16BIT_SUPPORTED
3153965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
3163965825b97a5809454f5810f7e603cbd02daa036scroggo/* Swaps byte order on 16-bit depth images */
3173965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */
3183965825b97a5809454f5810f7e603cbd02daa036scroggopng_do_swap(png_row_infop row_info, png_bytep row)
3193965825b97a5809454f5810f7e603cbd02daa036scroggo{
3203965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_do_swap");
3213965825b97a5809454f5810f7e603cbd02daa036scroggo
3223965825b97a5809454f5810f7e603cbd02daa036scroggo   if (row_info->bit_depth == 16)
3233965825b97a5809454f5810f7e603cbd02daa036scroggo   {
3243965825b97a5809454f5810f7e603cbd02daa036scroggo      png_bytep rp = row;
3253965825b97a5809454f5810f7e603cbd02daa036scroggo      png_uint_32 i;
3263965825b97a5809454f5810f7e603cbd02daa036scroggo      png_uint_32 istop= row_info->width * row_info->channels;
3273965825b97a5809454f5810f7e603cbd02daa036scroggo
3283965825b97a5809454f5810f7e603cbd02daa036scroggo      for (i = 0; i < istop; i++, rp += 2)
3293965825b97a5809454f5810f7e603cbd02daa036scroggo      {
3303965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
3313965825b97a5809454f5810f7e603cbd02daa036scroggo         /* Feature added to libpng-1.6.11 for testing purposes, not
3323965825b97a5809454f5810f7e603cbd02daa036scroggo          * enabled by default.
3333965825b97a5809454f5810f7e603cbd02daa036scroggo          */
3343965825b97a5809454f5810f7e603cbd02daa036scroggo         *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
3353965825b97a5809454f5810f7e603cbd02daa036scroggo#else
3363965825b97a5809454f5810f7e603cbd02daa036scroggo         png_byte t = *rp;
3373965825b97a5809454f5810f7e603cbd02daa036scroggo         *rp = *(rp + 1);
3383965825b97a5809454f5810f7e603cbd02daa036scroggo         *(rp + 1) = t;
3393965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
3403965825b97a5809454f5810f7e603cbd02daa036scroggo      }
3413965825b97a5809454f5810f7e603cbd02daa036scroggo   }
3423965825b97a5809454f5810f7e603cbd02daa036scroggo}
3433965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
3443965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
3453965825b97a5809454f5810f7e603cbd02daa036scroggo
3463965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
3473965825b97a5809454f5810f7e603cbd02daa036scroggostatic PNG_CONST png_byte onebppswaptable[256] = {
3483965825b97a5809454f5810f7e603cbd02daa036scroggo   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
3493965825b97a5809454f5810f7e603cbd02daa036scroggo   0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
3503965825b97a5809454f5810f7e603cbd02daa036scroggo   0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
3513965825b97a5809454f5810f7e603cbd02daa036scroggo   0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
3523965825b97a5809454f5810f7e603cbd02daa036scroggo   0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
3533965825b97a5809454f5810f7e603cbd02daa036scroggo   0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
3543965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
3553965825b97a5809454f5810f7e603cbd02daa036scroggo   0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
3563965825b97a5809454f5810f7e603cbd02daa036scroggo   0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
3573965825b97a5809454f5810f7e603cbd02daa036scroggo   0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
3583965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
3593965825b97a5809454f5810f7e603cbd02daa036scroggo   0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
3603965825b97a5809454f5810f7e603cbd02daa036scroggo   0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
3613965825b97a5809454f5810f7e603cbd02daa036scroggo   0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
3623965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
3633965825b97a5809454f5810f7e603cbd02daa036scroggo   0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
3643965825b97a5809454f5810f7e603cbd02daa036scroggo   0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
3653965825b97a5809454f5810f7e603cbd02daa036scroggo   0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
3663965825b97a5809454f5810f7e603cbd02daa036scroggo   0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
3673965825b97a5809454f5810f7e603cbd02daa036scroggo   0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
3683965825b97a5809454f5810f7e603cbd02daa036scroggo   0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
3693965825b97a5809454f5810f7e603cbd02daa036scroggo   0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
3703965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
3713965825b97a5809454f5810f7e603cbd02daa036scroggo   0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
3723965825b97a5809454f5810f7e603cbd02daa036scroggo   0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
3733965825b97a5809454f5810f7e603cbd02daa036scroggo   0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
3743965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
3753965825b97a5809454f5810f7e603cbd02daa036scroggo   0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
3763965825b97a5809454f5810f7e603cbd02daa036scroggo   0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
3773965825b97a5809454f5810f7e603cbd02daa036scroggo   0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
3783965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
3793965825b97a5809454f5810f7e603cbd02daa036scroggo   0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
3803965825b97a5809454f5810f7e603cbd02daa036scroggo};
3813965825b97a5809454f5810f7e603cbd02daa036scroggo
3823965825b97a5809454f5810f7e603cbd02daa036scroggostatic PNG_CONST png_byte twobppswaptable[256] = {
3833965825b97a5809454f5810f7e603cbd02daa036scroggo   0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
3843965825b97a5809454f5810f7e603cbd02daa036scroggo   0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
3853965825b97a5809454f5810f7e603cbd02daa036scroggo   0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
3863965825b97a5809454f5810f7e603cbd02daa036scroggo   0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
3873965825b97a5809454f5810f7e603cbd02daa036scroggo   0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
3883965825b97a5809454f5810f7e603cbd02daa036scroggo   0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
3893965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
3903965825b97a5809454f5810f7e603cbd02daa036scroggo   0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
3913965825b97a5809454f5810f7e603cbd02daa036scroggo   0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
3923965825b97a5809454f5810f7e603cbd02daa036scroggo   0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
3933965825b97a5809454f5810f7e603cbd02daa036scroggo   0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
3943965825b97a5809454f5810f7e603cbd02daa036scroggo   0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
3953965825b97a5809454f5810f7e603cbd02daa036scroggo   0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
3963965825b97a5809454f5810f7e603cbd02daa036scroggo   0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
3973965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
3983965825b97a5809454f5810f7e603cbd02daa036scroggo   0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
3993965825b97a5809454f5810f7e603cbd02daa036scroggo   0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
4003965825b97a5809454f5810f7e603cbd02daa036scroggo   0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
4013965825b97a5809454f5810f7e603cbd02daa036scroggo   0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
4023965825b97a5809454f5810f7e603cbd02daa036scroggo   0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
4033965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
4043965825b97a5809454f5810f7e603cbd02daa036scroggo   0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
4053965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
4063965825b97a5809454f5810f7e603cbd02daa036scroggo   0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
4073965825b97a5809454f5810f7e603cbd02daa036scroggo   0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
4083965825b97a5809454f5810f7e603cbd02daa036scroggo   0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
4093965825b97a5809454f5810f7e603cbd02daa036scroggo   0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
4103965825b97a5809454f5810f7e603cbd02daa036scroggo   0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
4113965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
4123965825b97a5809454f5810f7e603cbd02daa036scroggo   0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
4133965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
4143965825b97a5809454f5810f7e603cbd02daa036scroggo   0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
4153965825b97a5809454f5810f7e603cbd02daa036scroggo};
4163965825b97a5809454f5810f7e603cbd02daa036scroggo
4173965825b97a5809454f5810f7e603cbd02daa036scroggostatic PNG_CONST png_byte fourbppswaptable[256] = {
4183965825b97a5809454f5810f7e603cbd02daa036scroggo   0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
4193965825b97a5809454f5810f7e603cbd02daa036scroggo   0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
4203965825b97a5809454f5810f7e603cbd02daa036scroggo   0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
4213965825b97a5809454f5810f7e603cbd02daa036scroggo   0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
4223965825b97a5809454f5810f7e603cbd02daa036scroggo   0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
4233965825b97a5809454f5810f7e603cbd02daa036scroggo   0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
4243965825b97a5809454f5810f7e603cbd02daa036scroggo   0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
4253965825b97a5809454f5810f7e603cbd02daa036scroggo   0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
4263965825b97a5809454f5810f7e603cbd02daa036scroggo   0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
4273965825b97a5809454f5810f7e603cbd02daa036scroggo   0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
4283965825b97a5809454f5810f7e603cbd02daa036scroggo   0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
4293965825b97a5809454f5810f7e603cbd02daa036scroggo   0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
4303965825b97a5809454f5810f7e603cbd02daa036scroggo   0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
4313965825b97a5809454f5810f7e603cbd02daa036scroggo   0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
4323965825b97a5809454f5810f7e603cbd02daa036scroggo   0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
4333965825b97a5809454f5810f7e603cbd02daa036scroggo   0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
4343965825b97a5809454f5810f7e603cbd02daa036scroggo   0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
4353965825b97a5809454f5810f7e603cbd02daa036scroggo   0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
4363965825b97a5809454f5810f7e603cbd02daa036scroggo   0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
4373965825b97a5809454f5810f7e603cbd02daa036scroggo   0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
4383965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
4393965825b97a5809454f5810f7e603cbd02daa036scroggo   0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
4403965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
4413965825b97a5809454f5810f7e603cbd02daa036scroggo   0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
4423965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
4433965825b97a5809454f5810f7e603cbd02daa036scroggo   0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
4443965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
4453965825b97a5809454f5810f7e603cbd02daa036scroggo   0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
4463965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
4473965825b97a5809454f5810f7e603cbd02daa036scroggo   0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
4483965825b97a5809454f5810f7e603cbd02daa036scroggo   0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
4493965825b97a5809454f5810f7e603cbd02daa036scroggo   0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
4503965825b97a5809454f5810f7e603cbd02daa036scroggo};
4513965825b97a5809454f5810f7e603cbd02daa036scroggo
4523965825b97a5809454f5810f7e603cbd02daa036scroggo/* Swaps pixel packing order within bytes */
4533965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */
4543965825b97a5809454f5810f7e603cbd02daa036scroggopng_do_packswap(png_row_infop row_info, png_bytep row)
4553965825b97a5809454f5810f7e603cbd02daa036scroggo{
4563965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_do_packswap");
4573965825b97a5809454f5810f7e603cbd02daa036scroggo
4583965825b97a5809454f5810f7e603cbd02daa036scroggo   if (row_info->bit_depth < 8)
4593965825b97a5809454f5810f7e603cbd02daa036scroggo   {
4603965825b97a5809454f5810f7e603cbd02daa036scroggo      png_bytep rp;
4613965825b97a5809454f5810f7e603cbd02daa036scroggo      png_const_bytep end, table;
4623965825b97a5809454f5810f7e603cbd02daa036scroggo
4633965825b97a5809454f5810f7e603cbd02daa036scroggo      end = row + row_info->rowbytes;
4643965825b97a5809454f5810f7e603cbd02daa036scroggo
4653965825b97a5809454f5810f7e603cbd02daa036scroggo      if (row_info->bit_depth == 1)
4663965825b97a5809454f5810f7e603cbd02daa036scroggo         table = onebppswaptable;
4673965825b97a5809454f5810f7e603cbd02daa036scroggo
4683965825b97a5809454f5810f7e603cbd02daa036scroggo      else if (row_info->bit_depth == 2)
4693965825b97a5809454f5810f7e603cbd02daa036scroggo         table = twobppswaptable;
4703965825b97a5809454f5810f7e603cbd02daa036scroggo
4713965825b97a5809454f5810f7e603cbd02daa036scroggo      else if (row_info->bit_depth == 4)
4723965825b97a5809454f5810f7e603cbd02daa036scroggo         table = fourbppswaptable;
4733965825b97a5809454f5810f7e603cbd02daa036scroggo
4743965825b97a5809454f5810f7e603cbd02daa036scroggo      else
4753965825b97a5809454f5810f7e603cbd02daa036scroggo         return;
4763965825b97a5809454f5810f7e603cbd02daa036scroggo
4773965825b97a5809454f5810f7e603cbd02daa036scroggo      for (rp = row; rp < end; rp++)
4783965825b97a5809454f5810f7e603cbd02daa036scroggo         *rp = table[*rp];
4793965825b97a5809454f5810f7e603cbd02daa036scroggo   }
4803965825b97a5809454f5810f7e603cbd02daa036scroggo}
4813965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* PACKSWAP || WRITE_PACKSWAP */
4823965825b97a5809454f5810f7e603cbd02daa036scroggo
4833965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
4843965825b97a5809454f5810f7e603cbd02daa036scroggo    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
4853965825b97a5809454f5810f7e603cbd02daa036scroggo/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
4863965825b97a5809454f5810f7e603cbd02daa036scroggo * somewhat weird combination of flags to determine what to do.  All the calls
4873965825b97a5809454f5810f7e603cbd02daa036scroggo * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
4883965825b97a5809454f5810f7e603cbd02daa036scroggo * correct arguments.
4893965825b97a5809454f5810f7e603cbd02daa036scroggo *
4903965825b97a5809454f5810f7e603cbd02daa036scroggo * The routine isn't general - the channel must be the channel at the start or
4913965825b97a5809454f5810f7e603cbd02daa036scroggo * end (not in the middle) of each pixel.
4923965825b97a5809454f5810f7e603cbd02daa036scroggo */
4933965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */
4943965825b97a5809454f5810f7e603cbd02daa036scroggopng_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
4953965825b97a5809454f5810f7e603cbd02daa036scroggo{
4963965825b97a5809454f5810f7e603cbd02daa036scroggo   png_bytep sp = row; /* source pointer */
4973965825b97a5809454f5810f7e603cbd02daa036scroggo   png_bytep dp = row; /* destination pointer */
4983965825b97a5809454f5810f7e603cbd02daa036scroggo   png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
4993965825b97a5809454f5810f7e603cbd02daa036scroggo
5003965825b97a5809454f5810f7e603cbd02daa036scroggo   /* At the start sp will point to the first byte to copy and dp to where
5013965825b97a5809454f5810f7e603cbd02daa036scroggo    * it is copied to.  ep always points just beyond the end of the row, so
5023965825b97a5809454f5810f7e603cbd02daa036scroggo    * the loop simply copies (channels-1) channels until sp reaches ep.
5033965825b97a5809454f5810f7e603cbd02daa036scroggo    *
5043965825b97a5809454f5810f7e603cbd02daa036scroggo    * at_start:        0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
5053965825b97a5809454f5810f7e603cbd02daa036scroggo    *            nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
5063965825b97a5809454f5810f7e603cbd02daa036scroggo    */
5073965825b97a5809454f5810f7e603cbd02daa036scroggo
5083965825b97a5809454f5810f7e603cbd02daa036scroggo   /* GA, GX, XG cases */
5093965825b97a5809454f5810f7e603cbd02daa036scroggo   if (row_info->channels == 2)
5103965825b97a5809454f5810f7e603cbd02daa036scroggo   {
5113965825b97a5809454f5810f7e603cbd02daa036scroggo      if (row_info->bit_depth == 8)
5123965825b97a5809454f5810f7e603cbd02daa036scroggo      {
5133965825b97a5809454f5810f7e603cbd02daa036scroggo         if (at_start != 0) /* Skip initial filler */
5143965825b97a5809454f5810f7e603cbd02daa036scroggo            ++sp;
5153965825b97a5809454f5810f7e603cbd02daa036scroggo         else          /* Skip initial channel and, for sp, the filler */
5163965825b97a5809454f5810f7e603cbd02daa036scroggo            sp += 2, ++dp;
5173965825b97a5809454f5810f7e603cbd02daa036scroggo
5183965825b97a5809454f5810f7e603cbd02daa036scroggo         /* For a 1 pixel wide image there is nothing to do */
5193965825b97a5809454f5810f7e603cbd02daa036scroggo         while (sp < ep)
5203965825b97a5809454f5810f7e603cbd02daa036scroggo            *dp++ = *sp, sp += 2;
5213965825b97a5809454f5810f7e603cbd02daa036scroggo
5223965825b97a5809454f5810f7e603cbd02daa036scroggo         row_info->pixel_depth = 8;
5233965825b97a5809454f5810f7e603cbd02daa036scroggo      }
5243965825b97a5809454f5810f7e603cbd02daa036scroggo
5253965825b97a5809454f5810f7e603cbd02daa036scroggo      else if (row_info->bit_depth == 16)
5263965825b97a5809454f5810f7e603cbd02daa036scroggo      {
5273965825b97a5809454f5810f7e603cbd02daa036scroggo         if (at_start != 0) /* Skip initial filler */
5283965825b97a5809454f5810f7e603cbd02daa036scroggo            sp += 2;
5293965825b97a5809454f5810f7e603cbd02daa036scroggo         else          /* Skip initial channel and, for sp, the filler */
5303965825b97a5809454f5810f7e603cbd02daa036scroggo            sp += 4, dp += 2;
5313965825b97a5809454f5810f7e603cbd02daa036scroggo
5323965825b97a5809454f5810f7e603cbd02daa036scroggo         while (sp < ep)
5333965825b97a5809454f5810f7e603cbd02daa036scroggo            *dp++ = *sp++, *dp++ = *sp, sp += 3;
5343965825b97a5809454f5810f7e603cbd02daa036scroggo
5353965825b97a5809454f5810f7e603cbd02daa036scroggo         row_info->pixel_depth = 16;
5363965825b97a5809454f5810f7e603cbd02daa036scroggo      }
5373965825b97a5809454f5810f7e603cbd02daa036scroggo
5383965825b97a5809454f5810f7e603cbd02daa036scroggo      else
5393965825b97a5809454f5810f7e603cbd02daa036scroggo         return; /* bad bit depth */
5403965825b97a5809454f5810f7e603cbd02daa036scroggo
5413965825b97a5809454f5810f7e603cbd02daa036scroggo      row_info->channels = 1;
5423965825b97a5809454f5810f7e603cbd02daa036scroggo
5433965825b97a5809454f5810f7e603cbd02daa036scroggo      /* Finally fix the color type if it records an alpha channel */
5443965825b97a5809454f5810f7e603cbd02daa036scroggo      if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
5453965825b97a5809454f5810f7e603cbd02daa036scroggo         row_info->color_type = PNG_COLOR_TYPE_GRAY;
5463965825b97a5809454f5810f7e603cbd02daa036scroggo   }
5473965825b97a5809454f5810f7e603cbd02daa036scroggo
5483965825b97a5809454f5810f7e603cbd02daa036scroggo   /* RGBA, RGBX, XRGB cases */
5493965825b97a5809454f5810f7e603cbd02daa036scroggo   else if (row_info->channels == 4)
5503965825b97a5809454f5810f7e603cbd02daa036scroggo   {
5513965825b97a5809454f5810f7e603cbd02daa036scroggo      if (row_info->bit_depth == 8)
5523965825b97a5809454f5810f7e603cbd02daa036scroggo      {
5533965825b97a5809454f5810f7e603cbd02daa036scroggo         if (at_start != 0) /* Skip initial filler */
5543965825b97a5809454f5810f7e603cbd02daa036scroggo            ++sp;
5553965825b97a5809454f5810f7e603cbd02daa036scroggo         else          /* Skip initial channels and, for sp, the filler */
5563965825b97a5809454f5810f7e603cbd02daa036scroggo            sp += 4, dp += 3;
5573965825b97a5809454f5810f7e603cbd02daa036scroggo
5583965825b97a5809454f5810f7e603cbd02daa036scroggo         /* Note that the loop adds 3 to dp and 4 to sp each time. */
5593965825b97a5809454f5810f7e603cbd02daa036scroggo         while (sp < ep)
5603965825b97a5809454f5810f7e603cbd02daa036scroggo            *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
5613965825b97a5809454f5810f7e603cbd02daa036scroggo
5623965825b97a5809454f5810f7e603cbd02daa036scroggo         row_info->pixel_depth = 24;
5633965825b97a5809454f5810f7e603cbd02daa036scroggo      }
5643965825b97a5809454f5810f7e603cbd02daa036scroggo
5653965825b97a5809454f5810f7e603cbd02daa036scroggo      else if (row_info->bit_depth == 16)
5663965825b97a5809454f5810f7e603cbd02daa036scroggo      {
5673965825b97a5809454f5810f7e603cbd02daa036scroggo         if (at_start != 0) /* Skip initial filler */
5683965825b97a5809454f5810f7e603cbd02daa036scroggo            sp += 2;
5693965825b97a5809454f5810f7e603cbd02daa036scroggo         else          /* Skip initial channels and, for sp, the filler */
5703965825b97a5809454f5810f7e603cbd02daa036scroggo            sp += 8, dp += 6;
5713965825b97a5809454f5810f7e603cbd02daa036scroggo
5723965825b97a5809454f5810f7e603cbd02daa036scroggo         while (sp < ep)
5733965825b97a5809454f5810f7e603cbd02daa036scroggo         {
5743965825b97a5809454f5810f7e603cbd02daa036scroggo            /* Copy 6 bytes, skip 2 */
5753965825b97a5809454f5810f7e603cbd02daa036scroggo            *dp++ = *sp++, *dp++ = *sp++;
5763965825b97a5809454f5810f7e603cbd02daa036scroggo            *dp++ = *sp++, *dp++ = *sp++;
5773965825b97a5809454f5810f7e603cbd02daa036scroggo            *dp++ = *sp++, *dp++ = *sp, sp += 3;
5783965825b97a5809454f5810f7e603cbd02daa036scroggo         }
5793965825b97a5809454f5810f7e603cbd02daa036scroggo
5803965825b97a5809454f5810f7e603cbd02daa036scroggo         row_info->pixel_depth = 48;
5813965825b97a5809454f5810f7e603cbd02daa036scroggo      }
5823965825b97a5809454f5810f7e603cbd02daa036scroggo
5833965825b97a5809454f5810f7e603cbd02daa036scroggo      else
5843965825b97a5809454f5810f7e603cbd02daa036scroggo         return; /* bad bit depth */
5853965825b97a5809454f5810f7e603cbd02daa036scroggo
5863965825b97a5809454f5810f7e603cbd02daa036scroggo      row_info->channels = 3;
5873965825b97a5809454f5810f7e603cbd02daa036scroggo
5883965825b97a5809454f5810f7e603cbd02daa036scroggo      /* Finally fix the color type if it records an alpha channel */
5893965825b97a5809454f5810f7e603cbd02daa036scroggo      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
5903965825b97a5809454f5810f7e603cbd02daa036scroggo         row_info->color_type = PNG_COLOR_TYPE_RGB;
5913965825b97a5809454f5810f7e603cbd02daa036scroggo   }
5923965825b97a5809454f5810f7e603cbd02daa036scroggo
5933965825b97a5809454f5810f7e603cbd02daa036scroggo   else
5943965825b97a5809454f5810f7e603cbd02daa036scroggo      return; /* The filler channel has gone already */
5953965825b97a5809454f5810f7e603cbd02daa036scroggo
5963965825b97a5809454f5810f7e603cbd02daa036scroggo   /* Fix the rowbytes value. */
5973965825b97a5809454f5810f7e603cbd02daa036scroggo   row_info->rowbytes = dp-row;
5983965825b97a5809454f5810f7e603cbd02daa036scroggo}
5993965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
6003965825b97a5809454f5810f7e603cbd02daa036scroggo
6013965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
6023965825b97a5809454f5810f7e603cbd02daa036scroggo/* Swaps red and blue bytes within a pixel */
6033965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */
6043965825b97a5809454f5810f7e603cbd02daa036scroggopng_do_bgr(png_row_infop row_info, png_bytep row)
6053965825b97a5809454f5810f7e603cbd02daa036scroggo{
6063965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_do_bgr");
6073965825b97a5809454f5810f7e603cbd02daa036scroggo
6083965825b97a5809454f5810f7e603cbd02daa036scroggo   if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
6093965825b97a5809454f5810f7e603cbd02daa036scroggo   {
6103965825b97a5809454f5810f7e603cbd02daa036scroggo      png_uint_32 row_width = row_info->width;
6113965825b97a5809454f5810f7e603cbd02daa036scroggo      if (row_info->bit_depth == 8)
6123965825b97a5809454f5810f7e603cbd02daa036scroggo      {
6133965825b97a5809454f5810f7e603cbd02daa036scroggo         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
6143965825b97a5809454f5810f7e603cbd02daa036scroggo         {
6153965825b97a5809454f5810f7e603cbd02daa036scroggo            png_bytep rp;
6163965825b97a5809454f5810f7e603cbd02daa036scroggo            png_uint_32 i;
6173965825b97a5809454f5810f7e603cbd02daa036scroggo
6183965825b97a5809454f5810f7e603cbd02daa036scroggo            for (i = 0, rp = row; i < row_width; i++, rp += 3)
6193965825b97a5809454f5810f7e603cbd02daa036scroggo            {
6203965825b97a5809454f5810f7e603cbd02daa036scroggo               png_byte save = *rp;
6213965825b97a5809454f5810f7e603cbd02daa036scroggo               *rp = *(rp + 2);
6223965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 2) = save;
6233965825b97a5809454f5810f7e603cbd02daa036scroggo            }
6243965825b97a5809454f5810f7e603cbd02daa036scroggo         }
6253965825b97a5809454f5810f7e603cbd02daa036scroggo
6263965825b97a5809454f5810f7e603cbd02daa036scroggo         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
6273965825b97a5809454f5810f7e603cbd02daa036scroggo         {
6283965825b97a5809454f5810f7e603cbd02daa036scroggo            png_bytep rp;
6293965825b97a5809454f5810f7e603cbd02daa036scroggo            png_uint_32 i;
6303965825b97a5809454f5810f7e603cbd02daa036scroggo
6313965825b97a5809454f5810f7e603cbd02daa036scroggo            for (i = 0, rp = row; i < row_width; i++, rp += 4)
6323965825b97a5809454f5810f7e603cbd02daa036scroggo            {
6333965825b97a5809454f5810f7e603cbd02daa036scroggo               png_byte save = *rp;
6343965825b97a5809454f5810f7e603cbd02daa036scroggo               *rp = *(rp + 2);
6353965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 2) = save;
6363965825b97a5809454f5810f7e603cbd02daa036scroggo            }
6373965825b97a5809454f5810f7e603cbd02daa036scroggo         }
6383965825b97a5809454f5810f7e603cbd02daa036scroggo      }
6393965825b97a5809454f5810f7e603cbd02daa036scroggo
6403965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_16BIT_SUPPORTED
6413965825b97a5809454f5810f7e603cbd02daa036scroggo      else if (row_info->bit_depth == 16)
6423965825b97a5809454f5810f7e603cbd02daa036scroggo      {
6433965825b97a5809454f5810f7e603cbd02daa036scroggo         if (row_info->color_type == PNG_COLOR_TYPE_RGB)
6443965825b97a5809454f5810f7e603cbd02daa036scroggo         {
6453965825b97a5809454f5810f7e603cbd02daa036scroggo            png_bytep rp;
6463965825b97a5809454f5810f7e603cbd02daa036scroggo            png_uint_32 i;
6473965825b97a5809454f5810f7e603cbd02daa036scroggo
6483965825b97a5809454f5810f7e603cbd02daa036scroggo            for (i = 0, rp = row; i < row_width; i++, rp += 6)
6493965825b97a5809454f5810f7e603cbd02daa036scroggo            {
6503965825b97a5809454f5810f7e603cbd02daa036scroggo               png_byte save = *rp;
6513965825b97a5809454f5810f7e603cbd02daa036scroggo               *rp = *(rp + 4);
6523965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 4) = save;
6533965825b97a5809454f5810f7e603cbd02daa036scroggo               save = *(rp + 1);
6543965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 1) = *(rp + 5);
6553965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 5) = save;
6563965825b97a5809454f5810f7e603cbd02daa036scroggo            }
6573965825b97a5809454f5810f7e603cbd02daa036scroggo         }
6583965825b97a5809454f5810f7e603cbd02daa036scroggo
6593965825b97a5809454f5810f7e603cbd02daa036scroggo         else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
6603965825b97a5809454f5810f7e603cbd02daa036scroggo         {
6613965825b97a5809454f5810f7e603cbd02daa036scroggo            png_bytep rp;
6623965825b97a5809454f5810f7e603cbd02daa036scroggo            png_uint_32 i;
6633965825b97a5809454f5810f7e603cbd02daa036scroggo
6643965825b97a5809454f5810f7e603cbd02daa036scroggo            for (i = 0, rp = row; i < row_width; i++, rp += 8)
6653965825b97a5809454f5810f7e603cbd02daa036scroggo            {
6663965825b97a5809454f5810f7e603cbd02daa036scroggo               png_byte save = *rp;
6673965825b97a5809454f5810f7e603cbd02daa036scroggo               *rp = *(rp + 4);
6683965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 4) = save;
6693965825b97a5809454f5810f7e603cbd02daa036scroggo               save = *(rp + 1);
6703965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 1) = *(rp + 5);
6713965825b97a5809454f5810f7e603cbd02daa036scroggo               *(rp + 5) = save;
6723965825b97a5809454f5810f7e603cbd02daa036scroggo            }
6733965825b97a5809454f5810f7e603cbd02daa036scroggo         }
6743965825b97a5809454f5810f7e603cbd02daa036scroggo      }
6753965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
6763965825b97a5809454f5810f7e603cbd02daa036scroggo   }
6773965825b97a5809454f5810f7e603cbd02daa036scroggo}
6783965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* READ_BGR || WRITE_BGR */
6793965825b97a5809454f5810f7e603cbd02daa036scroggo
6803965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
6813965825b97a5809454f5810f7e603cbd02daa036scroggo    defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
6823965825b97a5809454f5810f7e603cbd02daa036scroggo/* Added at libpng-1.5.10 */
6833965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */
6843965825b97a5809454f5810f7e603cbd02daa036scroggopng_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
6853965825b97a5809454f5810f7e603cbd02daa036scroggo{
6863965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
6873965825b97a5809454f5810f7e603cbd02daa036scroggo      png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
6883965825b97a5809454f5810f7e603cbd02daa036scroggo   {
6893965825b97a5809454f5810f7e603cbd02daa036scroggo      /* Calculations moved outside switch in an attempt to stop different
6903965825b97a5809454f5810f7e603cbd02daa036scroggo       * compiler warnings.  'padding' is in *bits* within the last byte, it is
6913965825b97a5809454f5810f7e603cbd02daa036scroggo       * an 'int' because pixel_depth becomes an 'int' in the expression below,
6923965825b97a5809454f5810f7e603cbd02daa036scroggo       * and this calculation is used because it avoids warnings that other
6933965825b97a5809454f5810f7e603cbd02daa036scroggo       * forms produced on either GCC or MSVC.
6943965825b97a5809454f5810f7e603cbd02daa036scroggo       */
6953965825b97a5809454f5810f7e603cbd02daa036scroggo      int padding = (-row_info->pixel_depth * row_info->width) & 7;
6963965825b97a5809454f5810f7e603cbd02daa036scroggo      png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
6973965825b97a5809454f5810f7e603cbd02daa036scroggo
6983965825b97a5809454f5810f7e603cbd02daa036scroggo      switch (row_info->bit_depth)
6993965825b97a5809454f5810f7e603cbd02daa036scroggo      {
7003965825b97a5809454f5810f7e603cbd02daa036scroggo         case 1:
7013965825b97a5809454f5810f7e603cbd02daa036scroggo         {
7023965825b97a5809454f5810f7e603cbd02daa036scroggo            /* in this case, all bytes must be 0 so we don't need
7033965825b97a5809454f5810f7e603cbd02daa036scroggo             * to unpack the pixels except for the rightmost one.
7043965825b97a5809454f5810f7e603cbd02daa036scroggo             */
7053965825b97a5809454f5810f7e603cbd02daa036scroggo            for (; rp > png_ptr->row_buf; rp--)
7063965825b97a5809454f5810f7e603cbd02daa036scroggo            {
7073965825b97a5809454f5810f7e603cbd02daa036scroggo              if ((*rp >> padding) != 0)
7083965825b97a5809454f5810f7e603cbd02daa036scroggo                 png_ptr->num_palette_max = 1;
7093965825b97a5809454f5810f7e603cbd02daa036scroggo              padding = 0;
7103965825b97a5809454f5810f7e603cbd02daa036scroggo            }
7113965825b97a5809454f5810f7e603cbd02daa036scroggo
7123965825b97a5809454f5810f7e603cbd02daa036scroggo            break;
7133965825b97a5809454f5810f7e603cbd02daa036scroggo         }
7143965825b97a5809454f5810f7e603cbd02daa036scroggo
7153965825b97a5809454f5810f7e603cbd02daa036scroggo         case 2:
7163965825b97a5809454f5810f7e603cbd02daa036scroggo         {
7173965825b97a5809454f5810f7e603cbd02daa036scroggo            for (; rp > png_ptr->row_buf; rp--)
7183965825b97a5809454f5810f7e603cbd02daa036scroggo            {
7193965825b97a5809454f5810f7e603cbd02daa036scroggo              int i = ((*rp >> padding) & 0x03);
7203965825b97a5809454f5810f7e603cbd02daa036scroggo
7213965825b97a5809454f5810f7e603cbd02daa036scroggo              if (i > png_ptr->num_palette_max)
7223965825b97a5809454f5810f7e603cbd02daa036scroggo                 png_ptr->num_palette_max = i;
7233965825b97a5809454f5810f7e603cbd02daa036scroggo
7243965825b97a5809454f5810f7e603cbd02daa036scroggo              i = (((*rp >> padding) >> 2) & 0x03);
7253965825b97a5809454f5810f7e603cbd02daa036scroggo
7263965825b97a5809454f5810f7e603cbd02daa036scroggo              if (i > png_ptr->num_palette_max)
7273965825b97a5809454f5810f7e603cbd02daa036scroggo                 png_ptr->num_palette_max = i;
7283965825b97a5809454f5810f7e603cbd02daa036scroggo
7293965825b97a5809454f5810f7e603cbd02daa036scroggo              i = (((*rp >> padding) >> 4) & 0x03);
7303965825b97a5809454f5810f7e603cbd02daa036scroggo
7313965825b97a5809454f5810f7e603cbd02daa036scroggo              if (i > png_ptr->num_palette_max)
7323965825b97a5809454f5810f7e603cbd02daa036scroggo                 png_ptr->num_palette_max = i;
7333965825b97a5809454f5810f7e603cbd02daa036scroggo
7343965825b97a5809454f5810f7e603cbd02daa036scroggo              i = (((*rp >> padding) >> 6) & 0x03);
7353965825b97a5809454f5810f7e603cbd02daa036scroggo
7363965825b97a5809454f5810f7e603cbd02daa036scroggo              if (i > png_ptr->num_palette_max)
7373965825b97a5809454f5810f7e603cbd02daa036scroggo                 png_ptr->num_palette_max = i;
7383965825b97a5809454f5810f7e603cbd02daa036scroggo
7393965825b97a5809454f5810f7e603cbd02daa036scroggo              padding = 0;
7403965825b97a5809454f5810f7e603cbd02daa036scroggo            }
7413965825b97a5809454f5810f7e603cbd02daa036scroggo
7423965825b97a5809454f5810f7e603cbd02daa036scroggo            break;
7433965825b97a5809454f5810f7e603cbd02daa036scroggo         }
7443965825b97a5809454f5810f7e603cbd02daa036scroggo
7453965825b97a5809454f5810f7e603cbd02daa036scroggo         case 4:
7463965825b97a5809454f5810f7e603cbd02daa036scroggo         {
7473965825b97a5809454f5810f7e603cbd02daa036scroggo            for (; rp > png_ptr->row_buf; rp--)
7483965825b97a5809454f5810f7e603cbd02daa036scroggo            {
7493965825b97a5809454f5810f7e603cbd02daa036scroggo              int i = ((*rp >> padding) & 0x0f);
7503965825b97a5809454f5810f7e603cbd02daa036scroggo
7513965825b97a5809454f5810f7e603cbd02daa036scroggo              if (i > png_ptr->num_palette_max)
7523965825b97a5809454f5810f7e603cbd02daa036scroggo                 png_ptr->num_palette_max = i;
7533965825b97a5809454f5810f7e603cbd02daa036scroggo
7543965825b97a5809454f5810f7e603cbd02daa036scroggo              i = (((*rp >> padding) >> 4) & 0x0f);
7553965825b97a5809454f5810f7e603cbd02daa036scroggo
7563965825b97a5809454f5810f7e603cbd02daa036scroggo              if (i > png_ptr->num_palette_max)
7573965825b97a5809454f5810f7e603cbd02daa036scroggo                 png_ptr->num_palette_max = i;
7583965825b97a5809454f5810f7e603cbd02daa036scroggo
7593965825b97a5809454f5810f7e603cbd02daa036scroggo              padding = 0;
7603965825b97a5809454f5810f7e603cbd02daa036scroggo            }
7613965825b97a5809454f5810f7e603cbd02daa036scroggo
7623965825b97a5809454f5810f7e603cbd02daa036scroggo            break;
7633965825b97a5809454f5810f7e603cbd02daa036scroggo         }
7643965825b97a5809454f5810f7e603cbd02daa036scroggo
7653965825b97a5809454f5810f7e603cbd02daa036scroggo         case 8:
7663965825b97a5809454f5810f7e603cbd02daa036scroggo         {
7673965825b97a5809454f5810f7e603cbd02daa036scroggo            for (; rp > png_ptr->row_buf; rp--)
7683965825b97a5809454f5810f7e603cbd02daa036scroggo            {
7693965825b97a5809454f5810f7e603cbd02daa036scroggo               if (*rp > png_ptr->num_palette_max)
7703965825b97a5809454f5810f7e603cbd02daa036scroggo                  png_ptr->num_palette_max = (int) *rp;
7713965825b97a5809454f5810f7e603cbd02daa036scroggo            }
7723965825b97a5809454f5810f7e603cbd02daa036scroggo
7733965825b97a5809454f5810f7e603cbd02daa036scroggo            break;
7743965825b97a5809454f5810f7e603cbd02daa036scroggo         }
7753965825b97a5809454f5810f7e603cbd02daa036scroggo
7763965825b97a5809454f5810f7e603cbd02daa036scroggo         default:
7773965825b97a5809454f5810f7e603cbd02daa036scroggo            break;
7783965825b97a5809454f5810f7e603cbd02daa036scroggo      }
7793965825b97a5809454f5810f7e603cbd02daa036scroggo   }
7803965825b97a5809454f5810f7e603cbd02daa036scroggo}
7813965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* CHECK_FOR_INVALID_INDEX */
7823965825b97a5809454f5810f7e603cbd02daa036scroggo
7833965825b97a5809454f5810f7e603cbd02daa036scroggo#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
7843965825b97a5809454f5810f7e603cbd02daa036scroggo    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
7853965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
7863965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI
7873965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_user_transform_info(png_structrp png_ptr, png_voidp
7883965825b97a5809454f5810f7e603cbd02daa036scroggo   user_transform_ptr, int user_transform_depth, int user_transform_channels)
7893965825b97a5809454f5810f7e603cbd02daa036scroggo{
7903965825b97a5809454f5810f7e603cbd02daa036scroggo   png_debug(1, "in png_set_user_transform_info");
7913965825b97a5809454f5810f7e603cbd02daa036scroggo
7923965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
7933965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
7943965825b97a5809454f5810f7e603cbd02daa036scroggo
7953965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
7963965825b97a5809454f5810f7e603cbd02daa036scroggo   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
7973965825b97a5809454f5810f7e603cbd02daa036scroggo      (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
7983965825b97a5809454f5810f7e603cbd02daa036scroggo   {
7993965825b97a5809454f5810f7e603cbd02daa036scroggo      png_app_error(png_ptr,
8003965825b97a5809454f5810f7e603cbd02daa036scroggo            "info change after png_start_read_image or png_read_update_info");
8013965825b97a5809454f5810f7e603cbd02daa036scroggo      return;
8023965825b97a5809454f5810f7e603cbd02daa036scroggo   }
8033965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
8043965825b97a5809454f5810f7e603cbd02daa036scroggo
8053965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->user_transform_ptr = user_transform_ptr;
8063965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->user_transform_depth = (png_byte)user_transform_depth;
8073965825b97a5809454f5810f7e603cbd02daa036scroggo   png_ptr->user_transform_channels = (png_byte)user_transform_channels;
8083965825b97a5809454f5810f7e603cbd02daa036scroggo}
8093965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
8103965825b97a5809454f5810f7e603cbd02daa036scroggo
8113965825b97a5809454f5810f7e603cbd02daa036scroggo/* This function returns a pointer to the user_transform_ptr associated with
8123965825b97a5809454f5810f7e603cbd02daa036scroggo * the user transform functions.  The application should free any memory
8133965825b97a5809454f5810f7e603cbd02daa036scroggo * associated with this pointer before png_write_destroy and png_read_destroy
8143965825b97a5809454f5810f7e603cbd02daa036scroggo * are called.
8153965825b97a5809454f5810f7e603cbd02daa036scroggo */
8163965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
8173965825b97a5809454f5810f7e603cbd02daa036scroggopng_voidp PNGAPI
8183965825b97a5809454f5810f7e603cbd02daa036scroggopng_get_user_transform_ptr(png_const_structrp png_ptr)
8193965825b97a5809454f5810f7e603cbd02daa036scroggo{
8203965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr == NULL)
8213965825b97a5809454f5810f7e603cbd02daa036scroggo      return (NULL);
8223965825b97a5809454f5810f7e603cbd02daa036scroggo
8233965825b97a5809454f5810f7e603cbd02daa036scroggo   return png_ptr->user_transform_ptr;
8243965825b97a5809454f5810f7e603cbd02daa036scroggo}
8253965825b97a5809454f5810f7e603cbd02daa036scroggo#endif
8263965825b97a5809454f5810f7e603cbd02daa036scroggo
8273965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
8283965825b97a5809454f5810f7e603cbd02daa036scroggopng_uint_32 PNGAPI
8293965825b97a5809454f5810f7e603cbd02daa036scroggopng_get_current_row_number(png_const_structrp png_ptr)
8303965825b97a5809454f5810f7e603cbd02daa036scroggo{
8313965825b97a5809454f5810f7e603cbd02daa036scroggo   /* See the comments in png.h - this is the sub-image row when reading an
8323965825b97a5809454f5810f7e603cbd02daa036scroggo    * interlaced image.
8333965825b97a5809454f5810f7e603cbd02daa036scroggo    */
8343965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr != NULL)
8353965825b97a5809454f5810f7e603cbd02daa036scroggo      return png_ptr->row_number;
8363965825b97a5809454f5810f7e603cbd02daa036scroggo
8373965825b97a5809454f5810f7e603cbd02daa036scroggo   return PNG_UINT_32_MAX; /* help the app not to fail silently */
8383965825b97a5809454f5810f7e603cbd02daa036scroggo}
8393965825b97a5809454f5810f7e603cbd02daa036scroggo
8403965825b97a5809454f5810f7e603cbd02daa036scroggopng_byte PNGAPI
8413965825b97a5809454f5810f7e603cbd02daa036scroggopng_get_current_pass_number(png_const_structrp png_ptr)
8423965825b97a5809454f5810f7e603cbd02daa036scroggo{
8433965825b97a5809454f5810f7e603cbd02daa036scroggo   if (png_ptr != NULL)
8443965825b97a5809454f5810f7e603cbd02daa036scroggo      return png_ptr->pass;
8453965825b97a5809454f5810f7e603cbd02daa036scroggo   return 8; /* invalid */
8463965825b97a5809454f5810f7e603cbd02daa036scroggo}
8473965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* USER_TRANSFORM_INFO */
8483965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
8493965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* READ || WRITE */
850