
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
 *
 * Last changed in libpng 1.7.0 [(PENDING RELEASE)]
 * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
 *
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
 */
#include "pngpriv.h"
#define PNG_SRC_FILE PNG_SRC_FILE_pngtrans

#ifdef _XOPEN_SOURCE
#  include <unistd.h>
#endif /* for swab */

/* Memory format enquiries */
#ifdef PNG_GAMMA_SUPPORTED
static png_fixed_point
memory_gamma(png_const_structrp png_ptr)
{
#  ifdef PNG_READ_GAMMA_SUPPORTED
#     ifdef PNG_TRANSFORM_MECH_SUPPORTED
         if (png_ptr->read_struct)
            return png_ptr->row_gamma;
#     endif /* TRANSFORM_MECH */
#  endif /* READ_GAMMA */

   /* Else either no READ_GAMMA support or this is a write struct; in both
    * cases there are no gamma transforms.  In the write case the set of the
    * gamma in the info may not have been copied to the png_struct.
    */
#  if defined(PNG_GAMMA_SUPPORTED) && defined(PNG_READ_SUPPORTED)
      if ((png_ptr->colorspace.flags &
            (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
         PNG_COLORSPACE_HAVE_GAMMA)
         return png_ptr->colorspace.gamma;
#  else /* !(GAMMA && READ) */
      PNG_UNUSED(png_ptr)
#  endif /* !(GAMMA && READ) */

   /* '0' means the value is not know: */
   return 0;
}
#endif /* GAMMA */

unsigned int PNGAPI
png_memory_format(png_structrp png_ptr)
{
   /* The in-memory format as a bitmask of PNG_FORMAT_FLAG_ values.  All the
    * flags listed below are used.  If PNG_FORMAT_FLAG_INVALID is set the
    * following caveats apply to the interpretation of PNG_FORMAT_FLAG_LINEAR:
    *
    *    The gamma may differ from the sRGB (!LINEAR) or 1.0 (LINEAR).  Call
    *    png_memory_gamma to find the correct value.
    *
    *    The channel depth may differ from 8 (!LINEAR) or 16 (LINEAR).  Call
    *    png_memory_channel_depth to find the correct value.
    *
    * It is only valid to call these APIS *after* either png_read_update_info
    * or png_start_read_image on read or after the first row of an image has
    * been written on write.
    */
   if (png_ptr != NULL)
   {
#     ifdef PNG_TRANSFORM_MECH_SUPPORTED
         unsigned int format = png_ptr->row_format;
#     else /* !TRANSFORM_MECH */
         unsigned int format = PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type);
#     endif /* !TRANSFORM_MECH */

      if (png_ptr->read_struct) /* else no way to find the gamma! */
      {
#        ifdef PNG_GAMMA_SUPPORTED
#           ifdef PNG_TRANSFORM_MECH_SUPPORTED
               unsigned int bit_depth = png_ptr->row_bit_depth;
#           else /* !TRANSFORM_MECH */
               unsigned int bit_depth = png_ptr->bit_depth;
#           endif /* !TRANSFORM_MECH */

            /* Now work out whether this is a valid simplified API format. */
            switch (bit_depth)
            {
               case 8U:
                  {
                     png_fixed_point gamma = memory_gamma(png_ptr);

                     if (!PNG_GAMMA_IS_sRGB(gamma))
                        format |= PNG_FORMAT_FLAG_INVALID;
                  }
                  break;

               case 16:
                  if (memory_gamma(png_ptr) == PNG_GAMMA_LINEAR)
                  {
                     static const union
                     {
                        png_uint_16 u16;
                        png_byte    u8[2];
                     } sex = { 1U };

                     format |= PNG_FORMAT_FLAG_LINEAR;

                     /* But the memory layout of the 16-bit quantities must also
                      * match; we need swapped data on LSB platforms.
                      */
                     if (sex.u8[0] == ((format & PNG_FORMAT_FLAG_SWAPPED) != 0))
                        break; /* ok */
                  }

                  /* FALL THROUGH*/
               default: /* bit depth not supported for simplified API */
                  format |= PNG_FORMAT_FLAG_INVALID;
                  break;
            }
#        else /* !GAMMA */
            /* We have no way of knowing if the gamma value matches that
             * expected by the simplified API so mark the format as invalid:
             */
            format |= PNG_FORMAT_FLAG_INVALID;
#        endif
      } /* read_struct */

      return format;
   }

   return 0;
}

unsigned int PNGAPI png_memory_channel_depth(png_structrp png_ptr)
{
   /* The actual depth of each channel in the image. */
   if (png_ptr != NULL)
   {
#     ifdef PNG_TRANSFORM_MECH_SUPPORTED
         return png_ptr->row_bit_depth;
#     else
         return png_ptr->bit_depth;
#     endif
   }

   return 0;
}

#ifdef PNG_GAMMA_SUPPORTED
png_fixed_point PNGAPI
png_memory_gamma(png_structrp png_ptr)
{
   /* The actual gamma of the image data, scaled by 100,000.  This is the
    * encoding gamma, e.g. 1/2.2 for sRGB.  If the gamma is unknown this will
    * return 0.
    *
    * On write this invariably returns 0; libpng does not change the gamma of
    * the data on write.
    *
    * Note that this is not always the exact inverse of the 'screen gamma'
    * passed to png_set_gamma; internal optimizations remove attempts to make
    * small changes to the gamma value.  This function returns the actual
    * output value.
    */
   return (png_ptr != NULL) ? memory_gamma(png_ptr) : 0;
}
#endif /* GAMMA */

/* These are general purpose APIs that deal with the row buffer format in both
 * the read and write case.  The png_struct::row_* members describe the
 * in-memory format of the image data based on the transformations requested by
 * the application.
 */
#ifdef PNG_TRANSFORM_MECH_SUPPORTED
png_voidp /* PRIVATE */
png_transform_cast_check(png_const_structp png_ptr, unsigned int src_line,
   png_transformp tr, size_t size)
{
   /* Given a pointer to a transform, 'tr' validate that the underlying derived
    * class has size 'size' using the tr->size field and return the same
    * pointer.  If there is a size mismatch the function does an affirm using
    * the given line number.
    */
   if (tr->size != size)
      png_affirm(png_ptr, param_deb("transform upcast") src_line);

   return tr;
}

void /* PRIAVE */
png_transform_free(png_const_structrp png_ptr, png_transformp *list)
{
   if (*list != NULL)
   {
      png_transform_free(png_ptr, &(*list)-> next);
      if ((*list)->free != NULL)
         (*list)->free(png_ptr, *list);
      png_free(png_ptr, *list);
      *list = NULL;
   }
}

/* Utility to initialize a png_transform_control for read or write. */
void /* PRIVATE */
png_init_transform_control(png_transform_controlp tc, png_structp png_ptr)
{
   png_byte bd; /* bit depth of the row */
   png_byte cd; /* bit depth of color information */

   memset(tc, 0, sizeof *tc);
   tc->png_ptr = png_ptr; /* ALIAS */
   tc->sp = tc->dp = NULL;
   tc->width = 0;

#  ifdef PNG_READ_GAMMA_SUPPORTED
      /* The file gamma is set by png_set_gamma, as well as being read from the
       * input PNG gAMA chunk, if present, we don't have a png_info so can't get
       * the set_gAMA value but this doesn't matter because on read the gamma
       * value is in png_struct::colorspace and on write it isn't used.
       */
      if ((png_ptr->colorspace.flags &
            (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
         PNG_COLORSPACE_HAVE_GAMMA)
      {
         tc->gamma = png_ptr->colorspace.gamma;
         debug(tc->gamma > 0);
      }

      else
      {
         /* There is no input gamma, so there should be no overall gamma
          * correction going on.  This test works because the various things
          * that set an output gamma also default the input gamma.
          */
         debug(png_ptr->row_gamma == 0);
      }
#  endif

   /* Validate bit depth and color type here */
   cd = bd = png_ptr->bit_depth;

   switch (png_ptr->color_type)
   {
      case PNG_COLOR_TYPE_GRAY:
         affirm(bd == 1U || bd == 2U || bd == 4U || bd == 8U || bd == 16U);
         tc->format = 0U;
         break;

      case PNG_COLOR_TYPE_PALETTE:
         affirm(bd == 1U || bd == 2U || bd == 4U || bd == 8U);
         tc->format = PNG_FORMAT_FLAG_COLORMAP | PNG_FORMAT_FLAG_COLOR;
         cd = 8U;
         break;

      case PNG_COLOR_TYPE_GRAY_ALPHA:
         affirm(bd == 8U || bd == 16U);
         tc->format = PNG_FORMAT_FLAG_ALPHA;
         break;

      case PNG_COLOR_TYPE_RGB:
         affirm(bd == 8U || bd == 16U);
         tc->format = PNG_FORMAT_FLAG_COLOR;
         break;

      case PNG_COLOR_TYPE_RGB_ALPHA:
         affirm(bd == 8U || bd == 16U);
         tc->format = PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_ALPHA;
         break;

      default:
         impossible("PNG color type");
   }

   tc->bit_depth = bd;
   tc->range = 0;

   /* Preset the sBIT data to full precision/handled. */
   tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A = cd;
#  ifdef PNG_READ_sBIT_SUPPORTED
      {
         int handled = 1;

         if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
         {
            png_byte c = png_ptr->sig_bit.red;
            if (c > 0 && c < cd)
            {
               tc->sBIT_R = c;
               handled = 0;
            }

            c = png_ptr->sig_bit.green;
            if (c > 0 && c < cd)
            {
               tc->sBIT_G = c;
               handled = 0;
            }

            c = png_ptr->sig_bit.blue;
            if (c > 0 && c < cd)
            {
               tc->sBIT_B = c;
               handled = 0;
            }
         }

         else /* grayscale */
         {
            png_byte c = png_ptr->sig_bit.gray;
            if (c > 0 && c < cd)
            {
               tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = c;
               handled = 0;
            }
         }

         /* The palette-mapped format doesn't store alpha information, an
          * omission in the spec that is difficult to fix.  Notice that
          * 'handled' is not cleared below, this is because the alpha channel is
          * always linear, so the sBIT_A value can always be treated as a
          * precision value.
          */
         if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
         {
            png_byte c = png_ptr->sig_bit.alpha;
            if (c > 0 && c < cd)
               tc->sBIT_A = c;
         }

         /* If 'handled' did not get cleared there is no sBIT information. */
         if (handled)
            tc->invalid_info = PNG_INFO_sBIT;
      }
#  else /* !READ_sBIT */
      /* No sBIT information */
      tc->invalid_info = PNG_INFO_sBIT;
#  endif /* !READ_sBIT */
}

png_transformp /*PRIVATE*/
png_add_transform(png_structrp png_ptr, size_t size, png_transform_fn fn,
   unsigned int order)
{
   /* Add a transform.  This is a minimal implementation; the order is just
    * controlled by 'order', the result is a point to the new transform, or
    * to an existing one if one was already in the list.
    */
   png_transformp *p = &png_ptr->transform_list;

   while (*p != NULL && (*p)->order < order)
      p = &(*p)->next;

   if (size == 0)
      size = sizeof (png_transform);

   else
      affirm(size >= sizeof (png_transform));

   if (*p == NULL || (*p)->order > order)
   {
      png_transformp t;

      t = png_voidcast(png_transformp, png_malloc(png_ptr, size));
      memset(t, 0, size); /* zeros out the extra data too */
      /* *p comes after the new entry, t: */
      t->next = *p;
      t->fn = fn;
      t->free = NULL;
      t->order = order;
      t->size = 0xFFFFU & size;
      *p = t;
      return t;
   }

   else /* (*p)->order matches order, return *p */
   {
       affirm((*p)->fn == fn && (*p)->order == order && (*p)->size == size);
       return *p;
   }
}

png_transformp /* PRIVATE */
png_push_transform(png_structrp png_ptr, size_t size, png_transform_fn fn,
   png_transformp *transform, png_transform_controlp tc)
{
   png_transformp tr = *transform;
   unsigned int order = tr->order;

   /* Basic loop detection: */
   affirm(fn != NULL && tr->fn != fn);

   /* Move the following transforms up: */
   {
      unsigned int old_order = order;

      do
      {
         tr->order = ++old_order;
         tr = tr->next;
      }
      while (tr != NULL && tr->order == old_order);

      affirm(tr == NULL || tr->order > old_order);
   }

   *transform = png_add_transform(png_ptr, size, fn, order);

   if (tc != NULL)
      fn(transform, tc);

   return *transform;
}

#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
static png_transformp
png_find_transform(png_const_structrp png_ptr, unsigned int order)
   /* Find a transform with the given order, or return NULL.  Currently only
    * used here.
    */
{
   png_transformp p = png_ptr->transform_list;

   for (;;)
   {
      if (p == NULL || p->order > order)
         return NULL;

      if (p->order == order)
         return p;

      p = p->next;
   }
}
#endif /* USER_TRANSFORM_PTR */

static void
remove_transform(png_const_structp png_ptr, png_transformp *transform)
   /* Remove a transform on a running list */
{
   png_transformp tp = *transform;
   png_transformp next = tp->next;

   *transform = next;
   tp->next = NULL;
   png_transform_free(png_ptr, &tp);
}

#ifdef PNG_READ_TRANSFORMS_SUPPORTED
void /* PRIVATE */
png_remove_transform(png_const_structp png_ptr, png_transformp *transform)
{
   remove_transform(png_ptr, transform);
}
#endif /* READ_TRANSFORMS */

static unsigned int
run_transform_list_forwards(png_transform_controlp tc, png_transformp *start,
   png_transformp end/*NULL for whole list*/)
   /* Called from the init code and below, the caller must initialize 'tc' */
{
   png_const_structp png_ptr = tc->png_ptr;
   unsigned int max_depth = PNG_TC_PIXEL_DEPTH(*tc);

   /* Caller guarantees that *start is non-NULL */
   debug(*start != NULL);

   do
   {
      if ((*start)->fn != NULL)
         (*start)->fn(start, tc);

      if ((*start)->fn == NULL) /* delete this transform */
         remove_transform(png_ptr, start);

      else
      {
         /* Handle the initialization of the maximum pixel depth. */
         unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(*tc);

         if (tc_depth > max_depth)
            max_depth = tc_depth;

         /* Advance to the next transform. */
         start = &(*start)->next;
      }
   }
   while (*start != NULL && *start != end);

   /* This only goes wrong if 'end' was non-NULL and not in the list: */
   debug(*start == end);

   return max_depth;
}

#ifdef PNG_READ_TRANSFORMS_SUPPORTED
unsigned int /* PRIVATE */
png_run_this_transform_list_forwards(png_transform_controlp tc,
   png_transformp *start, png_transformp end)
{
   return run_transform_list_forwards(tc, start, end);
}
#endif /* READ_TRANSFORMS */

#ifdef PNG_READ_SUPPORTED
unsigned int /* PRIVATE */
png_run_transform_list_forwards(png_structp png_ptr, png_transform_controlp tc)
{
   if (png_ptr->transform_list != NULL)
      return run_transform_list_forwards(tc, &png_ptr->transform_list, NULL);

   else
      return PNG_PIXEL_DEPTH(*png_ptr);
}
#endif /* READ */

#ifdef PNG_WRITE_SUPPORTED /* only used from pngwrite.c */
static unsigned int
run_transform_list_backwards(png_transform_controlp tc, png_transformp *list)
{
   png_const_structp png_ptr = tc->png_ptr;
   unsigned int max_depth = 0;

   if ((*list)->next != NULL)
      max_depth = run_transform_list_backwards(tc, &(*list)->next);

   /* Note that the above might change (*list)->next, but it can't change
    * *list itself.
    */
   if ((*list)->fn != NULL)
      (*list)->fn(list, tc);

   /* If that set 'fn' to NULL this transform must be removed; this is how
    * (*list)->next gets changed in our caller:
    */
   if ((*list)->fn == NULL)
      remove_transform(png_ptr, list);

   else
   {
      unsigned int depth = PNG_TC_PIXEL_DEPTH(*tc);

      if (depth > max_depth)
         max_depth = depth;
   }

   return max_depth;
}

void /* PRIVATE */
png_run_transform_list_backwards(png_structp png_ptr, png_transform_controlp tc)
{
   if (png_ptr->transform_list != NULL)
   {
      /* This doesn't take account of the base PNG depth, but that shouldn't
       * matter, it's just a check:
       */
      unsigned int max_depth =
         run_transform_list_backwards(tc, &png_ptr->transform_list);

      /* Better late than never (if this fires a memory overwrite has happened):
       */
      affirm(max_depth <= png_ptr->row_max_pixel_depth);
   }
}
#endif /* WRITE */

static unsigned int
init_transform_mech(png_structrp png_ptr, png_transform_control *tc, int start)
   /* Called each time to run the transform list once during initialization. */
{
   png_init_transform_control(tc, png_ptr);
   tc->init = start ? PNG_TC_INIT_FORMAT : PNG_TC_INIT_FINAL;
#  ifdef PNG_READ_TRANSFORMS_SUPPORTED
      if (png_ptr->read_struct)
         return png_read_init_transform_mech(png_ptr, tc);
      else
#  endif
   return run_transform_list_forwards(tc, &png_ptr->transform_list, NULL);
}
#endif /* TRANSFORM_MECH */

#ifdef PNG_PALETTE_MAX_SUPPORTED
static int
set_palette_max(png_structrp png_ptr, png_transformp tr, unsigned int max,
      unsigned int format_max)
   /* Called whenever a new maximum pixel value is found */
{
   /* One of these must be true: */
#  ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
      if (max >= (tr->args & 0x1FFU) && !png_ptr->palette_index_check_issued)
      {
         /* In 1.7 only issue the error/warning by default; the 'check' API is
          * used to enable/disable the check.  Assume that if the app enabled it
          * then the app will be checking the result with get_palette_max in
          * read.  In write an error results unless the check is disabled.
          */
         if (png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT
#           ifdef PNG_WRITE_SUPPORTED
               || (!png_ptr->read_struct &&
                   png_ptr->palette_index_check != PNG_PALETTE_CHECK_OFF)
#           endif /* WRITE */
            )
#           ifdef PNG_READ_SUPPORTED
#              ifdef PNG_WRITE_SUPPORTED
                  (png_ptr->read_struct ? png_chunk_benign_error : png_error)
#              else /* !WRITE */
                  png_chunk_benign_error
#              endif /* READ */
#           else /* !READ */
               png_error
#           endif /* WRITE */
               (png_ptr, "palette index too large");

         png_ptr->palette_index_check_issued = 1;
      }
#  endif
#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
      png_ptr->palette_index_max = png_check_byte(png_ptr, max);
#  endif

   if (max == format_max)
   {
      tr->fn = NULL; /* no point continuing once the max has been seen */
      return 1; /* stop */
   }

   return 0; /* keep going */
}

static void
palette_max_1bpp(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_uint_32 width = tc->width;

   while (width >= 8)
   {
      if (*sp++) break;
      width -= 8;
   }

   if (width < 8)
   {
      if (width == 0 ||
          (*sp & (((1U<<width)-1U) << (8-width))) == 0)
         return; /* no '1' pixels */
   }

   /* If the code reaches this point there is a set pixel */
   (void)set_palette_max(tc->png_ptr, *tr, 1U, 1U);
}

static void
palette_max_2bpp(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_uint_32 width = tc->width;
   const png_uint_32 args = (*tr)->args;
   unsigned int max = args >> 24; /* saved maximum */

   while (width > 0)
   {
      png_uint_32 input = 0U, test;
      unsigned int new_max;

      /* This just skips 0 bytes: */
      while (width > 0)
      {
         unsigned int next = *sp++;

         /* There may be partial pixels at the end, just remove the absent
          * pixels with a right shift:
          */
         if (width >= 4)
            width -= 4;
         else
            next >>= (4U-width) * 2U, width = 0;

         if (next)
         {
            input = (input << 8) | next;
            if ((input & 0xFF000000U) != 0)
               break;
         }
      }

      test = input & 0xAAAAAAAAU;

      if (test != 0)
      {
         if ((input & (test >> 1)) != 0)
            new_max = 3U; /* both bits set in at least one pixel */

         else if (max < 2U)
            new_max = 2U;

         else
            continue; /* no change to max */
      }

      else /* test is 0 */ if (input != 0 && max == 0)
         new_max = 1U;

      else /* input is 0, or max is at least 1 */
         continue;

      /* new_max is greater than max: */
      if (set_palette_max(tc->png_ptr, *tr, new_max, 3U))
         return;

      /* Record new_max: */
      max = new_max;
   }

   /* End of input, check the next line. */
   (*tr)->args = (max << 24) + (args & 0xFFFFFFU);
}

static void
palette_max_4bpp(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_uint_32 width = tc->width;
   const png_uint_32 args = (*tr)->args;
   unsigned int max = args >> 24; /* saved maximum */

   while (width > 0)
   {
      unsigned int input = *sp++;

      if (width >= 2)
         width -= 2;
      else
         input >>= 1, width = 0;

      if ((input & 0xFU) > max)
         max = input & 0xFU;

      if (((input >> 4) & 0xFU) > max)
         max = (input >> 4) & 0xFU;
   }

   if (max > (args >> 24))
   {
      if (set_palette_max(tc->png_ptr, *tr, max, 15U))
         return;

      (*tr)->args = (max << 24) + (args & 0xFFFFFFU);
   }
}

static void
palette_max_8bpp(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_uint_32 width = tc->width;
   const png_uint_32 args = (*tr)->args;
   unsigned int max = args >> 24; /* saved maximum */

   while (width > 0)
   {
      unsigned int input = *sp++;

      if (input > max)
         max = input;

      --width;
   }

   if (max > (args >> 24))
   {
      if (set_palette_max(tc->png_ptr, *tr, max, 255U))
         return;

      (*tr)->args = (max << 24) + (args & 0xFFFFFFU);
   }
}

static void
palette_max_init(png_transformp *tr, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   affirm((tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0);
   debug(tc->init);

   if (tc->init == PNG_TC_INIT_FINAL)
   {
      /* Record the palette depth to check here along with the running total
       * in the top 8 bits (initially 0, which is always valid).
       */
      (*tr)->args = png_ptr->num_palette;

      switch (tc->bit_depth)
      {
         case 1: (*tr)->fn = palette_max_1bpp; break;
         case 2: (*tr)->fn = palette_max_2bpp; break;
         case 4: (*tr)->fn = palette_max_4bpp; break;
         case 8: (*tr)->fn = palette_max_8bpp; break;
         default:impossible("palette bit depth");
      }

      png_ptr->palette_index_have_max = 1U;
   }
#  undef png_ptr
}
#endif /* PALETTE_MAX */

#ifdef PNG_GET_PALETTE_MAX_SUPPORTED
int PNGAPI
png_get_palette_max(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
   if (png_ptr != NULL && png_ptr->palette_index_have_max)
      return png_ptr->palette_index_max;

   /* This indicates to the caller that the information is not available: */
   return -1;
   PNG_UNUSED(info_ptr)
}
#endif /* GET_PALETTE_MAX */

void /* PRIVATE */
png_init_row_info(png_structrp png_ptr)
{
   /* PNG pixels never exceed 64 bits in depth: */
   const png_byte png_depth =
      png_check_bits(png_ptr, PNG_PIXEL_DEPTH(*png_ptr), 7U);

#  ifdef PNG_TRANSFORM_MECH_SUPPORTED
      /* The palette index check stuff is *on* automatically.  To handle this
       * add it here, if it is supported.
       */
#     ifdef PNG_PALETTE_MAX_SUPPORTED
         /* The logic here is a little complex because of the plethora of
          * #defines controlling this stuff.
          */
         if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE/* fast escape */ && (
#           if defined (PNG_READ_GET_PALETTE_MAX_SUPPORTED) ||\
               defined (PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED)
               (png_ptr->read_struct
#              ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
                  && (png_ptr->palette_index_check == PNG_PALETTE_CHECK_ON ||
                      (png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT
                       && png_ptr->num_palette < (1U << png_ptr->bit_depth)))
#              endif /* READ_CHECK_FOR_INVALID_INDEX */
               )
#           else /* no READ support */
               0
#           endif /* READ checks */
            ||
#           if defined (PNG_WRITE_GET_PALETTE_MAX_SUPPORTED) ||\
               defined (PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
               (!png_ptr->read_struct
#              ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
                  && (png_ptr->palette_index_check == PNG_PALETTE_CHECK_ON ||
                      (png_ptr->palette_index_check == PNG_PALETTE_CHECK_DEFAULT
                       && png_ptr->num_palette < (1U << png_ptr->bit_depth)))
#              endif /* WRITE_CHECK_FOR_INVALID_INDEX */
               )
#           else /* no WRITE support */
               0
#           endif /* WRITE checks */
            ))
            png_add_transform(png_ptr, 0/*size*/, palette_max_init,
               PNG_TR_CHECK_PALETTE);
#     endif

      /* Application transforms may change the format of the data or, when
       * producing interlaced images, the number of pixels in a line.  This code
       * determines the maximum pixel depth required and allows transformations
       * a chance to initialize themselves.
       */
      if (png_ptr->transform_list != NULL)
      {
         png_transform_control tc;

         (void)init_transform_mech(png_ptr, &tc, 1/*start*/);

         png_ptr->row_format = png_check_bits(png_ptr, tc.format, PNG_RF_BITS);
         affirm(tc.bit_depth <= 32);
         png_ptr->row_bit_depth = png_check_bits(png_ptr, tc.bit_depth, 6);
         png_ptr->row_range = png_check_bits(png_ptr, tc.range, 3);
#        ifdef PNG_READ_GAMMA_SUPPORTED
            png_ptr->row_gamma = tc.gamma;
#        endif /* READ_GAMMA */

         /* The above may have cancelled all the transforms in the list. */
         if (png_ptr->transform_list != NULL)
         {
            /* Run the transform list again, also forward, and accumulate the
             * maximum pixel depth.  At this point the transforms can swap
             * out their initialization code.
             */
            unsigned int max_depth =
               init_transform_mech(png_ptr, &tc, 0/*final*/);

            /* init_transform_mech is expected to take the input depth into
             * account:
             */
            debug(max_depth >= png_depth);
            if (max_depth < png_depth)
                max_depth = png_depth;
            affirm(max_depth <= (png_ptr->read_struct ? 128U : 64U));

#           ifdef PNG_READ_TRANSFORMS_SUPPORTED
               /* Set this now because it only gets resolved finally at this
                * point.
                */
               png_ptr->invalid_info = tc.invalid_info;
#           endif /* READ_TRANSFORMS */

            /* And check the transform fields: */
            affirm(png_ptr->row_format == tc.format &&
               png_ptr->row_range == tc.range &&
               png_ptr->row_bit_depth == tc.bit_depth);
#           ifdef PNG_READ_GAMMA_SUPPORTED
               affirm(png_ptr->row_gamma == tc.gamma);
#           endif /* READ_GAMMA */

            png_ptr->row_max_pixel_depth =
               png_check_bits(png_ptr, max_depth, 8U);

            /* On 'read' input_depth is the PNG pixel depth and output_depth is
             * the depth of the pixels passed to the application, but on 'write'
             * the transform list is reversed so output_depth is the PNG depth
             * and input_depth the application depth.
             */
            {
               const png_byte app_depth =
                  png_check_bits(png_ptr, PNG_TC_PIXEL_DEPTH(tc), 8U);

               affirm(app_depth <= max_depth);

               if (png_ptr->read_struct)
               {
                  png_ptr->row_input_pixel_depth = png_depth;
                  png_ptr->row_output_pixel_depth = app_depth;
               }

               else
               {
                  png_ptr->row_input_pixel_depth = app_depth;
                  png_ptr->row_output_pixel_depth = png_depth;
               }

               return; /* to skip the default settings below */
            }
         }
      }

      else /* png_ptr->transform_list == NULL */
      {
         png_ptr->row_format = png_check_bits(png_ptr,
            PNG_FORMAT_FROM_COLOR_TYPE(png_ptr->color_type), PNG_RF_BITS);
         png_ptr->row_bit_depth = png_check_bits(png_ptr, png_ptr->bit_depth,
            6);
         png_ptr->row_range = 0;
#        ifdef PNG_READ_GAMMA_SUPPORTED
            if ((png_ptr->colorspace.flags &
                  (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
                 PNG_COLORSPACE_HAVE_GAMMA)
               png_ptr->row_gamma = png_ptr->colorspace.gamma;
#        endif /* READ_GAMMA */
#        ifdef PNG_READ_TRANSFORMS_SUPPORTED
            png_ptr->invalid_info = 0U;
#        endif /* READ_TRANSFORMS */
      }
#  endif /* TRANSFORM_MECH */

   /* We get here if there are no transforms therefore no change to the pixel
    * bit depths.
    */
   png_ptr->row_output_pixel_depth = png_ptr->row_max_pixel_depth =
      png_ptr->row_input_pixel_depth = png_depth;
}

#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
    defined(PNG_WRITE_INTERLACING_SUPPORTED)
int PNGAPI
png_set_interlace_handling(png_structrp png_ptr)
{
   png_debug(1, "in png_set_interlace handling");

   if (png_ptr != 0)
   {
      if (png_ptr->read_struct)
      {
#        ifdef PNG_READ_INTERLACING_SUPPORTED
            if (png_ptr->interlaced)
            {
               png_ptr->do_interlace = 1;
               return PNG_INTERLACE_ADAM7_PASSES;
            }

            return 1;
#        else /* !READ_INTERLACING */
            png_app_error(png_ptr, "no de-interlace support");
            /* return 0 below */
#        endif /* !READ_INTERLACING */
      }

      else /* write */
      {
#        ifdef PNG_WRITE_INTERLACING_SUPPORTED
            if (png_ptr->interlaced)
            {
               png_ptr->do_interlace = 1;
               return PNG_INTERLACE_ADAM7_PASSES;
            }

            return 1;
#        else /* !WRITE_INTERLACING */
            png_app_error(png_ptr, "no interlace support");
            /* return 0 below */
#        endif /* !WRITE_INTERLACING */
      }
   }

   /* API CHANGE: 1.7.0: returns 0 if called with a NULL png_ptr */
   return 0;
}
#endif /* READ_INTERLACING || WRITE_INTERLACING */

#ifdef PNG_MNG_READ_FEATURES_SUPPORTED
/* Undoes intrapixel differencing, this is called immediately after the PNG
 * filter has been undone.
 */
static void
png_do_read_intrapixel_RGB8(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   /* TAKE CARE: dp and sp may be the same, in which case the assignments to *dp
    * are overwriting sp[]
    */
   do
   {
      *dp++ = PNG_BYTE(sp[0] + sp[1]); /* red+green */
      *dp++ = *++sp; /* green */
      *dp++ = PNG_BYTE(sp[0] + sp[1]); /* green+blue */
      sp += 2;
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_do_read_intrapixel_RGBA8(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   do
   {
      *dp++ = PNG_BYTE(sp[0] + sp[1]); /* red+green */
      *dp++ = *++sp; /* green */
      *dp++ = PNG_BYTE(sp[0] + sp[1]); /* green+blue */
      sp += 2;
      *dp++ = *sp++; /* alpha */
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_do_read_intrapixel_RGB16(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   /* The input consists of 16-bit values and, by examination of the code
    * (please, someone, check; I didn't read the spec) the differencing is done
    * against the 16-bit green value.
    */
   do
   {
      unsigned int red   = png_get_uint_16(sp + 0);
      unsigned int green = png_get_uint_16(sp + 2);
      unsigned int blue  = png_get_uint_16(sp + 4);
      sp += 6;

      red  += green;
      blue += green;

      *dp++ = PNG_BYTE(red >> 8);
      *dp++ = PNG_BYTE(red);
      *dp++ = PNG_BYTE(green >> 8);
      *dp++ = PNG_BYTE(green);
      *dp++ = PNG_BYTE(blue >> 8);
      *dp++ = PNG_BYTE(blue);
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_do_read_intrapixel_RGBA16(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   /* As above but copy the alpha over too. */
   do
   {
      unsigned int red   = png_get_uint_16(sp + 0);
      unsigned int green = png_get_uint_16(sp + 2);
      unsigned int blue  = png_get_uint_16(sp + 4);
      sp += 6;

      red  += green;
      blue += green;

      *dp++ = PNG_BYTE(red >> 8);
      *dp++ = PNG_BYTE(red);
      *dp++ = PNG_BYTE(green >> 8);
      *dp++ = PNG_BYTE(green);
      *dp++ = PNG_BYTE(blue >> 8);
      *dp++ = PNG_BYTE(blue);
      *dp++ = *sp++;
      *dp++ = *sp++; /* alpha */
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_init_read_intrapixel(png_transformp *tr, png_transform_controlp tc)
{
   /* Double check the permitted MNG features in case the app turned the feature
    * on then off again.  Also make sure the color type is acceptable; it must
    * be RGB or RGBA.
    */
   png_const_structp png_ptr = tc->png_ptr;

   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
       (png_ptr->filter_method == PNG_INTRAPIXEL_DIFFERENCING) &&
       (tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) ==
         PNG_FORMAT_FLAG_COLOR)
   {
      if (tc->init == PNG_TC_INIT_FINAL) switch (PNG_TC_PIXEL_DEPTH(*tc))
      {
         case 24: (*tr)->fn = png_do_read_intrapixel_RGB8;   break;
         case 32: (*tr)->fn = png_do_read_intrapixel_RGBA8;  break;
         case 48: (*tr)->fn = png_do_read_intrapixel_RGB16;  break;
         case 64: (*tr)->fn = png_do_read_intrapixel_RGBA16; break;
         default: impossible("bit depth");
      }
   }

   else
      (*tr)->fn = NULL;
}
#endif /* MNG_READ_FEATURES_SUPPORTED */

#ifdef PNG_MNG_WRITE_FEATURES_SUPPORTED
/* This is just the forward direction of the above:
 *
 *    red := red - green
 *    blue:= blue- green
 *
 * Alpha is not changed.
 */
static void
png_do_write_intrapixel_RGB8(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   /* TAKE CARE: dp and sp may be the same, in which case the assignments to *dp
    * are overwriting sp[]
    */
   do
   {
      *dp++ = PNG_BYTE(sp[0] - sp[1]); /* red-green */
      *dp++ = *++sp; /* green */
      *dp++ = PNG_BYTE(sp[0] - sp[1]); /* green-blue */
      sp += 2;
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_do_write_intrapixel_RGBA8(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   do
   {
      *dp++ = PNG_BYTE(sp[0] - sp[1]); /* red-green */
      *dp++ = *++sp; /* green */
      *dp++ = PNG_BYTE(sp[0] - sp[1]); /* green-blue */
      sp += 2;
      *dp++ = *sp++; /* alpha */
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_do_write_intrapixel_RGB16(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   do
   {
      unsigned int red   = png_get_uint_16(sp + 0);
      unsigned int green = png_get_uint_16(sp + 2);
      unsigned int blue  = png_get_uint_16(sp + 4);
      sp += 6;

      red  -= green;
      blue -= green;

      *dp++ = PNG_BYTE(red >> 8);
      *dp++ = PNG_BYTE(red);
      *dp++ = PNG_BYTE(green >> 8);
      *dp++ = PNG_BYTE(green);
      *dp++ = PNG_BYTE(blue >> 8);
      *dp++ = PNG_BYTE(blue);
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_do_write_intrapixel_RGBA16(png_transformp *tr, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_uint_32 width = tc->width;

   tc->sp = dp;

   /* As above but copy the alpha over too. */
   do
   {
      unsigned int red   = png_get_uint_16(sp + 0);
      unsigned int green = png_get_uint_16(sp + 2);
      unsigned int blue  = png_get_uint_16(sp + 4);
      sp += 6;

      red  -= green;
      blue -= green;

      *dp++ = PNG_BYTE(red >> 8);
      *dp++ = PNG_BYTE(red);
      *dp++ = PNG_BYTE(green >> 8);
      *dp++ = PNG_BYTE(green);
      *dp++ = PNG_BYTE(blue >> 8);
      *dp++ = PNG_BYTE(blue);
      *dp++ = *sp++;
      *dp++ = *sp++; /* alpha */
   }
   while (--width > 0);

#  define png_ptr (tc->png_ptr)
   UNTESTED
#  undef png_ptr
   PNG_UNUSED(tr)
}

static void
png_init_write_intrapixel(png_transformp *tr, png_transform_controlp tc)
{
   /* Write filter_method 64 (intrapixel differencing) only if:
    *
    * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED, and;
    * 2. Libpng did not write a PNG signature (this filter_method is only
    *    used in PNG datastreams that are embedded in MNG datastreams),
    *    and;
    * 3. The application called png_permit_mng_features with a mask that
    *    included PNG_FLAG_MNG_FILTER_64, and;
    * 4. The filter_method is 64, and;
    * 5. The color_type is RGB or RGBA
    */
   png_const_structp png_ptr = tc->png_ptr;

   if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
       (png_ptr->filter_method == PNG_INTRAPIXEL_DIFFERENCING) &&
       (tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) ==
         PNG_FORMAT_FLAG_COLOR)
   {
      if (tc->init == PNG_TC_INIT_FINAL) switch (PNG_TC_PIXEL_DEPTH(*tc))
      {
         case 24: (*tr)->fn = png_do_write_intrapixel_RGB8;   break;
         case 32: (*tr)->fn = png_do_write_intrapixel_RGBA8;  break;
         case 48: (*tr)->fn = png_do_write_intrapixel_RGB16;  break;
         case 64: (*tr)->fn = png_do_write_intrapixel_RGBA16; break;
         default: impossible("bit depth");
      }
   }

   else
      (*tr)->fn = NULL;
}
#endif /* MNG_WRITE_FEATURES */

#ifdef PNG_MNG_FEATURES_SUPPORTED
png_uint_32 PNGAPI
png_permit_mng_features(png_structrp png_ptr, png_uint_32 mng_features)
{
   if (png_ptr != NULL)
   {
#     ifdef PNG_MNG_READ_FEATURES_SUPPORTED
         if ((mng_features & PNG_FLAG_MNG_FILTER_64) != 0)
            png_add_transform(png_ptr, 0/*size*/, png_init_read_intrapixel,
               PNG_TR_MNG_INTRAPIXEL);
#     else /* !MNG_READ_FEATURES */
         if (png_ptr->read_struct)
         {
            png_app_error(png_ptr, "MNG not supported on read");
            return;
         }
#     endif /* !MNG_READ_FEATURES */

#     ifdef PNG_MNG_WRITE_FEATURES_SUPPORTED
         if ((mng_features & PNG_FLAG_MNG_FILTER_64) != 0)
            png_add_transform(png_ptr, 0/*size*/, png_init_write_intrapixel,
               PNG_TR_MNG_INTRAPIXEL);
#     else /* !MNG_WRITE_FEATURES */
         if (!png_ptr->read_struct)
         {
            png_app_error(png_ptr, "MNG not supported on write");
            return;
         }
#     endif /* !MNG_WRITE_FEATURES */

      return png_ptr->mng_features_permitted =
         mng_features & PNG_ALL_MNG_FEATURES;
   }

   return 0;
}
#endif /* MNG_FEATURES */

#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) ||\
    defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) ||\
    defined(PNG_READ_SWAP_ALPHA_SUPPORTED) ||\
    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) ||\
    defined(PNG_READ_FILLER_SUPPORTED) ||\
    defined(PNG_WRITE_FILLER_SUPPORTED) ||\
    defined(PNG_READ_STRIP_ALPHA_SUPPORTED) ||\
    defined(PNG_READ_STRIP_16_TO_8_SUPPORTED) ||\
    defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) ||\
    defined(PNG_READ_EXPAND_16_SUPPORTED) ||\
    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
/* This is a generic transform which manipulates the bytes in an input row.  The
 * manipulations supported are:
 *
 *    Channel addition (alpha or filler)
 *    Channel removal (alpha or filler)
 *    Channel swaps - RGB to BGR, alpha/filler from last to first and vice versa
 *
 * The output is described in blocks of output pixel size 4-bit codes encoded
 * as follows:
 *
 *    0        Advance the source pointer by the source pixel size, start the
 *             code list again.  This code doesn't actually exist; it is simply
 *             the result of emptying the code list.
 *    1..3     An error (ignored; treated like 0)
 *    4..7     Put filler[code-4] into the output
 *    8..15    Put source byte[code-8] in the output
 *
 * The codes are held in a png_uint_32 parameter.  transform->args is used by
 * the init routine to work out the required codes.  The format change is a mask
 * which is XORed with the tc format.  Note that the init routine works out
 * whether to work from the beginning or end of the row and the codes are always
 * stored LSB first in the order needed.
 */
typedef struct
{
   png_transform tr;
   png_uint_32   codes;      /* As above */
   unsigned int  format;     /* format after transform */
   unsigned int  bit_depth;  /* bit depth after transform */
   png_byte      filler[4];  /* Filler or alpha bytes, LSB first (see below) */
}  png_transform_byte_op;

static void
png_do_byte_ops_up(png_transformp *transform, png_transform_controlp tc)
   /* Row width is unchanged or decreasing */
{
#  define png_ptr (tc->png_ptr)
   png_transform_byte_op *tr =
      png_transform_cast(png_transform_byte_op, *transform);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const unsigned int sp_advance = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);

   debug(tc->bit_depth == 8 || tc->bit_depth == 16);
   debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0);

   tc->sp = tc->dp;
   tc->format = tr->format;
   tc->bit_depth = tr->bit_depth;

   /* 'output' is a 32-byte buffer that is used to delay writes for 16 bytes,
    * avoiding overwrite when source and destination buffers are the same.
    * 'hwm' is either 32 or 16, initially '32', when the byte counter 'i'
    * reaches 'hwm' the last-but-one 16 bytes are written; the bytes
    * [hwm..hwm+15] modulo 32.  hwm is then swapped to hwm+16 mod 32 and i
    * continues to advance.  i is always below hwm.
    *
    * At the end the whole remaining buffer from hwm to i is written.
    */
   {
      const png_uint_32 codes = tr->codes;
      png_uint_32 code = codes;
      unsigned int i, hwm; /* buffer index and high-water-mark */
      png_byte output[32];

      hwm = 32;

      for (i=0;;)
      {
         unsigned int next_code = code & 0xf;

         if (next_code >= 8)
            output[i++] = sp[next_code-8];

         else if (next_code >= 4)
            output[i++] = tr->filler[next_code - 4];

         else /* end code */
         {
            sp += sp_advance;

            if (sp >= ep)
               break; /* i may be == hwm at this point. */

            code = codes;
            continue; /* no ouput produced, skip the check */
         }

         code >>= 4; /* find the next code */

         if (i == hwm)
         {
            hwm &= 0x10U; /* 0 or 16 */
            memcpy(dp, output + hwm, 16);
            dp += 16;
            i = hwm; /* reset i if hwm was 32 */
            /* hwm is only ever 16 or 32: */
            hwm += 16;
         }
      }

      /* Write from hwm to (i-1), the delay means there is always something to
       * write.
       */
      hwm &= 0x10U;
      if (hwm == 16)
      {
         debug(i <= 16);
         memcpy(dp, output + hwm, 16);
         dp += 16;
      }

      if (i > 0)
         memcpy(dp, output, i);

#     ifndef PNG_RELEASE_BUILD
         dp += i;
         /* The macro expansion exceeded the limit on ANSI strings, so split it:
          */
         dp -= PNG_TC_ROWBYTES(*tc);
         debug(dp == tc->dp);
#     endif
   }

   debug(sp == ep);
#  undef png_ptr
}

#ifdef PNG_READ_TRANSFORMS_SUPPORTED
static void
png_do_byte_ops_down(png_transformp *transform, png_transform_controlp tc)
   /* Row width is increasing */
{
#  define png_ptr (tc->png_ptr)
   png_transform_byte_op *tr =
      png_transform_cast(png_transform_byte_op, *transform);
   const png_const_bytep ep = png_voidcast(png_const_bytep, tc->sp);
   const unsigned int sp_advance = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
   png_const_bytep sp = ep + PNG_TC_ROWBYTES(*tc);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_alloc_size_t dest_rowbytes;

   debug(tc->bit_depth == 8U || tc->bit_depth == 16U);
   debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U);

   tc->sp = tc->dp;
   tc->format = tr->format;
   tc->bit_depth = tr->bit_depth;
   dest_rowbytes = PNG_TC_ROWBYTES(*tc);
   dp += dest_rowbytes;

   /* In this case the 32-byte buffer is written downwards with a writes delayed
    * by 16 bytes as before.  'hwm' is lower than i; 0 or 16.
    */
   {
      const png_uint_32 codes = tr->codes;
      png_uint_32 code = codes;
      unsigned int size, hwm, i;
      png_byte output[32] = { 0 };

      /* This catches an empty codes array, which would cause all the input to
       * be skipped and, potentially, a garbage output[] to be written (once) to
       * *dp.
       */
      affirm((codes & 0xFU) >= 4U);

      /* Align the writes to a 16-byte multiple from the start of the
       * destination buffer:
       */
      size = dest_rowbytes & 0xFU;
      if (size == 0U) size = 16U;
      i = size+16U;
      sp -= sp_advance; /* Move 1 pixel back */
      hwm = 0U;

      for (;;)
      {
         unsigned int next_code = code & 0xFU;

         if (next_code >= 8U)
            output[--i] = sp[next_code-8U];

         else if (next_code >= 4U)
            output[--i] = tr->filler[next_code - 4U];

         else /* end code */
         {
            sp -= sp_advance;

            if (sp < ep)
               break;

            code = codes;
            continue; /* no ouput produced, skip the check */
         }

         code >>= 4; /* find the next code */

         if (i == hwm)
         {
            /* A partial copy comes at the beginning to align the copies to a
             * 16-byte boundary.  The bytes to be written are the bytes
             * i+16..(hwm-1) except that the partial buffer may reduce this.
             */
            dp -= size;
            hwm ^= 0x10U; /* == i+16 mod 32 */
            memcpy(dp, output + hwm, size);
            size = 16U;
            if (i == 0U) i = 32U;
         }
      }

      /* The loop above only exits with an exit code, so 'i' has been checked
       * against 'hwm' before and, because of the alignment, i will always be
       * either 16 or 32:
       */
      debug((i == 16U || i == 32U) & (((i & 0x10U)^0x10U) == hwm));
      debug(sp+sp_advance == ep);

      /* At the end the bytes i..(hwm-1) need to be written, with the proviso
       * that 'size' will be less than 16 for short rows.  If 'size' is still a
       * short value then the range to be written is output[i..16+(size-1)],
       * otherwise (size == 16) either this is the first write and a full 32
       * bytes will be written (hwm == 0, i == 32) or 16 bytes need to be
       * written.
       */
      if (size < 16U)
      {
         debug(i == 16U);
         dp -= size;
         memcpy(dp, output + i, size);
      }

      else /* size == 16 */
      {
         debug(size == 16U);

         /* Write i..(hwm-1); 16 or 32 bytes, however if 32 bytes are written
          * they are contiguous and i==0.
          *
          * hwm is 0 or 16, i is 16 or 32, swap 0 and 32:
          */
         if (hwm == 0U) hwm = 32U;
         if (i == 32U) i = 0U;
         affirm(i < hwm);
         debug(hwm == i+16U || (i == 0U && hwm == 32U));

         hwm -= i;
         dp -= hwm;
         memcpy(dp, output+i, hwm);
      }
   }

   debug(dp == png_upcast(png_bytep, tc->dp));

#  undef png_ptr
}
#endif /* READ_TRANSFORMS */

/* 16 bit byte swapping */
static void
png_do_bswap(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_byte_op *tr =
      png_transform_cast(png_transform_byte_op, *transform);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   const png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc);

   tc->format = tr->format;
   tc->bit_depth = tr->bit_depth;
   tc->sp = dp;

#  ifdef _XOPEN_SOURCE
      /* byte swapping often has incredibly fast implementations because of the
       * importance in handling ethernet traffic.  X/Open defines swab() for
       * this purpose and it is widely supported and normally incredibly fast:
       */
      debug((rowbytes & 1) == 0);
      swab(sp, dp, rowbytes);
#  else /* !_XOPEN_SOURCE */
      {
         const png_const_bytep ep = sp + rowbytes - 1;

         while (sp < ep)
         {
            png_byte b0 = *sp++;
            *dp++ = *sp++;
            *dp++ = b0;
         }

         debug(sp == ep+1); /* even number of bytes */
      }
#  endif

   PNG_UNUSED(transform)
#  undef png_ptr
}

/* The following flags, store in tr->args, are set by the relevant PNGAPI
 * png_set calls then resolved below.
 */
#define PNG_BO_STRIP_ALPHA  0x0001U /* Remove an alpha channel (read only) */
#define PNG_BO_CHOP_16_TO_8 0x0002U /* Chop 16-bit to 8-bit channels */
#define PNG_BO_GRAY_TO_RGB  0x0004U /* G <-> RGB; replicate channels */
/* QUANTIZE happens here */
#define PNG_BO_EXPAND_16    0x0008U /* Expand 8-bit channels to 16-bit */
#define PNG_BO_BGR          0x0010U /* RGB <-> BGR */
#define PNG_BO_FILLER       0x0020U /* Add a filler/alpha */
#define PNG_BO_SWAP_ALPHA   0x0040U /* xA <-> Ax; alpha swap */
#define PNG_BO_SWAP_16      0x0080U /* 16-bit channel byte swapping */

/* The following are additional flags to qualify the transforms: */
#define PNG_BO_FILLER_ALPHA 0x4000U /* The filler is an alpha value */
#define PNG_BO_FILLER_FIRST 0x8000U /* The filler comes first */

static void
png_init_byte_ops(png_transformp *transform, png_transform_controlp tc)
{
   /* In the absence of png_set_quantize none of the above operations apply to a
    * palette row except indirectly; they may apply if the palette was expanded,
    * but this happens earlier in the pipeline.
    *
    * In the presence of png_set_quantize the rules are considerably more
    * complex.  In libpng 1.6.0 the following operations occur before
    * png_do_quantize:
    *
    *    PNG_BO_GRAY_TO_RGB (png_do_gray_to_rgb, but only sometimes)
    *    PNG_BO_STRIP_ALPHA (png_do_strip_channel; removes alpha)
    *    encode_alpha
    *    scale_16_to_8
    *    PNG_BO_CHOP_16_TO_8 (png_do_chop)
    *
    * The following occur afterward:
    *
    *    PNG_BO_EXPAND_16 (png_do_expand_16)
    *    PNG_BO_GRAY_TO_RGB (png_do_gray_to_rgb, normally)
    *    PNG_BO_BGR (png_do_bgr)
    *    PNG_BO_FILLER (png_do_read_filler)
    *    PNG_BO_SWAP_ALPHA (png_do_read_swap_alpha)
    *    PNG_BO_SWAP_16 (png_do_swap; 16-bit byte swap)
    *
    * The gray to RGB operation needs to occur early for GA or gray+tRNS images
    * where the pixels are being composed on a non-gray value.  For the moment
    * we assume that if this is necessary the following 'init' code will see RGB
    * at this point.
    *
    * The quantize operation operates only if:
    *
    *    1) tc->bit_depth is 8
    *    2) The color type exactly matches that required by the parameters to
    *       png_set_quantize; it can be RGB, RGBA or palette, but
    *       png_set_quantize (not the init routine) determines this.
    *
    * To avoid needing to know this here the two stage initialization is used
    * with two transforms, one pre-quantization the other post.  In the first
    * stage the correct row format and depth is set up.  In the second stage the
    * pre-quantization transform looks for a post-quantization transform
    * immediately following and, if it exists, transfers its flags to that.
    */
   png_structp png_ptr = tc->png_ptr;
   png_transform_byte_op *tr =
      png_transform_cast(png_transform_byte_op, *transform);
   png_uint_32 args = tr->tr.args;
   const unsigned int png_format = tc->format;
   unsigned int format = png_format; /* memory format */
   const unsigned int png_bit_depth = tc->bit_depth;
   unsigned int bit_depth = png_bit_depth; /* memory bit depth */

   debug(tc->init);

   /* Channel swaps do not occur on COLORMAP format data at present because the
    * COLORMAP is limited to 1 byte per pixel (so there is nothing to
    * manipulate). Likewise for low bit depth gray, however the code below may
    * widen 8-bit gray to RGB.
    */
   if ((png_format & PNG_FORMAT_FLAG_COLORMAP) != 0U || png_bit_depth < 8U)
   {
      tr->tr.fn = NULL;
      return;
   }

   /* This will normally happen in TC_INIT_FORMAT, but if there is a
    * png_do_quantize operation which doesn't apply (this is unlikely) it will
    * happen in TC_INIT_FINAL.
    */
   if (tr->tr.next != NULL && tr->tr.next->order == PNG_TR_CHANNEL_POSTQ)
   {
      debug(tr->tr.order == PNG_TR_CHANNEL_PREQ);

      /* So we can merge this transform into the next one, note that because the
       * PNG_BO_FILLER operation is POSTQ we don't need to copy anything other
       * than the flags.
       */
      debug((args & tr->tr.next->args) == 0U);
      tr->tr.next->args |= args;
      tr->tr.fn = NULL;
      return;
   }

   /* Else compact the flags for this transform - this is done in both
    * TC_INIT_FORMAT and TC_INIT_FINAL because it is safer that way; the copy
    * above shouldn't actually affect the results but might result in TO8 and
    * TO16 cancelling each other because they are in separate transforms before
    * the merge above.
    *
    * QUIET API CHANGE:
    * For compatiblity with earlier versions of libpng these tests need to
    * occur in the same order as the earlier transforms; 'TO8' combined with
    * 'TO16' did actually do something to 16-bit data, however now it just
    * preserves the original bit depth.
    */
   if ((args & PNG_BO_STRIP_ALPHA) != 0U)
   {
      if ((format & PNG_FORMAT_FLAG_ALPHA) != 0U)
         format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);

      else
         args &= PNG_BIC_MASK(PNG_BO_STRIP_ALPHA);
   }

   if ((args & PNG_BO_CHOP_16_TO_8) != 0U)
   {
      /* This is the quiet API CHANGE; in fact it isn't necessary, but it
       * seems likely that requesting both operations is a mistake:
       */
      if ((args & PNG_BO_EXPAND_16) != 0U)
         args &= PNG_BIC_MASK(PNG_BO_CHOP_16_TO_8|PNG_BO_EXPAND_16);

      else if (bit_depth == 16U)
      {
         bit_depth = 8U;

         /* This also makes the tRNS chunk unusable: */
         tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL;
         /* These need further processing: PNG_INFO_sBIT, PNG_INFO_bKGD */
      }

      else
         args &= PNG_BIC_MASK(PNG_BO_CHOP_16_TO_8);
   }

   /* QUANTIZE happens here */

   if ((args & PNG_BO_EXPAND_16) != 0U)
   {
      /* This only does the 8 to 16-bit part of the expansion by multiply by
       * 65535/255 (257) using byte replication.  The cases of low bit depth
       * gray being expanded to 16-bit have to be handled separately.
       */
      if (bit_depth == 8U)
         bit_depth = 16U;

      else
         args &= PNG_BIC_MASK(PNG_BO_EXPAND_16);
   }

   if ((args & PNG_BO_GRAY_TO_RGB) != 0U)
   {
      if ((format & PNG_FORMAT_FLAG_COLOR) == 0U)
         format |= PNG_FORMAT_FLAG_COLOR;

      else
         args &= PNG_BIC_MASK(PNG_BO_GRAY_TO_RGB);
   }

   if ((args & PNG_BO_BGR) != 0U)
   {
      /* This does not happen on colormaps: */
      if ((format & PNG_FORMAT_FLAG_COLOR) != 0U && !tc->palette)
         format |= PNG_FORMAT_FLAG_BGR;

      else
         args &= PNG_BIC_MASK(PNG_BO_BGR);
   }

   if ((args & PNG_BO_FILLER) != 0U)
   {
      if ((format & PNG_FORMAT_FLAG_ALPHA) == 0U)
      {
         format |= PNG_FORMAT_FLAG_ALPHA;
         tc->channel_add = 1U;
         /* And SWAP_ALPHA did not occur, because prior to 1.7.0 the filler op
          * did not set ALPHA in the color type, so use SWAP_ALPHA to handle the
          * before/after filler location.
          *
          * NOTE: this occurs twice, once in TC_START and once in TC_FINAL, but
          * that is ok, the operations are idempotent.
          *
          * For colormaps (tc->palette set) the filler will just end up setting
          * all the tRNS entries and PNG_BO_SWAP_ALPHA will be cancelled below.
          */
         if ((args & PNG_BO_FILLER_FIRST) != 0U)
            args |= PNG_BO_SWAP_ALPHA;

         else
            args &= PNG_BIC_MASK(PNG_BO_SWAP_ALPHA);

         if (!(args & PNG_BO_FILLER_ALPHA)) /* filler is not alpha */
            format |= PNG_FORMAT_FLAG_AFILLER;
      }

      else
         args &= PNG_BIC_MASK(PNG_BO_FILLER);
   }

   if ((args & PNG_BO_SWAP_ALPHA) != 0U)
   {
      /* This does not happen on color maps: */
      if ((format & PNG_FORMAT_FLAG_ALPHA) != 0U && !tc->palette)
         format |= PNG_FORMAT_FLAG_AFIRST;

      else
         args &= PNG_BIC_MASK(PNG_BO_SWAP_ALPHA);
   }

   if ((args & PNG_BO_SWAP_16) != 0U)
   {
      if (bit_depth == 16U)
         format |= PNG_FORMAT_FLAG_SWAPPED;

      else
         args &= PNG_BIC_MASK(PNG_BO_SWAP_16);
   }

   if (args != 0U)
   {
      /* At the end (TC_INIT_FINAL) work out the mapping array using the codes
       * defined above and store the format and bit depth changes (as changes,
       * so they will work either forward or backward).  The filler array must
       * be set up by the png_set API.
       */
      if (tc->init == PNG_TC_INIT_FINAL)
      {
         const unsigned int png_pixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3;

         tc->format = format;
         tc->bit_depth = bit_depth;

         {
            const unsigned int memory_pixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
            unsigned int code_size, src_size;
            int go_down;
            png_byte codes[8];

            /* The codes array maps the PNG format into the memory format
             * assuming the mapping works upwards in the address space.
             * Initially ignore the bit depth and just work on the first four
             * bytes.
             */
            codes[0] = 8U;
            codes[1] = 9U;
            codes[2] = 10U;
            codes[3] = 11U;
            codes[7] = codes[6] = codes[5] = codes[4] = 0U/*error*/;

            /* PNG_BO_STRIP_ALPHA: handled by memory_pixel_size */
            /* PNG_BO_CHOP_16_TO_8: handled below */
            /* PNG_BO_EXPAND_16: handled below */

            if ((args & PNG_BO_GRAY_TO_RGB) != 0U)
            {
               codes[3] = 9U; /* alpha, if present */
               codes[2] = codes[1] = 8U;

#              ifdef PNG_READ_tRNS_SUPPORTED
                  /* Gray to RGB, so copy the tRNS G value into r,g,b: */
                  if (png_ptr->num_trans == 1U)
                     png_ptr->trans_color.blue =
                        png_ptr->trans_color.green =
                        png_ptr->trans_color.red =
                        png_ptr->trans_color.gray;
#              endif /* READ_tRNS */
            }

            /* 'BGR' and gray-to-RGB are mutually exclusive; with gray-to-RGB
             * codes[0] == codes[2] == 8
             */
            else if ((args & PNG_BO_BGR) != 0U)
            {
               codes[0] = 10U;
               codes[2] = 8U;
            }

            if ((args & PNG_BO_FILLER) != 0U)
            {
               /* The filler alway goes after; for a 'before' filler the code
                * above turns on SWAP_ALPHA too.  The gray-to-RGB transform has
                * happened already, so the location of the filler channel is
                * given by 'format':
                */
               if ((format & PNG_FORMAT_FLAG_COLOR) != 0U)
                  codes[3] = 4U; /* low byte of filler */

               else
                  codes[1] = 4U;
            }

            if ((args & PNG_BO_SWAP_ALPHA) != 0U)
            {
               if ((format & PNG_FORMAT_FLAG_COLOR) != 0U)
               {
                  /* BGR may have swapped the early codes. gray-to-RGB may have
                   * set them all to '8':
                   */
                  png_byte acode = codes[3];
                  codes[3] = codes[2];
                  codes[2] = codes[1];
                  codes[1] = codes[0];
                  codes[0] = acode;
               }

               else /* GA format */
                  codes[0] = codes[1], codes[1] = 8U;
            }

            /* PNG_BO_SWAP_16: 16-bit only, handled below */

            /* Now the 16-bit dependent stuff. */
            if ((args & PNG_BO_CHOP_16_TO_8) != 0U)
            {
               /* 16-bit input, 8-bit output, happens before FILLER so the
                * filler must be an 8-bit value.  Apart from a filler code (4 in
                * this case) the code must be adjusted from byte 'x' to byte
                * '2x' to select the MSB of each 16-bit channel.
                *
                * We must use PNG_FORMAT_CHANNELS here because the memory pixel
                * size might (in the future) include a TO16 operation.
                */
               unsigned int i = PNG_FORMAT_CHANNELS(format);

               while (i > 0U)
               {
                  unsigned int code = codes[--i];

                  if (code > 8U) /* 8, 4 need not change */
                     codes[i] = PNG_BYTE(8U+2U*(code-8U));
               }
            }

            if ((args & PNG_BO_EXPAND_16) != 0U)
            {
               /* Don't expect this with CHOP, but it will work, setting the low
                * 8-bits of each 16-bit value to the high bits.
                */
               unsigned int i = PNG_FORMAT_CHANNELS(format);

               while (i > 0U)
               {
                  png_byte code = codes[--i];

                  /* BSWAP is after FILLER, however the data passed in is a
                   * machine native png_uint_16.  We don't know until this init
                   * routine whether the data is an 8 or 16-bit value because we
                   * don't know the full set of transforms the app will apply
                   * when the png_set_filler API is called.
                   *
                   * This means that the data in tr->filler[] needs to have the
                   * low bits in a known place, so the code here puts the low 8
                   * bits in filler[0], code 4.  Hence the following:
                   */
                  if (code == 4U)
                     codes[2U*i/*MSB*/] = 5U, codes[2U*i+1U/*LSB*/] = 4U;

                  else
                     codes[2U*i] = codes[2U*i+1U] = code;
               }

#              ifdef PNG_READ_tRNS_SUPPORTED
                  /* We're just duplicating bytes, so the tRNS chunk can be
                   * maintained if present.  If the tRNS is for a colormap this
                   * produces garbage in trans_color, but it isn't used.
                   */
                  if (png_ptr->num_trans == 1U)
                  {
#                    define TO16(x) x = PNG_UINT_16((x & 0xFFU) * 0x101U)
                     TO16(png_ptr->trans_color.gray);
                     TO16(png_ptr->trans_color.red);
                     TO16(png_ptr->trans_color.green);
                     TO16(png_ptr->trans_color.blue);
#                    undef TO16
                  }
#              endif /* READ_tRNS */
            }

            else if (bit_depth == 16U)
            {
               /* 16-bit input and output. */
               unsigned int i = PNG_FORMAT_CHANNELS(format);

               while (i > 0U)
               {
                  unsigned int code = codes[--i];

                  if (code == 4U) /* as above */
                     codes[2U*i/*MSB*/] = 5U, codes[2U*i+1U/*LSB*/] = 4U;

                  else
                  {
                     codes[2U*i] = PNG_BYTE(8U+2U*(code-8U));
                     codes[2U*i+1U] = PNG_BYTE(8U+2U*(code-8U)+1U);
                  }
               }
            }

            if ((args & PNG_BO_SWAP_16) != 0U)
            {
               /* bswap the memory bytes. */
               unsigned int i;
               png_byte bswap_codes[sizeof codes];

               debug((memory_pixel_size & 1U) == 0U);

               for (i=0U; i<sizeof codes; ++i)
                  bswap_codes[i] = codes[i ^ 1U];

               memcpy(codes, bswap_codes, sizeof codes);
            }

#           ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
               /* Handle the 'write' case; the codes[] array must be inverted,
                * it lists the PNG pixel for each memory pixel, we need it to
                * list the memory pixel for each PNG pixel.
                */
               if (!png_ptr->read_struct)
               {
                  /* There are no write transforms that add data to the PNG
                   * file; the 'filler' transform removes a channel, but that is
                   * the limit of the changes.
                   */
                  unsigned int i = 0U;
                  png_byte write_codes[8U];

                  memset(write_codes, 0, sizeof write_codes);

                  while (i<memory_pixel_size)
                  {
                     unsigned int code = codes[i];

                     if (code >= 8U) /* 8+index of PNG byte */
                        write_codes[code-8U] = PNG_BYTE(8U+i);
                     /* else this is a filler byte to be removed */
                     else
                        debug(code == 4U || code == 5U);

                     ++i;
                  }

                  code_size = png_pixel_size;
                  src_size = memory_pixel_size;
                  tr->format = png_format;
                  tr->bit_depth = png_bit_depth;

                  /* The PNG size should always be <= to the memory size, the
                   * source pointer will be the memory, the destination the PNG
                   * format, so it should always be possible to do the upwards
                   * copy.
                   */
                  go_down = png_pixel_size > memory_pixel_size;
                  affirm(!go_down);
                  memcpy(codes, write_codes, sizeof codes);
               }

               else
#           endif /* WRITE_TRANSFORMS */
            {
               code_size = memory_pixel_size;
               src_size = png_pixel_size;
               tr->format = format;
               tr->bit_depth = bit_depth;
               go_down = png_pixel_size < memory_pixel_size;
            }

            /* Record this for debugging: */
            tr->tr.args = args;

            /* For the same-pixel-size case check for a bswap; this is available
             * in heavily optimized forms and is a common operation (50% of the
             * time) with 16-bit PNG data, particularly given the handling in
             * the simplified API.
             */
            if (!go_down)
            {
               if (memory_pixel_size == png_pixel_size)
               {
                  int the_same = 1;
                  int swapped = (memory_pixel_size & 1) == 0; /* even count */
                  unsigned int i;

                  for (i=0U; i<memory_pixel_size; ++i)
                  {
                     if (codes[i] != 8U+i)
                     {
                        the_same = 0;
                        if (codes[i] != 8U+(i^1U))
                           swapped = 0;
                        if (!swapped)
                           break;
                     }

                     else /* byte is copied, so it can't be swapped! */
                     {
                        swapped = 0;
                        if (!the_same)
                           break;
                     }
                  }

                  /* Use the 'bswap' routine if possible. */
                  if (swapped)
                  {
                     tr->tr.fn = png_do_bswap;
                     return;
                  }

                  else if (the_same)
                     impossible("not reached");
               }

               tr->tr.fn = png_do_byte_ops_up;

               /* Construct the code, forwards: */
               {
                  unsigned int i = code_size;
                  png_uint_32 code = 0U;

                  while (i > 0U)
                  {
                     unsigned int next = codes[--i];

                     code <<= 4U;

                     if ((next >= 8U && next < 8U+src_size) ||
                           next == 4U || next == 5U)
                        code += next;

                     else
                        impossible("invalid code (up)");
                  }

                  tr->codes = code;
               }
            }

            else /* go_down */
#           ifdef PNG_READ_TRANSFORMS_SUPPORTED
               {
                  tr->tr.fn = png_do_byte_ops_down;

                  /* Construct the code, backwards: */
                  {
                     unsigned int i = 0U;
                     png_uint_32 code = 0U;

                     while (i < code_size)
                     {
                        unsigned int next = codes[i++];

                        code <<= 4;

                        if ((next >= 8U && next < 8U+src_size) ||
                              next == 4U || next == 5U)
                           code += next;

                        else
                           impossible("invalid code (down)");
                     }

                     tr->codes = code;
                  }
               }
#           else /* !READ_TRANSFORMS */
               impossible("not reached"); /* because of the affirm above */
#           endif /* !READ_TRANSFORMS */
         }
      }

      else /* TC_INIT_FORMAT: just store modified 'args' */
      {
         tc->format = format;
         tc->bit_depth = bit_depth;
         tr->tr.args = args;
      }
   }

   else /* the transform is not applicable */
      tr->tr.fn = NULL;
}
#endif /* SWAP poo */

#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
static void
png_init_rgb_to_gray_byte_ops(png_transformp *transform,
   png_transform_controlp tc)
{
   /* This just delay initializes the function; all the transform initialization
    * has been done below.
    */
   (*transform)->fn = png_do_byte_ops_up;

   /*  If this happens on a row do the transform immediately: */
   if (!tc->init)
      png_do_byte_ops_up(transform, tc);

   else
   {
      /* This doing the init - update the row information here */
#     define png_ptr (tc->png_ptr)
      png_transform_byte_op *tr =
         png_transform_cast(png_transform_byte_op, *transform);

      debug(tc->bit_depth == 8U || tc->bit_depth == 16U);
      debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U &&
            (tc->format & PNG_FORMAT_FLAG_COLOR) != 0U);

      tc->format = tr->format;
      tc->bit_depth = tr->bit_depth;
#     undef png_ptr
   }
}

void /* PRIVATE */
png_add_rgb_to_gray_byte_ops(png_structrp png_ptr, png_transform_controlp tc,
   unsigned int index, unsigned int order)
   /* Add a byte_ops transform to convert RGB or RGBA data to 'gray' by
    * selecting just the given change [index]  The transform added is added at
    * 'order'.
    */
{
   png_transform_byte_op *tr = png_transform_cast(png_transform_byte_op,
      png_add_transform(png_ptr, sizeof (png_transform_byte_op),
         png_init_rgb_to_gray_byte_ops, order));

   affirm((tc->format & (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_COLORMAP)) ==
            PNG_FORMAT_FLAG_COLOR &&
          index <= 2 && tc->init == PNG_TC_INIT_FINAL);

   tr->format = tc->format & PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);
   tr->bit_depth = tc->bit_depth;

   /* For 1 byte channel [index] plus, maybe, alpha: */
   if (tc->bit_depth == 8)
      tr->codes = 8U + index +
         ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ? (8U+3U) << 4 : 0U);

   else
   {
      affirm(tc->bit_depth == 16);

      /* As above, but two bytes; [2*index] and [2*index+1] */
      index *= 2U;
      tr->codes = (8U + index) + ((9U + index) << 4) +
         ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ?
            ((8U+6U) + ((9U+6U) << 4)) << 8 : 0U);
   }
}
#endif /* READ_RGB_TO_GRAY */

#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) &&\
    defined(PNG_READ_BACKGROUND_SUPPORTED)
void /* PRIVATE */
png_push_gray_to_rgb_byte_ops(png_transformp *transform,
   png_transform_controlp tc)
   /* This is an init-time utility to add appropriate byte ops to expand a
    * grayscale PNG data set to RGB.
    */
{
#  define png_ptr (tc->png_ptr)
   png_transformp tr = png_push_transform(png_ptr,
      sizeof (png_transform_byte_op), png_init_byte_ops, transform, NULL);

   tr->args = PNG_BO_GRAY_TO_RGB;
   debug(tr == *transform);
   png_init_byte_ops(transform, tc);
#  undef png_ptr
}
#endif /* GRAY_TO_RGB && READ_BACKGROUND */

#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
void /* PRIVATE */
png_add_strip_alpha_byte_ops(png_structrp png_ptr)
{
   png_add_transform(png_ptr, sizeof (png_transform_byte_op), png_init_byte_ops,
      PNG_TR_CHANNEL_PREQ)->args |= PNG_BO_STRIP_ALPHA;
}
#endif /* READ_STRIP_ALPHA */

#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
/* Chop 16-bit depth files to 8-bit depth */
void PNGAPI
png_set_strip_16(png_structrp png_ptr)
{
   if (png_ptr != NULL)
      png_add_transform(png_ptr, sizeof (png_transform_byte_op),
         png_init_byte_ops, PNG_TR_CHANNEL_PREQ)->args |=
         PNG_BO_CHOP_16_TO_8;
}
#endif /* READ_STRIP_16_TO_8 */

#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
void PNGAPI
png_set_gray_to_rgb(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
      png_set_expand_gray_1_2_4_to_8(png_ptr);
      png_add_transform(png_ptr, sizeof (png_transform_byte_op),
         png_init_byte_ops, PNG_TR_CHANNEL_PREQ)->args |=
         PNG_BO_GRAY_TO_RGB;
   }
}
#endif /* READ_GRAY_TO_RGB */

/* QUANTIZE */

#ifdef PNG_READ_EXPAND_16_SUPPORTED
/* Expand to 16-bit channels.  PNG_BO_EXPAND_16 also expands the tRNS chunk if
 * it is present, but it requires low bit depth grayscale expanded first.  This
 * must also force palette to RGB.
 */
void PNGAPI
png_set_expand_16(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
      png_set_expand_gray_1_2_4_to_8(png_ptr);
      png_set_palette_to_rgb(png_ptr);
      png_add_transform(png_ptr, sizeof (png_transform_byte_op),
         png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
         PNG_BO_EXPAND_16;
   }
}
#endif /* READ_EXPAND_16 */

#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
void PNGAPI
png_set_bgr(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
#     ifndef PNG_READ_BGR_SUPPORTED
         if (png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_bgr not supported on read");
            return;
         }
#     endif
#     ifndef PNG_WRITE_BGR_SUPPORTED
         if (!png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_bgr not supported on write");
            return;
         }
#     endif

      png_add_transform(png_ptr, sizeof (png_transform_byte_op),
         png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
         PNG_BO_BGR;
   }
}
#endif /* BGR */

#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
/* This includes png_set_filler and png_set_add_alpha.  The only difference
 * between the two is that the latter resulted in PNG_COLOR_MASK_ALPHA being
 * added to the info_ptr color type, if png_read_update_info was called whereas
 * the former did not.
 *
 * Regardless of whether the added channel resulted in the change to the
 * png_info color type, the SWAP_ALPHA transform was not performed, even though
 * it apparently occured after the add, because PNG_COLOR_MASK_ALPHA was never
 * set in the 1.6 'row_info'.
 *
 * Consequently 'SWAP_ALPHA' and 'FILLER' were independent; one or the other
 * would occur depending on the color type (not the number of channels) prior to
 * the two transforms.
 *
 * Prior to 1.7.0 the app could obtain information about the memory format by
 * calling png_read_update_info followed by png_get_color_type and
 * png_get_channels.  The first would return PNG_COLOR_TYPE..._ALPHA if
 * png_set_add_alpha was performed and the base type if png_set_filler was
 * performed, however in both cases png_get_channels would return the extra
 * channel; 2 or 4.
 *
 * The app could also insert a user transform callback and view the color type
 * in the old "row_info" structure, however this resulted in an inconsistent
 * color type because png_set_alpha did not add COLOR_MASK_ALPHA to the color
 * type.
 *
 * Hence API CHANGE: 1.7.0, row transform callbacks now see the same color type
 * as reported by png_get_color_type after png_read_update_info.
 */
/* Add a filler byte on read, or remove a filler or alpha byte on write.
 * The filler type has changed in v0.95 to allow future 2-byte fillers
 * for 48-bit input data, as well as to avoid problems with some compilers
 * that don't like bytes as parameters.
 */
static void
set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc, int alpha)
{
   if (png_ptr != NULL)
   {
      if (filler_loc != PNG_FILLER_BEFORE && filler_loc != PNG_FILLER_AFTER)
      {
         png_app_error(png_ptr, "png_set_filler: invalid filler location");
         return;
      }

#     ifndef PNG_READ_SWAP_SUPPORTED
         if (png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_filler not supported on read");
            return;
         }
#     endif
#     ifndef PNG_WRITE_SWAP_SUPPORTED
         if (!png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_filler not supported on write");
            return;
         }
#     endif

      {
         png_transform_byte_op *tr =
            png_transform_cast(png_transform_byte_op,
               png_add_transform(png_ptr, sizeof (png_transform_byte_op),
                  png_init_byte_ops, PNG_TR_CHANNEL_POSTQ));
         png_uint_32 args = PNG_BO_FILLER;

         if (filler_loc == PNG_FILLER_BEFORE)
            args |= PNG_BO_FILLER_FIRST;

         if (alpha)
            args |= PNG_BO_FILLER_ALPHA;

         tr->tr.args |= args;

         /* The filler must be stored LSByte first: */
         tr->filler[0] = PNG_BYTE(filler >>  0);
         tr->filler[1] = PNG_BYTE(filler >>  8);
         tr->filler[2] = PNG_BYTE(filler >> 16);
         tr->filler[3] = PNG_BYTE(filler >> 24);
      }
   }
}

void PNGAPI
png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
{
   set_filler(png_ptr, filler, filler_loc, 0/*!alpha*/);
}

/* Added to libpng-1.2.7 */
void PNGAPI
png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
{
   set_filler(png_ptr, filler, filler_loc, 1/*alpha*/);
}
#endif /* FILLER */

#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
    defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void PNGAPI
png_set_swap_alpha(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
#     ifndef PNG_READ_SWAP_SUPPORTED
         if (png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_swap_alpha not supported on read");
            return;
         }
#     endif
#     ifndef PNG_WRITE_SWAP_SUPPORTED
         if (!png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_swap_alpha not supported on write");
            return;
         }
#     endif

      png_add_transform(png_ptr, sizeof (png_transform_byte_op),
         png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
         PNG_BO_SWAP_ALPHA;
   }
}
#endif /* SWAP_ALPHA */

#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
void PNGAPI
png_set_swap(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
#     ifndef PNG_READ_SWAP_SUPPORTED
         if (png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_swap not supported on read");
            return;
         }
#     endif
#     ifndef PNG_WRITE_SWAP_SUPPORTED
         if (!png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_swap not supported on write");
            return;
         }
#     endif

      png_add_transform(png_ptr, sizeof (png_transform_byte_op),
         png_init_byte_ops, PNG_TR_CHANNEL_POSTQ)->args |=
         PNG_BO_SWAP_16;
   }
}
#endif /* SWAP */

#if defined(PNG_READ_PACKSWAP_SUPPORTED) ||\
    defined(PNG_WRITE_PACKSWAP_SUPPORTED) ||\
    defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\
    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) ||\
    defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
static png_alloc_size_t
row_align(png_transform_controlp tc)
   /* Utiltity to align the source row (sp) in a transform control; it does this
    * by simply copying it to dp if it is not already aligned.  As a convenience
    * the utility returns the number of bytes in the row.
    */
{
   png_const_structp png_ptr = tc->png_ptr;
   png_const_voidp sp = tc->sp;
   png_voidp dp = tc->dp;
   png_alloc_size_t rowbytes = PNG_TC_ROWBYTES(*tc);

   /* For alignment; if png_alignof is not supported by the compiler this will
    * always do an initial memcpy if the source and destination are not the
    * same.  We can only get here for write; the read case always uses locally
    * allocated buffers, only write reads from the application data directly.
    */
#  ifdef png_alignof
      debug(png_isaligned(dp, png_uint_32));
#  endif
   if (sp != dp && !png_ptr->read_struct && !png_isaligned(sp, png_uint_32))
   {
      UNTESTED
      memcpy(dp, sp, rowbytes);
      tc->sp = dp;
   }

   return rowbytes;
}
#endif /* Stuff that needs row_align */

#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\
    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) ||\
    defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
/* Bit-ops; invert bytes.  This works for mono inverts too because even the low
 * bit depths can be handled as bytes (since there can be no intervening
 * channels).
 */
#define PNG_B_INVERT_MONO  1U
#define PNG_B_INVERT_RGB   2U /* not set, used below */
#define PNG_B_INVERT_ALPHA 4U

typedef struct
{
   png_transform tr;
   unsigned int  step0; /* initial advance on sp and dp */
   unsigned int  step;  /* advance after start */
   png_uint_32   mask;  /* XOR mask */
}  png_transform_bit_op;

static void
png_do_invert_all(png_transformp *transform, png_transform_controlp tc)
{
   const png_const_structp png_ptr = tc->png_ptr;
   /* Invert the whole row, quickly */
   const png_const_voidp dp_end = png_upcast(png_bytep, tc->dp) + row_align(tc);
   png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);
   png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);

   tc->sp = dp;

   if (png_ptr->read_struct)
   {
      tc->format |= PNG_FORMAT_FLAG_RANGE;
      tc->range++;
   }

   else if (--(tc->range) == 0)
      tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE);

   while (png_upcast(void*,dp) < dp_end)
      *dp++ = ~*sp++;

   PNG_UNUSED(transform);
}

