
/* 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);
   }
}
#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)
   /* Called whenever a new maximum pixel value is found */
{
   /* One of these must be true: */
#  ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
      if (max >= png_ptr->num_palette && !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 == (1U << png_ptr->bit_depth)-1U)
   {
      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, 1);
}

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))
         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))
         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))
         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) 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)
{
   unsigned int max_depth = PNG_PIXEL_DEPTH(*png_ptr);

#  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 depth = init_transform_mech(png_ptr, &tc, 0/*final*/);

            if (depth > max_depth)
                max_depth = depth;

#           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 */
         }
      }

      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 */
      }

      /* 'max_depth' is now the maximum size of a pixel, including intermediate
       * results during the transforms.  The current limit is 4 32-bit channels:
       */
      affirm(max_depth <= 128);
      png_ptr->row_max_pixel = png_check_bits(png_ptr, max_depth, 8);
#  endif /* TRANSFORM_MECH */

   /* png_calc_rowbytes does a png_error on overflow.  This is how the libpng
    * code validates that there won't be overflows on future PNG_ROWBYTES
    * calls.
    *
    * The largest integer we can guarantee with ANSI-C is a 32-bit one (unsigned
    * long).  To allow the row to be accessed as png_uint_32[] this code sets
    * the allocation to a multiple of 4:
    */
   {
      png_alloc_size_t rowbytes = png_calc_rowbytes(png_ptr, max_depth,
         png_ptr->width);
      png_alloc_size_t alloc = (rowbytes + 3U) & ~3U;

      if (alloc < rowbytes)
         png_error(png_ptr, "PNG row exceeds system limits");

      png_ptr->row_allocated_bytes = alloc;
   }
}

#if defined(PNG_READ_DEINTERLACE_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_DEINTERLACE_SUPPORTED
            if (png_ptr->interlaced)
            {
               png_ptr->do_interlace = 1;
               return PNG_INTERLACE_ADAM7_PASSES;
            }

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

      else /* write */
      {
#        ifdef PNG_WRITE_INTERLACING_SUPPORTED
            if (png_ptr->interlaced)
            {
               png_ptr->do_interlace = 1;
               png_set_write_interlace(png_ptr);
               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_DEINTERLACE || 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 */
