
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
 *
 * Last changed in libpng 1.6.17 [(PENDING RELEASE)]
 * Copyright (c) 1998-2015 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 && !png_ptr->palette_index_check_issued)
      {
#        ifdef PNG_READ_SUPPORTED
#           ifdef PNG_WRITE_SUPPORTED
               (png_ptr->read_struct ? png_chunk_benign_error : png_error)
#           else /* !WRITE */
               png_chunk_benign_error
#           endif /* !WRITE */
#        else /* !READ */
            png_error
#        endif /* !READ */
            (png_ptr, "palette index too large");
         png_ptr->palette_index_check_issued = 1;
      }
#  endif
#  ifdef PNG_GET_PALETTE_MAX_SUPPORTED
      png_ptr->palette_index_max = png_check_bits(png_ptr, max, 9);
#  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;
   unsigned int max = (*tr)->args; /* 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;
}

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;
   unsigned int max = (*tr)->args; /* 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 > (*tr)->args)
   {
      if (set_palette_max(tc->png_ptr, *tr, max, 15U))
         return;

      (*tr)->args = max;
   }
}

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;
   unsigned int max = (*tr)->args; /* saved maximum */

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

      if (input > max)
         max = input;

      --width;
   }

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

      (*tr)->args = max;
   }
}

static void
palette_max_init(png_transformp *tr, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
   {
      if (tc->init == PNG_TC_INIT_FINAL)
      {
         /* Record the palette depth to check here: */
         (*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");
         }
      }
   }

   else
      (*tr)->fn = NULL; /* not applicable */
#  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
#     ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
         && !png_ptr->palette_index_check_disabled
#     endif
      )
      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 */

#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
   /* Whether to report invalid palette index; added at libng-1.5.10.
    * It is possible for an indexed (color-type==3) PNG file to contain
    * pixels with invalid (out-of-range) indexes if the PLTE chunk has
    * fewer entries than the image's bit-depth would allow. We recover
    * from this gracefully by filling any incomplete palette with zeros
    * (opaque black).  By default, when this occurs libpng will issue
    * a benign error.  This API can be used to override that behavior.
    */
void PNGAPI
png_set_check_for_invalid_index(png_structrp png_ptr, int enabled)
{
   /* This defaults to 0, therefore *on*: */
   if (png_ptr != NULL)
   {
      if (png_ptr->read_struct)
#        ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
            png_ptr->palette_index_check_disabled = enabled <= 0;
#        else /* !READ_CHECK_FOR_INVALID_INDEX */
            png_app_error(png_ptr, "no read palette check support");
#        endif /* !READ_CHECK_FOR_INVALID_INDEX */
      else /* write struct */
#        ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
            png_ptr->palette_index_check_disabled = enabled <= 0;
#        else /* !WRITE_CHECK_FOR_INVALID_INDEX */
            png_app_error(png_ptr, "no write palette check support");
#        endif /* !WRITE_CHECK_FOR_INVALID_INDEX */
   }
}
#endif /* CHECK_FOR_INVALID_INDEX */

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_disabled)
#              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_disabled)
#              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 */