static void
png_do_invert_channel(png_transformp *transform, png_transform_controlp tc)
{
   const png_const_structp png_ptr = tc->png_ptr;
   /* Invert just one channel in the row. */
   const png_transform_bit_op * const tr =
      png_transform_cast(png_transform_bit_op, *transform);
   const png_uint_32 mask = tr->mask;
   const unsigned int step = tr->step;
   const unsigned int step0 = tr->step0;
   const png_const_voidp dp_end = png_upcast(png_bytep, tc->dp) + row_align(tc);
   png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);
   png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);

   tc->sp = dp;

   if (png_ptr->read_struct)
   {
      tc->format |= PNG_FORMAT_FLAG_RANGE;
      tc->range++;
   }

   else if (--(tc->range) == 0)
      tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE);

   if (sp == dp || step == 1)
   {
      sp += step0;
      dp += step0;

      while (png_upcast(void*,dp) < dp_end)
         *dp = *sp ^ mask, dp += step, sp += step;
   }

   else /* step == 2, copy required */
   {
      if (step0) /* must be 1 */
         *dp++ = *sp++;

      while (png_upcast(void*,dp) < dp_end)
      {
         *dp++ = *sp++ ^ mask;
         if (!(png_upcast(void*,dp) < dp_end))
            break;
         *dp++ = *sp++;
      }
   }

   PNG_UNUSED(transform);
}

