
/* pngrtran.c - transforms the data in a row for PNG readers
 *
 * Last changed in libpng 1.7.0 [(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
 *
 * This file contains functions optionally called by an application
 * in order to tell libpng how to handle data when reading a PNG.
 * Transformations that are used in both reading and writing are
 * in pngtrans.c.
 */

#include "pngpriv.h"
#define PNG_SRC_FILE PNG_SRC_FILE_pngrtran

#ifdef PNG_READ_QUANTIZE_SUPPORTED
typedef struct
{
   png_transform tr;
   png_byte      map[256U]; /* Map of palette values */
   png_byte      lut[1U <<  /* LUT for RGB values */
      (PNG_QUANTIZE_RED_BITS+PNG_QUANTIZE_GREEN_BITS+PNG_QUANTIZE_BLUE_BITS)];
}  png_transform_quantize;

#define PNG_QUANTIZE_MAP 1U /* map is present and not a 1:1 mapping */
#define PNG_QUANTIZE_LUT 2U /* lut has been built */

static void
do_quantize_rgb(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_quantize *tr = png_transform_cast(png_transform_quantize,
      *transform);
   unsigned int channels = PNG_TC_CHANNELS(*tc);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - channels/*safety*/;
   png_bytep dp = png_voidcast(png_bytep, tc->dp);

   affirm(tc->bit_depth == 8 && (channels == 3 || channels == 4) &&
          !(tc->format & PNG_FORMAT_FLAG_SWAPPED) &&
          (tr->tr.args & PNG_QUANTIZE_LUT) != 0);

   tc->sp = dp;
   tc->format |= PNG_FORMAT_FLAG_COLORMAP;

   while (sp <= ep)
   {
      unsigned int r = sp[0];
      unsigned int g = sp[1];
      unsigned int b = sp[2];

      /* This looks real messy, but the compiler will reduce
       * it down to a reasonable formula.  For example, with
       * 5 bits per color, we get:
       * p = (((r >> 3) & 0x1f) << 10) |
       *    (((g >> 3) & 0x1f) << 5) |
       *    ((b >> 3) & 0x1f);
       */
      *dp++ = tr->lut[(((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
          ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
          (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
          (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
          ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
          (PNG_QUANTIZE_BLUE_BITS)) |
          ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
          ((1 << PNG_QUANTIZE_BLUE_BITS) - 1))];

      sp += channels;
   }

   affirm(sp == ep+channels);
   UNTESTED
#  undef png_ptr
}

static void
do_quantize_pal(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_quantize *tr = png_transform_cast(png_transform_quantize,
      *transform);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);

   affirm(tc->bit_depth == 8 && (tc->format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
          !(tc->format & PNG_FORMAT_FLAG_SWAPPED) &&
          (tr->tr.args & PNG_QUANTIZE_MAP) != 0);

   tc->sp = dp;

   while (sp < ep)
      *dp++ = tr->map[*sp++];

   UNTESTED
#  undef png_ptr
}

static void
png_init_quantize(png_transformp *transform, png_transform_controlp tc)
{
   if (tc->bit_depth == 8 && (tc->format & PNG_FORMAT_FLAG_COLOR) != 0)
   {
      /* Either colormapped input, RGB or RGBA: */
      if (!(tc->format & PNG_FORMAT_FLAG_COLORMAP)) /* RGB, RGBA */
      {
         /* This must be a 'palette' lookup */
         if (((*transform)->args & PNG_QUANTIZE_LUT) != 0)
         {
            /* This changes the format and invalidates pretty much everything in
             * the info struct:
             */
            tc->format |= PNG_FORMAT_FLAG_COLORMAP;

            if (tc->init == PNG_TC_INIT_FINAL)
            {
               (*transform)->fn = do_quantize_rgb;
               tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL+
                  PNG_INFO_sBIT+PNG_INFO_bKGD;
               tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =
                  png_check_byte(tc->png_ptr, tc->bit_depth);
            }

            return;
         }
      }

      else /* colormapped */
      {
         /* This must be a 'quantize' lookup */
         if (((*transform)->args & PNG_QUANTIZE_MAP) != 0)
         {
            /* This doesn't change the format, just the values: */
            if (tc->init == PNG_TC_INIT_FINAL)
            {
               (*transform)->fn = do_quantize_pal;
               tc->invalid_info |= PNG_INFO_sBIT+PNG_INFO_pCAL;
               tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =
                  png_check_byte(tc->png_ptr, tc->bit_depth);
            }

            return;
         }
      }
   }

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

/* Dither file to 8-bit.  Supply a palette, the current number
 * of elements in the palette, the maximum number of elements
 * allowed, and a histogram if possible.  If the current number
 * of colors is greater then the maximum number, the palette will be
 * modified to fit in the maximum number.  "full_quantize" indicates
 * whether we need a quantizing cube set up for RGB images, or if we
 * simply are reducing the number of colors in a paletted image.
 */
typedef struct png_dsort_struct
{
   struct png_dsort_struct * next;
   png_byte left;
   png_byte right;
} png_dsort;
typedef png_dsort *   png_dsortp;
typedef png_dsort * * png_dsortpp;

static void
init_map(png_bytep map)
   /* Initialize a mapping table to be 1:1 */
{
   png_byte b = 0U;

   do
      map[b] = b;
   while (b++ != 255U);
}

/* Save typing and make code easier to understand */
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
   abs((int)((c1).green) - (int)((c2).green)) + \
   abs((int)((c1).blue) - (int)((c2).blue)))

void PNGAPI
png_set_quantize(png_structrp png_ptr, png_colorp palette,
    int num_palette, int maximum_colors, png_const_uint_16p histogram,
    int full_quantize)
{
   png_debug(1, "in png_set_quantize");

   if (png_ptr != NULL)
   {
      png_transform_quantize *tr = png_transform_cast(png_transform_quantize,
         png_add_transform(png_ptr, sizeof (png_transform_quantize),
            png_init_quantize, PNG_TR_QUANTIZE));

      /* This is weird (consider what happens to png_set_background on a palette
       * image with a tRNS chunk).
       */
      if (palette == png_ptr->palette)
         png_app_warning(png_ptr, "png_set_quantize: PLTE will be damaged");

      if (maximum_colors <= 0 || num_palette > 256)
      {
         /* The spuriously allocated transform will be removed by the init
          * code.
          */
         png_app_error(png_ptr, "png_set_quantize: invalid color count");
         return;
      }

      /* The app passed in a palette with too many colors, it's not clear why
       * libpng is providing this functionality, it's nothing to do with PNG and
       * can be done by the application without any PNG specific knowledge.
       */
      if (num_palette > maximum_colors)
      {
         int map_changed = 0;

         /* The map table must be preset to do no mapping initially: */
         init_map(tr->map);

         if (histogram != NULL)
         {
            /* This is easy enough, just throw out the least used colors.
             * Perhaps not the best solution, but good enough.
             */
            int i;
            png_byte quantize_sort[256U];

            /* Initialize an array to sort colors */
            init_map(quantize_sort);

            /* Find the least used palette entries by starting a
             * bubble sort, and running it until we have sorted
             * out enough colors.  Note that we don't care about
             * sorting all the colors, just finding which are
             * least used.
             */
            for (i = num_palette - 1; i >= maximum_colors; i--)
            {
               int done; /* To stop early if the list is pre-sorted */
               int j;

               done = 1;
               for (j = 0; j < i; j++)
               {
                  if (histogram[quantize_sort[j]] <
                      histogram[quantize_sort[j+1]])
                  {
                     png_byte t = quantize_sort[j];
                     quantize_sort[j] = quantize_sort[j+1];
                     quantize_sort[j+1] = t;
                     done = 0;
                  }
               }

               if (done != 0)
                  break;
            }

            /* Swap the palette around, and set up a table, if necessary */
            if (full_quantize)
            {
               int j = num_palette;

               /* Put all the useful colors within the max, but don't
                * move the others.
                *
                * NOTE: if the app passes in the result of png_get_PLTE it will
                * be overwritten at this point, what is the API?
                */
               for (i = 0; i < maximum_colors; i++)
               {
                  if (quantize_sort[i] >= maximum_colors)
                  {
                     do
                        j--;
                     while (quantize_sort[j] >= maximum_colors);

                     /* NOTE: NOT swapped, so the original palette[i] has been
                      * lost.
                      */
                     palette[i] = palette[j];
                  }
               }
            }

            else /* !full_quantize */
            {
               int j = num_palette;

               /* Move all the used colors inside the max limit, and
                * develop a translation table.
                */
               for (i = 0; i < maximum_colors; i++)
               {
                  /* Only move the colors we need to */
                  if (quantize_sort[i] >= maximum_colors)
                  {
                     png_color tmp_color;

                     do
                        j--;
                     while (quantize_sort[j] >= maximum_colors);

                     tmp_color = palette[j];
                     palette[j] = palette[i];
                     palette[i] = tmp_color;
                     /* Indicate where the color went */
                     tr->map[j] = png_check_byte(png_ptr, i);
                     tr->map[i] = png_check_byte(png_ptr, j);
                     map_changed = 1;
                  }
               }

               /* Find closest color for those colors we are not using */
               for (i = 0; i < num_palette; i++)
               {
                  if (tr->map[i] >= maximum_colors)
                  {
                     int min_d, k, min_k, d_index;

                     /* Find the closest color to one we threw out */
                     d_index = tr->map[i];
                     min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
                     for (k = 1, min_k = 0; k < maximum_colors; k++)
                     {
                        int d;

                        d = PNG_COLOR_DIST(palette[d_index], palette[k]);

                        if (d < min_d)
                        {
                           min_d = d;
                           min_k = k;
                        }
                     }

                     /* Point to closest color */
                     tr->map[i] = png_check_byte(png_ptr, min_k);
                     map_changed = 1;
                  }
               }
            } /* !full_quantize */
         } /* have a histogram */

         else /* no histogram */
         {
            /* This is much harder to do simply (and quickly).  Perhaps
             * we need to go through a median cut routine, but those
             * don't always behave themselves with only a few colors
             * as input.  So we will just find the closest two colors,
             * and throw out one of them (chosen somewhat randomly).
             * [We don't understand this at all, so if someone wants to
             *  work on improving it, be our guest - AED, GRP]
             */
            int max_d;
            int num_new_palette;
            png_byte index_to_palette[256U];
            png_byte palette_to_index[256U];
            png_dsortp hash[769];

            /* Initialize palette index sort arrays */
            init_map(index_to_palette);
            init_map(palette_to_index);
            memset(hash, 0, sizeof hash);
            num_new_palette = num_palette;

            /* Initial wild guess at how far apart the farthest pixel
             * pair we will be eliminating will be.  Larger
             * numbers mean more areas will be allocated, Smaller
             * numbers run the risk of not saving enough data, and
             * having to do this all over again.
             *
             * I have not done extensive checking on this number.
             */
            max_d = 96;

            while (num_new_palette > maximum_colors)
            {
               int i;
               png_dsortp t = NULL;

               for (i = 0; i < num_new_palette - 1; i++)
               {
                  int j;

                  for (j = i + 1; j < num_new_palette; j++)
                  {
                     int d = PNG_COLOR_DIST(palette[i], palette[j]);

                     if (d <= max_d)
                     {

                        t = png_voidcast(png_dsortp, png_malloc_warn(png_ptr,
                              sizeof (*t)));

                        if (t == NULL)
                            break;

                        t->next = hash[d];
                        t->left = png_check_byte(png_ptr, i);
                        t->right = png_check_byte(png_ptr, j);
                        hash[d] = t;
                     }
                  }
                  if (t == NULL)
                     break;
               }

               if (t != NULL) for (i = 0; i <= max_d; i++)
               {
                  if (hash[i] != NULL)
                  {
                     png_dsortp p;

                     for (p = hash[i]; p != NULL; p = p->next)
                     {
                        if (index_to_palette[p->left] < num_new_palette &&
                            index_to_palette[p->right] < num_new_palette)
                        {
                           int j, next_j;

                           if (num_new_palette & 0x01)
                           {
                              j = p->left;
                              next_j = p->right;
                           }
                           else
                           {
                              j = p->right;
                              next_j = p->left;
                           }

                           num_new_palette--;
                           /* NOTE: overwrites palette */
                           palette[index_to_palette[j]] =
                              palette[num_new_palette];

                           if (full_quantize == 0)
                           {
                              int k;

                              for (k = 0; k < num_palette; k++)
                              {
                                 if (tr->map[k] == index_to_palette[j])
                                 {
                                    tr->map[k] = index_to_palette[next_j];
                                    map_changed = 1;
                                 }

                                 if (tr->map[k] == num_new_palette)
                                 {
                                    tr->map[k] = index_to_palette[j];
                                    map_changed = 1;
                                 }
                              }
                           }

                           index_to_palette[palette_to_index[num_new_palette]] =
                              index_to_palette[j];

                           palette_to_index[index_to_palette[j]] =
                              palette_to_index[num_new_palette];

                           index_to_palette[j] =
                              png_check_byte(png_ptr, num_new_palette);

                           palette_to_index[num_new_palette] =
                              png_check_byte(png_ptr, j);
                        }

                        if (num_new_palette <= maximum_colors)
                           break;
                     }

                     if (num_new_palette <= maximum_colors)
                        break;
                  }
               }

               for (i = 0; i < 769; i++)
               {
                  if (hash[i] != NULL)
                  {
                     png_dsortp p = hash[i];

                     while (p)
                     {
                        t = p->next;
                        png_free(png_ptr, p);
                        p = t;
                     }

                     hash[i] = NULL;
                  }
               }

               max_d += 96;
            } /* while num_new_colors > maximum_colors */
         } /* no histogram */

         num_palette = maximum_colors;

         if (map_changed) /* else the map is 1:1 */
            tr->tr.args |= PNG_QUANTIZE_MAP;
      } /* num_palette > maximum_colors */

      /* The palette has been reduced to the requested number of colors if it
       * was over maximum colors before.
       */

      /* TODO: what is this?  Apparently the png_struct::palette member gets
       * updated if it didn't originally have a palette, but the update relies
       * on the app not freeing the passed in palette.
       */
      if (png_ptr->palette == NULL)
         png_ptr->palette = palette;

      png_ptr->num_palette = png_check_bits(png_ptr, num_palette, 9);

      if (full_quantize)
      {
         int i;
         png_byte distance[1U << (PNG_QUANTIZE_RED_BITS+PNG_QUANTIZE_GREEN_BITS+
            PNG_QUANTIZE_BLUE_BITS)];

         memset(distance, 0xff, sizeof distance);

         for (i = 0; i < num_palette; i++)
         {
            int ir;
            int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
            int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
            int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));

            for (ir = 0; ir < (1<<PNG_QUANTIZE_RED_BITS); ir++)
            {
               /* int dr = abs(ir - r); */
               int ig;
               int dr = ((ir > r) ? ir - r : r - ir);
               int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
                   PNG_QUANTIZE_GREEN_BITS));

               for (ig = 0; ig < (1<<PNG_QUANTIZE_GREEN_BITS); ig++)
               {
                  /* int dg = abs(ig - g); */
                  int ib;
                  int dg = ((ig > g) ? ig - g : g - ig);
                  int dt = dr + dg;
                  int dm = ((dr > dg) ? dr : dg);
                  int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);

                  for (ib = 0; ib < (1<<PNG_QUANTIZE_BLUE_BITS); ib++)
                  {
                     int d_index = index_g | ib;
                     /* int db = abs(ib - b); */
                     int db = ((ib > b) ? ib - b : b - ib);
                     int dmax = ((dm > db) ? dm : db);
                     int d = dmax + dt + db;

                     if (d < distance[d_index])
                     {
                        distance[d_index] = png_check_byte(png_ptr, d);
                        tr->lut[d_index] = png_check_byte(png_ptr, i);
                     }
                  } /* for blue */
               } /* for green */
            } /* for red */
         } /* num_palette */
      } /* full_quantize */
   } /* png_ptr != NULL */
}
#endif /* READ_QUANTIZE */

#ifdef PNG_READ_PACK_SUPPORTED
/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
 * without changing the actual values.  Thus, if you had a row with
 * a bit depth of 1, you would end up with bytes that only contained
 * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
 * png_set_expand_gray_1_2_4_to_8 instead.
 */
static void
png_do_read_unpack(png_transformp *transform, png_transform_controlp tc)
{
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = png_voidcast(png_const_bytep, tc->dp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);

   sp += PNG_TC_ROWBYTES(*tc) - 1; /* Start from end */
   dp += tc->width; /* output bit depth is 8 */

#  define png_ptr (tc->png_ptr)
   png_debug(1, "in png_do_unpack");

   switch (tc->bit_depth)
   {
      case 1:
      {
         /* Because we copy from the last pixel down the shift required
          * at the start is 8-pixels_in_last_byte, which is just:
          */
         unsigned int shift = 7U & -tc->width;

         while (dp > ep)
         {
            *--dp = (*sp >> shift) & 1U;
            shift = 7U & (shift+1U);
            if (shift == 0U)
               --sp;
         }

         debug(shift == 0U);
         break;
      }

      case 2:
      {
         unsigned int shift = 7U & -(tc->width << 1);

         while (dp > ep)
         {
            *--dp = (*sp >> shift) & 3U;
            shift = 7U & (shift+2U);
            if (shift == 0U)
               --sp;
         }

         debug(shift == 0U);
         break;
      }

      case 4:
      {
         unsigned int shift = 7U & -(tc->width << 2);

         while (dp > ep)
         {
            *--dp = (*sp >> shift) & 15U;
            shift = 7U & (shift+4U);
            if (shift == 0U)
               --sp;
         }

         debug(shift == 0U);
         break;
      }

      default:
         impossible("bit depth");
   }

   debug(dp == ep && sp == png_upcast(png_const_bytep, tc->sp)-1U);
   tc->sp = dp;

   if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U)
   {
      tc->range++;
      tc->format |= PNG_FORMAT_FLAG_RANGE;
   }

   tc->bit_depth = 8U;
   PNG_UNUSED(transform)
#  undef png_ptr
}

/* Called from the curiously named png_set_packing API in pngtrans.c; the read
 * and write code is separated because read 'unpacks' (from PNG format) and
 * write 'packs' (to PNG format.)
 */
void /* PRIVATE */
png_init_read_pack(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr tc->png_ptr
   debug(tc->init);

   if (tc->bit_depth < 8) /* else no packing/unpacking */
   {
      /* For indexed images the pack operation does not invalidate the range; in
       * fact the corresponding shift operation would!
       */
      if ((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0U)
      {
         tc->range++;
         tc->format |= PNG_FORMAT_FLAG_RANGE;
      }

      tc->bit_depth = 8U;

      if (tc->init == PNG_TC_INIT_FINAL)
         (*transform)->fn = png_do_read_unpack/* sic: it unpacks */;
   }

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

#  undef png_ptr
}
#endif /* READ_PACK */

#if defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
#  ifdef PNG_READ_tRNS_SUPPORTED
static unsigned int
fill_transparent_pixel(png_const_structrp png_ptr, png_byte *trans)
   /* Fill a byte array according to the transparent pixel value and return a
    * count of the number of bytes.  Low bit depth gray values are replicated in
    * the first byte.  Writes from 1 to 6 bytes.
    */
{
   /* There must be a tRNS chunk and this must not be a palette image: */
   debug(png_ptr->num_trans == 1 &&
      !(png_ptr->color_type & (PNG_COLOR_MASK_ALPHA+PNG_COLOR_MASK_PALETTE)));

   if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* gray */
   {
      unsigned int t = png_ptr->trans_color.gray;
      unsigned int depth = png_ptr->bit_depth;

      if (depth < 16U)
      {
         /* ISO PNG 11.3.2.1 "tRNS Transparency": "If the image bit depth is
          * less than 16, the least significant bits are used and the others are
          * 0."  So mask out the upper bits.
          */
         t &= (1U<<depth)-1U;

         /* And replicate low bit-depth values across the byte: */
         while (depth < 8U)
         {
            t |= t << depth;
            depth <<= 1;
         }

         trans[0] = PNG_BYTE(t);
         return 1U;
      }

      /* Else a 16 bit value: */
      trans[0] = PNG_BYTE(t >> 8);
      trans[1] = PNG_BYTE(t);
      return 2U;
   }

   else /* color */ switch (png_ptr->bit_depth)
   {
      case 8: /* 8-bit RGB */
         trans[0] = PNG_BYTE(png_ptr->trans_color.red);
         trans[1] = PNG_BYTE(png_ptr->trans_color.green);
         trans[2] = PNG_BYTE(png_ptr->trans_color.blue);
         return 3U;

      case 16: /* 16-bit RGB */
         trans[0] = PNG_BYTE(png_ptr->trans_color.red >> 8);
         trans[1] = PNG_BYTE(png_ptr->trans_color.red);
         trans[2] = PNG_BYTE(png_ptr->trans_color.green >> 8);
         trans[3] = PNG_BYTE(png_ptr->trans_color.green);
         trans[4] = PNG_BYTE(png_ptr->trans_color.blue >> 8);
         trans[5] = PNG_BYTE(png_ptr->trans_color.blue);
         return 6U;

      default:
         NOT_REACHED;
         return 0U; /* safe */
   }
}
#  endif /* READ_tRNS */
#endif /* READ_EXPAND || READ_BACKGROUND */

#ifdef PNG_READ_EXPAND_SUPPORTED
/* Flags for png_init_expand */
#define PNG_EXPAND_PALETTE  1U /* palette images only, includes tRNS */
#define PNG_EXPAND_LBD_GRAY 2U /* grayscale low-bit depth only */
#define PNG_EXPAND_tRNS     4U /* non-palette images only */

/* This struct is only required for tRNS matching, but it is convenient to
 * allocated it anyway even if READ_tRNS is not supported.
 */
typedef struct
{
   png_transform tr;
   unsigned int  ntrans;               /* number of bytes below */
   png_byte      transparent_pixel[6]; /* the transparent pixel value */
}  png_expand;

#ifdef PNG_READ_tRNS_SUPPORTED
/* Look for colors matching the trans_color in png_ptr, low bit depth gray is
 * covered below so this only need handle 8 abd 16-bit channels.
 */
static void
png_do_expand_tRNS(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_expand *tr = png_transform_cast(png_expand, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp;
   const unsigned int spixel_size = PNG_TC_PIXEL_DEPTH(*tc) >> 3;
   unsigned int alpha_size;

   /* We expect opaque and transparent pixels to be interleaved but with long
    * sequences of each.  Because we are adding an alpha channel we must copy
    * down.
    */
   debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA));
   debug(spixel_size == tr->ntrans);
   sp += PNG_TC_ROWBYTES(*tc);
   tc->sp = dp;
   tc->format |= PNG_FORMAT_FLAG_ALPHA;
   tc->invalid_info |= PNG_INFO_tRNS;
   tc->transparent_alpha = 1U;
   alpha_size = (PNG_TC_PIXEL_DEPTH(*tc)>>3) - spixel_size;
   debug(alpha_size == 1 || alpha_size == 2);
   dp += PNG_TC_ROWBYTES(*tc);

   do
   {
      unsigned int i = spixel_size;
      png_byte alpha = 0U;

      dp -= alpha_size;
      alpha = 0U;

      /* Copy and check one source pixel (backwards, to avoid any
       * overwrite):
       */
      do if ((*--dp = *--sp) != tr->transparent_pixel[--i]) /* pixel != tRNS */
         alpha = 0xFFU;
      while (i != 0U);

      /* i == 0 */
      do
         dp[spixel_size + i] = alpha;
      while (++i < alpha_size);
   } while (sp > ep);

   debug(sp == ep && dp == tc->dp); /* else overwrite */
#  undef png_ptr
}
#endif /* READ_tRNS */

/* Expand grayscale images of less than 8-bit depth to 8 bits.
 * libpng 1.7.0: this no longer expands everything, it just expands the low bit
 * depth gray row.  It does *NOT* expand the tRNS into an alpha channel unless
 * it is told to do so.
 *
 * API CHANGE: the function now does what it was always meant to do.
 *
 * This is like do_unpack except that the packed data is expanded to the full
 * 8-bit range; scaled up.  This is not a good thing to do on an indexed image;
 * the indices will be invalid.
 *
 * The tRNS handling is included here too; speed is not important because the
 * result will always be cached unless the PNG is very small.
 */
