
/* 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
                  if (png_ptr->read_struct)
#              endif /* WRITE */
                  png_chunk_benign_error(png_ptr, "palette index too large");
#              ifdef PNG_WRITE_SUPPORTED
                  else
#              endif
#           endif /* READ */
#           ifdef PNG_WRITE_SUPPORTED
               png_error(png_ptr, "palette index too large");
#           endif /* WRITE */
         }

         png_ptr->palette_index_check_issued = 1;
      }
#  endif /* CHECK_FOR_INVALID_INDEX */
#  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 */