static void
png_init_invert(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_bit_op *tr =
      png_transform_cast(png_transform_bit_op, *transform);
   png_uint_32 invert = tr->tr.args;
   png_uint_32 present; /* channels present */

   if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
      present = 0;

   else /* not color mapped */
   {
      if ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0)
         present = PNG_B_INVERT_RGB;
      else
         present = PNG_B_INVERT_MONO;

      if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0)
         present |= PNG_B_INVERT_ALPHA;
   }

   /* Cannot invert things that aren't there: */
   invert &= present;

   /* If nothing can be inverted is present the transform is not applicable: */
   if (invert == 0)
      (*transform)->fn = NULL;

   else
   {
      tc->format |= PNG_FORMAT_FLAG_RANGE;
      tc->range++;

      if (tc->init == PNG_TC_INIT_FINAL)
      {
         /* If everything that is present is to be inverted just invert the
          * whole row:
          */
         if (invert == present)
            (*transform)->fn = png_do_invert_all;

         else
         {
            /* One thing is to be inverted, G or A: */
            unsigned int channels = PNG_TC_CHANNELS(*tc);
            unsigned int channel =
               (tc->format & PNG_FORMAT_FLAG_AFIRST) != 0 ? 0 : channels-1;

            affirm(channels == 2 || channels == 4);

            if (invert != PNG_B_INVERT_ALPHA)
            {
               debug(invert == PNG_B_INVERT_MONO && channels == 2 &&
                     present == PNG_B_INVERT_MONO+PNG_B_INVERT_ALPHA);
               channel = (channels-1) - channel;
            }

            affirm(tc->bit_depth == 8 || tc->bit_depth == 16);

            /* So channels[channel] is to be inverted, make a mask: */
            {
               union
               {
                  png_byte bytes[8];
                  png_uint_32 words[2];
               } masks;

               memset(&masks, 0, sizeof masks);

               if (tc->bit_depth == 8)
               {
                  /* channels is 2 or 4, channel < 4. */
                  masks.bytes[channel+channels] = masks.bytes[channel] = 0xff;
                  tr->step = 1;
                  tr->mask = masks.words[0];
                  tr->step0 = 0;
               }

               else /* tc->bit_depth == 16 */
               {
                  channel <<= 1; /* in bytes */
                  masks.bytes[channel+1] = masks.bytes[channel] = 0xff;

                  if (channels == 2)
                  {
                     tr->step = 1;
                     tr->mask = masks.words[0];
                     tr->step0 = 0;
                  }

                  else /* channels == 4 */
                  {
                     tr->step = 2;

                     if (masks.words[0] == 0)
                     {
                        tr->mask = masks.words[1];
                        tr->step0 = 1;
                     }

                     else
                     {
                        tr->mask = masks.words[0];
                        tr->step0 = 0;
                     }
                  }
               }
            }

            (*transform)->fn = png_do_invert_channel;
         }
      }
   }