static void
png_do_expand_lbd_gray(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   const png_const_bytep ep = dp;
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const unsigned int bit_depth = tc->bit_depth;
#  ifdef PNG_READ_sBIT_SUPPORTED
   unsigned int insignificant_bits = 0U;
#  endif /* READ_sBIT */
#  ifdef PNG_READ_tRNS_SUPPORTED
   unsigned int gray = 0xffffU; /* doesn't match anything */
   unsigned int do_alpha = 0U;
#  endif /* READ_tRNS */

   sp += PNG_TC_ROWBYTES(*tc); /* last byte +1 */
   tc->bit_depth = 8U;
   tc->invalid_info |= PNG_INFO_tRNS;
#  ifdef PNG_READ_sBIT_SUPPORTED
      if (bit_depth > 1U /* irrelevant for bit depth 1 */ &&
          !(tc->invalid_info & PNG_INFO_sBIT) &&
          tc->sBIT_G > 0U/*SAFETY*/ && tc->sBIT_G < bit_depth)
         insignificant_bits = bit_depth - tc->sBIT_G;
#  endif /* READ_sBIT */

#  ifdef PNG_READ_tRNS_SUPPORTED
      if (((*transform)->args & PNG_EXPAND_tRNS) != 0)
      {
         tc->format |= PNG_FORMAT_FLAG_ALPHA;
         tc->transparent_alpha = 1U;
         gray = png_ptr->trans_color.gray & ((1U << bit_depth)-1U);
         do_alpha = 1U;
      }

      /* This helps avoid cluttering the code up with #ifdefs: */
#     define check_tRNS if (do_alpha) *--dp = (pixel != gray) * 255U;
#  else /* !READ_tRNS */
#     define check_tRNS
#  endif /* READ_tRNS */

   dp += PNG_TC_ROWBYTES(*tc); /* pre-decremented below */

   switch (bit_depth)
   {
      case 1:
      {
         unsigned int shift = 7U & -tc->width;
         unsigned int s = *--sp;

         for(;;)
         {
            if (shift == 8U) s = *--sp, shift = 0;

            {
               const unsigned int pixel = (s >> shift) & 1U;

               check_tRNS
               *--dp = PNG_BYTE(pixel * 255U);
               if (dp <= ep) break;
            }
            ++shift;
         }

         debug(dp == ep && shift == 7U && sp == tc->sp);
         break;
      }

      case 2:
      {
         unsigned int shift = 7U & -(tc->width << 1)/*overflow ok*/;
         unsigned int s = *--sp;

         for (;;)
         {
            if (shift == 8U) s = *--sp, shift = 0;
            {
               const unsigned int pixel = (s >> shift) & 3U;

               check_tRNS

#  ifdef PNG_READ_sBIT_SUPPORTED
               /* 'sig_bits' must be 1 or 2 leaving insignificant_bits 0 or
                * 1.  This may look silly but it allows a compact representation
                * of 1 bit gray + 1 bit alpha (transparency):
                */
               if (insignificant_bits /* only 1 bit significant */)
                  *--dp = PNG_BYTE((pixel >> 1) * 255U);

               else
#  endif
                  *--dp = PNG_BYTE(pixel * 85U);

               if (dp <= ep) break;
            }
            shift += 2U;
         }

         debug(dp == ep && shift == 6U && sp == tc->sp);
         break;
      }

      case 4:
      {
         unsigned int shift = 7U & -(tc->width << 2)/*overflow ok*/;
         unsigned int s = *--sp;
#  ifdef PNG_READ_sBIT_SUPPORTED
         const unsigned int div = (1U << (4U-insignificant_bits)) - 1U;
#  endif

         for (;;)
         {
            if (shift == 8U) s = *--sp, shift = 0;
            {
               unsigned int pixel = (s >> shift) & 15U;

               check_tRNS

#  ifdef PNG_READ_sBIT_SUPPORTED
               /* insignificant_bits may be 0, 1, 2 or 3, requiring a multiply
                * by 17, 255/7, 85 or 255.  Since this operation is always
                * cached we don't much care about the time to do the divide
                * below.
                */
               if (insignificant_bits)
                  pixel = ((pixel>>insignificant_bits) * 255U + (div>>1)) / div;

               else
#  endif
                  pixel *= 17U;

               *--dp = PNG_BYTE(pixel);
               if (dp <= ep) break;
            }

            shift += 4U;
         }

         debug(dp == ep && shift == 4U && sp == tc->sp);
         break;
      }

      default:
         impossible("bit depth");
   }

   tc->sp = ep;

#  undef check_tRNS
#  undef png_ptr
}

static void
png_init_expand(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* The possible combinations are:
    *
    * 1) PALETTE: the 'palette' flag should be set on the transform control and
    *    all that need be done is cancel this to cause the cache code to do the
    *    expansion.
    *
    * 2) LBP_GRAY, LBP_GRAY+tRNS: use png_do_expand_lbd_gray to do the required
    *    expand.  Can be cached.
    *
    * 3) tRNS: scan the row for the relevant tRNS value.
    *
    * Note that expanding 8 to 16 bits is a byte op in pngtrans.c (it just
    * replicates bytes).
    */
   if (tc->palette)
   {
      debug(tc->caching && !(tc->format & PNG_FORMAT_FLAG_COLORMAP));

      if (((*transform)->args & PNG_EXPAND_PALETTE) != 0U)
      {
         tc->palette = 0U;
         tc->invalid_info |= PNG_INFO_PLTE + PNG_INFO_tRNS;
         tc->cost = PNG_CACHE_COST_LIMIT; /* the cache is required! */
      }

      /* Note that this needs to happen when the row is processed (!tc->init) as
       * well.
       */
   }

   else if (!(tc->format & PNG_FORMAT_FLAG_COLORMAP))
   {
      png_uint_32 args = (*transform)->args & PNG_BIC_MASK(PNG_EXPAND_PALETTE);
      unsigned int bit_depth = tc->bit_depth;

      debug(tc->init);

      if (bit_depth >= 8U)
         args &= PNG_BIC_MASK(PNG_EXPAND_LBD_GRAY);

#     ifdef PNG_READ_tRNS_SUPPORTED
         if (png_ptr->num_trans == 0U ||
             (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0U ||
             (tc->invalid_info & PNG_INFO_tRNS) != 0U)
#     endif
         args &= PNG_BIC_MASK(PNG_EXPAND_tRNS);

      (*transform)->args = args;

      switch (args)
      {
         case PNG_EXPAND_LBD_GRAY:
            tc->bit_depth = 8U;
            tc->invalid_info |= PNG_INFO_tRNS;

            if (tc->init == PNG_TC_INIT_FINAL)
               (*transform)->fn = png_do_expand_lbd_gray;
            break;

#     ifdef PNG_READ_tRNS_SUPPORTED
         case PNG_EXPAND_LBD_GRAY + PNG_EXPAND_tRNS:
            tc->bit_depth = 8U;
            tc->format |= PNG_FORMAT_FLAG_ALPHA;
            tc->invalid_info |= PNG_INFO_tRNS;
            tc->transparent_alpha = 1U;

            /* In this case tRNS must be left unmodified for the expansion code
             * to handle.
             */
            if (tc->init == PNG_TC_INIT_FINAL)
               (*transform)->fn = png_do_expand_lbd_gray;
            break;

         case PNG_EXPAND_tRNS:
            if (tc->init == PNG_TC_INIT_FINAL)
            {
               png_expand *tr = png_transform_cast(png_expand, *transform);

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

               tr->ntrans = fill_transparent_pixel(png_ptr,
                  tr->transparent_pixel);
               tr->tr.fn = png_do_expand_tRNS;
            } /* TC_INIT_FINAL */

            tc->format |= PNG_FORMAT_FLAG_ALPHA;
            tc->invalid_info |= PNG_INFO_tRNS;
            tc->transparent_alpha = 1U;
            break;
#     endif /* READ_tRNS */

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

      implies(tc->init == PNG_TC_INIT_FINAL,
              (*transform)->fn != png_init_expand);
   }

   else /* not applicable */
   {
      debug(tc->init);
      (*transform)->fn = NULL;
      NOT_REACHED;
   }
#  undef png_ptr
}

void PNGAPI
png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
{
   if (png_ptr != NULL)
      png_add_transform(png_ptr, sizeof (png_expand), png_init_expand,
         PNG_TR_EXPAND)->args |= PNG_EXPAND_LBD_GRAY;
}

/* Expand paletted images to 8-bit RGB or, if there is a tRNS chunk, RGBA.
 * Note that this is effectively handled by the read code palette optimizations.
 *
 * API CHANGE: this used to have the completely unexpected side effect of
 * turning on the above two optimizations.
 */
void PNGAPI
png_set_palette_to_rgb(png_structrp png_ptr)
{
   if (png_ptr != NULL)
      png_add_transform(png_ptr, sizeof (png_expand), png_init_expand,
         PNG_TR_EXPAND)->args |= PNG_EXPAND_PALETTE;
}

/* Expand paletted images to RGB, expand grayscale images of less than 8-bit
 * depth to 8-bit depth, and expand tRNS chunks to alpha channels.  I.e. all the
 * above.
 */
void PNGAPI
png_set_expand(png_structrp png_ptr)
{
   if (png_ptr != NULL)
   {
      png_set_palette_to_rgb(png_ptr);
      png_set_expand_gray_1_2_4_to_8(png_ptr);
      png_set_tRNS_to_alpha(png_ptr);
   }
}
#endif /* READ_EXPAND */

#if defined(PNG_READ_EXPAND_SUPPORTED) ||\
    defined(PNG_READ_STRIP_ALPHA_SUPPORTED)

#define PNG_INIT_STRIP_ALPHA 1U
#define PNG_INIT_EXPAND_tRNS 2U
static void
png_init_alpha(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   int required = 0;

#  if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_tRNS_SUPPORTED)
      if ((*transform)->args & PNG_INIT_EXPAND_tRNS)
      {
         /* Prior to 1.7 the alpha channel was stripped after expanding the tRNS
          * chunk, so this effectively cancelled out the expand.
          */
         if (png_ptr->num_trans > 0 && !tc->palette &&
             !((*transform)->args & PNG_INIT_STRIP_ALPHA))
         {
            debug((tc->format & PNG_FORMAT_FLAG_COLORMAP) == 0);

            required = 1;
            tc->expand_tRNS = 1U;

            /* This happens as a result of an explicit API call to
             * png_set_tRNS_to_alpha, so expand low-bit-depth gray too:
             */
            if (tc->init == PNG_TC_INIT_FORMAT)
               png_add_transform(png_ptr, sizeof (png_expand), png_init_expand,
                  PNG_TR_EXPAND)->args |= PNG_EXPAND_tRNS + PNG_EXPAND_LBD_GRAY;
         }

         else
            (*transform)->args &= PNG_BIC_MASK(PNG_INIT_EXPAND_tRNS);
      }
#  endif /* READ_EXPAND && READ_tRNS */

#  ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
      if ((*transform)->args & PNG_INIT_STRIP_ALPHA)
      {
         /* When compose is being done tRNS will be expanded regardless of the
          * above test.  Rather that trying to work out if this will happen the
          * code just inserts a strip operation; it will be removed later if it
          * is not needed.
          */
         required = 1;
         tc->strip_alpha = 1U;

         if (tc->init == PNG_TC_INIT_FORMAT)
            png_add_strip_alpha_byte_ops(png_ptr);
      }
#  endif /* READ_STRIP_ALPHA */

   if (!required)
      (*transform)->fn = NULL;
#  undef png_ptr
}
#endif /* READ_EXPAND || READ_STRIP_ALPHA */

#ifdef PNG_READ_EXPAND_SUPPORTED
/* Expand tRNS chunks to alpha channels.  This only expands the tRNS chunk on
 * non-palette formats; call png_set_palette_to_rgb to get the corresponding
 * effect for a palette.
 *
 * Note that this will expand low bit depth gray if there is a tRNS chunk, but
 * if not nothing will happen.
 *
 * API CHANGE: this used to do all the expansions, it was rather pointless
 * calling it.
 */
void PNGAPI
png_set_tRNS_to_alpha(png_structrp png_ptr)
{
   if (png_ptr != NULL)
      png_add_transform(png_ptr, 0/*size*/, png_init_alpha, PNG_TR_INIT_ALPHA)->
         args |= PNG_INIT_EXPAND_tRNS;
}
#endif /* READ_EXPAND */

#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
void PNGAPI
png_set_strip_alpha(png_structrp png_ptr)
{
   if (png_ptr != NULL)
      png_add_transform(png_ptr, 0/*size*/, png_init_alpha, PNG_TR_INIT_ALPHA)->
         args |= PNG_INIT_STRIP_ALPHA;
}
#endif /* READ_STRIP_ALPHA */

#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
static void
png_do_chop_16_to_8(png_transformp *transform, png_transform_controlp tc)
   /* This is actually a repeat of the byte transform, unnecessary code
    * replication.
    *
    * TODO: remove this
    */
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); /* source */
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); /* end+1 */
   png_bytep dp = png_voidcast(png_bytep, tc->dp); /* destination */

   debug(tc->bit_depth == 16U);
   tc->sp = dp;
   tc->bit_depth = 8U;

   while (sp < ep)
      *dp++ = *sp, sp += 2;

   debug(sp == ep);
#  undef png_ptr

   PNG_UNUSED(transform)
}

/* A transform containing some useful scaling values... */
typedef struct
{
   png_transform   tr;
   png_uint_32     shifts; /* 4 4-bit values preceeded by a shibboleth (1) */
   png_uint_32     channel_scale[4];
} png_transform_scale_16_to_8;

/* Scale rows of bit depth 16 down to 8 accurately */
static void
png_do_scale_16_to_8(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp); /* source */
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc); /* end+1 */
   png_bytep dp = png_voidcast(png_bytep, tc->dp); /* destination */
   png_transform_scale_16_to_8 *tr =
      png_transform_cast(png_transform_scale_16_to_8, *transform);
   png_uint_32p scale = 0;
   png_uint_32 shift = 1U; /* set the shibboleth at the start */

   debug(tc->bit_depth == 16U);
   tc->sp = dp;
   tc->bit_depth = 8U;

   while (sp < ep)
   {
      /* The input is an array of 16 bit components, these must be scaled to
       * 8 bits each taking into account the sBIT setting.  The calculation
       * requires that the insignificant bits be stripped from the input value
       * via a shift then scaled back to 8 bits:
       *
       *      output = ((input >> shift) * scale + round) >> 24
       *
       * The shifts are packed into tr->shifts, with the end of the list marked
       * by a shibboleth, 1, which is preset above.
       */
      png_uint_32 v = png_get_uint_16(sp);

      sp += 2;

      if (shift == 1U)
      {
         shift = tr->shifts;
         scale = tr->channel_scale;
      }

      *dp++ = PNG_BYTE(((v >> (shift & 0xFU)) * *scale++ + 0x800000U) >> 24);
      shift >>= 4;
   }

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

static int
add_scale(png_transform_scale_16_to_8 *tr, unsigned int sBIT, unsigned int ch)
{
   /* This is the output max (255) scaled by 2^24 divided by the input max'
    * (which is variable) and rounded.  It gives the exact 8-bit answer for all
    * input sBIT depths when used in the calculation:
    *
    *    output = ((input >> shift) * scale + 0x800000U) >> 24
    */
   tr->channel_scale[ch] = (0xFF000000U + ((1U<<sBIT)>>1)) / ((1U<<sBIT)-1U);
   tr->shifts |= ((16U-sBIT) & 0xFU) << (4U*ch);

   /* The result says whether there are 8 or fewer significant bits in the
    * input value; if so we can just drop the low byte.
    */
   return sBIT <= 8U;
}

static void
png_init_scale_16_to_8(png_transformp *transform, png_transform_controlp tc)
{
   if (tc->bit_depth == 16U)
   {
#     define png_ptr (tc->png_ptr)
      tc->bit_depth = 8U;
      /* But this invalidates tRNS (a 16-bit tRNS cannot be updated to match
       * 8-bit data correctly).
       */
      tc->invalid_info |= PNG_INFO_tRNS+PNG_INFO_hIST+PNG_INFO_pCAL;
      /* TODO: These need further processing: PNG_INFO_bKGD */

      if (tc->init == PNG_TC_INIT_FINAL)
      {
         png_transform_scale_16_to_8 *tr =
            png_transform_cast(png_transform_scale_16_to_8, *transform);

         /* Set the scale factors for each channel (up to 4), the factors are
          * made so that:
          *
          *     ((channel >> shift) * factor + 0x800000U) >> 24
          *
          * Gives the required 8-bit value.  The 'shift' is stored in a single
          * png_uint_32 with a shibboleth at the end.
          */
         unsigned int channels = 0U;
         int chop_ok = 1;

         tr->shifts = 0U;

         /* This adds up to four scale factors, the remainder are left as 0
          * which is safe and leads to obvious errors in the output images in
          * the event of an (internal) error.
          */
         if (tc->format & PNG_FORMAT_FLAG_COLOR)
            chop_ok &= add_scale(tr, tc->sBIT_R, channels++);

         chop_ok &= add_scale(tr, tc->sBIT_G, channels++);

         if (tc->format & PNG_FORMAT_FLAG_COLOR)
            chop_ok &= add_scale(tr, tc->sBIT_B, channels++);

         if (tc->format & PNG_FORMAT_FLAG_ALPHA)
            chop_ok &= add_scale(tr, tc->sBIT_A, channels++);

         if (chop_ok)
            tr->tr.fn = png_do_chop_16_to_8;

         else
         {
            int handled = 1;

            /* Add the shibboleth at the end */
            tr->shifts |= 1U << (4U*channels);
            tr->tr.fn = png_do_scale_16_to_8;

            /* sBIT is a little tricky; it has to be processed in the scaling
             * operation.  The result will have the same number of bits unless
             * there were more than 8 before.  The sBIT flags in the transform
             * control are left unchanged here because the data is still valid,
             * unless all the values end up as 8 in which case there is no
             * remaining sBIT info.
             *
             * Note that fields, such as alpha, which are not set for this row
             * format will always have max values, so won't reset 'handled':
             */
            if (tc->sBIT_R >= 8U) tc->sBIT_R = 8U; else handled = 0;
            if (tc->sBIT_G >= 8U) tc->sBIT_G = 8U; else handled = 0;
            if (tc->sBIT_B >= 8U) tc->sBIT_B = 8U; else handled = 0;
            if (tc->sBIT_A >= 8U) tc->sBIT_A = 8U; else handled = 0;

            /* If all the sBIT values were >= 8U all the bits are now
             * significant:
             */
            if (handled)
               tc->invalid_info |= PNG_INFO_sBIT;
         }
      }

#     undef png_ptr
   }

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

void PNGAPI
png_set_scale_16(png_structrp png_ptr)
{
   if (png_ptr != NULL)
      png_add_transform(png_ptr, sizeof (png_transform_scale_16_to_8),
         png_init_scale_16_to_8, PNG_TR_SCALE_16_TO_8);
}
#endif /* READ_SCALE_16_TO_8 */

#ifdef PNG_READ_GAMMA_SUPPORTED
   /* Code that depends on READ_GAMMA support; RGB to gray convertion and
    * background composition (including the various alpha-mode handling
    * operations which produce pre-multiplied alpha by composing on 0).
    */
/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
static png_fixed_point
png_reciprocal(png_fixed_point a)
{
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
   double r = floor(1E10/a+.5);

   if (r <= 2147483647. && r >= -2147483648.)
      return (png_fixed_point)r;
#else
   png_fixed_point res;

   if (png_muldiv(&res, PNG_FP_1, PNG_FP_1, a) != 0)
      return res;
#endif

   return 0; /* error/overflow */
}

/* This is the shared test on whether a gamma value is 'significant' - whether
 * it is worth doing gamma correction.  'significant_bits' is the number of bits
 * in the values to be corrected which are significant.
 */
static int
png_gamma_significant(png_const_structrp png_ptr, png_fixed_point gamma_val,
   unsigned int sbits)
{
#if 0
   /* This seems to be wrong.  The issue is that when the app asks for a higher
    * bit depth output than the input has significant bits it causes gamma
    * correction to be skipped (this was the intent) however there's no
    * particular guarantee that the app won't go on to do further gamma
    * processing - pngstest does this - and this messes up the results
    * completely.
    *
    * TODO: work out how to optimize this correctly.
    */
   /* The following table lists the threshold as a difference from PNG_FP_1 at
    * which the gamma correction will make a change to at least an 'sbits'
    * value.  There is no entry for 1 bit values; gamma correction is never
    * significant.
    */
   static const png_uint_16 gamma_threshold_by_sbit[15][2] =
   {
      { 36907, 63092 }, /*  2 bits */
      { 17812, 21518 }, /*  3 bits */
      {  8675,  9496 }, /*  4 bits */
      {  4290,  4484 }, /*  5 bits */
      {  2134,  2181 }, /*  6 bits */
      {  1064,  1075 }, /*  7 bits */
      {   531,   534 }, /*  8 bits */
      {   265,   266 }, /*  9 bits */
      {   132,   132 }, /* 10 bits */
      {    66,    66 }, /* 11 bits */
      {    33,    33 }, /* 12 bits */
      {    16,    16 }, /* 13 bits */
      {     8,     8 }, /* 14 bits */
      {     4,     4 }, /* 15 bits */
      {     2,     2 }, /* 16 bits */
   };

   /* Handle out of range values in release by doing the gamma correction: */
   debug_handled(sbits > 0U && sbits <= 16U);
   if (sbits == 0U || sbits > 16U)
      return 1;

   /* 1 bit input or zero gamma, no correction possible/required: */
   if (gamma_val == 0 || sbits < 2U)
      return 0;

   if (gamma_val < PNG_FP_1 - gamma_threshold_by_sbit[sbits-2U][0U])
      return gamma_val < PNG_FP_1 - png_ptr->gamma_threshold;

   else if (gamma_val > PNG_FP_1 + gamma_threshold_by_sbit[sbits-2U][1U])
      return gamma_val > PNG_FP_1 + png_ptr->gamma_threshold;
#else /* FIXUP */
   if (gamma_val < PNG_FP_1)
      return gamma_val < PNG_FP_1 - png_ptr->gamma_threshold;

   else if (gamma_val > PNG_FP_1)
      return gamma_val > PNG_FP_1 + png_ptr->gamma_threshold;

   PNG_UNUSED(sbits)
#endif /* FIXUP */

   return 0; /* not significant */
}

static int
png_gamma_equal(png_const_structrp png_ptr, png_fixed_point g1,
   png_fixed_point g2, png_fixed_point *c, unsigned int sbits)
   /* Gamma values are equal, or at least one is unknown; c is the correction
    * factor from g1 to g2, i.e. g2/g1.
    */
{
   return sbits == 1U || g1 == 0 || g2 == 0 || g1 == g2 ||
      (png_muldiv(c, g2, PNG_FP_1, g1) &&
       !png_gamma_significant(png_ptr, *c, sbits));
}

#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
int
png_need_gamma_correction(png_const_structrp png_ptr, png_fixed_point gamma,
   int sRGB_output)
   /* This is a hook for the simplified code; it just decides whether or not the
    * given gamma (which defaults to that of the PNG data) is close enough to
    * linear or sRGB not to require gamma correction.
    */
{
   if (gamma == 0)
      gamma = png_ptr->colorspace.gamma;

   if (gamma != 0 &&
       (png_ptr->colorspace.flags &
         (PNG_COLORSPACE_INVALID|PNG_COLORSPACE_HAVE_GAMMA)) ==
            PNG_COLORSPACE_HAVE_GAMMA)
   {

      if (sRGB_output && !png_muldiv(&gamma, gamma, PNG_GAMMA_sRGB, PNG_FP_1))
         return 0; /* overflow, so no correction */

      return png_gamma_significant(png_ptr, gamma, (png_ptr->color_type &
               PNG_COLOR_MASK_PALETTE) ? 8U : png_ptr->bit_depth);
   }

   return 0; /* no info, no correction */
}
#endif /* SIMPLIFIED_READ */

#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
/* Fixed point gamma.
 *
 * The code to calculate the tables used below can be found in the shell script
 * contrib/tools/intgamma.sh
 *
 * To calculate gamma this code implements fast log() and exp() calls using only
 * fixed point arithmetic.  This code has sufficient precision for either 8-bit
 * or 16-bit sample values.
 *
 * The tables used here were calculated using simple 'bc' programs, but C double
 * precision floating point arithmetic would work fine.
 *
 * 8-bit log table
 *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
 *   255, so it's the base 2 logarithm of a normalized 8-bit floating point
 *   mantissa.  The numbers are 32-bit fractions.
 */
static const png_uint_32
png_8bit_l2[128] =
{
   4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
   3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
   3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
   3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
   3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
   2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
   2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
   2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
   2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
   2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
   1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
   1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
   1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
   1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
   1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
   971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
   803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
   639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
   479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
   324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
   172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
   24347096U, 0U

#if 0 /* NOT USED */
   /* The following are the values for 16-bit tables - these work fine for the
    * 8-bit conversions but produce very slightly larger errors in the 16-bit
    * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
    * use these all the shifts below must be adjusted appropriately.
    */
   65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
   57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
   50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
   43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
   37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
   31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
   25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
   20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
   15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
   10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
   6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
   1119, 744, 372
#endif
};

#if 0 /* UNUSED */
static png_int_32
png_log8bit(unsigned int x)
{
   png_uint_32 lg2 = 0U;

   /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
    * because the log is actually negate that means adding 1.  The final
    * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
    * input), return -1 for the overflow (log 0) case, - so the result is
    * always at most 19 bits.
    */
   if ((x &= 0xffU) == 0U) /* 0 input, -inf output */
      return -0xfffff;

   if ((x & 0xf0U) == 0U)
      lg2  = 4U, x <<= 4;

   if ((x & 0xc0U) == 0U)
      lg2 += 2U, x <<= 2;

   if ((x & 0x80U) == 0U)
      lg2 += 1U, x <<= 1;

   /* result is at most 19 bits, so this cast is safe: */
   return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128U]+32768U)>>16));
}
#endif /* UNUSED */

/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
 * for 16-bit images we use the most significant 8 bits of the 16-bit value to
 * get an approximation then multiply the approximation by a correction factor
 * determined by the remaining up to 8 bits.  This requires an additional step
 * in the 16-bit case.
 *
 * We want log2(value/65535), we have log2(v'/255), where:
 *
 *    value = v' * 256 + v''
 *          = v' * f
 *
 * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
 * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
 * than 258.  The final factor also needs to correct for the fact that our 8-bit
 * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
 *
 * This gives a final formula using a calculated value 'x' which is value/v' and
 * scaling by 65536 to match the above table:
 *
 *   log2(x/257) * 65536
 *
 * Since these numbers are so close to '1' we can use simple linear
 * interpolation between the two end values 256/257 (result -368.61) and 258/257
 * (result 367.179).  The values used below are scaled by a further 64 to give
 * 16-bit precision in the interpolation:
 *
 * Start (256): -23591
 * Zero  (257):      0
 * End   (258):  23499
 *
 * In libpng 1.7.0 this is further generalized to return -log2(value/maxval) for
 * any maxval up to 65535.  This is done by evaluating -log2(value/65535) first
 * then adjusting for the required maxval:
 *
 *         ( value)        (value    65535)        (value)     ( 65535)
 *    -log2(------) = -log2(----- x ------) = -log2(-----)-log2(------)
 *         (maxval)        (65535   maxval)        (65535)     (maxval)
 *
 * The extra argument, 'factor', is (2^(16+12))*log2(65535/maxval) (a positive
 * value less than 2^32) and this is *subtracted* from the intermediate
 * calculation below.
 */
static png_int_32
png_log(unsigned int x, png_uint_32 factor)
   /* x: a value of up to 16 bits,
    * factor: a 4.28 number which is subtracted from the log below
    */
{
   png_uint_32 lg2 = 0U;

   /* As above, but now the input has 16 bits. */
   if ((x &= 0xffffU) == 0U)
      return -0xfffff;

   if ((x & 0xff00U) == 0U)
      lg2  = 8U, x <<= 8;

   if ((x & 0xf000U) == 0U)
      lg2 += 4U, x <<= 4;

   if ((x & 0xc000U) == 0U)
      lg2 += 2U, x <<= 2;

   if ((x & 0x8000U) == 0U)
      lg2 += 1U, x <<= 1;

   /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
    * value.
    */
   lg2 <<= 28;
   lg2 += (png_8bit_l2[(x>>8)-128U]+8U) >> 4;

   /* Now we need to interpolate the factor, this requires a division by the top
    * 8 bits.  Do this with maximum precision.
    */
   {
      png_uint_32 i = x;

      i = ((i << 16) + (i >> 9)) / (x>> 8);

      /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
       * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us
       * exactly 16 bits to interpolate to get the low bits of the result.
       * Round the answer.  Note that the end point values are scaled by 64 to
       * retain overall precision and that 'lg2' is current scaled by an extra
       * 12 bits, so adjust the overall scaling by 6-12.  Round at every step.
       */
      i -= 1U << 24;

      if (i <= 65536U) /* <= '257' */
         lg2 += ((23591U * (65536U-i)) + (1U << (16+6-12-1))) >> (16+6-12);

      else
         lg2 -= ((23499U * (i-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
   }

   if (lg2 >= factor)
      return (png_int_32)/*SAFE*/((lg2 - factor + 2048U) >> 12);

   else /* the result will be greater than 1.0, so negative: */
      return -(png_int_32)/*SAFE*/((factor - lg2 + 2048U) >> 12);
}

#if 0 /* UNUSED */
static png_int_32
png_log16bit(unsigned int x)
{
   return png_log(x, 0U);
}
#endif /* UNUSED */

/* libpng 1.7.0: generalization of png_log{8,16}bit to accept an n-bit input
 * value.  We want to maintain 1% accuracy in linear light space.  This
 * corresponds to, approximately, (1*g)% in a gamma encoded space where the
 * gamma encoding is 'g' (in the PNG sense, e.g. 0.45455 for sRGB).  Apparently
 * this requires unbounded accuracy as the gamma encoding value goes down and
 * this is a problem for modern HDR data because it may require a high gamma to
 * accurately encode image data over a wide dynamic range; the dynamic range of
 * 16-bit linear data is only 655:1 if 1% accuracy is needed!
 *
 * However 16-bit gamma encoded data is still limited because PNG can only
 * express gamma encoding.  (A log-to-base-1.01 encoding is unlimited; a 12-bit
 * value, with 4094 steps, has a dynamic range of more than 1:10^17, which
 * exceeds the human eye's range of 1:10^14.)
 *
 * Notice that sRGB uses a 1/2.4 encoding and CIELab uses a 1/3 encoding.  It is
 * obvious that, if we assume a maximum D difference in the luminance of
 * adjacent pixel values the dynamic range is given by the lowest pixel value
 * which is D or less greater than its predecessor, so:
 *
 *   ( P ) (1)
 *   (---)^(-) = D
 *   (P-1) (g)
 *
 * and the maximum dynamic range that can be achieved using M+1 separate values,
 * where M+1 is 2^N-1 for an N bit value, reserving the first value for 0, is:
 *
 *              (M) (1)
 *   range(R) = (-)^(-)
 *              (P) (g)
 *
 * So we can eliminate 'P' from the two equations:
 *
 *   P = (P-1) x (D^g)
 *
 *        D^g
 *   P = -----
 *       D^g-1
 *
 *       (M x (D^g-1)) (1)
 *   R = (-----------)^(-)
 *       (    D^g    ) (g)
 *
 *       (M x (D^g-1)) ^ (1/g)
 *     = ---------------------
 *                D
 *
 * Which is a function in two variables (R and g) for a given D (maximum delta
 * between two adjacent pixel values) and M (number of pixel values, controlled
 * by the channel bit depth).
 *
 * See contrib/tools/dynamic-range.c for code exploring this function.  This
 * program will output the optimal gamma for a given number of bits and
 * precision.
 *
 * The range of sensitivity of human vision is roughly as follows (this comes
 * from the wikipedia article on scotopic vision):
 *
 *     scotopic: 10^-6 to 10^-3.5 cd/m^2
 *     mesopic:  10^-3 to 10^0.5 cd/m^2
 *     photopic: 10 to 10^8 cd/m^2
 *
 * Giving a total range of about 1:10^14.  The maximum precision at which this
 * range can be achieved using 16-bit channels is about .15% using a gamma of
 * 36, higher ranges are possible using higher gammas but precision is reduced.
 * The range with 1% precision and 16-bit channels is 1:10^104, using a gamma of
 * 240.
 *
 * In general the optimal gamma for n-bit channels (where 'n' is at least 7 and
 * precision is .01 or less) is:
 *
 *                  2^n * precision
 *          gamma = ---------------
 *                       2.736
 *
 * Or: (24000 * precision) for 16-bit data.
 *
 * The net effect is that we can't rely on the encoding gamma being limited to
 * values around 1/2.5!
 */
static png_int_32
png_log_nbit(unsigned int x, unsigned int nbits)
{
   static const png_uint_32 factors[16] =
   {
      4294961387U, /* 1 bit */
      3869501255U, /* 2 bit */
      3541367788U, /* 3 bit */
      3246213428U, /* 4 bit */
      2965079441U, /* 5 bit */
      2690447525U, /* 6 bit */
      2418950626U, /* 7 bit */
      2148993476U, /* 8 bit */
      1879799410U, /* 9 bit */
      1610985205U, /* 10 bit */
      1342360514U, /* 11 bit */
      1073830475U, /* 12 bit */
       805347736U, /* 13 bit */
       536888641U, /* 14 bit */
       268441365U, /* 15 bit */
               0U  /* 16 bit */
   };

   return png_log(x, factors[nbits-1]);
}


/* The 'exp()' case must invert the above, taking a 20-bit fixed point
 * logarithmic value and returning a 16 or 8-bit number as appropriate.  In
 * each case only the low 16 bits are relevant - the fraction - since the
 * integer bits (the top 4) simply determine a shift.
 *
 * The worst case is the 16-bit distinction between 65535 and 65534. This
 * requires perhaps spurious accuracy in the decoding of the logarithm to
 * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance
 * of needing this accuracy in practice.
 *
 * To deal with this the following exp() function works out the exponent of the
 * frational part of the logarithm by using an accurate 32-bit value from the
 * top four fractional bits then multiplying in the remaining bits.
 */
static const png_uint_32
png_32bit_exp[16] =
{
   /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
   4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
   3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
   2553802834U, 2445529972U, 2341847524U, 2242560872U
};

/* Adjustment table; provided to explain the numbers in the code below. */
#if 0 /* BC CODE */
for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
   11 44937.64284865548751208448
   10 45180.98734845585101160448
    9 45303.31936980687359311872
    8 45364.65110595323018870784
    7 45395.35850361789624614912
    6 45410.72259715102037508096
    5 45418.40724413220722311168
    4 45422.25021786898173001728
    3 45424.17186732298419044352
    2 45425.13273269940811464704
    1 45425.61317555035558641664
    0 45425.85339951654943850496
#endif

static png_uint_32
png_exp(png_int_32 x)
   /* Utility, the value 'x' must be in the range 0..0x1fffff */
{
   /* Obtain a 4-bit approximation */
   png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];

   /* Incorporate the low 12 bits - these decrease the returned value by
    * multiplying by a number less than 1 if the bit is set.  The multiplier
    * is determined by the above table and the shift. Notice that the values
    * converge on 45426 and this is used to allow linear interpolation of the
    * low bits.
    */
   if (x & 0x800)
      e -= (((e >> 16) * 44938U) +  16U) >> 5;

   if (x & 0x400)
      e -= (((e >> 16) * 45181U) +  32U) >> 6;

   if (x & 0x200)
      e -= (((e >> 16) * 45303U) +  64U) >> 7;

   if (x & 0x100)
      e -= (((e >> 16) * 45365U) + 128U) >> 8;

   if (x & 0x080)
      e -= (((e >> 16) * 45395U) + 256U) >> 9;

   if (x & 0x040)
      e -= (((e >> 16) * 45410U) + 512U) >> 10;

   /* And handle the low 6 bits in a single block. */
   e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;

   /* Handle the upper bits of x, note that this works for x up to 0x1fffff but
    * fails for larger or negative x, where the shift (x >> 16) exceeds 31:
    */
   e >>= x >> 16;
   return e;
}

#if 0 /* UNUSED */
static png_byte
png_exp8bit(png_int_32 lg2)
{
   /* The input is a negative fixed point (16:16) logarithm with a useable range
    * of [0.0..8.0).  Clamp the value so that the output of png_exp is in the
    * range (254.5/255..0.5/255):
    */
   if (lg2 <= 185) /* -log2(254.5/255) */
      return 255U;

   else if (lg2 > 589453) /* -log2(0.5/255) */
      return 0U;

   else
   {
      /* Get a 32-bit value: */
      png_uint_32 x = png_exp(lg2);

      /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that
       * the second, rounding, step can't overflow because of the first,
       * subtraction, step.
       */
      x -= x >> 8;
      return PNG_BYTE((x + 0x7fffffU) >> 24);
   }
}

static png_uint_16
png_exp16bit(png_int_32 lg2)
{
   if (lg2 <= 0) /* -log2(65534.5/65535) */
      return 65535U;

   else if (lg2 > 1114110) /* -log2(0.5/65535) */
      return 0U;

   else
   {
      /* Get a 32-bit value: */
      png_uint_32 x = png_exp(lg2);

      /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
      x -= x >> 16;
      return PNG_UINT_16((x + 32767U) >> 16);
   }
}
#endif /* UNUSED */

static png_uint_32
png_exp_nbit(png_int_32 lg2, unsigned int n)
{
   /* These pre-computed limits give the low value of lg2 at and below which
    * 2^(-lg2/65536) * (2^n-1) gives (2^n-1) and the high value of lg2 above
    * which 2(^-lg2/65536) * (2^n-1) gives 0:
    */
   static const png_int_32 limits[16][2] =
   {
      { 65535,   65535 }, /* bits =  1 */
      { 17238,  169408 }, /* bits =  2 */
      {  7006,  249518 }, /* bits =  3 */
      {  3205,  321577 }, /* bits =  4 */
      {  1537,  390214 }, /* bits =  5 */
      {   753,  457263 }, /* bits =  6 */
      {   372,  523546 }, /* bits =  7 */
      {   185,  589453 }, /* bits =  8 */
      {    92,  655175 }, /* bits =  9 */
      {    46,  720803 }, /* bits = 10 */
      {    23,  786385 }, /* bits = 11 */
      {    11,  851944 }, /* bits = 12 */
      {     5,  917492 }, /* bits = 13 */
      {     2,  983034 }, /* bits = 14 */
      {     1, 1048573 }, /* bits = 15 */
      {     0, 1114110 }  /* bits = 16 */
   };

   /* If 'max' is 2^n-1: */
   if (lg2 <= limits[n-1][0]) /* -log2((max-.5)/max) */
      return (1U << n)-1U;

   else if (lg2 > limits[n-1][1]) /* -log2(.5/max) */
      return 0U;

   else /* 'n' will be at least 2 */
   {
      /* Get a 32-bit value: */
      png_uint_32 x = png_exp(lg2);

      /* Convert the 32-bit value to 0..(2^n-1) by multiplying by 2^n-1: */
      x -= x >> n;
      return (x + ((1U<<(31U-n))-1U)) >> (32U-n);
   }
}
#endif /* !FLOATING_ARITHMETIC */

#if 0 /* UNUSED */
static png_byte
png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
{
   if (value == 0U)
      return 0U;

   else if (value >= 255U)
      return 255U;

   else
   {
#     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
         /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
          * convert this to a floating point value.  This includes values that
          * would overflow if 'value' were to be converted to 'int'.
          *
          * Apparently GCC, however, does an intermediate conversion to (int)
          * on some (ARM) but not all (x86) platforms, possibly because of
          * hardware FP limitations.  (E.g. if the hardware conversion always
          * assumes the integer register contains a signed value.)  This results
          * in ANSI-C undefined behavior for large values.
          *
          * Other implementations on the same machine might actually be ANSI-C90
          * conformant and therefore compile spurious extra code for the large
          * values.
          *
          * We can be reasonably sure that an unsigned to float conversion
          * won't be faster than an int to float one.  Therefore this code
          * assumes responsibility for the undefined behavior, which it knows
          * can't happen because of the check above.
          *
          * Note the argument to this routine is an (unsigned int) because, on
          * 16-bit platforms, it is assigned a value which might be out of
          * range for an (int); that would result in undefined behavior in the
          * caller if the *argument* ('value') were to be declared (int).
          */
         double r = 255*pow((int)/*SAFE*/value/255.,gamma_val*.00001);
         if (r < .5)
            return 0U;

         else if (r >= 254.5)
            return 255U;

         r = floor(r+.5);
         return (png_byte)/*SAFE*/r;
#     else
         png_int_32 lg2 = png_log8bit(value);
         png_int_32 res;

         /* Overflow in the muldiv means underflow in the calculation, this is
          * OK (it happens for ridiculously high gamma).
          */
         if (!png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
            return 0U; /* underflow */

         return png_exp8bit(res);
#     endif
   }
}
#endif /* UNUSED */

/* libpng-1.7.0: this private function converts an n-bit input value to an
 * m-bit output value.
 */
unsigned int
png_gamma_nxmbit_correct(unsigned int value, png_fixed_point gamma_val,
   unsigned int n/*input bits*/, unsigned int m/*output bits */)
{
   if (value == 0U)
      return 0U;

   else
   {
      unsigned int min  = (1U<<n) - 1U;
      unsigned int mout = (1U<<m) - 1U;

      if (value >= min)
         return mout;

      else
      {
#        ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
            double r = value;
            r /= min;
            r = floor(mout * pow(r, gamma_val*.00001)+.5);
            if (r < 1)
               return 0U;

            else if (r >= mout)
               return mout;

            return (unsigned int)/*SAFE*/r;
#        else
            png_int_32 lg2 = png_log_nbit(value, n);
            png_int_32 res;

            if (!png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
               return 0U; /* underflow */

            return png_exp_nbit(res, m);
#        endif
      }
   }
}

#if 0 /*UNUSED*/
static unsigned int
png_gamma_sbit_correct(unsigned int value, png_fixed_point gamma_val,
   unsigned int n/*input bits*/, unsigned int sbits,
   unsigned int m/*output bits */)
   /* As above but the number of significant bits in 'n' is passed in. */
{
   if (sbits < n)
   {
      value >>= (n-sbits);
      n = sbits;
   }

   return png_gamma_nxmbit_correct(value, gamma_val, n, m);
}
#endif /*UNUSED*/

static int
push_gamma_expand(png_transformp *transform, png_transform_controlp tc,
      int need_alpha)
   /* Utility to push a transform to expand low-bit-depth gray and, where
    * required, tRNS chunks.  The caller must return immediately if this
    * returns true because the init of the new transform has been run in place
    * of the caller's.
    */
{
#  define png_ptr (tc->png_ptr)
   unsigned int expand = 0;

   affirm(tc->init == PNG_TC_INIT_FINAL);

   if (tc->bit_depth < 8U) /* low bit gray: expand to 8 bits */
      expand = PNG_EXPAND_LBD_GRAY;

   /* Gamma correction invalidates tRNS, so if it is being expanded and
    * alpha is not being stripped expand it now.
    */
   if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette &&
       png_ptr->num_trans == 1 && (tc->invalid_info & PNG_INFO_tRNS) == 0)
   {
      if (need_alpha || (tc->expand_tRNS && !tc->strip_alpha))
         expand |= PNG_EXPAND_tRNS;

      else
         tc->invalid_info |= PNG_INFO_tRNS;
   }

   if (expand == 0)
      return 0; /* nothing needs to be done */

   {
      png_transformp tr = png_push_transform(png_ptr, sizeof (png_expand),
         png_init_expand, transform, NULL/*don't run init*/);

      debug(tr == *transform);
      tr->args |= expand;

      /* This must be run immediately, because it just got inserted where this
       * transform is; this is safe, the caller must return immediately.
       */
      png_init_expand(transform, tc);
      affirm(tr->fn != NULL); /* because it should need to do something! */
   }

   return 1;
#  undef png_ptr
}

/* Low bit depth gray gamma correction.  The 1-bit case is a no-op because 0 and
 * 1 always map to 0 and 1.  The 2-bit case has the following possiblities:
 *
 *   bits/correction: g0 g1 g2 g3 g4 g5 g6
 *    00      ->      00 00 00 00 00 00 00
 *    01      ->      11 10 10 01 00 00 00
 *    10      ->      11 11 10 10 10 01 00
 *    11      ->      11 11 11 11 11 11 11
 *
 * Where the breakpoints are:
 *
 *    g0:          correction <=  16595 (1 - log(2.5/3))
 *    g1:  16595 < correction <=  44966 (log(2.5/3)/log(2/3))
 *    g2:  44966 < correction <=  63092 (1 - log(1.5/3))
 *    g3:  63092 < correction <= 163092 (1 - log(.5/3))
 *    g4: 163092 < correction <= 170951 (log(1.5/3)/log(2/3))
 *    g5: 170951 < correction <= 441902 (log(.5/3)/log(2/3)
 *    g6  441902 < correction
 *
 * This can be done by bit-hacking on the byte values (4 pixels), given that
 * the correction is fixed (indeed, it can be done on whole 32-bit values!)
 *
 *    g0: B |= B>>1; B &= 0x55U; B |= B<<1;  * either bit set
 *    g1: B ^= B>>1; B &= 0x55U; B += B;     * one bit set
 *    g2: B &= (~B)>>1; B &= 0x55U; B += B;  * low bit set, high bit unset
 *    g3: no-op
 *    g4: B &= (~B)>>1; B &= 0x55U; B -= B;  * low bit set, high bit unset
 *    g5: B ^= B>>1; B &= 0x55U; B -= B;     * one bit set
 *    g6: B &= B>>1; B &= 0x55U; B |= B<<1;  * both bits set
 */
typedef struct
{
   png_transform   tr;
   png_fixed_point correct;
   png_fixed_point to_gamma;
   png_uint_32     shifts;           /* 1 followed by up to 4 4-bit shifts */
   png_uint_32     channel_scale[4]; /* up to 4 channel scale factors */
   /* These factors are used:
    *
    *     (input >> (shifts & 0xFU) * channel_scale + SCALE_R) >> SCALE_S
    *
    * Where the rounding value, SCALE_R and the shift SCALE_S are dependent
    * on the bit depth:
    *
    *    SCALE_S = 32 - bit_depth     range 16..31
    *    SCALE_R = 1 << (SCALE_S-1)
    */
   unsigned int    to_bit_depth;
   unsigned int    encode_alpha :1;
   unsigned int    optimize_alpha :1;
} png_transform_gamma;

static unsigned int
init_gamma_sBIT(png_transform_gamma *tr, png_transform_controlp tc)
   /* Returns true if sBIT processing is required, otherwise all relevant sBIT
    * values match the from (tc) bit depth.
    */
{
   /* The to_bit_depth and to_gamma fields are already set, but updated values
    * are needed for sBIT and the shifts and channel_scale fields must be filled
    * in correctly.  The do_gamma setting says whether gamma correction will be
    * done, but the scale factors are filled in regardless.
    *
    * The general scaling equation is:
    *
    *    ((in >> shift) * factor + round) >> (32 - to_bit_depth)
    *
    * 'factor' is then the rounded value of:
    *
    *      out_max
    *      ------- . (1 << (32-to_bit_depth))
    *       in_max
    */
#  define png_ptr (tc->png_ptr)
   const unsigned int to_bit_depth = tr->to_bit_depth;
   const png_uint_32 numerator = ((1U<<to_bit_depth)-1U) << (32U-to_bit_depth);
   /* in_max depends on the number of significant bits */
   const unsigned int from_bit_depth = tc->bit_depth;

   /* The data in the gamma transform is stored in the order of the channels in
    * the input row, which is the PNG order.  It may be reversed below.
    */
   png_uint_32p channel_scale = tr->channel_scale;
   png_uint_32 shifts = 0U;
   unsigned int count = 0U;
   unsigned int need_sBIT = 0U;

   if (tc->format & PNG_FORMAT_FLAG_COLOR)
   {
      const unsigned int sBIT = tc->sBIT_R;

      if (sBIT < from_bit_depth)
         need_sBIT = 1U;

      debug(sBIT > 0U && sBIT <= from_bit_depth);
      shifts |= (from_bit_depth - sBIT) << count;
      count += 4U;
      /* round the scale: */
      *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);
   }

   {
      const unsigned int sBIT = tc->sBIT_G;

      if (sBIT < from_bit_depth)
         need_sBIT = 1U;

      debug(sBIT > 0U && sBIT <= from_bit_depth);
      shifts |= (from_bit_depth - sBIT) << count;
      count += 4U;
      *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);
   }

   if (tc->format & PNG_FORMAT_FLAG_COLOR)
   {
      const unsigned int sBIT = tc->sBIT_B;

      if (sBIT < from_bit_depth)
         need_sBIT = 1U;

      debug(sBIT > 0U && sBIT <= from_bit_depth);
      shifts |= (from_bit_depth - sBIT) << count;
      count += 4U;
      /* round the scale: */
      *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);
   }

   if (tc->format & PNG_FORMAT_FLAG_ALPHA)
   {
      const unsigned int sBIT = tc->sBIT_A;

      if (sBIT < from_bit_depth)
         need_sBIT = 1U;

      debug(sBIT > 0U && sBIT <= from_bit_depth);
      shifts |= (from_bit_depth - sBIT) << count;
      count += 4U;
      /* round the scale: */
      *channel_scale++ = (numerator + (1U<<(sBIT-1U))) / ((1U << sBIT)-1U);
   }

   tr->shifts = shifts | (1U << count);

   return need_sBIT;
#  undef png_ptr
}

static void
reverse_gamma_sBIT(png_transform_gamma *tr)
{
   /* This is called for the 'down' gamma implementations, they read the shifts
    * and the channel scales in reverse, so:
    */
   png_uint_32 shifts = tr->shifts;
   png_uint_32 scales[4U];
   unsigned int count = 0U;

   tr->shifts = 1U;

   while (shifts != 1U)
   {
      scales[3U-count] = tr->channel_scale[count];
      ++count;
      tr->shifts <<= 4;
      tr->shifts |= shifts & 0xFU;
      shifts >>= 4;
   }

   memcpy(tr->channel_scale, scales+(4U-count), count * sizeof (png_uint_32));
}

static void
png_do_gamma8_up(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);
   const png_fixed_point correct = tr->correct;
   const unsigned int bit_depth = tr->to_bit_depth;
   const png_uint_32 shifts = tr->shifts;

   affirm(tc->bit_depth == 8U);
   affirm(tr->shifts != 0U/*uninitialized*/);
   debug((shifts & 0x8888U) == 0U); /* all shifts 7 or less */
   debug(!tr->encode_alpha && !tr->optimize_alpha); /* only set for 16 bits */

   tc->sp = dp;
   tc->bit_depth = bit_depth;
   tc->gamma = tr->to_gamma;

   /* Handle the <8 bit output case differently because there can be no alpha
    * channel.
    */
   if (bit_depth < 8U)
   {
      const unsigned int shift = shifts & 0xFU;
      unsigned int bits = 8U;
      unsigned int ob = 0U;

      debug((shifts >> 4) == 1U && shift < 8U);
      affirm(PNG_TC_CHANNELS(*tc) == 1);

      do
      {
         const unsigned int inb = png_gamma_nxmbit_correct(
            *sp++ >> shift, correct, 8U-shift, bit_depth);
         bits -= bit_depth;
         ob = ob | (inb << bits);
         if (bits == 0U)
            bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;
      }
      while (sp < ep);

      if (bits < 8U)
         *dp++ = PNG_BYTE(ob);
   }

   else /* 8-bit --> 8-bit */
   {
      png_uint_32 alpha_scale;
      const unsigned int channels = PNG_TC_CHANNELS(*tc);
      unsigned int channel, alpha;

      debug(bit_depth == 8U && (shifts >> (4*channels)) == 1U);

      /* The alpha channel is always last, so if present checking against the
       * top bits of 'channels' works because of the 1U shibboleth at the end.
       */
      if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0)
         alpha_scale = alpha = 0U;

      else
      {
         alpha = shifts >> (4U*(channels-1U));
         alpha_scale = tr->channel_scale[channels-1U];
      }

      channel = 1U;

      do
      {
         unsigned int inb = *sp++, shift;

         if (channel == 1U)
            channel = shifts;

         shift = channel & 0xFU;
         inb >>= shift;

         /* The alpha channel is not gamma encoded but it may need some
          * appropriate scaling.
          */
         if (channel == alpha)
            inb = (inb * alpha_scale + 0x800000U) >> 24;

         else
            inb = png_gamma_nxmbit_correct(inb, correct, 8U-shift, 8U);

         channel >>= 4; /* for the next channel, or the shibboleth */
         *dp++ = PNG_BYTE(inb);
      }
      while (sp < ep);

      debug(channel == 1U);
   }
#  undef png_ptr
}