#  undef png_ptr
}

#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) ||\
    defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void PNGAPI
png_set_invert_alpha(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
      png_add_transform(png_ptr, sizeof (png_transform_bit_op),
         png_init_invert, PNG_TR_INVERT)->args |= PNG_B_INVERT_ALPHA;
#     ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
         /* This is necessary to avoid palette processing on write; the only
          * transform that applies to colormapped images is the tRNS chunk
          * invert.
          */
         png_ptr->write_invert_alpha = 1U;
#     endif
   }
}
#endif /* INVERT_ALPHA */

#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
void PNGAPI
png_set_invert_mono(png_structrp png_ptr)
{
   if (png_ptr != NULL)
      png_add_transform(png_ptr, sizeof (png_transform_bit_op),
         png_init_invert, PNG_TR_INVERT)->args |= PNG_B_INVERT_MONO;
}
#endif /* INVERT */
#endif /* INVERT_ALPHA || INVERT */

/*
 *   WARNING
 *     WARNING
 *       WARNING
 *         WARNING
 *           WARNING  The transforms below are temporary; they can and will be
 *         WARNING    heavily optimized before release.
 *       WARNING
 *     WARNING
 *   WARNING
 */
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
typedef struct
{
   png_transform  tr;
   png_color_8    true_bits;
}  png_transform_shift;