static void
png_do_gamma16_up(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 1U/*safety*/;
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);
   const png_fixed_point correct = tr->correct;
   const unsigned int bit_depth = tr->to_bit_depth;
   const png_uint_32 shifts = tr->shifts;

   affirm(tc->bit_depth == 16U);
   affirm(tr->shifts != 0U/*uninitialized*/);
   debug(!tr->optimize_alpha);

   /* This is exactly the same as above but the input has 16 bits per component,
    * not 8.
    */
   tc->sp = dp;
   tc->bit_depth = bit_depth;
   tc->gamma = tr->to_gamma;

   /* Handle the <8 bit output case differently, the input cannot be color (at
    * present) and, if there is an alpha channel, then it is for the
    * low-bit-depth gray input case and we expect the alpha to be transparent.
    */
   if (bit_depth < 8U)
   {
      const unsigned int shift = shifts & 0xFU;
      unsigned int bits = 8U;
      unsigned int ob = 0U;

      affirm((tc->format & PNG_FORMAT_FLAG_COLOR) == 0U);

      if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0U)
      {
         debug((shifts >> 4) == 1U && shift < 16U);
         debug(!tr->encode_alpha && !tr->optimize_alpha);

         do
         {
            unsigned int inb = *sp++ << 8; /* high bits first */
            inb = png_gamma_nxmbit_correct(
               (inb + *sp++) >> shift, correct, 16U-shift, bit_depth);

            bits -= bit_depth;
            ob = ob | (inb << bits);
            if (bits == 0U)
               bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;
         }
         while (sp < ep);

         UNTESTED
      }

      else /* low bit GA intermediate format */
      {
         debug((shifts >> 8) == 1U && shift < 16U);
         debug(!tr->encode_alpha && !tr->optimize_alpha);
         debug(tc->transparent_alpha);

         /* Gray is first then the alpha component, the alpha component is just
          * mapped to 0 or 1.
          */
         do
         {
            unsigned int gray = *sp++ << 8; /* high bits first */
            unsigned int alpha;
            gray += *sp++;

            alpha = (*sp++ << 8);
            alpha += *sp++;

            if (alpha == 0U)
               gray = 0U; /* will be replaced later */

            else
            {
               gray = png_gamma_nxmbit_correct(gray >> shift, correct,
                     16U-shift, bit_depth);
               debug(alpha == 65535U);
               alpha = (1U << bit_depth)-1U;
            }

            bits -= bit_depth;
            ob = ob | (gray << bits);
            bits -= bit_depth;
            ob = ob | (alpha << bits);

            if (bits == 0U)
               bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;
         }
         while (sp < ep-2U);
      }

      if (bits < 8U)
         *dp++ = PNG_BYTE(ob);

      debug(sp == ep+1U);
   }

   else
   {
      png_uint_32 alpha_scale;
      const unsigned int channels = PNG_TC_CHANNELS(*tc);
      unsigned int channel, alpha;

      debug((bit_depth == 8U || bit_depth == 16U) &&
            (shifts >> (4*channels)) == 1U);

      /* Note that 'encode_alpha' turns on gamma encoding of the alpha
       * channel (and this is a really weird operation!)
       */
      if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 || tr->encode_alpha)
         alpha_scale = alpha = 0U;

      else
      {
         alpha = shifts >> (4U*(channels-1U));
         alpha_scale = tr->channel_scale[channels-1U];
      }

      channel = 1U;

      if (bit_depth == 16U)
      {
         do
         {
            unsigned int inb = *sp++ << 8, shift;
            inb += *sp++;

            if (channel == 1U)
               channel = shifts;

            shift = channel & 0xFU;
            inb >>= shift;

            /* The 16-16bit scaling factor equation may be off-by-1 but this
             * hardly matters for alpha or for gamma operations.
             */
            if (channel == alpha)
               inb = (inb * alpha_scale + 0x8000U) >> 16;

            else
               inb = png_gamma_nxmbit_correct(inb, correct, 16U-shift, 16U);

            channel >>= 4; /* for the next channel, or the shibboleth */
            *dp++ = PNG_BYTE(inb >> 8);
            *dp++ = PNG_BYTE(inb);
         }
         while (sp < ep);

         debug(channel == 1U && sp == ep+1U);
      }

      else /* bit_depth == 8U */
      {
         do
         {
            unsigned int inb = *sp++ << 8, shift;
            inb += *sp++;

            if (channel == 1U)
               channel = shifts;

            shift = channel & 0xFU;
            inb >>= shift;

            if (channel == alpha)
               inb = (inb * alpha_scale + 0x800000U) >> 24;

            else
               inb = png_gamma_nxmbit_correct(inb, correct, 16U-shift, 8U);

            channel >>= 4; /* for the next channel, or the shibboleth */
            *dp++ = PNG_BYTE(inb);
         }
         while (sp < ep);

         debug(channel == 1U && sp == ep+1U);
      }
   }
#  undef png_ptr
}

#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
static void
png_do_gamma16_up_optimize(png_transformp *transform, png_transform_controlp tc)
   /* As above, but the alpha channel is 'optimized' */
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);
   const png_fixed_point correct = tr->correct;

   /* The input always as 16 bits, the output 8 or 16.  There is always an alpha
    * channel and it is converted to the 'optimized' form, where pixels with
    * alpha not 0.0 or 1.0 are left in linear form (not gamma corrected.)  Where
    * bit depth convertion is required it is from 16-bits to 8-bits and the
    * DIV257 macro can be used.
    *
    * The following affirms and NOT_REACHED cases are consequences of the way
    * the background (compose) code works:
    */
   affirm(tr->optimize_alpha && !tr->encode_alpha && tc->bit_depth == 16U);

   /* TODO: split this into separate functions */
   switch (tr->to_bit_depth)
   {
      case 8U: /* 16-bit --> 8-bit */
         tc->sp = dp;
         tc->bit_depth = 8U;
         tc->gamma = tr->to_gamma;

         switch (PNG_TC_CHANNELS(*tc))
         {
            case 2:/* GA */
               debug(tr->shifts == 0x100U);
               ep -= 3U; /*SAFETY*/

               do
               {
                  png_uint_32 alpha = PNG_DIV257((sp[2] << 8) + sp[3]);

                  switch (alpha)
                  {
                     case 0U:
                        dp[1] = dp[0] = 0U;
                        break;

                     default: /* optimized case: linear color data */
                        dp[0] = png_check_byte(png_ptr,
                              PNG_DIV257((sp[0] << 8) + sp[1]));
                        dp[1] = PNG_BYTE(alpha);
                        break;

                     case 255U: /* opaque pixels are encoded */
                        dp[0] = PNG_BYTE(png_gamma_nxmbit_correct(
                           (sp[0] << 8) + sp[1], correct, 16U, 8U));
                        dp[1] = 255U;
                        break;
                  }

                  sp += 4U;
                  dp += 2U;
               }
               while (sp < ep);

               debug(sp == ep+3U);
               break;

            case 4:/* RGBA */
               debug(tr->shifts == 0x10000U);
               ep -= 7U; /*SAFETY*/

               do
               {
                  png_uint_32 alpha = PNG_DIV257((sp[6] << 8) + sp[7]);

                  switch (alpha)
                  {
                     case 0U:
                        memset(dp, 0U, 4U);
                        break;

                     default: /* optimized case: linear color data */
                        dp[0] = PNG_BYTE(PNG_DIV257((sp[0] << 8) + sp[1]));
                        dp[1] = PNG_BYTE(PNG_DIV257((sp[2] << 8) + sp[3]));
                        dp[2] = PNG_BYTE(PNG_DIV257((sp[4] << 8) + sp[5]));
                        dp[3] = PNG_BYTE(alpha);
                        break;

                     case 255U: /* opaque pixels are encoded */
                        dp[0] = PNG_BYTE(png_gamma_nxmbit_correct(
                           (sp[0] << 8) + sp[1], correct, 16U, 8U));
                        dp[1] = PNG_BYTE(png_gamma_nxmbit_correct(
                           (sp[2] << 8) + sp[3], correct, 16U, 8U));
                        dp[2] = PNG_BYTE(png_gamma_nxmbit_correct(
                           (sp[4] << 8) + sp[5], correct, 16U, 8U));
                        dp[3] = 255U;
                        break;
                  }

                  sp += 8U;
                  dp += 4U;
               }
               while (sp < ep);

               debug(sp == ep+7U);
               break;

            default:
               NOT_REACHED;
               break;
         }
         break;

      case 16: /* 16-bit to 16-bit */
         tc->sp = dp;
         tc->bit_depth = 16U;
         tc->gamma = tr->to_gamma;

         switch (PNG_TC_CHANNELS(*tc))
         {
            case 2:/* GA */
               debug(tr->shifts == 0x100U);
               ep -= 3U; /*SAFETY*/

               do
               {
                  unsigned int alpha = (sp[2] << 8) + sp[3];

                  switch (alpha)
                  {
                     case 0U:
                        memset(dp, 0U, 4U);
                        break;

                     default: /* optimized case: linear color data */
                        if (dp != sp)
                        {
                           memcpy(dp, sp, 4U);
                           UNTESTED
                        }
                        break;

                     case 65535U: /* opaque pixels are encoded */
                        {
                           unsigned int gray = png_gamma_nxmbit_correct(
                              (sp[0] << 8) + sp[1], correct, 16U, 16U);
                           dp[0] = PNG_BYTE(gray >> 8);
                           dp[1] = PNG_BYTE(gray);
                        }
                        dp[3] = dp[2] = 255U;
                        break;
                  }

                  sp += 4U;
                  dp += 4U;
               }
               while (sp < ep);

               debug(sp == ep+3U);
               break;

            case 4:/* RGBA */
               debug(tr->shifts == 0x10000U);
               ep -= 7U; /*SAFETY*/

               do
               {
                  unsigned int alpha = (sp[6] << 8) + sp[7];

                  switch (alpha)
                  {
                     case 0U:
                        memset(dp, 0U, 8U);
                        break;

                     default: /* optimized case: linear color data */
                        if (dp != sp)
                        {
                           memcpy(dp, sp, 8U);
                           UNTESTED
                        }
                        break;

                     case 65535U: /* opaque pixels are encoded */
                        {
                           unsigned int c = png_gamma_nxmbit_correct(
                              (sp[0] << 8) + sp[1], correct, 16U, 16U);
                           dp[0] = PNG_BYTE(c >> 8);
                           dp[1] = PNG_BYTE(c);

                           c = png_gamma_nxmbit_correct(
                              (sp[2] << 8) + sp[3], correct, 16U, 16U);
                           dp[2] = PNG_BYTE(c >> 8);
                           dp[3] = PNG_BYTE(c);

                           c = png_gamma_nxmbit_correct(
                              (sp[4] << 8) + sp[5], correct, 16U, 16U);
                           dp[4] = PNG_BYTE(c >> 8);
                           dp[5] = PNG_BYTE(c);
                        }
                        dp[7] = dp[6] = 255U;
                        break;
                  }

                  sp += 8U;
                  dp += 8U;
               }
               while (sp < ep);

               debug(sp == ep+7U);
               break;

            default:
               NOT_REACHED;
               break;
         }
         break;

      default:
         NOT_REACHED;
         break;
   }
#  undef png_ptr
}
#endif /* READ_ALPHA_MODE */

static void
png_do_scale16_up(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);
   const unsigned int bit_depth = tr->to_bit_depth;

   affirm(tc->bit_depth == 16U && bit_depth < 8U);
   affirm(tr->shifts != 0U/*uninitialized*/);

   /* This is exactly the same as above but without the gamma correction and
    * without the 8-bit target support.  The code handles one or two channels,
    * but the result is not a PNG format unless the number of channels is just
    * 1 (grayscale).
    *
    * For multi-channel low bit depth the channels are packed into bytes using
    * the standard PNG big-endian packing.
    */
   affirm((tc->format & PNG_FORMAT_FLAG_COLOR) == 0);
   /* The alpha shift is actually ignored; at present we only get here with an
    * alpha channel if it is to be removed for transparent alpha processing.
    */
   debug(tc->format & PNG_FORMAT_FLAG_ALPHA ?
         (tr->shifts >> 8) == 1U : (tr->shifts >> 4) == 1U);
   debug(tc->transparent_alpha);

   tc->sp = dp;
   /* This is a pure scaling operation so sBIT is not invalidated or altered. */
   tc->bit_depth = bit_depth;

   /* TODO: maybe do this properly and use the alpha shift, but only the top bit
    * matters.
    */
   {
      const unsigned int shift = tr->shifts & 0xFU;
      const png_uint_32 factor = tr->channel_scale[0];
      const png_uint_32 round = 1U << (31U-bit_depth);
      unsigned int bits = 8U;
      unsigned int ob = 0U;

      do
      {
         png_uint_32 inb = *sp++ << 8; /* high bits first */
         inb += *sp++;

         inb = ((inb >> shift) * factor + round) >> (32U-bit_depth);
         bits -= bit_depth;
         ob = ob | (inb << bits);
         if (bits == 0U)
            bits = 8U, *dp++ = PNG_BYTE(ob), ob = 0U;
      }
      while (sp < ep);

      if (bits < 8U)
         *dp++ = PNG_BYTE(ob);
   }
#  undef png_ptr
}

static void
png_do_gamma8_down(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep ep = dp + 1U/*safety*/;
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);
   const png_fixed_point correct = tr->correct;
   const png_uint_32 shifts = tr->shifts;

   affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U);
   affirm(tr->shifts != 0U/*uninitialized*/);
   debug((shifts & 0x8888U) == 0U); /* all shifts 7 or less */
   debug(!tr->encode_alpha && !tr->optimize_alpha); /* only set for 16 bits */

   sp += PNG_TC_ROWBYTES(*tc);
   tc->sp = dp;
   tc->bit_depth = tr->to_bit_depth;
   tc->gamma = tr->to_gamma;
   dp += PNG_TC_ROWBYTES(*tc);

   {
      png_uint_32 alpha_scale;
      unsigned int channel, alpha;

      debug((shifts >> (4*PNG_TC_CHANNELS(*tc))) == 1U);

      /* We are going down so alpha, if present, is first.  Notice that the init
       * routine has to reverse both 'shifts' and 'channel_scale' for the _down
       * cases.
       */
      if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0)
         alpha_scale = alpha = 0U;

      else
      {
         alpha = shifts;
         alpha_scale = tr->channel_scale[0U];
      }

      channel = 1U;

      do /* 8-bit --> 16-bit */
      {
         unsigned int inb = *--sp, shift;

         if (channel == 1U)
            channel = shifts;

         shift = channel & 0xFU;
         inb >>= shift;

         if (channel == alpha) /* unencoded alpha, must scale */
            inb = (inb * alpha_scale + 0x8000U) >> 16;

         else
            inb = png_gamma_nxmbit_correct(inb, correct, 8U-shift, 16U);

         channel >>= 4;

         *--dp = PNG_BYTE(inb);
         *--dp = PNG_BYTE(inb >> 8);
      }
      while (dp > ep);

      debug(channel == 1U && dp == ep-1U);
   }
#  undef png_ptr
}

static void
png_do_expand8_down(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep ep = dp + 1U/*safety*/;
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);
   const png_uint_32 shifts = tr->shifts;

   affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U);
   affirm(tr->shifts != 0U/*uninitialized*/);

   sp += PNG_TC_ROWBYTES(*tc);
   tc->sp = dp;
   tc->bit_depth = 16U;
   dp += PNG_TC_ROWBYTES(*tc);

   {
      png_uint_32 channel = 1U;
      png_const_uint_32p scale = 0U;

      do /* 8-bit -> 16-bit */
      {
         unsigned int inb = *--sp, shift;

         if (channel == 1U)
            channel = shifts, scale = tr->channel_scale;

         shift = channel & 0xFU;
         channel >>= 4;
         inb >>= shift;
         inb = (inb * *scale++ + 0x8000U) >> 16;
         /* dp starts beyond the end: */
         *--dp = PNG_BYTE(inb);
         *--dp = PNG_BYTE(inb >> 8);
      }
      while (dp > ep);

      debug(channel == 1U && dp == ep-1U);
   }
#  undef png_ptr
}

static void
png_do_expand8_down_fast(png_transformp *transform, png_transform_controlp tc)
   /* Optimized version of the above for when the sBIT settings are all a full 8
    * bits (the normal case).
    */
{
#  define png_ptr (tc->png_ptr)
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep ep = dp + 1U/*safety*/;
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);

   affirm(tc->bit_depth == 8U && tr->to_bit_depth == 16U);
   affirm(tr->shifts != 0U/*uninitialized*/);

   sp += PNG_TC_ROWBYTES(*tc);
   tc->sp = dp;
   tc->bit_depth = 16U;
   dp += PNG_TC_ROWBYTES(*tc);

   do
      dp -= 2, dp[0] = dp[1] = *--sp;
   while (dp > ep);

   debug(dp == ep-1U);
#  undef png_ptr
}

static void
png_init_gamma_uncached(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);

   debug(tc->init == PNG_TC_INIT_FINAL);

   /* Set this first; the result says if the sBIT data is significant, but it is
    * ignored here.
    */
   (void)init_gamma_sBIT(tr, tc);

   /* If png_set_alpha_mode is called but no background processing needs to be
    * done (because there is no alpha channel or tRNS) we get to here with
    * potentially spurious alpha mode flags.
    */
   if (!(tc->format & PNG_FORMAT_FLAG_ALPHA))
      tr->encode_alpha = tr->optimize_alpha = 0U;

   /* Use separate functions for the two input depths but not for the five
    * possible output depths and four channel counts.
    */
   if (tc->bit_depth == 8U)
   {
      if (tr->to_bit_depth <= 8U)
         tr->tr.fn = png_do_gamma8_up;

      else
      {
         debug(tr->to_bit_depth == 16U);
         reverse_gamma_sBIT(tr);
         tr->tr.fn = png_do_gamma8_down;
      }
   }

   else
   {
      affirm(tc->bit_depth == 16U);
#     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
         if (!tr->optimize_alpha)
            tr->tr.fn = png_do_gamma16_up;
         else
            tr->tr.fn = png_do_gamma16_up_optimize;
#     else /* !READ_ALPHA_MODE */
         tr->tr.fn = png_do_gamma16_up;
#     endif /* !READ_ALPHA_MODE */
   }

   /* Since the 'do' routines always perform gamma correction they will always
    * expand the significant bits to the full output bit depth.
    */
   tc->invalid_info |= PNG_INFO_sBIT;
   tc->bit_depth = tr->to_bit_depth;
   tc->sBIT_R = tc->sBIT_G = tc->sBIT_B =
      png_check_byte(png_ptr, tc->bit_depth);
   if (tr->encode_alpha)
      tc->sBIT_A = tc->sBIT_G;
   tc->gamma = tr->to_gamma;
#  undef png_ptr
}

#ifdef PNG_READ_sBIT_SUPPORTED
static unsigned int
tc_sBIT(png_const_transform_controlp tc)
   /* Determine the maximum number of significant bits in the row at this point.
    * This uses the png_struct::sig_bit field if it has not been invalidated,
    * otherwise it just returns the current bit depth.
    */
{
   const png_structrp png_ptr = tc->png_ptr;
   unsigned int bit_depth = tc->bit_depth;

   if ((tc->invalid_info & PNG_INFO_sBIT) == 0U)
   {
      /* Normally the bit depth will not have been changed from the original PNG
       * depth, but it currently is changed by the grayscale expand to 8 bits,
       * an operation which doesn't invalidate sBIT.
       */
      unsigned int sBIT;

      if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0U)
      {
         /* Must use the largest of the sBIT depths, except that unset values
          * take priority.
          */
         sBIT = png_ptr->sig_bit.red && png_ptr->sig_bit.green &&
            png_ptr->sig_bit.blue;

         if (sBIT != 0U)
         {
            sBIT = png_ptr->sig_bit.red;

            if (png_ptr->sig_bit.green > sBIT)
               sBIT = png_ptr->sig_bit.green;
            if (png_ptr->sig_bit.blue > sBIT)
               sBIT = png_ptr->sig_bit.blue;
         }
      }

      else
         sBIT = png_ptr->sig_bit.gray;

      if (sBIT > 0U && sBIT < bit_depth)
         bit_depth = sBIT;
   }

   return bit_depth;
}
#else /* !READ_sBIT */
#  define tc_sBIT(tc) ((tc)->bit_depth)
#endif /* READ_sBIT */

static void
png_init_gamma(png_transformp *transform, png_transform_controlp tc)
{
   const png_structrp png_ptr = tc->png_ptr;
   png_transform_gamma *tr =
      png_transform_cast(png_transform_gamma, *transform);

   if (tc->init == PNG_TC_INIT_FORMAT)
   {
      /* This should only happen for the final encode gamma transform, which
       * never initializes the target bit depth (see png_set_gamma and
       * png_set_alpha_mode).  The affirm is required here; in we can't continue
       * safely if the bit depth has been set somehow.
       */
      debug(tr->tr.order == PNG_TR_GAMMA_ENCODE);
      affirm(tr->to_gamma > 0 && tr->to_bit_depth == 0U);

      /* At this point the output gamma should not have been set yet: */
      debug(png_ptr->row_gamma == 0);

      /* The following must be true; png_set_gamma and png_set_alpha_mode set
       * (or default) the PNG gamma and other routines that insert a gamma
       * transform must only do in PNG_TC_INIT_FINAL:
       */
      debug(tc->gamma > 0);

      /* At this point the data gamma must be updated so that we get the correct
       * png_struct::row_gamma at the end of the init:
       */
      tc->gamma = tr->to_gamma;

      /* For safety invalidate the sBIT information too; we don't know yet
       * whether a gamma transform will be required but if it is the sBIT
       * information becomes invalid.
       */
      tc->invalid_info |= PNG_INFO_sBIT;
   }

   else /* PNG_TC_INIT_FINAL */
   {
      /* It is very bad if we get here when processing a row: */
      affirm(tc->init == PNG_TC_INIT_FINAL && png_ptr->row_bit_depth > 0);

      /* There are three cases:
       *
       * 1) Gamma correction is required, output bit depth may need to be
       *    defaulted.
       * 2) Gamma correction is not required but a bit depth change is
       *    necessary.
       * 3) Neither is required; the transform can be eliminated.
       *
       * First default the bit depth if it is not already set.  Note that if the
       * output is a palette then 'row_bit_depth' refers to the palette size and
       * 8U must be used here.  tc->palette is irrelevant; it only tells us that
       * the data came from a palette.
       */
      if (tr->to_bit_depth == 0)
      {
         if ((png_ptr->row_format & PNG_FORMAT_FLAG_COLORMAP) != 0U)
            tr->to_bit_depth = 8U;

         else
            tr->to_bit_depth = png_ptr->row_bit_depth;
      }

      /* (1); is gamma correction required?  If tc->gamma is 0 at this point it
       * is not, but then the png_struct::row_gamma should be 0 too.
       */
      implies(tc->gamma == 0, png_ptr->row_gamma == 0);
      implies(tr->to_gamma == 0, tc->gamma == 0);

      if (!png_gamma_equal(png_ptr, tc->gamma, tr->to_gamma, &tr->correct,
                           tc_sBIT(tc)))
      {
         /* First make sure the input doesn't have a tRNS chunk which needs to
          * be expanded now; if it does push_gamma_expand will push an
          * appropriate transform *before* this one and we need to return
          * immediately (the caller will call back to this function).
          */
         if (push_gamma_expand(transform, tc, 0/*need alpha*/))
         {
            affirm(tc->bit_depth >= 8U &&
                   (tc->invalid_info & PNG_INFO_tRNS) != 0U &&
                   *transform != &tr->tr);
            return;
         }

         debug(*transform == &tr->tr && tc->bit_depth >= 8U);

         /* The format is now 8 or 16-bit G, GA, RGB or RGBA and gamma
          * correction is required.
          */
         png_init_gamma_uncached(transform, tc);
         /* TODO: implement caching for the !tc->caching cases! */
         return;
      }

      /* The cases where the two gamma values are close enough to be considered
       * equal.  The code lies about the gamma; this prevents apps and the
       * simplified API getting into loops or bad conditions because the gamma
       * was not set to the expected value.
       *
       * Note that png_transform_control::gamma is only set here if both the
       * input and output gamma values are known, otherwise the transform
       * introduces a spurious know gamma value.
       */
      if (tr->to_gamma > 0 && tc->gamma > 0)
         tc->gamma = tr->to_gamma;

      if (tr->to_bit_depth > tc->bit_depth)
      {
         /* This is either the to-linear operation, in which case the expected
          * bit depth is 16U, or it is the final encode in the case where an
          * 'expand' operation was also specified.
          *
          * We don't care about the PNG_TR_GAMMA_ENCODE case because we know
          * that there has to be an expand operation further down the pipeline.
          */
         if (tr->tr.order < PNG_TR_GAMMA_ENCODE)
         {
            affirm(tr->to_bit_depth == 16U);

            if (push_gamma_expand(transform, tc, 0/*need alpha*/))
            {
               affirm(tc->bit_depth == 8U &&
                      (tc->invalid_info & PNG_INFO_tRNS) != 0U &&
                      *transform != &tr->tr);
               return;
            }

            debug(*transform == &tr->tr);
            affirm(tc->bit_depth == 8U); /* if 16U we would not be here! */

            /* not using byte_ops here, but if there is no sBIT required
             * (normally the case) the fast code can be used:
             */
            if (init_gamma_sBIT(tr, tc))
               tr->tr.fn = png_do_expand8_down;

            else
               tr->tr.fn = png_do_expand8_down_fast;

            tc->bit_depth = 16U;
         }

         else /* PNG_TR_GAMMA_ENCODE: nothing need be done */
            tr->tr.fn = NULL;
      }

      else if (tr->to_bit_depth < tc->bit_depth)
      {
         /* No gamma correction but bit depth *reduction* is required.  Expect
          * the 'from' bit depth to always be 16, otherwise this transform
          * should not have been pushed.  Also expect this to be the gamma
          * 'encode' operation at the end of the arithmetic.
          */
         affirm(tc->bit_depth == 16U && tr->tr.order == PNG_TR_GAMMA_ENCODE);

         /* If the target bit depth is 8-bit delay the operation and use the
          * standard 16-8-bit scale code.  For low bit depth do it now.
          */
         if (tr->to_bit_depth == 8U)
         {
            png_set_scale_16(png_ptr);
            tr->tr.fn = NULL;
         }

         else /* low bit depth */
         {
            (void)init_gamma_sBIT(tr, tc);
            tr->tr.fn = png_do_scale16_up;
            tc->bit_depth = tr->to_bit_depth;
         }
      }

      else /* gamma !significant and nothing to do */
         tr->tr.fn = NULL;
   }
}

static png_fixed_point
translate_gamma_flags(png_const_structrp png_ptr, png_fixed_point gamma,
   int is_screen)
   /* If 'is_screen' is set this returns the inverse of the supplied value; i.e.
    * this routine always returns an encoding value.
    */
{
   /* Check for flag values.  The main reason for having the old Mac value as a
    * flag is that it is pretty near impossible to work out what the correct
    * value is from Apple documentation - a working Mac system is needed to
    * discover the value!
    */
   switch (gamma)
   {
      case PNG_DEFAULT_sRGB:
      case PNG_GAMMA_sRGB:
      case PNG_FP_1/PNG_GAMMA_sRGB: /* stupid case: -100000 */
         gamma = PNG_GAMMA_sRGB_INVERSE;
         break;

      case PNG_GAMMA_MAC_18:
      case PNG_FP_1/PNG_GAMMA_MAC_18: /* stupid case: -50000 */
         gamma = PNG_GAMMA_MAC_INVERSE;
         break;

      default:
         if (is_screen)
         {
            /* Check for a ridiculously low value; this will result in an
             * overflow
             * in the reciprocal calculation.
             */
            if (gamma < 5)
            {
               png_app_error(png_ptr, "invalid screen gamma (too low)");
               gamma = 0;
            }

            else if (gamma != PNG_FP_1) /* optimize linear */
               gamma = png_reciprocal(gamma);
         }

         else if (gamma <= 0)
         {
            png_app_error(png_ptr, "invalid file gamma (too low)");
            gamma = 0;
         }
         break;
   }

   return gamma;
}

static png_transform_gamma *
add_gamma_transform(png_structrp png_ptr, unsigned int order,
   png_fixed_point gamma, unsigned int bit_depth, int force)
{
   /* Add a png_transform_gamma transform at the given position; this is a
    * utility which just adds the transform and (unconditionally) overwrites the
    * to_gamma field.  gamma must be valid.  If 'force' is true the gamma value
    * in an existing transform will be overwritten, otherwise this is just a
    * default value.
    */
   png_transform_gamma *tr = png_transform_cast(png_transform_gamma,
      png_add_transform(png_ptr, sizeof (png_transform_gamma), png_init_gamma,
         order));

   if (force || tr->to_gamma == 0)
      tr->to_gamma = gamma;

   tr->to_bit_depth = bit_depth;

   return tr;
}

void PNGFAPI
png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
   png_fixed_point file_gamma)
{
   png_debug(1, "in png_set_gamma_fixed");

   /* Validate the passed in file gamma value: */
   file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);

   /* The returned value may be 0, this results in a png_app_error above which
    * may be ignored; if that happens simply ignore the setting.
    */
   if (file_gamma > 0)
   {
      /* Set the colorspace gamma value unconditionally - this overrides the
       * value in the PNG file if a gAMA chunk was present.  png_set_alpha_mode
       * provides a different, easier, way to default the file gamma.
       */
      png_ptr->colorspace.gamma = file_gamma;
      if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
         png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA;
      else
         png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
   }

   /* Do the same thing with the screen gamma; check it and handle it if valid.
    * This adds/sets the encoding of the final gamma transform in the chain.
    * png_set_alpha_mode does the same thing.
    */
   scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);

   if (scrn_gamma > 0)
      (void)add_gamma_transform(png_ptr, PNG_TR_GAMMA_ENCODE, scrn_gamma,
            0/*bit depth*/, 1/*force to_gamma to scrn_gamma*/);
}

#ifdef PNG_FLOATING_POINT_SUPPORTED
static png_fixed_point
convert_gamma_value(png_structrp png_ptr, double output_gamma)
{
   /* The following silently ignores cases where fixed point (times 100,000)
    * gamma values are passed to the floating point API.  This is safe and it
    * means the fixed point constants work just fine with the floating point
    * API.  The alternative would just lead to undetected errors and spurious
    * bug reports.  Negative values fail inside the _fixed API unless they
    * correspond to the flag values.
    */
   if (output_gamma < 0 || output_gamma > 128)
      output_gamma *= .00001;

   return png_fixed(png_ptr, output_gamma, "gamma value");
}

void PNGAPI
png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
{
   png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
      convert_gamma_value(png_ptr, file_gamma));
}
#endif /* FLOATING_POINT */
#endif /* READ_GAMMA */

#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
static void
png_do_rtog_48(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   const png_uint_32 r = (*transform)->args >> 16;
   const png_uint_32 g = (*transform)->args & 0xFFFFU;
   const png_uint_32 b = 65536U - r - g;

   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 6U;
   png_bytep dp = png_voidcast(png_bytep, tc->dp);

   debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_FLAG_COLOR &&
         (tc->gamma == 0U || !png_gamma_significant(png_ptr, tc->gamma, 16U)));

   tc->sp = dp;
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);

   while (sp <= ep)
   {
      png_uint_32 gray = (((sp[0] << 8) + sp[1]) * r +
         ((sp[2] << 8) + sp[3]) * g +
         ((sp[4] << 8) + sp[5]) * b + 32767U) >> 16;

      debug(gray < 65536U);
      *dp++ = PNG_BYTE(gray >> 8);
      *dp++ = PNG_BYTE(gray);
      sp += 6U;
   }
#  undef png_ptr
}

static void
png_do_rtog_64(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   const png_uint_32 r = (*transform)->args >> 16;
   const png_uint_32 g = (*transform)->args & 0xFFFFU;
   const png_uint_32 b = 65536U - r - g;

   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 8U;
   png_bytep dp = png_voidcast(png_bytep, tc->dp);

   debug(tc->bit_depth == 16U &&
         tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA &&
         (tc->gamma == 0U || !png_gamma_significant(png_ptr, tc->gamma, 16U)));

   tc->sp = dp;
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);

   while (sp <= ep)
   {
      png_uint_32 gray = (((sp[0] << 8) + sp[1]) * r +
         ((sp[2] << 8) + sp[3]) * g +
         ((sp[4] << 8) + sp[5]) * b + 32767U) >> 16;

      debug(gray < 65536U);
      *dp++ = PNG_BYTE(gray >> 8);
      *dp++ = PNG_BYTE(gray);
      sp += 6U;
      *dp++ = *sp++; /* alpha */
      *dp++ = *sp++;
   }
#  undef png_ptr
}

static void
png_init_rgb_to_gray_arithmetic(png_transformp *transform,
   png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* This only gets used in the final init stage: */
   debug(tc->init == PNG_TC_INIT_FINAL && tc->bit_depth == 16U &&
         (tc->format & PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA)) ==
            PNG_FORMAT_FLAG_COLOR);

   (*transform)->fn = (tc->format & PNG_FORMAT_FLAG_ALPHA) ? png_do_rtog_64 :
      png_do_rtog_48;

   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);
   tc->invalid_info |= PNG_INFO_sBIT;
   tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =
      png_check_byte(png_ptr, tc->bit_depth);
#  undef png_ptr
}

typedef struct
{
   png_transform tr;
   png_fixed_point red_coefficient;
   png_fixed_point green_coefficient;
   unsigned int    coefficients_set   :1;
   unsigned int    error_action       :2;
}  png_transform_rgb_to_gray;

static void
png_update_rgb_status(png_structrp png_ptr, png_transformp *transform)
{
   png_transform_rgb_to_gray *tr = png_transform_cast(png_transform_rgb_to_gray,
      *transform);

   png_ptr->rgb_to_gray_status = 1U;
   tr->tr.fn = NULL; /* one warning/error only */

   switch (tr->error_action)
   {
      case PNG_ERROR_ACTION_WARN:
         png_warning(png_ptr, "RGB to gray found nongray pixel");
         break;

      case PNG_ERROR_ACTION_ERROR:
         png_error(png_ptr, "RGB to gray found nongray pixel");
         break;

      default:
         break;
   }
}

static void
png_do_rgb_check24(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue
    * channels are not equal.
    */
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U;

   debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_FLAG_COLOR);

   while (sp <= ep)
   {
      if ((sp[0] ^ sp[1]) | (sp[2] ^ sp[1]))
      {
         png_update_rgb_status(png_ptr, transform);
         break;
      }

      sp += 3U;
   }
#  undef png_ptr
}

static void
png_do_rgb_check32(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue
    * channels are not equal and alpha is not zero.
    */
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 4U;

   debug(tc->bit_depth == 8U &&
         tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);

   while (sp <= ep)
   {
      if (((sp[0] ^ sp[1]) | (sp[2] ^ sp[1])) && sp[3] != 0)
      {
         png_update_rgb_status(png_ptr, transform);
         break;
      }

      sp += 4U;
   }
#  undef png_ptr
}

static void
png_do_rgb_check48(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue
    * channels are not equal.
    */
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 6U;

   debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_FLAG_COLOR);

   while (sp <= ep)
   {
      if ((sp[0] ^ sp[2]) | (sp[4] ^ sp[2]) |
          (sp[1] ^ sp[3]) | (sp[5] ^ sp[3]))
      {
         png_update_rgb_status(png_ptr, transform);
         break;
      }

      sp += 6U;
   }
#  undef png_ptr
}

static void
png_do_rgb_check64(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* Sets 'rgb_to_gray' status if a pixel is found where the red green and blue
    * channels are not equal and alpha is not zero.
    */
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 8U;

   debug(tc->bit_depth == 16U &&
         tc->format == PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA);

   while (sp <= ep)
   {
      if (((sp[0] ^ sp[2]) | (sp[4] ^ sp[2]) |
          (sp[1] ^ sp[3]) | (sp[5] ^ sp[3])) &&
          (sp[6] | sp[7]) != 0)
      {
         png_update_rgb_status(png_ptr, transform);
         break;
      }

      sp += 8U;
   }
#  undef png_ptr
}

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

   /* Basic checks: if there is no color in the format this transform is not
    * applicable.
    */
   if ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0)
   {
      png_transform_rgb_to_gray *tr = png_transform_cast(
         png_transform_rgb_to_gray, *transform);

      /* no colormap allowed: */
      affirm(tc->init && !(tc->format & PNG_FORMAT_FLAG_COLORMAP));
      /* no extra flags yet: */
      debug(!(tc->format &
               PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR+PNG_FORMAT_FLAG_ALPHA)));
      /* at present no non-palette caching: */
      implies(tc->caching, tc->palette);

      if (tc->init == PNG_TC_INIT_FORMAT)
      {
         /* The convertion should just remove the 'COLOR' flag and do nothing
          * else, but if a tRNS chunk is present this would invalidate it.
          * Handle this by expanding it now.
          */
         if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette &&
             png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS))
         {
            /* Only if expand was requested and not cancelled: */
            if (tc->expand_tRNS && !tc->strip_alpha)
               tc->format |= PNG_FORMAT_FLAG_ALPHA;

            tc->invalid_info |= PNG_INFO_tRNS; /* prevent expansion later */
         }

         tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_COLOR);
      }

      else /* PNG_TC_INIT_FINAL */
      {
         unsigned int index;   /* channel to select (invalid) */
         png_byte sBIT_color;  /* sBIT of that channel if valid */
         png_fixed_point r, g; /* Coefficients in range 0..65536 */

         /* Push a tRNS transform if required.  Because this is a push the
          * transform the init needs to be run now.  This needs to go in
          * before the check on r==g==b because a color key might be used.
          */
         if ((tc->format & PNG_FORMAT_FLAG_ALPHA) == 0 && !tc->palette &&
             png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS))
         {
            if (tc->expand_tRNS && !tc->strip_alpha)
            {
               png_transformp tr_expand = png_push_transform(png_ptr,
                  sizeof (png_expand), png_init_expand, transform, NULL);

               debug(*transform == tr_expand);
               tr_expand->args |= PNG_EXPAND_tRNS;
               png_init_expand(transform, tc);
               /* Check for the infinite loop possibility: */
               affirm((tc->invalid_info & PNG_INFO_tRNS) != 0);
               return;
            }

            else
               tc->invalid_info |= PNG_INFO_tRNS;
         }

         {
            png_fixed_point red, green;

            if (tr->coefficients_set)
            {
               red = tr->red_coefficient;
               green = tr->green_coefficient;
            }

#           ifdef PNG_COLORSPACE_SUPPORTED
               else if ((png_ptr->colorspace.flags &
                         (PNG_COLORSPACE_HAVE_ENDPOINTS+PNG_COLORSPACE_INVALID))
                         == PNG_COLORSPACE_HAVE_ENDPOINTS)
               {
                  red = png_ptr->colorspace.end_points_XYZ.red_Y;
                  green = png_ptr->colorspace.end_points_XYZ.green_Y;
               }
#           endif

            else /* no colorspace support, assume sRGB */
            {
               /* From IEC 61966-2-1:1999, the reverse transformation from sRGB
                * RGB values to XYZ D65 values (not CIEXYZ!).  These are not
                * exact inverses of the forward transformation; they only have
                * four (decimal) digits of precision.
                *
                * API CHANGE: in 1.7.0 the sRGB values from the official IEC
                * specification are used, previously libpng used values from
                * Charles Poynton's ColorFAQ of 1998-01-04.  The original page
                * is gone, however up to date information can be found below:
                *
                *    http://www.poynton.com/ColorFAQ.html
                *
                * At the time of reading (20150628) this web site quotes the
                * same values as below and cites ITU Rec 709 as the source.
                */
               red = 21260;
               green = 71520;
            }

            /* Prior to 1.7 this calculation was done with 15-bit precision,
             * this is because the code was written pre-muldiv and tried to
             * work round the problems caused by the signs in integer
             * calculations.
             */
            (void)png_muldiv(&r, red, 65536, PNG_FP_1);
            (void)png_muldiv(&g, green, 65536, PNG_FP_1);
         }

         /* If the convertion can be deduced to select a single channel do so.
          * If the error action is set to error just copy the red channel, if
          * the coefficients select just one channel use that.
          */
         if (tr->error_action == PNG_ERROR_ACTION_ERROR || r >= 65536)
            index = 0U, sBIT_color = tc->sBIT_R; /* select red */

         else if (g >= 65536)
            index = 1U, sBIT_color = tc->sBIT_G; /* select green */

         else if (r + g == 0)
            index = 2U, sBIT_color = tc->sBIT_B; /* select blue */

         else
            index = 3U, sBIT_color = 0U/*UNUSED*/;

         if (index == 3U)
         {
            /* Arithmetic will have to be done.  For this we need linear 16-bit
             * data which must then be converted back to the required bit depth,
             * png_init_gamma handles this.  It may push other expand operations
             * (it shouldn't but it can), so give it some space.
             *
             * The gamma must be restored to the original value, 0U for the bit
             * depth means use the output bit depth.
             */
            (void)add_gamma_transform(png_ptr, PNG_TR_GAMMA_ENCODE, tc->gamma,
               0U/*bit depth*/, 0/*default*/);

            /* If png_init_gamma is called with tc->gamma 0 it does the right
             * thing in PNG_TC_INIT_FINAL; it just does any required bit depth
             * adjustment.
             */
            (void)add_gamma_transform(png_ptr, tr->tr.order + 0x10U, PNG_FP_1,
               16U, 1/*force: doesn't matter*/);

            {
               /* This init routine will update the sBIT information
                * appropriately.
                */
               png_transformp tr_rtog = png_add_transform(png_ptr, 0/*size*/,
                  png_init_rgb_to_gray_arithmetic, tr->tr.order + 0x20U);

               /* r and g are known to be in the range 0..65535, so pack them
                * into the 'args' argument of a new transform.
                */
               tr_rtog->args = (((png_uint_32)r) << 16) + g;
            }
         }

         else /* index < 3 */
         {
            /* TODO: does this need to select the correct sBIT value too? */
            png_add_rgb_to_gray_byte_ops(png_ptr, tc, index,
               tr->tr.order + 0x10U);
            tc->sBIT_G = sBIT_color;
         }

         /* Prior to 1.7 libpng would always check for r!=g!=b.  In 1.7 an extra
          * error_action setting is added to prevent this overhead.
          */
         if (tr->error_action)
            tr->tr.fn = tc->bit_depth == 8 ?
               ((tc->format & PNG_FORMAT_FLAG_ALPHA) ?
                png_do_rgb_check32 : png_do_rgb_check24) :
               ((tc->format & PNG_FORMAT_FLAG_ALPHA) ?
                png_do_rgb_check64 : png_do_rgb_check48);

         else
            tr->tr.fn = NULL; /* PNG_ERROR_ACTION_NO_CHECK */
      }
   }

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

void PNGFAPI
png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
    png_fixed_point red, png_fixed_point green)
   /* API CHANGE: in 1.7 calling this on a palette PNG no longer causes the
    * palette to be expanded (unless explicitly requested), rather it converts
    * the palette to grayscale.
    */
{
   /* The coefficients must be reasonable, the error handling is to warn (pre
    * 1.7) or app error (1.7) and drop back to the cHRM definition of Y.  The
    * drop back is done in the init routine if relevant flag is unset.  Passing
    * negative values causes this default to be used without a warning.
    */
   int pset = 0;

   if (red >= 0 && green >= 0)
   {
      if (red <= PNG_FP_1 && green <= PNG_FP_1 && red + green <= PNG_FP_1)
         pset = 1;

      else /* overflow */
         png_app_error(png_ptr, "rgb_to_gray coefficients too large (ignored)");
   }

   {
      png_transform_rgb_to_gray *tr =
         png_transform_cast(png_transform_rgb_to_gray,
            png_add_transform(png_ptr, sizeof (png_transform_rgb_to_gray),
               png_init_rgb_to_gray, PNG_TR_RGB_TO_GRAY));

      tr->error_action = 0x3U & error_action;

      if (red < 0 || green < 0) /* use cHRM default */
         tr->coefficients_set = 0U;

      else if (pset) /* else bad coefficients which get ignored */
      {
         tr->coefficients_set = 1U;
         tr->red_coefficient = red;
         tr->green_coefficient = green;
      }
   }
}

#ifdef PNG_FLOATING_POINT_SUPPORTED
/* Convert a RGB image to a grayscale of the same width.  This allows us,
 * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
 */

void PNGAPI
png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
   double green)
{
   png_set_rgb_to_gray_fixed(png_ptr, error_action,
      png_fixed(png_ptr, red, "rgb to gray red coefficient"),
      png_fixed(png_ptr, green, "rgb to gray green coefficient"));
}
#endif /* FLOATING POINT */
#endif /* RGB_TO_GRAY */

#ifdef PNG_READ_BACKGROUND_SUPPORTED
typedef struct
{
   png_transform     tr;
   struct
   {
      png_color_16      background;
      unsigned int      need_expand :1; /* Background matches format of PNG */
      unsigned int      rgb_to_gray :1; /* RGB-to-gray transform found */
      unsigned int      compose_background   :1; /* png_set_background */
      unsigned int      associate_alpha      :1;
      unsigned int      encode_alpha         :1;
      unsigned int      optimize_alpha       :1;
      unsigned int      background_is_gray   :1; /* Background color is gray */
      unsigned int      background_bit_depth :5; /* bit depth, 1..16 */
      unsigned int      ntrans               :3; /* 1..6 bytes */
      png_byte          transparent_pixel[6];
      png_byte          background_pixel[6];
      png_fixed_point   background_gamma;
   }  st; /* to allow the whole state to be copied reliably */
}  png_transform_background;

static void
resolve_background_color(png_transform_background *tr,
   png_transform_controlp tc)
{
   png_const_structp png_ptr = tc->png_ptr;

   /* Deduce the bit depth and color information for the background, the
    * special case is when need_expand is set and the PNG has palette format,
    * then (and only then) the background value is a palette index.
    */
   if (tr->st.need_expand && tc->palette)
   {
      unsigned int i = tr->st.background.index;
      png_byte r, g, b;

      if (i >= png_ptr->num_palette)
      {
         png_app_error(png_ptr, "background index out of range");
         tr->tr.fn = NULL;
         return;
      }

      tr->st.background_bit_depth = 8U;
      r = png_ptr->palette[i].red;
      g = png_ptr->palette[i].green;
      b = png_ptr->palette[i].blue;

      if (r == g && g == b)
      {
         tr->st.background_is_gray = 1U;
         tr->st.background.gray = g;
         UNTESTED
      }

      else
      {
         tr->st.background_is_gray = 0U;
         tr->st.background.red = r;
         tr->st.background.green = g;
         tr->st.background.blue = b;
         UNTESTED
      }
   }

   else /* background is not a palette index */
   {
      int use_rgb;
      png_uint_16 mask;

      /* First work out the bit depth and whether or not to use the RGB
       * fields of the background.
       */
      if (tr->st.need_expand)
      {
         affirm(!(tc->format & PNG_FORMAT_FLAG_COLORMAP));
         tr->st.background_bit_depth =
            png_check_bits(png_ptr, png_ptr->bit_depth, 5U);
         use_rgb = (png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0;
      }

      else /* screen format background */
      {
         /* If the final output is in palette format assume the background
          * is in a matching format.  This covers two cases, an original
          * COLORMAP PNG  and png_set_quantize.
          */
         if ((png_ptr->row_format & PNG_FORMAT_FLAG_COLORMAP) != 0)
            tr->st.background_bit_depth = 8U;

         else
            tr->st.background_bit_depth =
               png_check_bits(png_ptr, png_ptr->row_bit_depth, 5U);

         use_rgb = (png_ptr->row_format & PNG_FORMAT_FLAG_COLOR) != 0;
      }

      /* The PNG spec says to use the low bits of the values, so we mask out
       * the high bits here (at present no warning is produced if they are
       * set.)
       */
      mask = png_check_u16(png_ptr, (1U << tr->st.background_bit_depth)-1U);

      if (use_rgb)
      {
         png_uint_16 r, g, b;

         r = tr->st.background.red & mask;
         g = tr->st.background.green & mask;
         b = tr->st.background.blue & mask;

         if (r == g && g == b)
         {
            tr->st.background_is_gray = 1U;
            tr->st.background.gray = g;
         }

         else
         {
            tr->st.background_is_gray = 0U;
            tr->st.background.red = r;
            tr->st.background.green = g;
            tr->st.background.blue = b;
         }
      }

      else /* gray */
      {
         tr->st.background_is_gray = 1U;
         tr->st.background.gray = tr->st.background.gray & mask;
      }
   }
}

static void
gamma_correct_background_component(png_const_structrp png_ptr, png_uint_16p cp,
   unsigned int bdc, png_fixed_point correction, unsigned int bdout)
   /* Utility function for gamma_correct_background. */
{
   unsigned int c = *cp;

   /* 0.0 and 1.0 are unchanged (and common): */
   if (c > 0U && c < (1U<<bdc)-1U)
   {
      if (correction != 0)
         c = png_check_bits(png_ptr,
            png_gamma_nxmbit_correct(c, correction, bdc, bdout), bdout);

      else if (bdc != bdout)
      {
         /* Scale the value from bdc to bdout bits. */
         png_int_32 i;
         affirm(png_muldiv(&i, c, (1U<<bdout)-1U, (1U<<bdc)-1U));
         c = png_check_bits(png_ptr, i, bdout);
      }
   }

   else if (c != 0U)
      c = (1U << bdout) - 1U;

   *cp = PNG_UINT_16(c);
   PNG_UNUSED(png_ptr) /* if checking disabled */
}

static void
gamma_correct_background(png_transform_background *tr,
   png_const_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_fixed_point correction = tc->gamma;
   const unsigned int bdback = tr->st.background_bit_depth;
   const unsigned int bdrow = tc->bit_depth;

   /* This is harmless if it fails but it will damage the output pixels - they
    * won't have the requested color depth accuracy where the background is
    * used.
    */
   debug(bdback <= bdrow);
   debug(tr->st.background_is_gray || (bdrow >= 8U && bdback >= 8U));

   /* The background is assumed to be full precision; there is no sBIT
    * information for it.  The convertion converts from the current depth and
    * gamma of the background to that in the transform control.  It uses the
    * full 16-bit precision when considering the gamma values even though this
    * is probably spurious.
    */
   if (correction != 0 && (tr->st.background_gamma == 0 ||
       png_gamma_equal(png_ptr, tr->st.background_gamma, correction,
          &correction, 16U)))
      correction = 0; /* no correction! */

   if (tr->st.background_is_gray)
      gamma_correct_background_component(png_ptr, &tr->st.background.gray,
            bdback, correction, bdrow);

   else
   {
      gamma_correct_background_component(png_ptr, &tr->st.background.red,
            bdback, correction, bdrow);
      gamma_correct_background_component(png_ptr, &tr->st.background.green,
            bdback, correction, bdrow);
      gamma_correct_background_component(png_ptr, &tr->st.background.blue,
            bdback, correction, bdrow);
   }

   /* Regardless of whether there was a correction set the background gamma: */
   tr->st.background_gamma = tc->gamma;
   tr->st.background_bit_depth = png_check_bits(png_ptr, bdrow, 5U);
#  undef png_ptr
}

static void
fill_background_pixel(png_transform_background *tr, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   /* Fill in 'background_pixel' if the appropriate sequence of bytes for the
    * format given in the transform control.
    */
   unsigned int bdtc = tc->bit_depth;

   /* If necessary adjust the background pixel to the current row format (it is
    * important to do this as late as possible to avoid spurious
    * interconvertions).
    */
   gamma_correct_background(tr, tc);

   if (tr->st.background_is_gray)
   {
      unsigned int g = tr->st.background.gray;

      /* 'g' now has enough bits for the destination, note that in the case of
       * low bit depth gray this causes the pixel to be replicated through the
       * written byte.  Fill all six bytes with the replicated background:
       */
      while (bdtc < 8U)
      {
         g &= (1U << bdtc) - 1U; /* use only the low bits */
         g |= g << bdtc;
         bdtc <<= 1;
      }

      memset(tr->st.background_pixel, PNG_BYTE(g), 6U);
      if (bdtc == 16U)
         tr->st.background_pixel[0] = tr->st.background_pixel[2] =
            tr->st.background_pixel[4] = PNG_BYTE(g >> 8);
      /* Must not include the alpha channel here: */
      tr->st.ntrans = png_check_bits(png_ptr,
         ((tc->format & PNG_FORMAT_FLAG_COLOR)+1U) << (bdtc == 16U), 3U);
   }

   else
   {
      unsigned int r = tr->st.background.red;
      unsigned int g = tr->st.background.green;
      unsigned int b = tr->st.background.blue;

      debug((tc->format & PNG_FORMAT_FLAG_COLOR) != 0);

      switch (bdtc)
      {
         case 8U:
            tr->st.background_pixel[0] = PNG_BYTE(r);
            tr->st.background_pixel[1] = PNG_BYTE(g);
            tr->st.background_pixel[2] = PNG_BYTE(b);
            tr->st.ntrans = 3U;
            break;

         case 16U:
            tr->st.background_pixel[0] = PNG_BYTE(r>>8);
            tr->st.background_pixel[1] = PNG_BYTE(r);
            tr->st.background_pixel[2] = PNG_BYTE(g>>8);
            tr->st.background_pixel[3] = PNG_BYTE(g);
            tr->st.background_pixel[4] = PNG_BYTE(b>>8);
            tr->st.background_pixel[5] = PNG_BYTE(b);
            tr->st.ntrans = 6U;
            break;

         default:
            NOT_REACHED;
      }
   }
#  undef png_ptr
}

/* Look for colors matching the trans_color in png_ptr and replace them.  This
 * must handle all the non-alpha formats.
 */
static void
png_do_replace_tRNS_multi(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   const unsigned int cbytes = tr->st.ntrans;
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - cbytes/*safety*/;
   const int copy = dp != sp;

   /* We expect opaque and transparent pixels to be interleaved but with long
    * sequences of each.
    */
   debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) &&
         PNG_TC_PIXEL_DEPTH(*tc) == cbytes << 3);
   tc->invalid_info |= PNG_INFO_tRNS;
   tc->sp = dp;

   /* Look for pixels that match the transparent value, copying opaque ones as
    * required.
    */
   do
   {
      const png_const_bytep opaque_start = sp;
      size_t cb;

      /* Find a transparent pixel, or the end: */
      do
      {
         if (memcmp(sp, tr->st.transparent_pixel, cbytes) == 0) /*transparent*/
            break;
         sp += cbytes;
      }
      while (sp <= ep);

      cb = sp - opaque_start;

      /* Copy any opaque pixels: */
      if (cb > 0)
      {
         if (copy)
            memcpy(dp, opaque_start, cb);
         dp += cb;
      }

      /* Set transparent pixels to the background (this has to be done one-by
       * one; the case where all the bytes in the background are equal is not
       * optimized.)
       */
      if (sp <= ep) do
      {
         memcpy(dp, tr->st.background_pixel, cbytes);
         sp += cbytes;
         dp += cbytes;
      }
      while (sp <= ep && memcmp(sp, tr->st.transparent_pixel, cbytes) == 0);
   } while (sp <= ep);

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