/* Shift pixel values to take advantage of whole range.  Pass the
 * true number of bits in bit_depth.  The row should be packed
 * according to tc->bit_depth.  Thus, if you had a row of
 * bit depth 4, but the pixels only had values from 0 to 7, you
 * would pass 3 as bit_depth, and this routine would translate the
 * data to 0 to 15.
 *
 * NOTE: this is horrible complexity for no value.  Once people suggested they
 * were selling 16-bit displays with 5:6:5 bits spread R:G:B but so far as I
 * could determine these displays produced intermediate grey (uncolored) colors,
 * which is impossible with a true 5:6:5, so most likely 5:6:5 was marketing.
 */
static unsigned int
set_shifts(unsigned int format, unsigned int bit_depth,
   png_const_color_8p true_bits, int *shift_start, int *shift_dec)
{
   unsigned int channels = 0;

   if ((format & (PNG_FORMAT_FLAG_ALPHA+PNG_FORMAT_FLAG_AFIRST)) ==
       (PNG_FORMAT_FLAG_ALPHA+PNG_FORMAT_FLAG_AFIRST))
      ++channels; /* filled in below */

   if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
   {
      unsigned int offset = /* 0 or 2 as appropriate for red */
         ((format & PNG_FORMAT_FLAG_BGR) != 0) << 1;

      shift_start[channels+offset] = bit_depth - true_bits->red;
      if (shift_dec != NULL) shift_dec[channels+offset] = true_bits->red;

      shift_start[channels+1] = bit_depth - true_bits->green;
      if (shift_dec != NULL) shift_dec[channels+1] = true_bits->green;

      offset ^= 2; /* for blue */
      shift_start[channels+offset] = bit_depth - true_bits->blue;
      if (shift_dec != NULL) shift_dec[channels+offset] = true_bits->blue;

      channels += 3;
   }

   else /* no color: gray */
   {
      shift_start[channels] = bit_depth - true_bits->gray;
      if (shift_dec != NULL) shift_dec[channels] = true_bits->gray;
      ++channels;
   }

   if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)
   {
      const unsigned int offset =
         (format & PNG_FORMAT_FLAG_AFIRST) != 0 ? 0 : channels++;

      shift_start[offset] = bit_depth - true_bits->alpha;
      if (shift_dec != NULL) shift_dec[offset] = true_bits->alpha;
   }

   return channels;
}