static void
png_do_replace_tRNS_8(png_transformp *transform, png_transform_controlp tc)
   /* The single byte version: 8-bit gray */
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_alloc_size_t row_bytes = tc->width;
   const int copy = dp != sp;
   const int transparent_pixel = tr->st.transparent_pixel[0];
   const int background_pixel = tr->st.background_pixel[0];

   /* We expect opaque and transparent pixels to be interleaved but with long
    * sequences of each.
    */
   debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) &&
         PNG_TC_PIXEL_DEPTH(*tc) == 8 && tr->st.ntrans == 1);
   tc->invalid_info |= PNG_INFO_tRNS;
   tc->sp = dp;

   /* Now search for a byte that matches the transparent pixel. */
   do
   {
      const png_const_bytep tp = png_voidcast(png_const_bytep,
         memchr(sp, transparent_pixel, row_bytes));
      png_alloc_size_t cb;

      if (tp == NULL) /* all remaining pixels are opaque */
      {
         if (copy)
            memcpy(dp, sp, row_bytes);
         return;
      }

      cb = tp - sp;
      if (cb > 0) /* some opaque pixels found */
      {
         if (copy)
            memcpy(dp, sp, cb);
         sp = tp;
         dp += cb;
         debug(row_bytes > cb);
         row_bytes -= cb;
      }

      /* Now count the transparent pixels, this could use strspn but for the
       * moment does not.
       */
      debug(row_bytes > 0);
      ++sp; /* next to check, may be beyond the last */
      while (--row_bytes > 0 && *sp == transparent_pixel) ++sp;

      cb = sp - tp;
      memset(dp, background_pixel, cb);
      dp += cb;
   } while (row_bytes > 0);
   UNTESTED
#  undef png_ptr
}

static void
png_do_set_row(png_transformp *transform, png_transform_controlp tc)
   /* This is a no-op transform that both invalidates INFO from args and sets
    * the entire row to the byte given in the top bits.
    */
{
   png_bytep dp = png_voidcast(png_bytep, tc->dp);

   tc->sp = dp;
   memset(dp, (*transform)->args >> 24, PNG_TC_ROWBYTES(*tc));
}

static void
png_do_replace_tRNS_lbd(png_transformp *transform, png_transform_controlp tc)
{
   /* This is the 2 or 4 bit depth grayscale case; the 1 bit case is handled by
    * the two routines above and the 8-bit and 16-bit cases by the two before
    * that.
    *
    * The transform contains pixel values that have been expanded to one byte,
    * the code needs to match the tRNS pixel and substitute the background one
    * in each byte.
    */
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
   const unsigned int copy = sp != dp;
   const png_byte transparent_pixel = tr->st.transparent_pixel[0];
   const png_byte background_pixel = tr->st.background_pixel[0];

   /* We expect opaque and transparent pixels to be interleaved but with long
    * sequences of each.
    */
   debug(!(tc->format & PNG_FORMAT_FLAG_ALPHA) &&
         PNG_TC_PIXEL_DEPTH(*tc) < 8 && tr->st.ntrans == 1);
   tc->sp = dp;

   /* Now search for a byte that contains the transparent pixel
    *
    * NOTE: this is the "strlen" algorithm, I first saw a variant implemented in
    * Acorn RISC iX (strlen) around 1991, almost certainly derived from a
    * suggestion by Alan Mycroft dating from April 27, 1987 (Mycroft was one of
    * the authors of the 'Norcroft' compiler used for RISC iX, and well known to
    * the RISC iX implementors.) See, e.g.:
    *
    *    http://bits.stephan-brumme.com/null.html.
    *
    * The exact form used here is the one reported by Brumme; I haven't been
    * able to find the original Mycroft posting, it was probably on comp.arch.
    *
    * The 4-bit and 2-bit versions (probably slower in the 4-bit case than the
    * do-it-by-pixel version, but definately faster once 32-bit handling is
    * implemented):
    *
    *    4 bit: (byte - 0x11) & ~byte & 0x88
    *    2 bit: (byte - 0x55) & ~byte & 0xcc
    *
    * The generalizations to 32 bits (8 and 16 pixels per step) should be
    * obvious.
    *
    * This algorithm reads pixels within a byte beyond the end of the row and,
    * potentially, changes the non-existent pixels.  This is harmless and not
    * a security risk.
    */
   if (tc->bit_depth == 4U)
   {
      /* For the moment the algorithm isn't used; there are only two pixels in
       * each byte so it is likely to be quicker to check as below:
       */
      do
      {
         const png_byte b = *sp++;
         const unsigned int m = b ^ transparent_pixel;

         if (m == 0U) /* both transparent */
            *dp = background_pixel;

         else if ((m & 0xF0U) == 0U) /* first transparent */
            *dp = PNG_BYTE((background_pixel & 0xF0U) | (b & 0x0FU));

         else if ((m & 0x0FU) == 0U) /* second transparent */
            *dp = PNG_BYTE((background_pixel & 0x0FU) | (b & 0xF0U));

         else if (copy) /* neither transparent */
            *dp = b;

         ++dp;
      } while (sp < ep);
   }

   else
   {
      affirm(tc->bit_depth == 2U);

      do
      {
         const png_byte b = *sp++;
         const unsigned int m = b ^ transparent_pixel;

         if (m == 0U) /* transparent */
            *dp = background_pixel;

         else if (0xAAU & ((m - 0x55U) & ~m))
         {
            /* One or more pixels transparent */
            const unsigned int mask =
               (m & 0xC0U ? 0xC0U : 0U) |
               (m & 0x30U ? 0x30U : 0U) |
               (m & 0x0CU ? 0x0CU : 0U) |
               (m & 0x03U ? 0x03U : 0U);

            *dp = PNG_BYTE((b & mask) | (background_pixel & ~mask));
         }

         else if (copy) /* no transparent pixels */
            *dp = b;

         ++dp;
      } while (sp < ep);
   }

#  undef png_ptr
}

static void
png_do_background_with_transparent_GA8(png_transformp *transform,
   png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 1U/*safety*/;
   const png_byte background_pixel = tr->st.background_pixel[0];

   /* Because this is an alpha format and we are removing the alpha channel we
    * can copy up.
    */
   debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_GA &&
         tr->st.ntrans == 1U);
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
   tc->sp = dp;

   /* Look for pixels that have alpha 0; all others should have alpha 1.0,
    * however they are simply treated as opaque regardless.
    */
   do
   {
      *dp++ = (sp[1] == 0U) ? background_pixel : sp[0];
      sp += 2U;
   } while (sp < ep);

   debug(sp == ep+1U);
#  undef png_ptr
}

static void
png_do_background_with_transparent_GA16(png_transformp *transform,
   png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/;

   debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_GA &&
         tr->st.ntrans == 2U);
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
   tc->sp = dp;

   do
   {
      if (sp[2] == 0U && sp[3] == 0U) /* transparent */
         dp[0] = tr->st.background_pixel[0], dp[1] = tr->st.background_pixel[1];

      else
         dp[0] = sp[0], dp[1] = sp[1];

      dp += 2U;
      sp += 4U;
   } while (sp < ep);

   debug(sp == ep+3U);
#  undef png_ptr
}

static void
png_do_background_with_transparent_GAlbd(png_transformp *transform,
   png_transform_controlp tc)
   /* This is the low-bit-depth gray case, the input is 1, 2 or 4-bit per
    * channel gray-alpha.
    */
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc);
   const unsigned int bit_depth = tc->bit_depth;
   const unsigned int mask = (1U << bit_depth) - 1U;
   const unsigned int back = tr->st.background_pixel[0] & mask;
   unsigned int opos, ob, inb;

   debug(bit_depth < 8U && tc->format == PNG_FORMAT_GA && tr->st.ntrans == 1U);
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
   tc->sp = dp;

   ob = 0U;   /* output byte */
   opos = 0U; /* bit index of previous output pixel (counts down) */
   inb = 0U;  /* quiet a GCC 4.8.5 warning */

   for (;;)
   {
      /* The output is half the size of the input, so we need a new input byte
       * for every 4 bits of output:
       */
      if (opos == 0U || opos == 4U)
      {
         if (sp >= ep)
            break;

         inb = *sp++;
      }

      /* Move to the next *output* pixel, this wraps when bits is 0U: */
      opos = (opos - bit_depth) & 0x7U;

      /* Extract the whole input pixel to the low bits of a temporary: */
      {
         unsigned int pixel = inb >> ((opos*2U) & 0x7U);

         /* The alpha channel is second, check for a value of 0: */
         if ((pixel & mask)/* A component*/ == 0U)
            pixel = back;

         else
         {
            debug((pixel & mask) == mask);
            pixel = (pixel >> bit_depth) & mask; /* G component */
         }

         ob |= pixel << opos;
      }

      if (opos == 0U)
         *dp++ = PNG_BYTE(ob), ob = 0U;
   }

   if (opos != 0U)
      *dp++ = PNG_BYTE(ob);

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

static void
png_do_background_with_transparent_RGBA8(png_transformp *transform,
   png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/;

   debug(tc->bit_depth == 8U && tc->format == PNG_FORMAT_RGBA &&
         tr->st.ntrans == 3U);
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
   tc->sp = dp;

   do
   {
      if (sp[3] == 0U) /* transparent */
         memcpy(dp, tr->st.background_pixel, 3U);

      else
         memmove(dp, sp, 3U);

      dp += 3U;
      sp += 4U;
   } while (sp < ep);

   debug(sp == ep+3U);
#  undef png_ptr
}

static void
png_do_background_with_transparent_RGBA16(png_transformp *transform,
   png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 7U/*safety*/;

   debug(tc->bit_depth == 16U && tc->format == PNG_FORMAT_RGBA &&
         tr->st.ntrans == 6U);
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
   tc->sp = dp;

   do
   {
      if (sp[6] == 0U && sp[7] == 0U) /* transparent */
         memcpy(dp, tr->st.background_pixel, 6U);

      else
         memmove(dp, sp, 6U);

      dp += 6U;
      sp += 8U;
   } while (sp < ep);

   debug(sp == ep+7U);
#  undef png_ptr
}

static void
png_init_background_transparent(png_transformp *transform,
   png_transform_controlp tc)
   /* Select the correct version of the above routines. */
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);

   debug(tc->init == PNG_TC_INIT_FINAL /* never called in 'FORMAT' */ &&
         (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);

   /* Now we know the format on which processing will happen so it is possible
    * to generate the correct fill pixel value to use.
    */
   fill_background_pixel(tr, tc);
   tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
   tc->invalid_info |= PNG_INFO_sBIT;
   tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =
      png_check_byte(png_ptr, tc->bit_depth);

   if (!(tc->format & PNG_FORMAT_FLAG_COLOR))
   {
      if (tc->bit_depth == 8U)
         tr->tr.fn = png_do_background_with_transparent_GA8;

      else if (tc->bit_depth == 16U)
         tr->tr.fn = png_do_background_with_transparent_GA16;

      else /* low-bit-depth gray with alpha (not a PNG format!) */
         tr->tr.fn = png_do_background_with_transparent_GAlbd;
   }

   else /* color */
   {
      if (tc->bit_depth == 8U)
         tr->tr.fn = png_do_background_with_transparent_RGBA8;

      else
      {
         debug(tc->bit_depth == 16U);
         tr->tr.fn = png_do_background_with_transparent_RGBA16;
      }
   }
#  undef png_ptr
}

/* The calculated values below have the range 0..65535*65535, the output has the
 * range 0..65535, so divide by 65535.  Two approaches are given here, one
 * modifies the value in place, the other uses a more complex expression.  With
 * gcc on an AMD64 system the in-place approach is very slightly faster.
 *
 * The two expressions are slightly different in what they calculate but both
 * give the exact answer (verified by exhaustive testing.)
 *
 * The macro must be given a png_uint_32 variable (lvalue), normally an auto
 * variable.
 */
#ifndef PNG_COMPOSE_DIV_65535
#  ifdef PNG_COMPOSE_DIV_EXPRESSION_SUPPORTED
#     define PNG_COMPOSE_DIV_65535(v)\
         (v = ((v + (v>>16) + (v>>31) + 32768U) >> 16))
#  else
#     define PNG_COMPOSE_DIV_65535(v)\
         (v += v >> 16, v += v >> 31, v += 32768U, v >>= 16)
#  endif
#endif

static void
png_do_background_alpha_GA(png_transformp *transform, png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 3U/*safety*/;
   const unsigned int background = tr->st.background.gray;
   const int copy = (sp != dp);
   const int compose = tr->st.compose_background;

   affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_GA &&
         tr->st.background_bit_depth == 16U);

   /* If gamma transforms are eliminated this might fail: */
   debug(tr->st.background_gamma == tc->gamma ||
         tr->st.background_gamma == 0 ||
         tc->sBIT_G == 1);

   tc->sp = tc->dp; /* nothing else changes */

   do
   {
      const png_uint_32 alpha = (sp[2] << 8) + sp[3];

      switch (alpha)
      {
         case 0U: /* transparent */
            memset(dp, 0U, 4U);
            break;

         default:
            {
               png_uint_32 v = ((sp[0] << 8) + sp[1]) * alpha +
                  background * (65535U - alpha);

               PNG_COMPOSE_DIV_65535(v);
               debug(v <= 65535U);
               dp[0] = PNG_BYTE(v >> 8);
               dp[1] = PNG_BYTE(v);
            }

            if (compose)
               dp[3] = dp[2] = 0xFFU; /* alpha; set to 1.0 */

            else if (copy)
            {
               dp[2] = PNG_BYTE(alpha >> 8);
               dp[3] = PNG_BYTE(alpha);
            }
            break;

         case 65535U: /* opaque */
            if (copy)
               memcpy(dp, sp, 4U);
            break;
      }

      sp += 4U;
      dp += 4U;
   }
   while (sp < ep);

   debug(sp == ep+3U);
#  undef png_ptr
}

static void
png_do_background_alpha_RGBA(png_transformp *transform,
   png_transform_controlp tc)
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   const png_const_bytep ep = sp + PNG_TC_ROWBYTES(*tc) - 7U/*safety*/;
   const unsigned int bred = tr->st.background.red;
   const unsigned int bgreen = tr->st.background.green;
   const unsigned int bblue = tr->st.background.blue;
   const int copy = (sp != dp);
   const int compose = tr->st.compose_background;

   affirm(tc->bit_depth == 16U && tc->format == PNG_FORMAT_RGBA &&
         tr->st.background_bit_depth == 16U);

   debug(tr->st.background_gamma == tc->gamma ||
         tr->st.background_gamma == 0 ||
         (tc->sBIT_R == 1 && tc->sBIT_G == 1 && tc->sBIT_B == 1));

   tc->sp = tc->dp; /* nothing else changes */

   do
   {
      const png_uint_32 alpha = (sp[6] << 8) + sp[7];

      switch (alpha)
      {
         case 0U: /* transparent */
            memset(dp, 0U, 8U);
            break;

         default:
            {
               const png_uint_32 balpha = (65535U - alpha);
               png_uint_32 r = ((sp[0] << 8) + sp[1]) * alpha + bred * balpha;
               png_uint_32 g = ((sp[2] << 8) + sp[3]) * alpha + bgreen * balpha;
               png_uint_32 b = ((sp[4] << 8) + sp[5]) * alpha + bblue * balpha;

               PNG_COMPOSE_DIV_65535(r);
               PNG_COMPOSE_DIV_65535(g);
               PNG_COMPOSE_DIV_65535(b);
               debug(r <= 65535U && g <= 65535U && b <= 65535U);
               dp[0] = PNG_BYTE(r >> 8);
               dp[1] = PNG_BYTE(r);
               dp[2] = PNG_BYTE(g >> 8);
               dp[3] = PNG_BYTE(g);
               dp[4] = PNG_BYTE(b >> 8);
               dp[5] = PNG_BYTE(b);
            }

            if (compose)
               dp[7] = dp[6] = 0xFFU;

            else if (copy)
            {
               dp[6] = PNG_BYTE(alpha >> 8);
               dp[7] = PNG_BYTE(alpha);
            }
            break;

         case 65535U: /* opaque */
            if (copy)
               memcpy(dp, sp, 8U);
            break;
      }

      sp += 8U;
      dp += 8U;
   }
   while (sp < ep);

   debug(sp == ep+7U);
#  undef png_ptr
}

static void
png_init_background_alpha_end(png_transformp *transform,
   png_transform_controlp tc)
   /* This is just the last part of png_init_background_alpha (below) */
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);

   debug(tc->init == PNG_TC_INIT_FINAL);

   /* Repeat the tests at the end of png_init_background_alpha: */
   affirm(tc->bit_depth == 16U && (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);
   debug(tc->gamma == 0 ||
         !png_gamma_significant(png_ptr, tc->gamma, tc_sBIT(tc)));

   /* tr->st.background_is_gray was filled in by resolve_background_color and
    * records if either the background was a gray value or it was a color
    * value with all the channels equal.
    */
   if (!tr->st.background_is_gray && !(tc->format & PNG_FORMAT_FLAG_COLOR))
   {
#     ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
         /* Color background with gray data: this happens when there is a
          * gray to RGB transform in the pipeline but it hasn't happened
          * yet.  Unfortunately it has to happen now to be able to do the
          * compose against the colored background.
          */
         png_push_gray_to_rgb_byte_ops(transform, tc);
         affirm((tc->format & PNG_FORMAT_FLAG_COLOR) != 0);
         return;
#     else /* !GRAY_TO_RGB */
         impossible("gray to RGB"); /* how can this happen? */
#     endif /* !GRAY_TO_RGB */
   }

   /* The transform happens in two parts, a part to do the arithmetic on
    * pixels where it is required followed by a part to replace transparent
    * pixels.  These two parts require different versions of the background
    * pixel.  Set up the second part first.
    *
    * This only happens with background composition, otherwise the
    * transparent pixels are already 0 and nothing needs to be done.
    */
   if (tr->st.compose_background)
   {
      /* The transparent pixel handling happens *after* the data has been
       * re-encoded to the output gamma:
       */
      png_transform_background *tr_alpha =
         png_transform_cast(png_transform_background,
            png_add_transform(png_ptr, sizeof (png_transform_background),
               png_init_background_transparent, PNG_TR_GAMMA_ENCODE+0xF0U));

      /* Copy the current state into the new png_transform_background: */
      tr_alpha->st = tr->st;
      tr_alpha->tr.args = tr->tr.args;
   }

   /* Now it is possible to overwrite tr->st.background with the linear version.
    */
   gamma_correct_background(tr, tc);

   /* sBIT informationmust also be invalidated here, because a gamma
    * transform may run before the transparent pixel handling.
    */
   tc->invalid_info |= PNG_INFO_sBIT;
   tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =
      png_check_byte(png_ptr, tc->bit_depth);

   /* And select an appropriate function; there are only two choices: */
   switch (tc->format)
   {
      case PNG_FORMAT_GA:
         /* If the background format is color this indicates that there is a
          * gray to RGB transform missing and we need it to happen before
          * this point!
          */
         affirm(tr->st.background_is_gray);
         tr->tr.fn = png_do_background_alpha_GA;
         break;

      case PNG_FORMAT_RGBA:
         if (tr->st.background_is_gray)
            tr->st.background.blue = tr->st.background.green =
               tr->st.background.red = tr->st.background.gray;
         tr->tr.fn = png_do_background_alpha_RGBA;
         break;

      default:
         NOT_REACHED;
   }
#  undef png_ptr
}

static void
png_init_background_alpha(png_transformp *transform, png_transform_controlp tc)
   /* This is used when alpha composition is required because the alpha channel
    * may contain values that are between 0 and 1.  Because doing alpha
    * composition requires linear arithmetic the data is converted to 16-bit
    * linear, however this means that the background pixel gets converted too
    * and, for 16-bit output, this tends to smash the value.  Consequently the
    * algorithm used here is to skip those pixels and use the 'transparent
    * alpha' routines to replace them after the gamma correction step.
    */
{
#  define png_ptr (tc->png_ptr)
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);

   debug(tc->init == PNG_TC_INIT_FINAL);
   /* png_init_background ensures this is true: */
   debug((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);

   /* Always push gamma transforms; don't try to optimize the case when they
    * aren't needed because that would be an attempt to duplicate the tests in
    * png_init_gamma and it might now work reliably.
    *
    * Need to push the to-linear transform *before* this transform and add gamma
    * correction afterward to get back to the screen format.  Do the afterward
    * bit first to avoid complexity over *transform:
    */
   {
      png_transform_gamma *tr_end = add_gamma_transform(png_ptr,
         PNG_TR_GAMMA_ENCODE, tc->gamma, 0U/*bit depth*/, 0/*default*/);

      /* Encoding the alpha channel happens in the last step, so this needs to
       * be set here.  Notice that in C++ terms we are very friendly with
       * png_transform_gamma.
       */
      tr_end->encode_alpha = tr->st.encode_alpha;
      tr_end->optimize_alpha = tr->st.optimize_alpha;
   }

   {
      /* Now add tr_gamma before this transform, expect it to go in at
       * *transform or the whole thing won't work:
       */
      png_transform_gamma *tr_gamma = png_transform_cast(png_transform_gamma,
         png_push_transform(png_ptr, sizeof (png_transform_gamma),
            png_init_gamma, transform, NULL/*don't run init*/));

      /* This must happen before we run png_gamma_init: */
      tr_gamma->to_gamma = PNG_FP_1;
      tr_gamma->to_bit_depth = 16U;

      /* Now run the this transform; it was pushed before this one, so it gets
       * to do its init first and this function must return as the caller will
       * immediately call here again.
       */
      debug(*transform == &tr_gamma->tr);
      png_init_gamma(transform, tc);
      affirm(tc->bit_depth == 16U &&
             (tc->format & PNG_FORMAT_FLAG_ALPHA) != 0);
      /* This is only a 'debug' because it needs to replicate the test in
       * png_init_gamma and that is easy to get wrong (a harmless mistake).
       */
      debug(tc->gamma == 0 ||
            !png_gamma_significant(png_ptr, tc->gamma, tc_sBIT(tc)));
   }

   /* A transform was pushed, so this transform init will be run again: */
   tr->tr.fn = png_init_background_alpha_end;
#  undef png_ptr
}

/* Handle alpha and tRNS via a background color */
static void
png_init_background(png_transformp *transform, png_transform_controlp tc)
{
   /* This init function is called right at the start, this means it can get at
    * the tRNS values if appropriate.  If not the RGB to gray transform comes
    * next followed by PNG_TR_COMPOSE_ALPHA, which actually does the non-tRNS
    * work.
    */
   png_structp png_ptr = tc->png_ptr;
   png_transform_background *tr =
      png_transform_cast(png_transform_background, *transform);

   if (tc->init == PNG_TC_INIT_FORMAT)
   {
      /* Background composition removes the alpha channel, so the other
       * operations become irrelevant:
       */
      if (tr->st.compose_background)
         tr->st.associate_alpha = tr->st.encode_alpha = tr->st.optimize_alpha =
            0U;

      else if (!tr->st.associate_alpha)
      {
         /* There is nothing to do, delete the whole transform. */
         tr->tr.fn = NULL;
         return;
      }

      /* Else alpha association ('pre-multiplication') which is achieved by
       * composing on a 0 background.  The background color will be black (all
       * zeros) and the background gamma will be zero.
       */

      /* Because we are in PNG_TC_INIT_FORMAT no other transforms will have been
       * inserted between this one and an rgb-to-gray transform, so we can find
       * out if rgb-to-gray has been requested:
       */
      tr->st.rgb_to_gray = tr->tr.next != NULL &&
         tr->tr.next->order == PNG_TR_RGB_TO_GRAY;

      if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0)
      {
         /* Associated alpha does not strip the alpha channel! */
         if (tr->st.compose_background)
            tc->format &= PNG_BIC_MASK(PNG_FORMAT_FLAG_ALPHA);
      }

      else if (!tc->palette &&
         png_ptr->num_trans == 1 && !(tc->invalid_info & PNG_INFO_tRNS))
      {
         /* tRNS will be expanded, or handled */
         tc->invalid_info |= PNG_INFO_tRNS;
         if (!tr->st.compose_background)
         {
            tc->format |= PNG_FORMAT_FLAG_ALPHA;
            /* And in this case, only, because we are adding an alpha channel we
             * need to have a channel depth of at least 8:
             */
            if (tc->bit_depth < 8U)
               tc->bit_depth = 8U;
         }
      }

      else /* no transparent pixels to change */
         tr->tr.fn = NULL;
   }

   else /* PNG_TC_INIT_FINAL */
   {
      png_fixed_point correction;

      debug(tc->init == PNG_TC_INIT_FINAL &&
            ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 ||
             (!tc->palette && png_ptr->num_trans == 1 &&
              !(tc->invalid_info & PNG_INFO_tRNS))));

      /* The screen gamma is known, so the background gamma can be found, note
       * that both the gamma values used below will be 0 if no gamma information
       * was in the PNG and no gamma information has been provided by
       * png_set_gamma or png_set_alpha_mode.
       */
      switch (tr->st.background_gamma)
      {
         case PNG_BACKGROUND_GAMMA_FILE:
            /* png_init_transform_control has already found the file gamma,
             * and because this is the first arithmetic transformation
             * nothing has changed it.
             */
            tr->st.background_gamma = tc->gamma;
            break;

         case PNG_BACKGROUND_GAMMA_SCREEN:
            tr->st.background_gamma = png_ptr->row_gamma;
            break;

         default:
            /* already set */
            break;
      }

      /* Work out what the background color is, this only depends on 'tc' for
       * palette information, so it can be done now before we know the actual
       * bit_depth/format that will be required:
       */
      resolve_background_color(tr, tc);

      /* Is this format compatible with the current row data?  If it is then it
       * is possible to avoid the arithmetic if no alpha processing is required.
       * This is a useful optimization because PNG files with just transparent
       * pixels and no alpha are common.
       *
       * NOTE: if an RGB-to-gray transform is present this is fine so long as
       * the background is gray, otherwise (non-gray background) there is a
       * following gray-to-RGB transform and the now gray image must be
       * composited on a color background.
       */
      if (tr->st.compose_background /* alpha channel stripped */ &&
          (tr->st.background_is_gray ||
           ((tc->format & PNG_FORMAT_FLAG_COLOR) != 0 && !tr->st.rgb_to_gray))
            /* color compatible */ &&
          tc->bit_depth >= tr->st.background_bit_depth
            /* bit depth compatible */ &&
          (tc->transparent_alpha ||
           (!tc->palette && png_ptr->num_trans == 1 &&
            !(tc->invalid_info & PNG_INFO_tRNS)))
            /* no alpha processing */ &&
          png_gamma_equal(png_ptr, tc->gamma, png_ptr->row_gamma, &correction,
             tc->bit_depth) /* gamma compatible (so no gamma processing) */)
      {
         /* How the operation gets performed depends on whether the current data
          * has an alpha channel or not.
          */
         if ((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0)
         {
            affirm(tc->transparent_alpha);
            /* This init routine does the sBIT handling: */
            png_init_background_transparent(transform, tc);
         }

         else if (!tc->palette && png_ptr->num_trans == 1 &&
            !(tc->invalid_info & PNG_INFO_tRNS))
         {
            /* The background pixel needs to be filled in now; no more init
             * routines are called in this case.  It is important to delay this
             * as late as possible because it needs to know the actual tc format
             * that must be used.
             */
            fill_background_pixel(tr, tc);

            debug(!(png_ptr->color_type & PNG_COLOR_MASK_PALETTE));

            /* The pixel depth should not have been changed yet: */
            debug(PNG_PIXEL_DEPTH(*png_ptr) == PNG_TC_PIXEL_DEPTH(*tc));

            /* The transparent_pixel value needs to be filled in. */
            affirm(tr->st.ntrans ==
               fill_transparent_pixel(png_ptr, tr->st.transparent_pixel));

            /* The whole operation is a no-op if the transparent pixel and the
             * background pixel match, even in the associated alpha case where
             * both will be 0 throughout.
             *
             * NOTE: for palette images this test happens in the caching
             * operation, so the answer is still correct.
             *
             * NOTE: for low bit depth gray both 'transparent_pixel' and
             * 'background_pixel' have been expanded to fill a byte, so this
             * works.
             */
            if (memcmp(tr->st.transparent_pixel, tr->st.background_pixel,
                     tr->st.ntrans) == 0)
               tr->tr.fn = NULL;

            /* Then the processing function depends on the pixel size: */
            else if (tr->st.ntrans > 1U)
               tr->tr.fn = png_do_replace_tRNS_multi;

            else if (tc->bit_depth == 8U)
               tr->tr.fn = png_do_replace_tRNS_8;

            else if (tc->bit_depth == 1U)
            {
               /* This is the silly case: the replacement pixel does not match
                * the transparent pixel (handled above) so either all the '0'
                * bits are replaced by '1' or all the '1' bits are replaced by
                * '0':
                */
               png_uint_32 args = tr->st.background_pixel[0];

               args <<= 24;
               args |= PNG_INFO_tRNS | PNG_INFO_sRGB;
               tr->tr.args = args;
               tr->tr.fn = png_do_set_row;
            }

            else
               tr->tr.fn = png_do_replace_tRNS_lbd;

            tc->invalid_info |= PNG_INFO_tRNS | PNG_INFO_sBIT;
            tc->sBIT_R = tc->sBIT_G = tc->sBIT_B = tc->sBIT_A =
               png_check_byte(png_ptr, tc->bit_depth);
         }

         else
         {
            /* Nothing to do; should have been eliminated before! */
            tr->tr.fn = NULL;
            NOT_REACHED;
         }
      }

      else /* alpha, or maybe gamma, processing required */
      {
         /* Alpha case, add an appropriate transform; this has to be done
          * *after* the RGB-to-gray case so move the transform info there:
          */
         png_transform_background *tr_alpha =
            png_transform_cast(png_transform_background,
               png_add_transform(png_ptr, sizeof (png_transform_background),
                  png_init_background_alpha, PNG_TR_COMPOSE_ALPHA));

         /* Copy the current state into the new png_transform_background: */
         tr_alpha->st = tr->st;
         tr_alpha->tr.args = tr->tr.args;

         /* The rest of the init occurs later; this transform is no longer
          * needed.
          */
         tr->tr.fn = NULL;

         /* Ensure that png_init_background_alpha gets an alpha channel, this
          * needs to happen here because otherwise intervening transforms can
          * invalidate tRNS.
          */
         tc->expand_tRNS = 1U;
         if (tr->st.compose_background)
            tc->strip_alpha = 0U;

         /* And push the expand: */
         (void)push_gamma_expand(transform, tc, 1/*need alpha*/);

         /* Regardless of whether anything got pushed the following should now
          * be true:
          */
         affirm((tc->format & PNG_FORMAT_FLAG_ALPHA) != 0 &&
                tc->bit_depth >= 8U);
      }
   }
}

void PNGFAPI
png_set_background_fixed(png_structrp png_ptr,
    png_const_color_16p background_color, int background_gamma_code,
    int need_expand, png_fixed_point background_gamma)
{
   if (png_ptr != NULL)
   {
      if (background_color != NULL)
      {
         png_transform_background *tr =
            png_transform_cast(png_transform_background,
               png_add_transform(png_ptr, sizeof (png_transform_background),
                  png_init_background, PNG_TR_COMPOSE));

         /* This silently overwrites the information if png_set_background is
          * called more than once.
          */
         tr->st.background = *background_color;
         tr->st.need_expand = need_expand != 0;
         tr->st.compose_background = 1U; /* png_set_background called */
         switch (background_gamma_code)
         {
            case PNG_BACKGROUND_GAMMA_SCREEN:
            case PNG_BACKGROUND_GAMMA_FILE:
               tr->st.background_gamma = background_gamma_code;
               break;

            case PNG_BACKGROUND_GAMMA_UNIQUE:
               if (background_gamma >= 16 && background_gamma <= 625000000)
               {
                  tr->st.background_gamma = background_gamma;
                  break;
               }

               png_app_error(png_ptr, "gamma value out of range");
               /* FALL THROUGH */
            default:
               png_app_error(png_ptr, "invalid gamma information");
               tr->st.background_gamma = (need_expand ?
                  PNG_BACKGROUND_GAMMA_FILE : PNG_BACKGROUND_GAMMA_SCREEN);
               break;
         }
      }

      else
         png_app_error(png_ptr, "missing background color");
   }
}

#  ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
png_set_background(png_structrp png_ptr,
    png_const_color_16p background_color, int background_gamma_code,
    int need_expand, double background_gamma)
{
   png_set_background_fixed(png_ptr, background_color, background_gamma_code,
      need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
}
#  endif  /* FLOATING_POINT */
#endif /* READ_BACKGROUND */

#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
void PNGFAPI
png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
   png_fixed_point output_gamma)
{
   if (png_ptr != NULL)
   {
      /* Check the passed in output_gamma value; it must be valid and it must be
       * converted to the reciprocal for use below:
       */
      output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);

      if (output_gamma > 0) /* Else an app_error has been signalled. */
      {
         /* Only set the colorspace gamma if it has not already been set (this
          * has the side effect that the gamma in a second call to
          * png_set_alpha_mode will be ignored.)
          */
         if ((png_ptr->colorspace.flags &
              (PNG_COLORSPACE_INVALID | PNG_COLORSPACE_HAVE_GAMMA)) !=
              PNG_COLORSPACE_HAVE_GAMMA)
         {
            /* The default file gamma is the output gamma encoding: */
            png_ptr->colorspace.gamma = output_gamma;
            if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
               png_ptr->colorspace.flags = PNG_COLORSPACE_HAVE_GAMMA;
            else
               png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
         }

         /* Always set the output gamma, note that it may be changed to PNG_FP_1
          * for the associated alpha support.  This means that the last call to
          * png_set_gamma[_fixed] or png_set_alpha_mode sets the output gamma,
          * which is probably what is expected.
          */
         {
            png_transform_gamma *tr_gamma = add_gamma_transform(png_ptr,
               PNG_TR_GAMMA_ENCODE,
               mode == PNG_ALPHA_ASSOCIATED ? PNG_FP_1 : output_gamma, 0U,
               1/*force*/);

            /* Get a background transform and set the appropriate fields.
             *
             * png_set_background removes the alpha channel so it effectively
             * disbles png_set_alpha_mode however png_set_alpha_mode is still
             * useful to set a default gamma value.
             */
            png_transform_background *tr =
               png_transform_cast(png_transform_background,
                  png_add_transform(png_ptr, sizeof (png_transform_background),
                     png_init_background, PNG_TR_COMPOSE));

            /* There are really 8 possibilities here, composed of any
             * combination of:
             *
             *    premultiply the color channels
             *    do not encode non-opaque pixels (leave as linear)
             *    encode the alpha as well as the color channels
             *
             * The differences disappear if the input/output ('screen') gamma is
             * 1.0,  because then the encoding is a no-op and there is only the
             * choice of premultiplying the color channels or not.
             */
            switch (mode)
            {
               case PNG_ALPHA_PNG:        /* default: png standard */
                  /* No compose, but it may be set by png_set_background!  This
                   * is the only mode that doesn't interfere with what
                   * png_set_background does.
                   */
                  tr->st.associate_alpha = 0U;
                  tr_gamma->encode_alpha = tr->st.encode_alpha = 0U;
                  tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U;
                  break;

               case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
                  tr->st.associate_alpha = 1U;
                  tr_gamma->encode_alpha = tr->st.encode_alpha = 0U;
                  tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U;
                  break;

               case PNG_ALPHA_OPTIMIZED:
                  /* associated with opaque pixels having the given gamma and
                   * non-opaque pixels being linear.
                   */
                  tr->st.associate_alpha = 1U;
                  tr_gamma->encode_alpha = tr->st.encode_alpha = 0U;
                  tr_gamma->optimize_alpha = tr->st.optimize_alpha = 1U;
                  /* output_gamma records the encoding of opaque pixels! */
                  break;

               case PNG_ALPHA_BROKEN:
                  /* associated+non-linear+alpha encoded */
                  tr->st.associate_alpha = 1U;
                  tr_gamma->encode_alpha = tr->st.encode_alpha = 1U;
                  tr_gamma->optimize_alpha = tr->st.optimize_alpha = 0U;
                  break;

               default:
                  png_app_error(png_ptr, "invalid alpha mode");
                  /* A return at this point is safe; if a background transform
                   * was created the init routine will remove it because
                   * nothing is set.
                   */
                  break;
            } /* alpha mode switch */
         } /* add gamma and background transforms */
      } /* valid output gamma */
   } /* png_ptr != NULL */
}

#ifdef PNG_FLOATING_POINT_SUPPORTED
void PNGAPI
png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
{
   png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
      output_gamma));
}
#endif /* FLOATING_POINT */
#endif /* READ_ALPHA_MODE */

#ifdef PNG_READ_TRANSFORMS_SUPPORTED
typedef struct
{
   png_transform         tr;
   png_transform_control tc;
   union
   {
      png_uint_32        u32[1]; /* ensure alignment */
      png_uint_16        u16[1];
      png_byte           b8[1];
   }  cache;
}  png_transform_cache;

#define png_transform_cache_size(size)\
   (offsetof(png_transform_cache, cache)+(size))
#define png_transform_cache_cast(pointer,size)\
   png_voidcast(png_transform_cache*,\
      png_transform_cast_check(png_ptr, PNG_SRC_LINE, (pointer),\
         png_transform_cache_size(size)))
   /* This is like png_transform_cast except that 'size' is the size of the
    * cache part in the above structure and the type returned is always
    * 'png_transform_cache*'.
    */

/* Functions to handle the cache operation.  These don't do any initialization;
 * that happens below when PNG_TC_INIT_FINAL is being run on the whole list.
 * These functions are only implemented for read so the transform control
 * source and destination are always aligned.
 *
 * First some utility functions:
 */
static void
png_transform_control_cp(png_transform_controlp tcDest,
   png_const_transform_controlp tcSrc)
{
   /* Copy tcSrc over tcDest without overwriting the information specific to the
    * row being transformed.
    */
   png_structp     png_ptr = tcDest->png_ptr;
   png_const_voidp sp      = tcDest->sp;
   png_voidp       dp      = tcDest->dp;
   png_uint_32     width   = tcDest->width;
   unsigned int    init    = tcDest->init;

   *tcDest = *tcSrc;

   tcDest->png_ptr = png_ptr;
   tcDest->sp      = sp;
   tcDest->dp      = dp;
   tcDest->width   = width;
   tcDest->init    = png_check_bits(tcDest->png_ptr, init, 2);
}

#if !PNG_RELEASE_BUILD
static int
png_transform_control_eq(png_const_transform_controlp tc1,
   png_const_transform_controlp tc2)
{
   /* Say if *tc1 == *tc2, ignoring differences in uncopied fields and 'cost':
    */
   return
#     ifdef PNG_READ_GAMMA_SUPPORTED
         tc1->gamma == tc2->gamma &&
#     endif
      tc1->format == tc2->format &&
      tc1->range == tc2->range &&
      tc1->bit_depth == tc2->bit_depth &&
      tc1->caching == tc2->caching &&
      tc1->palette == tc2->palette;
      /* invalid_info, cost, interchannel and channel_add are only set during
       * init, so don't do the compare.
       */
}
#endif /* !RELEASE_BUILD */

/* Now the routines that actually perform the transform.  There are two basic
 * cases:
 *
 * 1) A cached transform that does not change the pixel size and where the pixel
 *    size 8 bits or less.  This can be done by a 256-entry single byte lookup
 *    table, regardless of the bit depth.  Two versions of the code exist, one
 *    which just transforms the row, the other which transforms and records the
 *    maximum pixel depth.
 *
 * 2) A cached transform that increases pixel depth.  The destination pixel
 *    depth will always be a multiple of 8 bits, the source pixel will be less
 *    than or equal to 8 bits and will be in the PNG native (big endian) layout.
 */
#define png_ptr (tc->png_ptr) /* Used in all functions below */
/* (1): single-byte cached transforms: */
static void
do_transform_cache_byte(png_transformp *trIn, png_transform_controlp tc)
{
   png_transform_cache *tr = png_transform_cache_cast(*trIn, 256U);

   /* Copy the bytes through the 256-byte LUT: */
   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep ep = dp + PNG_TC_ROWBYTES(*tc);
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);

   tc->sp = dp;

   do
      *dp++ = tr->cache.b8[*sp++];
   while (dp < ep);

   png_transform_control_cp(tc, &tr->tc);
}

/* (2) A cached transform that increases pixel depth.
 *
 * There are six output depth possibilites, all a whole number of bytes:
 *
 *    1 byte,   8 bits: palette or grayscale
 *    2 bytes, 16 bits: 16-bit grayscale or 8-bit gray+alpa
 *    3 bytes, 24 bits: 8-bit RGB
 *    4 bytes, 32 bits: 16-bit gray+alpha or 8-bit RGBA
 *    6 bytes, 48 bits: 16-bit RGB
 *    8 bytes, 64 bits: 16-bit RGBA
 *
 * The input must be 1, 2, 4 or 8-bit gray or palette.  The first 1-byte case is
 * handled for 8-bit gray/palette above, so there are 22 possibilities.  The
 * function names below are:
 *
 *    do_transform_cache_<input-bits>_<output-bits>
 */
#define transform_cache_size(ipd,opd) ((((1U << (ipd)) * (opd))+7U) >> 3)
static void
do_transform_cache_(png_transformp *trIn, png_transform_controlp tc,
   unsigned int ipd, unsigned int opd)
   /* This is the implementation for unknown ipd, opd, below it is called with
    * fixed values.  The purpose of this is to allow the compiler/system builder
    * to decide how to optimize for size vs space vs speed.  Note that this
    * implementation, while it would work for 8 bit ipd, is not used in that
    * case.
    */
{
   png_transform_cache *tr =
      png_transform_cache_cast(*trIn, transform_cache_size(ipd, opd));

   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep ep = dp;
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);
   unsigned int s, shift, mask;

   sp += PNG_TC_ROWBYTES(*tc); /* One byte beyond the end */

   png_transform_control_cp(tc, &tr->tc);
   dp += PNG_TC_ROWBYTES(*tc);

   shift = 7U & -(tc->width * ipd);
      /* MSB: shift right required to get last pixel */
   mask = (1U << ipd) - 1U;
      /* Mask to extract a single pixel from the low bits of a byte */
   opd >>= 3;
      /* Output pixel size in bytes */
   s = *--sp;
      /* The first byte; the last byte of the input row */

   for (;;)
   {
      png_const_bytep opixel = (((s >> shift) & mask)+1U) * opd + tr->cache.b8;
         /* Points to the byte after last byte of the output value */
      unsigned int i;

      for (i=0; i<opd; ++i)
         *--dp = *--opixel;

      if (dp <= ep)
         break;

      shift += ipd; /* To find shift for *previous* pixel */

      if (shift == 8U)
         s = *--sp, shift = 0U/*right-most pixel*/;
   }

   debug(dp == ep && shift == 8U-ipd && sp == tc->sp);
   tc->sp = ep; /* start of row, safe even if the above fails */
}

#define do_transform_cache(ipd,opd)\
static void \
do_transform_cache_##ipd##_##opd(png_transformp *tr, png_transform_controlp tc)\
{\
   do_transform_cache_(tr, tc, ipd, opd);\
}

#define TCLOW(opd)\
do_transform_cache(1,opd)\
do_transform_cache(2,opd)\
do_transform_cache(4,opd)

TCLOW(8)
TCLOW(16)
TCLOW(24)
TCLOW(32)
TCLOW(48)
TCLOW(64)

#undef TCLOW
#undef do_transform_cache

static void
do_transform_cache_8_(png_transformp *trIn, png_transform_controlp tc,
   unsigned int opd)
   /* This is the 8-bit input implementation. */
{
   png_transform_cache *tr =
      png_transform_cache_cast(*trIn, transform_cache_size(8, opd));

   png_bytep dp = png_voidcast(png_bytep, tc->dp);
   png_const_bytep ep = dp;
   png_const_bytep sp = png_voidcast(png_const_bytep, tc->sp);

   sp += PNG_TC_ROWBYTES(*tc); /* One byte beyond the end */

   png_transform_control_cp(tc, &tr->tc);
   dp += PNG_TC_ROWBYTES(*tc);

   opd >>= 3; /* Output pixel size in bytes */
   do
   {
      png_const_bytep opixel = (*--sp + 1U) * opd + tr->cache.b8;
         /* Points to the byte after last byte of the output value */
      unsigned int i;

      for (i=0; i<opd; ++i)
         *--dp = *--opixel;
   }
   while (dp > ep);

   debug(dp == ep && sp == tc->sp);
   tc->sp = ep; /* start of row, safe even if the above fails */
}

#define do_transform_cache(opd)\
static void \
do_transform_cache_8_##opd(png_transformp *tr, png_transform_controlp tc)\
{\
   do_transform_cache_8_(tr, tc, opd);\
}

/* The 8-bit to 8-bit case uses the byte transform code */
do_transform_cache(16)
do_transform_cache(24)
do_transform_cache(32)
do_transform_cache(48)
do_transform_cache(64)

#undef do_transform_cache

#define do_transform_cache(ipd,opd) do_transform_cache_##ipd##_##opd

#undef png_ptr

typedef struct
{
   png_transformp *start;
      /* This is a pointer to the pointer to the start of the list being cached,
       * i.e. *start is the first transform in the list.
       */
   png_transform_control tstart;
      /* This is the transform control at the start; i.e. before (*start)->fn is
       * called.  Note that for palette data it will contain the original
       * palette format/bit-depth, not that passed to (*start)->fn which will
       * represent the palette.
       */
   png_transformp *end;
   png_transform_control tend;
      /* The same data from the end of the run to be cached, i.e. after the
       * function of the transform which *contains* '*end' (end points to
       * tr->next).
       */
}  png_cache_params, *png_cache_paramsp;

static void
init_caching(png_structp png_ptr, png_cache_paramsp cp)
   /* Given an already initialized cp->tend turn on caching if appropriate. */
{
   /* Handle the colormap case, where a cache is always required: */
   if (cp->tend.format & PNG_FORMAT_FLAG_COLORMAP)
   {
      /* This turns starts the palette caching with the next transform: */
      cp->tend.palette = cp->tend.caching = 1U;
      cp->tend.transparent_alpha = png_ptr->transparent_palette;
      cp->tend.format = PNG_FORMAT_FLAG_COLOR;
#     ifdef PNG_READ_tRNS_SUPPORTED
         if (png_ptr->num_trans > 0 && !(cp->tend.invalid_info & PNG_INFO_tRNS))
         {
            cp->tend.format |= PNG_FORMAT_FLAG_ALPHA;
         }
#     endif /* READ_tRNS */
      cp->tend.bit_depth = 8U;
   }

   else if (PNG_TC_PIXEL_DEPTH(cp->tend) <= 8)
   {
      /* Cacheable pixel transforms; the pixel is less than 8 bits in size so
       * the cache makes sense.
       *
       * TODO: check the cost estimate and the image size to avoid expensive
       * caches of very small images.
       */
      cp->tend.caching = 1U;
   }

   /* TODO: handle handle 8-bit GA/RGB/RGBA */
}

static void
add_cache_transform(png_structp png_ptr, unsigned int order,
   png_transform_fn fn, png_cache_paramsp cp,
   png_const_bytep cache, unsigned int size)
   /* Add a transform from the input format cp->tstart to the output format
    * stored in cp->tend.
    */
{
   affirm(size <= 2048U); /* 256 8-byte pixels at most */
   {
      png_transform_cache *tr = png_transform_cache_cast(
         png_add_transform(png_ptr, png_transform_cache_size(size), fn, order),
            size);

      /* This must have replaced the transform in *cp->start: */
      affirm(&tr->tr == *cp->start);

      /* Fill in the respective members: */
      tr->tc = cp->tend;
      memcpy(tr->cache.b8, cache, size);

      /* Skip this transform, because the calling routine has already executed
       * the cache (it could be executed again, just to verify that it works;
       * cp->tstart should be correct.)
       */
      cp->start = &tr->tr.next;
   }
}

static unsigned int
setup_palette_cache(png_structp png_ptr, png_byte cache[8*256])
   /* This returns the number of entries in the cache; the width */
{
   const unsigned int num_palette = png_ptr->num_palette;
#  ifdef PNG_READ_tRNS_SUPPORTED
      unsigned int num_trans = png_ptr->num_trans;
#  endif /* READ_tRNS */
   const png_colorp  palette = png_ptr->palette;
   png_bytep p;
   unsigned int i;
#  ifdef PNG_READ_tRNS_SUPPORTED
      const png_bytep trans_alpha = png_ptr->trans_alpha;
#  endif /* READ_tRNS */

   for (i=0, p=cache; i<num_palette; ++i)
   {
      *p++ = palette[i].red;
      *p++ = palette[i].green;
      *p++ = palette[i].blue;
#     ifdef PNG_READ_tRNS_SUPPORTED
         if (num_trans > 0)
         {
            if (i < num_trans)
               *p++ = trans_alpha[i];

            else
               *p++ = 0xFFU;
         }
#     endif /* READ_tRNS */
   }

   return num_palette;
}