#ifdef PNG_WRITE_SHIFT_SUPPORTED
static void
png_do_shift(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_shift *tr =
      png_transform_cast(png_transform_shift, *transform);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep dp_end = dp + PNG_TC_ROWBYTES(*tc);

   png_debug(1, "in png_do_shift");

   if (--(tc->range) == 0)
      tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_RANGE);

   tc->sp = dp;

   {
      int shift_start[4], shift_dec[4];
      unsigned int channels = set_shifts(tc->format, tc->bit_depth,
         &tr->true_bits, shift_start, shift_dec);

      debug(PNG_TC_CHANNELS(*tc) == channels);

      /* With low res depths, could only be grayscale, so one channel */
      if (tc->bit_depth < 8)
      {
         unsigned int mask;

         UNTESTED
         affirm(channels == 1);
         /* This doesn't matter but we expect to run before packswap: */
         debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED));

         if (tr->true_bits.gray == 1 && tc->bit_depth == 2)
            mask = 0x55;

         else if (tc->bit_depth == 4 && tr->true_bits.gray == 3)
            mask = 0x11;

         else
            mask = 0xff;

         while (dp < dp_end)
         {
            int j;
            unsigned int v, out;

            v = *sp++;
            out = 0;

            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
            {
               if (j > 0)
                  out |= v << j;

               else
                  out |= (v >> (-j)) & mask;
            }

            *dp++ = png_check_byte(png_ptr, out);
         }
      }

      else if (tc->bit_depth == 8)
      {
         unsigned int c = 0;

         UNTESTED
         while (dp < dp_end)
         {

            int j;
            unsigned int v, out;

            v = *sp++;
            out = 0;

            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
            {
               if (j > 0)
                  out |= v << j;

               else
                  out |= v >> (-j);
            }

            *dp++ = png_check_byte(png_ptr, out);
            if (++c == channels) c = 0;
         }
      }

      else /* tc->bit_depth == 16 */
      {
         unsigned int c = 0, s0, s1;

         UNTESTED
         if ((tc->format & PNG_FORMAT_FLAG_SWAPPED) != 0)
            s0 = 0, s1 = 8; /* LSB */

         else
            s0 = 8, s1 = 0; /* MSB */

         while (dp < dp_end)
         {
            int j;
            unsigned int value, v;

            v = *sp++ << s0;
            v += *sp++ << s1;
            value = 0;

            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
            {
               if (j > 0)
                  value |= v << j;

               else
                  value |= v >> (-j);
            }

            *dp++ = PNG_BYTE(value >> s0);
            *dp++ = PNG_BYTE(value >> s1);
         }
      }
   }