static void
png_remove_PLTE_and_tRNS(png_structrp png_ptr)
{
   if (png_ptr->palette != NULL)
      png_free(png_ptr, png_ptr->palette);

   png_ptr->palette = NULL;
   png_ptr->num_palette = 0;

#  ifdef PNG_READ_tRNS_SUPPORTED
      if (png_ptr->trans_alpha != NULL)
         png_free(png_ptr, png_ptr->trans_alpha);

      png_ptr->trans_alpha = NULL;
      png_ptr->num_trans = 0;
#  endif /* READ_tRNS */
}

static void
update_palette(png_structp png_ptr, png_cache_paramsp cp,
   unsigned int max_depth)
{
   union
   {
      png_uint_32 u32[1];
      png_uint_16 u16[1];    /* For alignment */
      png_byte    b8[8*256]; /* For 16-bit RGBA intermediate */
   }  cache;

   /* The caller only calls this function if the initial transform control had
    * the palette flag set, implying that the original 'format' was a COLORMAP
    * one.  Also this can only happen (at present) when starting the transform
    * list, so:
    */
   affirm((cp->tstart.format & PNG_FORMAT_FLAG_COLORMAP) != 0); /* required */
   debug(cp->start == &png_ptr->transform_list); /* should be harmless */

   /* Run the whole of the given list on the palette data.  PNG_TC_INIT_FINAL
    * has already been run; this is a full run (with init == 0).
    */
   {
      unsigned int check_depth;
      only_deb(png_transform_control orig = cp->tend;)

      cp->tend = cp->tstart;
      init_caching(png_ptr, cp);
      /* And set up tend to actually work out the palette: */
      cp->tend.init = 0U;
      cp->tend.width = setup_palette_cache(png_ptr, cache.b8);
      cp->tend.sp = cache.b8;
      cp->tend.dp = cache.b8;

      check_depth =
         png_run_this_transform_list_forwards(&cp->tend, cp->start, *cp->end);

      /* If we get here these two things must be true or there are been some
       * buggy difference of opinion between the INIT code and the actual run:
       */
      affirm(check_depth == max_depth && cp->tend.palette);

      /* This should match the passed in final format obtained before, this
       * debug statement detects discrepancies between the init code and the
       * run code:
       */
      debug(png_transform_control_eq(&cp->tend, &orig));

      /* Also, expect the palette to still be valid: */
      debug((cp->tend.invalid_info & PNG_INFO_PLTE) == 0);
   }

   /* The result must be compatible with a PNG palette with respect to bit
    * depth; specifically the expand-16 transform has no effect on palette data.
    *
    * The colormap setting must not have been re-introduced here either; there
    * may be some quantize interactions here, neither can unexpected flags be
    * handled; just COLOR and ALPHA.
    */
   affirm(cp->tend.bit_depth == 8 &&
          (cp->tend.format & PNG_FORMAT_FLAG_COLORMAP) == 0);

   /* Remove all the transforms between start(inclusive) and end(exclusive);
    * they have been processed.  The effect they had on the transform control
    * is irrelevant because the caller re-instates the settings from tstart.
    */
   {
      png_transformp list = *cp->start; /* list to free */

      *cp->start = *cp->end; /* part of list not to be freed */
      *cp->end = NULL; /* terminate the list to be freed */
      cp->end = cp->start; /* else cp->end points to the end of the list! */

      png_transform_free(png_ptr, &list);
   }

   /* Adjust the PNG palette and, if required, the tRNS entries.  Note that
    * if the transforms stripped the alpha channel from the palette num_trans
    * will get set to 0 here.
    *
    * This is the point where the gamma gets frozen too.  The alternative
    * design is to pass palette, tRNS and gamma up the transform chain, but
    * that doesn't work because the palette change would, apparently, have to
    * be repeated on each row.  This seems simpler at the cost of a little
    * obscurity; the answer to the question, "Where does the palette get
    * updated?", is "Here!"
    *
    * API CHANGE: (fix): previously the init code would silently overwrite
    * the palette information shared with png_info, breaking the API for
    * png_read_update_info, which doesn't update the info if it isn't called,
    * by changing the palette and maybe tRNS when the first row was read!
    *
    * NOTE: PNG_FORMAT_FLAG_RANGE is lost at this point, even if the palette
    * entries were shifted or inverted.  This could be fixed, but it would
    * complicate the libpng API to expose the information.
    */
   /* Write the transformed palette: */
   {
      png_colorp palette = png_voidcast(png_colorp, png_calloc(png_ptr,
               sizeof (png_color[PNG_MAX_PALETTE_LENGTH])));
      png_const_bytep p;
      const int is_color = (cp->tend.format & PNG_FORMAT_FLAG_COLOR) != 0;
      unsigned int i;
#     ifdef PNG_READ_tRNS_SUPPORTED
         unsigned int num_trans = 0;
         const int do_trans = (cp->tend.format & PNG_FORMAT_FLAG_ALPHA) != 0;
         png_byte trans_alpha[PNG_MAX_PALETTE_LENGTH];
#     endif /* READ_tRNS */

      memset(palette, 0xFFU, sizeof (png_color[PNG_MAX_PALETTE_LENGTH]));
      png_free(png_ptr, png_ptr->palette);
      png_ptr->palette = palette;

      for (i=0, p=cache.b8; i<cp->tend.width; ++i)
      {
         if (is_color)
         {
            palette[i].red = *p++;
            palette[i].green = *p++;
            palette[i].blue = *p++;
         }

         else
            palette[i].blue = palette[i].green = palette[i].red = *p++;

#        ifdef PNG_READ_tRNS_SUPPORTED
            if (do_trans)
            {
               png_byte a = *p++;
               trans_alpha[i] = a;

               /* Strip opaque entries from the end: */
               if (a < 0xFFU)
                  num_trans = i+1;
            }
#        endif /* READ_tRNS */
      }

      png_ptr->num_palette = png_check_bits(png_ptr, cp->tend.width, 9);

#     ifdef PNG_READ_tRNS_SUPPORTED
         if (num_trans > 0)
         {
            png_bytep tRNS = png_voidcast(png_bytep, png_malloc(png_ptr,
                     PNG_MAX_PALETTE_LENGTH));

            memset(tRNS, 0xFFU, PNG_MAX_PALETTE_LENGTH);

            if (png_ptr->trans_alpha != NULL)
               png_free(png_ptr, png_ptr->trans_alpha);

            png_ptr->trans_alpha = tRNS;

            memcpy(tRNS, trans_alpha, num_trans);
            png_ptr->num_trans = png_check_bits(png_ptr, num_trans, 9);
         }
#     endif /* READ_tRNS */
   }

   /* NOTE: the caller sets cp->start to cp->end and cp->tend to cp->tstart,
    * this causes processing to continue with the palette format and the
    * first unprocessed transform.  The reset of the transform control loses the
    * gamma information as well, of course, as any information about the palette
    * and tRNS changes (such as the RANGE flags).
    */
}

/* These structure and the save/restore routines that follow it exist to save
 * data from a png_transform_control that is specific to the sample encoding of
 * the PNG data, rather than the row format itself.
 */
typedef struct
{
#  ifdef PNG_READ_GAMMA_SUPPORTED
      png_fixed_point gamma;
#  endif
   png_byte           sBIT_R;
   png_byte           sBIT_G;
   png_byte           sBIT_B;
   png_byte           sBIT_A;       /* Signnificant bits in the row channels. */
   unsigned int       invalid_info; /* PNG_INFO_* for invalidated chunks */
} png_tc_channel_data;

static void
save_cp_channel_data(png_tc_channel_data *save, png_const_transform_controlp tc)
{
#  ifdef PNG_READ_GAMMA_SUPPORTED
      save->gamma = tc->gamma;
#  endif /* READ_GAMMA */

   /* The sBIT information and the list of invalidated chunks must also be
    * preserved:
    */
   save->sBIT_R = tc->sBIT_R;
   save->sBIT_G = tc->sBIT_G;
   save->sBIT_B = tc->sBIT_B;
   save->sBIT_A = tc->sBIT_A;
   save->invalid_info = tc->invalid_info;
}

static void
restore_cp_channel_data(png_transform_controlp tc,
      const png_tc_channel_data *save)
   /* Reverse the above */
{
#  ifdef PNG_READ_GAMMA_SUPPORTED
      tc->gamma = save->gamma;
#  endif /* READ_GAMMA */

   tc->sBIT_R = save->sBIT_R;
   tc->sBIT_G = save->sBIT_G;
   tc->sBIT_B = save->sBIT_B;
   tc->sBIT_A = save->sBIT_A;
   tc->invalid_info = save->invalid_info;
}

static void
make_cache(png_structp png_ptr, png_cache_paramsp cp, unsigned int max_depth)
{
   /* At present the cache is just a byte lookup table.  We need the original
    * pixel depth to work out how big the working buffer needs to be.
    */
   const unsigned int ipd = PNG_TC_PIXEL_DEPTH(cp->tstart);
   const unsigned int opd = PNG_TC_PIXEL_DEPTH(cp->tend);
   unsigned int order; /* records position of start transform */
   unsigned int width; /* width of cache in pixels */
   png_tc_channel_data save; /* Record of the final channel info */
   union
   {
      png_uint_32 u32[1];
      png_uint_16 u16[1];    /* For alignment */
      png_byte    b8[8*256]; /* For 16-bit RGBA */
   }  cache;

   debug(cp->tend.init == PNG_TC_INIT_FINAL);
   affirm(opd <= 64 && max_depth <= 64); /* or the cache is not big enough */
   affirm(ipd == opd || (opd & 0x7U) == 0);

   if ((cp->tstart.format & PNG_FORMAT_FLAG_COLORMAP) != 0)
      width = setup_palette_cache(png_ptr, cache.b8);

   else switch (ipd)
   {
      /* The input to the cache is the full range of possible pixel values: */
      case 1:
         /* 2 1-bit pixels, MSB first */
         cache.b8[0] = 0x40U;
         width = 2;
         break;

      case 2:
         /* 4 2-bit pixels, MSB first */
         cache.b8[0] = 0x1BU;
         width = 4;
         break;

      case 4:
         /* 16 4-bit pixels, MSB first */
         cache.b8[0] = 0x01U;
         cache.b8[1] = 0x23U;
         cache.b8[2] = 0x45U;
         cache.b8[3] = 0x67U;
         cache.b8[4] = 0x89U;
         cache.b8[5] = 0xABU;
         cache.b8[6] = 0xCDU;
         cache.b8[7] = 0xEFU;
         width = 16;
         break;

      case 8:
         /* 256 8-bit pixels */
         {
            unsigned int i;

            for (i=0; i<256; ++i)
               cache.b8[i] = PNG_BYTE(i);
         }
         width = 256;
         break;

      default:
         impossible("cache input bit depth");
   }

   /* Reset the transform control to run the transforms on this data, but save
    * the channel info because the row processing functions do not always
    * write it.
    */
   save_cp_channel_data(&save, &cp->tend);
   cp->tend = cp->tstart;
   init_caching(png_ptr, cp);
   /* And set tend to work out the result of transforming each possible pixel
    * value:
    */
   cp->tend.init = 0U;
   cp->tend.width = width;
   cp->tend.sp = cache.b8;
   cp->tend.dp = cache.b8;

   {
      unsigned int check_depth =
         png_run_this_transform_list_forwards(&cp->tend, cp->start, *cp->end);

      /* This must not change: */
      affirm(PNG_TC_PIXEL_DEPTH(cp->tend) == opd && check_depth == max_depth);
   }

   /* Restore the potentially lost channel data. */
   restore_cp_channel_data(&cp->tend, &save);

   /* This is all the information required to cache the set of transforms
    * between 'start' and 'end'.  We take the transformed pixels and make a
    * cache transform of them.  The cache transform skips the work, transforms
    * the row, and sets the tranform_control to (a copy of) cp->tend.
    *
    * Remove all the transforms between start(inclusive) and end(exclusive);
    * they have been processed.  The effect they had on the transform control
    * is irrelevant because the caller re-instates the settings from tstart.
    */
   {
      png_transformp list = *cp->start; /* list to free */

      *cp->start = *cp->end; /* part of list not to be freed */
      *cp->end = NULL; /* terminate the list to be freed */
      cp->end = NULL; /* reset below */

      order = list->order; /* used below when adding the cache transform */
      png_transform_free(png_ptr, &list);
   }

   /* Make the required cache, as enumerated above there are 22 possibilities,
    * this selects between them, fixes up the cache for the 'byte' cases (where
    * multiple pixels can be handled byte-by-byte) and selects the correct
    * transform function.
    */
   if (ipd == opd)
   {
      /* We already know that ipd is <= 8 bits, so we can expand this case to
       * the byte transform.  The complexity is that for ipd < 8 bits we only
       * have information for individual pixel values and these may be
       * pixel-swapped within the byte.
       */
      if (ipd < 8)
      {
         const int lsb = (cp->tend.format & PNG_FORMAT_FLAG_SWAPPED) != 0;
         unsigned int ishift, b;
         png_byte bcache[256];

         switch (ipd)
         {
            case 1: ishift = 3U; break;
            case 2: ishift = 2U; break;
            case 4: ishift = 1U; break;
            default: impossible("ipd");
         }

         /* Work out the right answer for each byte of pixels: */
         for (b=0U; b<256U; ++b)
         {
            unsigned int o = 0U; /* output byte */
            unsigned int p = 8U; /* right shift to find input pixel */

            do
            {
               unsigned int q = ((1U<<ipd)-1U) & (b >> (p-=ipd));
                  /* The input pixel.  For a palette this value might be outside
                   * the range of palette indices, in which case simply insert
                   * '0':
                   */
               if (q < width)
               {
                  unsigned int r = cache.b8[q >> ishift];
                  r >>= ((lsb ? q : ~q) & ((1U<<ishift)-1U)) << (3U-ishift);
                  r &= ((1U<<ipd)-1U);
                  o |= r << (lsb ? (8U-ipd)-p : p);
               }

               else
               {
                  UNTESTED
               }
            }
            while (p != 0U);

            bcache[b] = png_check_byte(png_ptr, o);
         }

         /* This is a byte transform, with the optional check-for-invalid-index
          * functionality.
          */
         add_cache_transform(png_ptr, order, do_transform_cache_byte, cp,
            bcache, 256U);
      }

      else /* ipd == 8 */
         add_cache_transform(png_ptr, order, do_transform_cache_byte, cp,
            cache.b8, 256U);
   }

   else
   {
      /* opd is a whole number of bytes, ipd is 1, 2, 4 or 8 and not equal to
       * opd.
       */
      png_transform_fn fn;

#     define C(ipd,opd) ((ipd) + 8*(opd))
      switch (C(ipd,opd))
      {
#        define CASE(ipd,opd)\
            case C(ipd,opd): fn = do_transform_cache(ipd,opd); break

            CASE(1,8);
            CASE(2,8);
            CASE(4,8);
            /* No 8,8 */

#        define CASES(opd)\
            CASE(1,opd);\
            CASE(2,opd);\
            CASE(4,opd);\
            CASE(8,opd)

            CASES(16);
            CASES(24);
            CASES(32);
            CASES(48);
            CASES(64);
#        undef CASES
#        undef CASE

         default:
            impossible("cache bit depths");
      }
#     undef C

      /* In the event that the cache is not the full width implied by ipd zero
       * the remaining bytes for security; otherwise they get copied into the
       * cache transform and might get used.  (Specifically if there is an
       * out-of-range palette index they do get used!)
       */
      {
         unsigned int size = transform_cache_size(ipd, opd);
         png_alloc_size_t cachebytes = PNG_TC_ROWBYTES(cp->tend);

         affirm(cachebytes <= sizeof cache.b8);

         if (cachebytes < size)
            memset(cache.b8+cachebytes, 0, size - cachebytes);

         add_cache_transform(png_ptr, order, fn, cp, cache.b8, size);
      }
   }

   /* Because a transform was inserted cp->end needs to be set to the new
    * pointer to the original end.  add_cache_transform sets cp->start to this,
    * so:
    */
   cp->end = cp->start;

   /* This invalidates the palette if that is what was cached because the
    * palette and, if present, tRNS chunk did not get updated above.
    */
   if (cp->tstart.palette)
      png_remove_PLTE_and_tRNS(png_ptr);
}

static void restore_cp(png_cache_paramsp cp)
{
   /* A utility to restore cp->tstart by copying it into cp->tend.  This is used
    * both in the palette case when restoring the transform control for the
    * indexed data and in the case where no transforms were cached.  It
    * preserves the color-channel-specific data from cp->tend because in either
    * case it is possible for this data to be modified without preserving any
    * transforms, e.g. if only the gamma is changed but no gamma transform is
    * retained because the change was not significant.
    */
   png_tc_channel_data save;

   save_cp_channel_data(&save, &cp->tend);
   cp->tend = cp->tstart;
   restore_cp_channel_data(&cp->tend, &save);
}

static void
handle_cache(png_structp png_ptr, png_cache_paramsp cp, unsigned int max_depth)
{
   /* There is nothing to do if there are no transforms between 'start' and
    * 'end':
    */
   if (cp->start != cp->end)
   {
      only_deb(png_transformp tr_check = *cp->end;)

      /* libpng doesn't currently implement any pixel size of more than 64 bits
       * so:
       */
      affirm(max_depth <= 64);

      if (cp->tend.palette)
      {
         /* The transforms being cached apply to the palette, the following
          * transforms will apply to the original index data and the transformed
          * data must be used to update the palette:
          */
         if (cp->tend.init == PNG_TC_INIT_FINAL)
            update_palette(png_ptr, cp, max_depth);

         cp->start = cp->end;
         restore_cp(cp); /* reset to palette data */
      }

      else
      {
         /* Continue with the transform control in cp.tend; even if there was
          * palette data in cp.tstart it has been expanded.
          */
         if (cp->tend.init == PNG_TC_INIT_FINAL)
            make_cache(png_ptr, cp, max_depth);

         cp->tstart = cp->tend; /* keep current context */
      }

      debug(tr_check == *cp->end);
   }

   else /* no transforms cached */
      restore_cp(cp); /* removes any palette caching info */
}

#ifdef PNG_READ_tRNS_SUPPORTED
static void
check_tRNS_for_alpha(png_structrp png_ptr)
{
   unsigned int num_trans = png_ptr->num_trans;

   debug(png_ptr->color_type == PNG_COLOR_TYPE_PALETTE);

   while (num_trans > 0)
   {
      {
         const png_byte trans = png_ptr->trans_alpha[--num_trans];

         if (trans == 0xFFU)
            continue;

         if (trans > 0U)
            return; /* Palette has at least one entry >0, <0xff */
      }

      /* There is some point to the tRNS chunk; it has a non-opaque entry, this
       * code could truncate it but there is no obvious performance advantage to
       * doing this.
       */
      while (num_trans > 0)
      {
         const png_byte trans = png_ptr->trans_alpha[--num_trans];

         if (trans > 0U && trans < 0xFFU)
            return;
      }

      /* Here if the above did not find an entry >0 && <0xFFU but did find a
       * transparent entry (0u).  Record this.
       */
      png_ptr->transparent_palette = 1U;
      return;
   }

   /* All entries opaque; remove the tRNS data: */
   png_ptr->num_trans = 0U;
}
#endif /* READ_tRNS */

unsigned int /* PRIVATE */
png_read_init_transform_mech(png_structp png_ptr, png_transform_controlp tc)
   /* This is called once for each init stage (PNG_TC_INIT_FORMAT and
    * PNG_TC_INIT_FINAL) to run the transform list forwards, returning the
    * maximum depth required to process the row.  It handles caching of the
    * transforms and the processing of the palette for color-mapped PNG data.
    */
{
   png_transformp *list = &png_ptr->transform_list;
   unsigned int max_depth;
   png_cache_params cp;

   /* PNG color-mapped data must be handled here so that the palette is updated
    * correctly.  png_set_palette_to_rgb causes the palette flag to be removed
    * from the transform control but does no other change.  png_set_quantize
    * causes 8-bit RGB, RGBA or palette data to be converted into palette
    * indices, setting the palette flag.
    */
#  ifdef PNG_READ_tRNS_SUPPORTED
      /* This happens once at the start to find out if the tRNS chunk consisted
       * entirely of opaque (255) and/or transparent (0) entries.
       */
      if (tc->init == PNG_TC_INIT_FORMAT &&
          png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
         check_tRNS_for_alpha(png_ptr);
#  endif /* READ_tRNS */
   cp.end = cp.start = list;
   cp.tend = cp.tstart = *tc;
   init_caching(png_ptr, &cp);
   max_depth = PNG_TC_PIXEL_DEPTH(cp.tend);

   while (*cp.end != NULL)
   {
      png_transformp tr = *cp.end;

      /* The user transform cannot be cached. */
      if (tr->order >= PNG_TR_USER)
         break;

      /* If the 'palette' flag is set and the next transform has order
       * PNG_TR_ENCODING or later cache the results so far and continue with the
       * original palette data (cp.tstart).
       */
      if (cp.tend.palette && tr->order >= PNG_TR_ENCODING)
      {
         handle_cache(png_ptr, &cp, max_depth);

         /* The cache handling function must maintain cp.end; */
         affirm(tr == *cp.end);
         max_depth = PNG_TC_PIXEL_DEPTH(cp.tend);
      }

      /* Now run the transform list entry: */
      if (tr->fn != NULL)
      {
         tr->fn(cp.end, &cp.tend);
         tr = *cp.end; /* in case something was inserted */
      }

      if (tr->fn == NULL) /* delete this transform */
         png_remove_transform(png_ptr, cp.end);

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

         if (tc_depth > max_depth)
            max_depth = tc_depth;

         /* Advance to the next transform. */
         cp.end = &tr->next;
      }
   }

   /* At the end if still caching record the cache information (this is common;
    * this is generally the case for an expanded palette.)
    */
   if (cp.tend.caching)
   {
      png_transformp tr = *cp.end;
      handle_cache(png_ptr, &cp, max_depth);
      affirm(tr == *cp.end);
      max_depth = PNG_TC_PIXEL_DEPTH(cp.tend);
   }

   /* At the end run the init on the user transform: */
   if (*cp.end != NULL)
   {
      png_transformp tr = *cp.end;
      affirm(tr->order == PNG_TR_USER);
      if (tr->fn != NULL)
         tr->fn(cp.end, &cp.tend);
      /* This cannot insert anything, so: */
      affirm(tr == *cp.end && tr->next == NULL);

      if (tr->fn == NULL) /* delete this transform */
         png_remove_transform(png_ptr, cp.end);

      else
      {
         unsigned int tc_depth = PNG_TC_PIXEL_DEPTH(cp.tend);

         if (tc_depth > max_depth)
            max_depth = tc_depth;
      }
   }

   /* And write the input transform control: */
   *tc = cp.tend;

   return max_depth;
}

/* Modify the info structure to reflect the transformations.  The
 * info should be updated so a PNG file could be written with it,
 * assuming the transformations result in valid PNG data.
 */
void /* PRIVATE */
png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
{
   png_debug(1, "in png_read_transform_info");

   /* WARNING: this is very basic at present.  It just updates the format
    * information.  It should update the palette (and will eventually) as well
    * as invalidating chunks that the transforms break.
    */
#  ifdef PNG_TRANSFORM_MECH_SUPPORTED
      info_ptr->format = png_ptr->row_format;
      info_ptr->bit_depth = png_ptr->row_bit_depth;
#     ifdef PNG_READ_GAMMA_SUPPORTED
         /* If an info struct is used with a different png_ptr in a call to
          * png_set_gAMA then the png_struct information won't be updated, this
          * doesn't matter on write, but don't zap the value in the info on read
          * unless it is known:
          *
          * TODO: review this whole mess.
          */
         if (png_ptr->row_gamma > 0)
            info_ptr->colorspace.gamma = png_ptr->row_gamma;
#     endif

      /* Invalidate chunks marked as invalid: */
#     ifdef PNG_READ_TRANSFORMS_SUPPORTED
         info_ptr->valid &= ~png_ptr->invalid_info;

         /* If the palette or tRNS chunk was changed copy them over to the info
          * structure; this may actually re-validate the PLTE or tRNS chunks,
          * but only if png_ptr has a new version, otherwise the invalid_info
          * settings from above can still invalidate the chunk.
          */
         if (png_ptr->palette != info_ptr->palette)
         {
            png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
            info_ptr->palette = png_ptr->palette;
            info_ptr->num_palette = png_ptr->num_palette;
            if (info_ptr->palette != NULL && info_ptr->num_palette > 0)
               info_ptr->valid |= PNG_INFO_PLTE;

#           ifdef PNG_READ_tRNS
               /* ONLY do this if the palette was changed above because, in
                * fact, the tRNS data is not shared (yes, this is inconsistent,
                * perhaps fix it?)
                */
               if ((info_ptr->format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
                   png_ptr->trans_alpha != info_ptr->trans_alpha)
               {
                  png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
                  /* NOTE: it is shared now! */
                  info_ptr->trans_alpha = png_ptr->trans_alpha;
                  info_ptr->num_trans = png_ptr->num_trans;
                  if (info_ptr->trans_alpha != NULL && info_ptr->num_trans > 0)
                     info_ptr->valid |= PNG_INFO_tRNS;
               }
#           endif /* READ_tRNS */
         }
#     endif /* READ_TRANSFORMS */
#  else /* !TRANSFORM_MECH */
      PNG_UNUSED(png_ptr)
      PNG_UNUSED(info_ptr)
#  endif /* !TRANSFORM_MECH */
}
#endif /* READ_TRANSFORMS */