#  undef png_ptr
}
#endif /* WRITE_SHIFT */

#ifdef PNG_READ_SHIFT_SUPPORTED
/* Reverse the effects of png_do_shift.  This routine merely shifts the
 * pixels back to their significant bits values.  Thus, if you have
 * a row of bit depth 8, but only 5 are significant, this will shift
 * the values back to 0 through 31.
 */
static void
png_do_unshift(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_shift *tr =
      png_transform_cast(png_transform_shift, *transform);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep dp_end = dp + PNG_TC_ROWBYTES(*tc);

   png_debug(1, "in png_do_unshift");

   tc->range++;
   tc->format |= PNG_FORMAT_FLAG_RANGE;

   {
      int shift[4];
      unsigned int channels = set_shifts(tc->format, tc->bit_depth,
         &tr->true_bits, shift, NULL);

      debug(PNG_TC_CHANNELS(*tc) == channels);

      {
         unsigned int c, have_shift;

         for (c = have_shift = 0; c < channels; ++c)
         {
            /* A shift of more than the bit depth is an error condition but it
             * gets ignored here.
             */
            if (shift[c] <= 0 || (unsigned)/*SAFE*/shift[c] >= tc->bit_depth)
               shift[c] = 0;

            else
               have_shift = 1;
         }

         if (have_shift == 0)
            return;
      }

      /* The code below will copy sp to dp, so: */
      tc->sp = dp;

      switch (tc->bit_depth)
      {
         default:
            /* Must be 1bpp gray: should not be here! */
            impossible("unshift bit depth");
            /* NOTREACHED */
            break;

         case 2:
            /* Must be 2bpp gray */
            debug(channels == 1 && shift[0] == 1);
            debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED));

            while (dp < dp_end)
               *dp++ = (*sp++ >> 1) & 0x55;
            break;

         case 4:
            /* Must be 4bpp gray */
            debug(channels == 1);
            debug(!(tc->format & PNG_FORMAT_FLAG_SWAPPED));
            {
               unsigned int gray_shift = shift[0];
               unsigned int mask =  0xf >> gray_shift; /* <= 4 bits */

               mask |= mask << 4; /* <= 8 bits */

               while (dp < dp_end)
                  *dp++ = (png_byte)/*SAFE*/((*sp++ >> gray_shift) & mask);
            }
            break;

         case 8:
            /* Single byte components, G, GA, RGB, RGBA */
            {
               unsigned int channel = 0;

               while (dp < dp_end)
               {
                  *dp++ = (png_byte)/*SAFE*/(*sp++ >> shift[channel]);
                  if (++channel >= channels)
                     channel = 0;
               }
            }
            break;

         case 16:
            /* Double byte components, G, GA, RGB, RGBA */
            {
               unsigned int channel = 0;
               unsigned int s0, s1;

               if ((tc->format & PNG_FORMAT_FLAG_SWAPPED) != 0)
                  s0 = 0, s1 = 8; /* LSB */

               else
                  s0 = 8, s1 = 0; /* MSB */

               while (dp < dp_end)
               {
                  unsigned int value = *sp++ << s0;

                  value += *sp++ << s1; /* <= 16 bits */

                  value >>= shift[channel];
                  if (++channel >= channels) channel = 0;
                  *dp++ = PNG_BYTE(value >> s0);
                  *dp++ = PNG_BYTE(value >> s1);
               }
            }
            break;
      }
   }

#  undef png_ptr
}
#endif /* READ_SHIFT */

static void
init_shift(png_transformp *transform, png_transform_controlp tc)
{
   png_const_structp png_ptr = tc->png_ptr;

   /* These shifts apply to the component value, not the pixel index, so skip
    * palette data.  In addition there is no *write* shift for palette entries;
    * only a read one, so skip the write/palette case too.
    */
   if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0 &&
       (png_ptr->read_struct || !tc->palette))
   {
      /* The only change to the format is to mark the data as having a non-PNG
       * range.
       */
      tc->range++;
      tc->format |= PNG_FORMAT_FLAG_RANGE;

      if (tc->init == PNG_TC_INIT_FINAL)
      {
#     ifdef PNG_READ_SHIFT_SUPPORTED
         if (png_ptr->read_struct)
         {
            (*transform)->fn = png_do_unshift;
            return;
         }
#     endif
#     ifdef PNG_WRITE_SHIFT_SUPPORTED
         if (png_ptr->read_struct)
         {
            (*transform)->fn = png_do_shift;
            return;
         }
#     endif
      }
   }

   else /* transform not applicable */
      (*transform)->fn = NULL;
}

void PNGAPI
png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
{
   if (png_ptr != NULL && true_bits != NULL)
   {
#     ifndef PNG_READ_SHIFT_SUPPORTED
         if (png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_shift not supported on read");
            return;
         }
#     endif
#     ifndef PNG_WRITE_SHIFT_SUPPORTED
         if (!png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_shift not supported on write");
            return;
         }
#     endif

      {
         png_transform_shift *trs = png_transform_cast(png_transform_shift,
            png_add_transform(png_ptr, sizeof (png_transform_shift),
               init_shift, PNG_TR_SHIFT));
         trs->true_bits = *true_bits;
      }
   }
}
#endif /* SHIFT */

#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
/* Turn on pixel packing */
void PNGAPI
png_set_packing(png_structrp png_ptr)
{
   /* The transforms aren't symmetric, so even though there is one API there are
    * two internal init functions, one for read, the other write:
    */
   if (png_ptr != NULL)
   {
      if (png_ptr->read_struct)
      {
#        ifdef PNG_READ_PACK_SUPPORTED
            png_add_transform(png_ptr, 0/*size*/, png_init_read_pack,
               PNG_TR_PACK);
#        else
            png_app_error(png_ptr, "png_set_packing not supported on read");
#        endif
      }

      else
      {
#        ifdef PNG_WRITE_PACK_SUPPORTED
            png_add_transform(png_ptr, 0/*size*/, png_init_write_pack,
               PNG_TR_PACK);
#        else
            png_app_error(png_ptr, "png_set_packing not supported on write");
#        endif
      }
   }
}
#endif /* PACK */

#if defined(PNG_READ_PACKSWAP_SUPPORTED) ||\
    defined(PNG_WRITE_PACKSWAP_SUPPORTED)
/* Turn on pixel-swapping within a byte, this is symmetric - doing the swap
 * twice produces the original value, so only one implementation is required for
 * either read or write.
 *
 * Used to be refered to as "packswap", but pixel-swap seems more
 * self-documenting.
 */
static void
png_do_swap_1bit(png_transformp *transform, png_transform_controlp tc)
{
   png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */
   png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
   png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);

   tc->sp = dp;
   tc->format ^= PNG_FORMAT_FLAG_SWAPPED;

   for (;;)
   {
      png_uint_32 s = *sp++;
      s = ((s >> 1) & 0x55555555) | ((s & 0x55555555) << 1);
      s = ((s >> 2) & 0x33333333) | ((s & 0x33333333) << 2);
      s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4);
      *dp++ = s;
      if (rowbytes <= 4) break;
      rowbytes -= 4;
   }

   PNG_UNUSED(transform)
}

static void
png_do_swap_2bit(png_transformp *transform, png_transform_controlp tc)
{
   png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */
   png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
   png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);

   tc->sp = dp;
   tc->format ^= PNG_FORMAT_FLAG_SWAPPED;

   for (;;)
   {
      png_uint_32 s = *sp++;
      s = ((s >> 2) & 0x33333333) | ((s & 0x33333333) << 2);
      s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4);
      *dp++ = s;
      if (rowbytes <= 4) break;
      rowbytes -= 4;
   }

   PNG_UNUSED(transform)
}

static void
png_do_swap_4bit(png_transformp *transform, png_transform_controlp tc)
{
   png_alloc_size_t rowbytes = row_align(tc); /* may change tc->sp */
   png_const_uint_32p sp = png_voidcast(png_const_uint_32p, tc->sp);
   png_uint_32p dp = png_voidcast(png_uint_32p, tc->dp);

   tc->sp = dp;
   tc->format ^= PNG_FORMAT_FLAG_SWAPPED;

   for (;;)
   {
      png_uint_32 s = *sp++;
      s = ((s >> 4) & 0x0f0f0f0f) | ((s & 0x0f0f0f0f) << 4);
      *dp++ = s;
      if (rowbytes <= 4) break;
      rowbytes -= 4;
   }

   PNG_UNUSED(transform)
}

static void
init_packswap(png_transformp *transform, png_transform_controlp tc)
{
   png_transform_fn fn;

#  define png_ptr tc->png_ptr
   debug(tc->init);
#  undef png_ptr

   switch (tc->bit_depth)
   {
      case 1: fn = png_do_swap_1bit; break;
      case 2: fn = png_do_swap_2bit; break;
      case 4: fn = png_do_swap_4bit; break;

      default: /* transform not applicable */
         (*transform)->fn = NULL;
         return;
   }

   tc->format ^= PNG_FORMAT_FLAG_SWAPPED;
   if (tc->init == PNG_TC_INIT_FINAL)
      (*transform)->fn = fn;
}

void PNGAPI
png_set_packswap(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
#     ifndef PNG_READ_PACKSWAP_SUPPORTED
         if (png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_packswap not supported on read");
            return;
         }
#     endif
#     ifndef PNG_WRITE_PACKSWAP_SUPPORTED
         if (!png_ptr->read_struct)
         {
            png_app_error(png_ptr, "png_set_packswap not supported on write");
            return;
         }
#     endif

      png_add_transform(png_ptr, 0/*size*/, init_packswap, PNG_TR_PIXEL_SWAP);
   }
}
#endif /* PACKSWAP */

/* User transform handling */
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
png_uint_32 PNGAPI
png_get_current_row_number(png_const_structrp png_ptr)
{
   /* See the comments in png.h - this is the sub-image row when reading an
    * interlaced image.
    */
   if (png_ptr != NULL)
   {
      /* In the read case png_struct::row_number is the row in the final image,
       * not the pass, this will return the previous row number if the row isn't
       * in the pass:
       */
      if (png_ptr->read_struct)
         return PNG_PASS_ROWS(png_ptr->row_number+1, png_ptr->pass)-1U;

      else
         return png_ptr->row_number;
   }

   return PNG_UINT_32_MAX; /* help the app not to fail silently */
}

png_byte PNGAPI
png_get_current_pass_number(png_const_structrp png_ptr)
{
   if (png_ptr != NULL)
      return png_ptr->pass;
   return 8; /* invalid */
}
#endif /* USER_TRANSFORM_INFO */

#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) ||\
    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
typedef struct
{
   png_transform          tr;
   png_user_transform_ptr user_fn;
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
   png_voidp              user_ptr;
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
   unsigned int           user_depth;
   unsigned int           user_channels;
#endif
#endif
}  png_user_transform, *png_user_transformp;

typedef const png_user_transform *png_const_user_transformp;

static png_user_transformp
get_user_transform(png_structrp png_ptr)
{
   /* Note that in an added transform the whole transform is memset to 0, so we
    * don't need to initialize anything.
    */
   return png_transform_cast(png_user_transform, png_add_transform(png_ptr,
      sizeof (png_user_transform), NULL/*function*/, PNG_TR_USER));
}
#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */

#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
png_voidp PNGAPI
png_get_user_transform_ptr(png_const_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
      png_transformp tr = png_find_transform(png_ptr, PNG_TR_USER);

      if (tr != NULL)
      {
         png_user_transformp tru = png_transform_cast(png_user_transform, tr);
         return tru->user_ptr;
      }
   }

   return NULL;
}
#endif /* USER_TRANSFORM_PTR */

#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
void PNGAPI
png_set_user_transform_info(png_structrp png_ptr, png_voidp ptr, int depth,
   int channels)
{
   if (png_ptr != NULL)
   {
      /* NOTE: this function only sets the user transform pointer on write, i.e.
       * the depth and channels arguments are ignored.
       */
      png_user_transformp tr = get_user_transform(png_ptr);

      tr->user_ptr = ptr;

#     ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
         if (png_ptr->read_struct)
         {
            if (png_ptr->row_bit_depth == 0)
            {
               if (depth > 0 && depth <= 32 && channels > 0 && channels <= 4 &&
                   (-depth & depth) == depth /* power of 2 */)
               {
                  tr->user_depth = png_check_bits(png_ptr, depth, 6);
                  tr->user_channels = png_check_bits(png_ptr, channels, 3);
               }

               else
                  png_app_error(png_ptr, "unsupported bit-depth or channels");
            }
            else
               png_app_error(png_ptr,
                  "cannot change user info after image start");
         }
#     else /* !READ_USER_TRANSFORM */
         PNG_UNUSED(depth)
         PNG_UNUSED(channels)
#     endif /* !READ_USER_TRANSFORM */
   }
}
#endif /* USER_TRANSFORM_PTR */

#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
static void
png_do_read_user_transform(png_transformp *trIn, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_user_transformp tr = png_transform_cast(png_user_transform, *trIn);

   if (!tc->init && tr->user_fn != NULL)
   {
      png_row_info row_info;

      row_info.width = tc->width;
      row_info.rowbytes = PNG_TC_ROWBYTES(*tc);
      row_info.color_type = png_check_byte(png_ptr,
         PNG_COLOR_TYPE_FROM_FORMAT(tc->format));
      row_info.bit_depth = png_check_byte(png_ptr, tc->bit_depth);
      row_info.channels = png_check_byte(png_ptr,
         PNG_FORMAT_CHANNELS(tc->format));
      row_info.bit_depth = png_check_byte(png_ptr,
         PNG_TC_PIXEL_DEPTH(*tc));

      /* TODO: fix this API, but for the moment we have to copy the row data to
       * the working buffer.  This is an unnecessary perf overhead when a user
       * transform is used to read information without a transform or when it is
       * used on write.
       */
      if (tc->sp != tc->dp)
      {
         memcpy(tc->dp, tc->sp, PNG_TC_ROWBYTES(*tc));
         tc->sp = tc->dp;
      }

      tr->user_fn(png_ptr, &row_info, png_voidcast(png_bytep, tc->dp));
   }

#  ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
      if (tr->user_depth > 0)
      {
         /* The read transform can modify the bit depth and number of
          * channels; the interface doesn't permit anything else to be
          * changed.  If the information isn't set the user callback has to
          * produce pixels with the correct pixel depth (otherwise the
          * de-interlace won't work) but there really is no other constraint.
          */
         tc->bit_depth = tr->user_depth;

         /* The API is very restricted in functionality; the user_channels
          * can be changed, but the color_type can't, so the format is simply
          * fixed up to match the channels.
          */
         if (tr->user_channels != PNG_FORMAT_CHANNELS(tc->format))
            switch (tr->user_channels)
         {
            case 1:
               tc->format &=
                  PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);
               break;

            case 2: /* has to be GA */
               tc->format &=
                  PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP+PNG_FORMAT_FLAG_COLOR);
               tc->format |= PNG_FORMAT_FLAG_ALPHA;
               break;

            case 3: /* has to be RGB */
               tc->format &=
                  PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP|PNG_FORMAT_FLAG_ALPHA);
               tc->format |= PNG_FORMAT_FLAG_COLOR;
               break;

            case 4: /* has to be RGBA */
               tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLORMAP);
               tc->format |= (PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);
               break;

            default: /* checked before */
               impossible("user channels");
         }

         debug(PNG_FORMAT_CHANNELS(tc->format) == tr->user_channels);
      }
#  endif /* USER_TRANSFORM_PTR */
#  undef png_ptr
}

void PNGAPI
png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
    read_user_transform_fn)
{
   /* There is no 'init' function, just the callback above to handle the
    * transform.
    */
   if (png_ptr != NULL)
   {
      if (png_ptr->read_struct)
      {
         png_user_transformp tr = get_user_transform(png_ptr);

         tr->user_fn = read_user_transform_fn;
         tr->tr.fn = png_do_read_user_transform;
      }

      else
         png_app_error(png_ptr, "cannot set a read transform on write");
   }
}
#endif /* READ_USER_TRANSFORM */

#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
static void
png_do_write_user_transform(png_transformp *trIn, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* The write side is pretty simple; call the call-back, it will make the row
    * data right.
    *
    * BUG: we need to copy the input row (it would be a non-quiet API change
    * otherwise) and we don't know how big it is because the information passed
    * to png_set_user_transform_info never was used on write, but that's fine
    * because the write code never did get this right, so presumably all the
    * apps have worked round it...
    */
   if (!tc->init)
   {
      png_user_transformp tr = png_transform_cast(png_user_transform, *trIn);
      png_row_info row_info;

      if (tc->sp != tc->dp) /* no interlace */
      {
         memcpy(tc->dp, tc->sp, PNG_TC_ROWBYTES(*tc));
         tc->sp = tc->dp;
      }

      row_info.width = tc->width;
      row_info.rowbytes = PNG_TC_ROWBYTES(*tc);
      row_info.color_type = png_check_byte(png_ptr,
         PNG_COLOR_TYPE_FROM_FORMAT(tc->format));
      row_info.bit_depth = png_check_byte(png_ptr, tc->bit_depth);
      row_info.channels = png_check_byte(png_ptr,
         PNG_FORMAT_CHANNELS(tc->format));
      row_info.bit_depth = png_check_byte(png_ptr,
         PNG_TC_PIXEL_DEPTH(*tc));

      /* The user function promises to give us this format: */
      tr->user_fn(png_ptr, &row_info, png_voidcast(png_bytep, tc->dp));
   }
#  undef png_ptr
}

void PNGAPI
png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
    write_user_transform_fn)
{

   if (png_ptr != NULL)
   {
      if (!png_ptr->read_struct)
      {
         png_user_transformp tr = get_user_transform(png_ptr);

         tr->user_fn = write_user_transform_fn;
         tr->tr.fn = png_do_write_user_transform;
      }

      else
         png_app_error(png_ptr, "cannot set a write transform on read");
   }
}
#endif /* WRITE_USER_TRANSFORM */
