Home | History | Annotate | Download | only in libpng
      1 
      2 /* pngrtran.c - transforms the data in a row for PNG readers
      3  *
      4  * Last changed in libpng 1.6.24 [August 4, 2016]
      5  * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
      6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
      7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
      8  *
      9  * This code is released under the libpng license.
     10  * For conditions of distribution and use, see the disclaimer
     11  * and license in png.h
     12  *
     13  * This file contains functions optionally called by an application
     14  * in order to tell libpng how to handle data when reading a PNG.
     15  * Transformations that are used in both reading and writing are
     16  * in pngtrans.c.
     17  */
     18 
     19 #include "pngpriv.h"
     20 
     21 #ifdef PNG_READ_SUPPORTED
     22 
     23 /* Set the action on getting a CRC error for an ancillary or critical chunk. */
     24 void PNGAPI
     25 png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
     26 {
     27    png_debug(1, "in png_set_crc_action");
     28 
     29    if (png_ptr == NULL)
     30       return;
     31 
     32    /* Tell libpng how we react to CRC errors in critical chunks */
     33    switch (crit_action)
     34    {
     35       case PNG_CRC_NO_CHANGE:                        /* Leave setting as is */
     36          break;
     37 
     38       case PNG_CRC_WARN_USE:                               /* Warn/use data */
     39          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
     40          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
     41          break;
     42 
     43       case PNG_CRC_QUIET_USE:                             /* Quiet/use data */
     44          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
     45          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
     46                            PNG_FLAG_CRC_CRITICAL_IGNORE;
     47          break;
     48 
     49       case PNG_CRC_WARN_DISCARD:    /* Not a valid action for critical data */
     50          png_warning(png_ptr,
     51              "Can't discard critical data on CRC error");
     52       case PNG_CRC_ERROR_QUIT:                                /* Error/quit */
     53 
     54       case PNG_CRC_DEFAULT:
     55       default:
     56          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
     57          break;
     58    }
     59 
     60    /* Tell libpng how we react to CRC errors in ancillary chunks */
     61    switch (ancil_action)
     62    {
     63       case PNG_CRC_NO_CHANGE:                       /* Leave setting as is */
     64          break;
     65 
     66       case PNG_CRC_WARN_USE:                              /* Warn/use data */
     67          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     68          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
     69          break;
     70 
     71       case PNG_CRC_QUIET_USE:                            /* Quiet/use data */
     72          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     73          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
     74                            PNG_FLAG_CRC_ANCILLARY_NOWARN;
     75          break;
     76 
     77       case PNG_CRC_ERROR_QUIT:                               /* Error/quit */
     78          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     79          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
     80          break;
     81 
     82       case PNG_CRC_WARN_DISCARD:                      /* Warn/discard data */
     83 
     84       case PNG_CRC_DEFAULT:
     85       default:
     86          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
     87          break;
     88    }
     89 }
     90 
     91 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
     92 /* Is it OK to set a transformation now?  Only if png_start_read_image or
     93  * png_read_update_info have not been called.  It is not necessary for the IHDR
     94  * to have been read in all cases; the need_IHDR parameter allows for this
     95  * check too.
     96  */
     97 static int
     98 png_rtran_ok(png_structrp png_ptr, int need_IHDR)
     99 {
    100    if (png_ptr != NULL)
    101    {
    102       if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
    103          png_app_error(png_ptr,
    104              "invalid after png_start_read_image or png_read_update_info");
    105 
    106       else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
    107          png_app_error(png_ptr, "invalid before the PNG header has been read");
    108 
    109       else
    110       {
    111          /* Turn on failure to initialize correctly for all transforms. */
    112          png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
    113 
    114          return 1; /* Ok */
    115       }
    116    }
    117 
    118    return 0; /* no png_error possible! */
    119 }
    120 #endif
    121 
    122 #ifdef PNG_READ_BACKGROUND_SUPPORTED
    123 /* Handle alpha and tRNS via a background color */
    124 void PNGFAPI
    125 png_set_background_fixed(png_structrp png_ptr,
    126     png_const_color_16p background_color, int background_gamma_code,
    127     int need_expand, png_fixed_point background_gamma)
    128 {
    129    png_debug(1, "in png_set_background_fixed");
    130 
    131    if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
    132       return;
    133 
    134    if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
    135    {
    136       png_warning(png_ptr, "Application must supply a known background gamma");
    137       return;
    138    }
    139 
    140    png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
    141    png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    142    png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    143 
    144    png_ptr->background = *background_color;
    145    png_ptr->background_gamma = background_gamma;
    146    png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
    147    if (need_expand != 0)
    148       png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
    149    else
    150       png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
    151 }
    152 
    153 #  ifdef PNG_FLOATING_POINT_SUPPORTED
    154 void PNGAPI
    155 png_set_background(png_structrp png_ptr,
    156     png_const_color_16p background_color, int background_gamma_code,
    157     int need_expand, double background_gamma)
    158 {
    159    png_set_background_fixed(png_ptr, background_color, background_gamma_code,
    160       need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
    161 }
    162 #  endif /* FLOATING_POINT */
    163 #endif /* READ_BACKGROUND */
    164 
    165 /* Scale 16-bit depth files to 8-bit depth.  If both of these are set then the
    166  * one that pngrtran does first (scale) happens.  This is necessary to allow the
    167  * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
    168  */
    169 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
    170 void PNGAPI
    171 png_set_scale_16(png_structrp png_ptr)
    172 {
    173    png_debug(1, "in png_set_scale_16");
    174 
    175    if (png_rtran_ok(png_ptr, 0) == 0)
    176       return;
    177 
    178    png_ptr->transformations |= PNG_SCALE_16_TO_8;
    179 }
    180 #endif
    181 
    182 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
    183 /* Chop 16-bit depth files to 8-bit depth */
    184 void PNGAPI
    185 png_set_strip_16(png_structrp png_ptr)
    186 {
    187    png_debug(1, "in png_set_strip_16");
    188 
    189    if (png_rtran_ok(png_ptr, 0) == 0)
    190       return;
    191 
    192    png_ptr->transformations |= PNG_16_TO_8;
    193 }
    194 #endif
    195 
    196 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
    197 void PNGAPI
    198 png_set_strip_alpha(png_structrp png_ptr)
    199 {
    200    png_debug(1, "in png_set_strip_alpha");
    201 
    202    if (png_rtran_ok(png_ptr, 0) == 0)
    203       return;
    204 
    205    png_ptr->transformations |= PNG_STRIP_ALPHA;
    206 }
    207 #endif
    208 
    209 #if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
    210 static png_fixed_point
    211 translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
    212     int is_screen)
    213 {
    214    /* Check for flag values.  The main reason for having the old Mac value as a
    215     * flag is that it is pretty near impossible to work out what the correct
    216     * value is from Apple documentation - a working Mac system is needed to
    217     * discover the value!
    218     */
    219    if (output_gamma == PNG_DEFAULT_sRGB ||
    220       output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
    221    {
    222       /* If there is no sRGB support this just sets the gamma to the standard
    223        * sRGB value.  (This is a side effect of using this function!)
    224        */
    225 #     ifdef PNG_READ_sRGB_SUPPORTED
    226          png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
    227 #     else
    228          PNG_UNUSED(png_ptr)
    229 #     endif
    230       if (is_screen != 0)
    231          output_gamma = PNG_GAMMA_sRGB;
    232       else
    233          output_gamma = PNG_GAMMA_sRGB_INVERSE;
    234    }
    235 
    236    else if (output_gamma == PNG_GAMMA_MAC_18 ||
    237       output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
    238    {
    239       if (is_screen != 0)
    240          output_gamma = PNG_GAMMA_MAC_OLD;
    241       else
    242          output_gamma = PNG_GAMMA_MAC_INVERSE;
    243    }
    244 
    245    return output_gamma;
    246 }
    247 
    248 #  ifdef PNG_FLOATING_POINT_SUPPORTED
    249 static png_fixed_point
    250 convert_gamma_value(png_structrp png_ptr, double output_gamma)
    251 {
    252    /* The following silently ignores cases where fixed point (times 100,000)
    253     * gamma values are passed to the floating point API.  This is safe and it
    254     * means the fixed point constants work just fine with the floating point
    255     * API.  The alternative would just lead to undetected errors and spurious
    256     * bug reports.  Negative values fail inside the _fixed API unless they
    257     * correspond to the flag values.
    258     */
    259    if (output_gamma > 0 && output_gamma < 128)
    260       output_gamma *= PNG_FP_1;
    261 
    262    /* This preserves -1 and -2 exactly: */
    263    output_gamma = floor(output_gamma + .5);
    264 
    265    if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
    266       png_fixed_error(png_ptr, "gamma value");
    267 
    268    return (png_fixed_point)output_gamma;
    269 }
    270 #  endif
    271 #endif /* READ_ALPHA_MODE || READ_GAMMA */
    272 
    273 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
    274 void PNGFAPI
    275 png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
    276     png_fixed_point output_gamma)
    277 {
    278    int compose = 0;
    279    png_fixed_point file_gamma;
    280 
    281    png_debug(1, "in png_set_alpha_mode");
    282 
    283    if (png_rtran_ok(png_ptr, 0) == 0)
    284       return;
    285 
    286    output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
    287 
    288    /* Validate the value to ensure it is in a reasonable range. The value
    289     * is expected to be 1 or greater, but this range test allows for some
    290     * viewing correction values.  The intent is to weed out users of this API
    291     * who use the inverse of the gamma value accidentally!  Since some of these
    292     * values are reasonable this may have to be changed:
    293     *
    294     * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit
    295     * gamma of 36, and its reciprocal.)
    296     */
    297    if (output_gamma < 1000 || output_gamma > 10000000)
    298       png_error(png_ptr, "output gamma out of expected range");
    299 
    300    /* The default file gamma is the inverse of the output gamma; the output
    301     * gamma may be changed below so get the file value first:
    302     */
    303    file_gamma = png_reciprocal(output_gamma);
    304 
    305    /* There are really 8 possibilities here, composed of any combination
    306     * of:
    307     *
    308     *    premultiply the color channels
    309     *    do not encode non-opaque pixels
    310     *    encode the alpha as well as the color channels
    311     *
    312     * The differences disappear if the input/output ('screen') gamma is 1.0,
    313     * because then the encoding is a no-op and there is only the choice of
    314     * premultiplying the color channels or not.
    315     *
    316     * png_set_alpha_mode and png_set_background interact because both use
    317     * png_compose to do the work.  Calling both is only useful when
    318     * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
    319     * with a default gamma value.  Otherwise PNG_COMPOSE must not be set.
    320     */
    321    switch (mode)
    322    {
    323       case PNG_ALPHA_PNG:        /* default: png standard */
    324          /* No compose, but it may be set by png_set_background! */
    325          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    326          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    327          break;
    328 
    329       case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
    330          compose = 1;
    331          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    332          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    333          /* The output is linear: */
    334          output_gamma = PNG_FP_1;
    335          break;
    336 
    337       case PNG_ALPHA_OPTIMIZED:  /* associated, non-opaque pixels linear */
    338          compose = 1;
    339          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
    340          png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
    341          /* output_gamma records the encoding of opaque pixels! */
    342          break;
    343 
    344       case PNG_ALPHA_BROKEN:     /* associated, non-linear, alpha encoded */
    345          compose = 1;
    346          png_ptr->transformations |= PNG_ENCODE_ALPHA;
    347          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
    348          break;
    349 
    350       default:
    351          png_error(png_ptr, "invalid alpha mode");
    352    }
    353 
    354    /* Only set the default gamma if the file gamma has not been set (this has
    355     * the side effect that the gamma in a second call to png_set_alpha_mode will
    356     * be ignored.)
    357     */
    358    if (png_ptr->colorspace.gamma == 0)
    359    {
    360       png_ptr->colorspace.gamma = file_gamma;
    361       png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
    362    }
    363 
    364    /* But always set the output gamma: */
    365    png_ptr->screen_gamma = output_gamma;
    366 
    367    /* Finally, if pre-multiplying, set the background fields to achieve the
    368     * desired result.
    369     */
    370    if (compose != 0)
    371    {
    372       /* And obtain alpha pre-multiplication by composing on black: */
    373       memset(&png_ptr->background, 0, (sizeof png_ptr->background));
    374       png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
    375       png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
    376       png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
    377 
    378       if ((png_ptr->transformations & PNG_COMPOSE) != 0)
    379          png_error(png_ptr,
    380              "conflicting calls to set alpha mode and background");
    381 
    382       png_ptr->transformations |= PNG_COMPOSE;
    383    }
    384 }
    385 
    386 #  ifdef PNG_FLOATING_POINT_SUPPORTED
    387 void PNGAPI
    388 png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
    389 {
    390    png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
    391        output_gamma));
    392 }
    393 #  endif
    394 #endif
    395 
    396 #ifdef PNG_READ_QUANTIZE_SUPPORTED
    397 /* Dither file to 8-bit.  Supply a palette, the current number
    398  * of elements in the palette, the maximum number of elements
    399  * allowed, and a histogram if possible.  If the current number
    400  * of colors is greater than the maximum number, the palette will be
    401  * modified to fit in the maximum number.  "full_quantize" indicates
    402  * whether we need a quantizing cube set up for RGB images, or if we
    403  * simply are reducing the number of colors in a paletted image.
    404  */
    405 
    406 typedef struct png_dsort_struct
    407 {
    408    struct png_dsort_struct * next;
    409    png_byte left;
    410    png_byte right;
    411 } png_dsort;
    412 typedef png_dsort *   png_dsortp;
    413 typedef png_dsort * * png_dsortpp;
    414 
    415 void PNGAPI
    416 png_set_quantize(png_structrp png_ptr, png_colorp palette,
    417     int num_palette, int maximum_colors, png_const_uint_16p histogram,
    418     int full_quantize)
    419 {
    420    png_debug(1, "in png_set_quantize");
    421 
    422    if (png_rtran_ok(png_ptr, 0) == 0)
    423       return;
    424 
    425    png_ptr->transformations |= PNG_QUANTIZE;
    426 
    427    if (full_quantize == 0)
    428    {
    429       int i;
    430 
    431       png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
    432           (png_uint_32)(num_palette * (sizeof (png_byte))));
    433       for (i = 0; i < num_palette; i++)
    434          png_ptr->quantize_index[i] = (png_byte)i;
    435    }
    436 
    437    if (num_palette > maximum_colors)
    438    {
    439       if (histogram != NULL)
    440       {
    441          /* This is easy enough, just throw out the least used colors.
    442           * Perhaps not the best solution, but good enough.
    443           */
    444 
    445          int i;
    446 
    447          /* Initialize an array to sort colors */
    448          png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
    449              (png_uint_32)(num_palette * (sizeof (png_byte))));
    450 
    451          /* Initialize the quantize_sort array */
    452          for (i = 0; i < num_palette; i++)
    453             png_ptr->quantize_sort[i] = (png_byte)i;
    454 
    455          /* Find the least used palette entries by starting a
    456           * bubble sort, and running it until we have sorted
    457           * out enough colors.  Note that we don't care about
    458           * sorting all the colors, just finding which are
    459           * least used.
    460           */
    461 
    462          for (i = num_palette - 1; i >= maximum_colors; i--)
    463          {
    464             int done; /* To stop early if the list is pre-sorted */
    465             int j;
    466 
    467             done = 1;
    468             for (j = 0; j < i; j++)
    469             {
    470                if (histogram[png_ptr->quantize_sort[j]]
    471                    < histogram[png_ptr->quantize_sort[j + 1]])
    472                {
    473                   png_byte t;
    474 
    475                   t = png_ptr->quantize_sort[j];
    476                   png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
    477                   png_ptr->quantize_sort[j + 1] = t;
    478                   done = 0;
    479                }
    480             }
    481 
    482             if (done != 0)
    483                break;
    484          }
    485 
    486          /* Swap the palette around, and set up a table, if necessary */
    487          if (full_quantize != 0)
    488          {
    489             int j = num_palette;
    490 
    491             /* Put all the useful colors within the max, but don't
    492              * move the others.
    493              */
    494             for (i = 0; i < maximum_colors; i++)
    495             {
    496                if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
    497                {
    498                   do
    499                      j--;
    500                   while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
    501 
    502                   palette[i] = palette[j];
    503                }
    504             }
    505          }
    506          else
    507          {
    508             int j = num_palette;
    509 
    510             /* Move all the used colors inside the max limit, and
    511              * develop a translation table.
    512              */
    513             for (i = 0; i < maximum_colors; i++)
    514             {
    515                /* Only move the colors we need to */
    516                if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
    517                {
    518                   png_color tmp_color;
    519 
    520                   do
    521                      j--;
    522                   while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
    523 
    524                   tmp_color = palette[j];
    525                   palette[j] = palette[i];
    526                   palette[i] = tmp_color;
    527                   /* Indicate where the color went */
    528                   png_ptr->quantize_index[j] = (png_byte)i;
    529                   png_ptr->quantize_index[i] = (png_byte)j;
    530                }
    531             }
    532 
    533             /* Find closest color for those colors we are not using */
    534             for (i = 0; i < num_palette; i++)
    535             {
    536                if ((int)png_ptr->quantize_index[i] >= maximum_colors)
    537                {
    538                   int min_d, k, min_k, d_index;
    539 
    540                   /* Find the closest color to one we threw out */
    541                   d_index = png_ptr->quantize_index[i];
    542                   min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
    543                   for (k = 1, min_k = 0; k < maximum_colors; k++)
    544                   {
    545                      int d;
    546 
    547                      d = PNG_COLOR_DIST(palette[d_index], palette[k]);
    548 
    549                      if (d < min_d)
    550                      {
    551                         min_d = d;
    552                         min_k = k;
    553                      }
    554                   }
    555                   /* Point to closest color */
    556                   png_ptr->quantize_index[i] = (png_byte)min_k;
    557                }
    558             }
    559          }
    560          png_free(png_ptr, png_ptr->quantize_sort);
    561          png_ptr->quantize_sort = NULL;
    562       }
    563       else
    564       {
    565          /* This is much harder to do simply (and quickly).  Perhaps
    566           * we need to go through a median cut routine, but those
    567           * don't always behave themselves with only a few colors
    568           * as input.  So we will just find the closest two colors,
    569           * and throw out one of them (chosen somewhat randomly).
    570           * [We don't understand this at all, so if someone wants to
    571           *  work on improving it, be our guest - AED, GRP]
    572           */
    573          int i;
    574          int max_d;
    575          int num_new_palette;
    576          png_dsortp t;
    577          png_dsortpp hash;
    578 
    579          t = NULL;
    580 
    581          /* Initialize palette index arrays */
    582          png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
    583              (png_uint_32)(num_palette * (sizeof (png_byte))));
    584          png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
    585              (png_uint_32)(num_palette * (sizeof (png_byte))));
    586 
    587          /* Initialize the sort array */
    588          for (i = 0; i < num_palette; i++)
    589          {
    590             png_ptr->index_to_palette[i] = (png_byte)i;
    591             png_ptr->palette_to_index[i] = (png_byte)i;
    592          }
    593 
    594          hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
    595              (sizeof (png_dsortp))));
    596 
    597          num_new_palette = num_palette;
    598 
    599          /* Initial wild guess at how far apart the farthest pixel
    600           * pair we will be eliminating will be.  Larger
    601           * numbers mean more areas will be allocated, Smaller
    602           * numbers run the risk of not saving enough data, and
    603           * having to do this all over again.
    604           *
    605           * I have not done extensive checking on this number.
    606           */
    607          max_d = 96;
    608 
    609          while (num_new_palette > maximum_colors)
    610          {
    611             for (i = 0; i < num_new_palette - 1; i++)
    612             {
    613                int j;
    614 
    615                for (j = i + 1; j < num_new_palette; j++)
    616                {
    617                   int d;
    618 
    619                   d = PNG_COLOR_DIST(palette[i], palette[j]);
    620 
    621                   if (d <= max_d)
    622                   {
    623 
    624                      t = (png_dsortp)png_malloc_warn(png_ptr,
    625                          (png_uint_32)(sizeof (png_dsort)));
    626 
    627                      if (t == NULL)
    628                          break;
    629 
    630                      t->next = hash[d];
    631                      t->left = (png_byte)i;
    632                      t->right = (png_byte)j;
    633                      hash[d] = t;
    634                   }
    635                }
    636                if (t == NULL)
    637                   break;
    638             }
    639 
    640             if (t != NULL)
    641             for (i = 0; i <= max_d; i++)
    642             {
    643                if (hash[i] != NULL)
    644                {
    645                   png_dsortp p;
    646 
    647                   for (p = hash[i]; p; p = p->next)
    648                   {
    649                      if ((int)png_ptr->index_to_palette[p->left]
    650                          < num_new_palette &&
    651                          (int)png_ptr->index_to_palette[p->right]
    652                          < num_new_palette)
    653                      {
    654                         int j, next_j;
    655 
    656                         if (num_new_palette & 0x01)
    657                         {
    658                            j = p->left;
    659                            next_j = p->right;
    660                         }
    661                         else
    662                         {
    663                            j = p->right;
    664                            next_j = p->left;
    665                         }
    666 
    667                         num_new_palette--;
    668                         palette[png_ptr->index_to_palette[j]]
    669                             = palette[num_new_palette];
    670                         if (full_quantize == 0)
    671                         {
    672                            int k;
    673 
    674                            for (k = 0; k < num_palette; k++)
    675                            {
    676                               if (png_ptr->quantize_index[k] ==
    677                                   png_ptr->index_to_palette[j])
    678                                  png_ptr->quantize_index[k] =
    679                                      png_ptr->index_to_palette[next_j];
    680 
    681                               if ((int)png_ptr->quantize_index[k] ==
    682                                   num_new_palette)
    683                                  png_ptr->quantize_index[k] =
    684                                      png_ptr->index_to_palette[j];
    685                            }
    686                         }
    687 
    688                         png_ptr->index_to_palette[png_ptr->palette_to_index
    689                             [num_new_palette]] = png_ptr->index_to_palette[j];
    690 
    691                         png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
    692                             = png_ptr->palette_to_index[num_new_palette];
    693 
    694                         png_ptr->index_to_palette[j] =
    695                             (png_byte)num_new_palette;
    696 
    697                         png_ptr->palette_to_index[num_new_palette] =
    698                             (png_byte)j;
    699                      }
    700                      if (num_new_palette <= maximum_colors)
    701                         break;
    702                   }
    703                   if (num_new_palette <= maximum_colors)
    704                      break;
    705                }
    706             }
    707 
    708             for (i = 0; i < 769; i++)
    709             {
    710                if (hash[i] != NULL)
    711                {
    712                   png_dsortp p = hash[i];
    713                   while (p)
    714                   {
    715                      t = p->next;
    716                      png_free(png_ptr, p);
    717                      p = t;
    718                   }
    719                }
    720                hash[i] = 0;
    721             }
    722             max_d += 96;
    723          }
    724          png_free(png_ptr, hash);
    725          png_free(png_ptr, png_ptr->palette_to_index);
    726          png_free(png_ptr, png_ptr->index_to_palette);
    727          png_ptr->palette_to_index = NULL;
    728          png_ptr->index_to_palette = NULL;
    729       }
    730       num_palette = maximum_colors;
    731    }
    732    if (png_ptr->palette == NULL)
    733    {
    734       png_ptr->palette = palette;
    735    }
    736    png_ptr->num_palette = (png_uint_16)num_palette;
    737 
    738    if (full_quantize != 0)
    739    {
    740       int i;
    741       png_bytep distance;
    742       int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
    743           PNG_QUANTIZE_BLUE_BITS;
    744       int num_red = (1 << PNG_QUANTIZE_RED_BITS);
    745       int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
    746       int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
    747       png_size_t num_entries = ((png_size_t)1 << total_bits);
    748 
    749       png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
    750           (png_uint_32)(num_entries * (sizeof (png_byte))));
    751 
    752       distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
    753           (sizeof (png_byte))));
    754 
    755       memset(distance, 0xff, num_entries * (sizeof (png_byte)));
    756 
    757       for (i = 0; i < num_palette; i++)
    758       {
    759          int ir, ig, ib;
    760          int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
    761          int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
    762          int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
    763 
    764          for (ir = 0; ir < num_red; ir++)
    765          {
    766             /* int dr = abs(ir - r); */
    767             int dr = ((ir > r) ? ir - r : r - ir);
    768             int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
    769                 PNG_QUANTIZE_GREEN_BITS));
    770 
    771             for (ig = 0; ig < num_green; ig++)
    772             {
    773                /* int dg = abs(ig - g); */
    774                int dg = ((ig > g) ? ig - g : g - ig);
    775                int dt = dr + dg;
    776                int dm = ((dr > dg) ? dr : dg);
    777                int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
    778 
    779                for (ib = 0; ib < num_blue; ib++)
    780                {
    781                   int d_index = index_g | ib;
    782                   /* int db = abs(ib - b); */
    783                   int db = ((ib > b) ? ib - b : b - ib);
    784                   int dmax = ((dm > db) ? dm : db);
    785                   int d = dmax + dt + db;
    786 
    787                   if (d < (int)distance[d_index])
    788                   {
    789                      distance[d_index] = (png_byte)d;
    790                      png_ptr->palette_lookup[d_index] = (png_byte)i;
    791                   }
    792                }
    793             }
    794          }
    795       }
    796 
    797       png_free(png_ptr, distance);
    798    }
    799 }
    800 #endif /* READ_QUANTIZE */
    801 
    802 #ifdef PNG_READ_GAMMA_SUPPORTED
    803 void PNGFAPI
    804 png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
    805     png_fixed_point file_gamma)
    806 {
    807    png_debug(1, "in png_set_gamma_fixed");
    808 
    809    if (png_rtran_ok(png_ptr, 0) == 0)
    810       return;
    811 
    812    /* New in libpng-1.5.4 - reserve particular negative values as flags. */
    813    scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
    814    file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
    815 
    816    /* Checking the gamma values for being >0 was added in 1.5.4 along with the
    817     * premultiplied alpha support; this actually hides an undocumented feature
    818     * of the previous implementation which allowed gamma processing to be
    819     * disabled in background handling.  There is no evidence (so far) that this
    820     * was being used; however, png_set_background itself accepted and must still
    821     * accept '0' for the gamma value it takes, because it isn't always used.
    822     *
    823     * Since this is an API change (albeit a very minor one that removes an
    824     * undocumented API feature) the following checks were only enabled in
    825     * libpng-1.6.0.
    826     */
    827    if (file_gamma <= 0)
    828       png_error(png_ptr, "invalid file gamma in png_set_gamma");
    829 
    830    if (scrn_gamma <= 0)
    831       png_error(png_ptr, "invalid screen gamma in png_set_gamma");
    832 
    833    /* Set the gamma values unconditionally - this overrides the value in the PNG
    834     * file if a gAMA chunk was present.  png_set_alpha_mode provides a
    835     * different, easier, way to default the file gamma.
    836     */
    837    png_ptr->colorspace.gamma = file_gamma;
    838    png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
    839    png_ptr->screen_gamma = scrn_gamma;
    840 }
    841 
    842 #  ifdef PNG_FLOATING_POINT_SUPPORTED
    843 void PNGAPI
    844 png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
    845 {
    846    png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
    847        convert_gamma_value(png_ptr, file_gamma));
    848 }
    849 #  endif /* FLOATING_POINT */
    850 #endif /* READ_GAMMA */
    851 
    852 #ifdef PNG_READ_EXPAND_SUPPORTED
    853 /* Expand paletted images to RGB, expand grayscale images of
    854  * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
    855  * to alpha channels.
    856  */
    857 void PNGAPI
    858 png_set_expand(png_structrp png_ptr)
    859 {
    860    png_debug(1, "in png_set_expand");
    861 
    862    if (png_rtran_ok(png_ptr, 0) == 0)
    863       return;
    864 
    865    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    866 }
    867 
    868 /* GRR 19990627:  the following three functions currently are identical
    869  *  to png_set_expand().  However, it is entirely reasonable that someone
    870  *  might wish to expand an indexed image to RGB but *not* expand a single,
    871  *  fully transparent palette entry to a full alpha channel--perhaps instead
    872  *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
    873  *  the transparent color with a particular RGB value, or drop tRNS entirely.
    874  *  IOW, a future version of the library may make the transformations flag
    875  *  a bit more fine-grained, with separate bits for each of these three
    876  *  functions.
    877  *
    878  *  More to the point, these functions make it obvious what libpng will be
    879  *  doing, whereas "expand" can (and does) mean any number of things.
    880  *
    881  *  GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
    882  *  to expand only the sample depth but not to expand the tRNS to alpha
    883  *  and its name was changed to png_set_expand_gray_1_2_4_to_8().
    884  */
    885 
    886 /* Expand paletted images to RGB. */
    887 void PNGAPI
    888 png_set_palette_to_rgb(png_structrp png_ptr)
    889 {
    890    png_debug(1, "in png_set_palette_to_rgb");
    891 
    892    if (png_rtran_ok(png_ptr, 0) == 0)
    893       return;
    894 
    895    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    896 }
    897 
    898 /* Expand grayscale images of less than 8-bit depth to 8 bits. */
    899 void PNGAPI
    900 png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
    901 {
    902    png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
    903 
    904    if (png_rtran_ok(png_ptr, 0) == 0)
    905       return;
    906 
    907    png_ptr->transformations |= PNG_EXPAND;
    908 }
    909 
    910 /* Expand tRNS chunks to alpha channels. */
    911 void PNGAPI
    912 png_set_tRNS_to_alpha(png_structrp png_ptr)
    913 {
    914    png_debug(1, "in png_set_tRNS_to_alpha");
    915 
    916    if (png_rtran_ok(png_ptr, 0) == 0)
    917       return;
    918 
    919    png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
    920 }
    921 #endif /* READ_EXPAND */
    922 
    923 #ifdef PNG_READ_EXPAND_16_SUPPORTED
    924 /* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
    925  * it may not work correctly.)
    926  */
    927 void PNGAPI
    928 png_set_expand_16(png_structrp png_ptr)
    929 {
    930    png_debug(1, "in png_set_expand_16");
    931 
    932    if (png_rtran_ok(png_ptr, 0) == 0)
    933       return;
    934 
    935    png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
    936 }
    937 #endif
    938 
    939 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
    940 void PNGAPI
    941 png_set_gray_to_rgb(png_structrp png_ptr)
    942 {
    943    png_debug(1, "in png_set_gray_to_rgb");
    944 
    945    if (png_rtran_ok(png_ptr, 0) == 0)
    946       return;
    947 
    948    /* Because rgb must be 8 bits or more: */
    949    png_set_expand_gray_1_2_4_to_8(png_ptr);
    950    png_ptr->transformations |= PNG_GRAY_TO_RGB;
    951 }
    952 #endif
    953 
    954 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    955 void PNGFAPI
    956 png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
    957     png_fixed_point red, png_fixed_point green)
    958 {
    959    png_debug(1, "in png_set_rgb_to_gray");
    960 
    961    /* Need the IHDR here because of the check on color_type below. */
    962    /* TODO: fix this */
    963    if (png_rtran_ok(png_ptr, 1) == 0)
    964       return;
    965 
    966    switch (error_action)
    967    {
    968       case PNG_ERROR_ACTION_NONE:
    969          png_ptr->transformations |= PNG_RGB_TO_GRAY;
    970          break;
    971 
    972       case PNG_ERROR_ACTION_WARN:
    973          png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
    974          break;
    975 
    976       case PNG_ERROR_ACTION_ERROR:
    977          png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
    978          break;
    979 
    980       default:
    981          png_error(png_ptr, "invalid error action to rgb_to_gray");
    982    }
    983 
    984    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    985 #ifdef PNG_READ_EXPAND_SUPPORTED
    986       png_ptr->transformations |= PNG_EXPAND;
    987 #else
    988    {
    989       /* Make this an error in 1.6 because otherwise the application may assume
    990        * that it just worked and get a memory overwrite.
    991        */
    992       png_error(png_ptr,
    993           "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
    994 
    995       /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
    996    }
    997 #endif
    998    {
    999       if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
   1000       {
   1001          png_uint_16 red_int, green_int;
   1002 
   1003          /* NOTE: this calculation does not round, but this behavior is retained
   1004           * for consistency; the inaccuracy is very small.  The code here always
   1005           * overwrites the coefficients, regardless of whether they have been
   1006           * defaulted or set already.
   1007           */
   1008          red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
   1009          green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
   1010 
   1011          png_ptr->rgb_to_gray_red_coeff   = red_int;
   1012          png_ptr->rgb_to_gray_green_coeff = green_int;
   1013          png_ptr->rgb_to_gray_coefficients_set = 1;
   1014       }
   1015 
   1016       else
   1017       {
   1018          if (red >= 0 && green >= 0)
   1019             png_app_warning(png_ptr,
   1020                 "ignoring out of range rgb_to_gray coefficients");
   1021 
   1022          /* Use the defaults, from the cHRM chunk if set, else the historical
   1023           * values which are close to the sRGB/HDTV/ITU-Rec 709 values.  See
   1024           * png_do_rgb_to_gray for more discussion of the values.  In this case
   1025           * the coefficients are not marked as 'set' and are not overwritten if
   1026           * something has already provided a default.
   1027           */
   1028          if (png_ptr->rgb_to_gray_red_coeff == 0 &&
   1029              png_ptr->rgb_to_gray_green_coeff == 0)
   1030          {
   1031             png_ptr->rgb_to_gray_red_coeff   = 6968;
   1032             png_ptr->rgb_to_gray_green_coeff = 23434;
   1033             /* png_ptr->rgb_to_gray_blue_coeff  = 2366; */
   1034          }
   1035       }
   1036    }
   1037 }
   1038 
   1039 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1040 /* Convert a RGB image to a grayscale of the same width.  This allows us,
   1041  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
   1042  */
   1043 
   1044 void PNGAPI
   1045 png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
   1046     double green)
   1047 {
   1048    png_set_rgb_to_gray_fixed(png_ptr, error_action,
   1049        png_fixed(png_ptr, red, "rgb to gray red coefficient"),
   1050       png_fixed(png_ptr, green, "rgb to gray green coefficient"));
   1051 }
   1052 #endif /* FLOATING POINT */
   1053 
   1054 #endif /* RGB_TO_GRAY */
   1055 
   1056 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
   1057     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
   1058 void PNGAPI
   1059 png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
   1060     read_user_transform_fn)
   1061 {
   1062    png_debug(1, "in png_set_read_user_transform_fn");
   1063 
   1064 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
   1065    png_ptr->transformations |= PNG_USER_TRANSFORM;
   1066    png_ptr->read_user_transform_fn = read_user_transform_fn;
   1067 #endif
   1068 }
   1069 #endif
   1070 
   1071 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   1072 #ifdef PNG_READ_GAMMA_SUPPORTED
   1073 /* In the case of gamma transformations only do transformations on images where
   1074  * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
   1075  * slows things down slightly, and also needlessly introduces small errors.
   1076  */
   1077 static int /* PRIVATE */
   1078 png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
   1079 {
   1080    /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
   1081     * correction as a difference of the overall transform from 1.0
   1082     *
   1083     * We want to compare the threshold with s*f - 1, if we get
   1084     * overflow here it is because of wacky gamma values so we
   1085     * turn on processing anyway.
   1086     */
   1087    png_fixed_point gtest;
   1088    return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
   1089        png_gamma_significant(gtest);
   1090 }
   1091 #endif
   1092 
   1093 /* Initialize everything needed for the read.  This includes modifying
   1094  * the palette.
   1095  */
   1096 
   1097 /* For the moment 'png_init_palette_transformations' and
   1098  * 'png_init_rgb_transformations' only do some flag canceling optimizations.
   1099  * The intent is that these two routines should have palette or rgb operations
   1100  * extracted from 'png_init_read_transformations'.
   1101  */
   1102 static void /* PRIVATE */
   1103 png_init_palette_transformations(png_structrp png_ptr)
   1104 {
   1105    /* Called to handle the (input) palette case.  In png_do_read_transformations
   1106     * the first step is to expand the palette if requested, so this code must
   1107     * take care to only make changes that are invariant with respect to the
   1108     * palette expansion, or only do them if there is no expansion.
   1109     *
   1110     * STRIP_ALPHA has already been handled in the caller (by setting num_trans
   1111     * to 0.)
   1112     */
   1113    int input_has_alpha = 0;
   1114    int input_has_transparency = 0;
   1115 
   1116    if (png_ptr->num_trans > 0)
   1117    {
   1118       int i;
   1119 
   1120       /* Ignore if all the entries are opaque (unlikely!) */
   1121       for (i=0; i<png_ptr->num_trans; ++i)
   1122       {
   1123          if (png_ptr->trans_alpha[i] == 255)
   1124             continue;
   1125          else if (png_ptr->trans_alpha[i] == 0)
   1126             input_has_transparency = 1;
   1127          else
   1128          {
   1129             input_has_transparency = 1;
   1130             input_has_alpha = 1;
   1131             break;
   1132          }
   1133       }
   1134    }
   1135 
   1136    /* If no alpha we can optimize. */
   1137    if (input_has_alpha == 0)
   1138    {
   1139       /* Any alpha means background and associative alpha processing is
   1140        * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
   1141        * and ENCODE_ALPHA are irrelevant.
   1142        */
   1143       png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
   1144       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
   1145 
   1146       if (input_has_transparency == 0)
   1147          png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
   1148    }
   1149 
   1150 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
   1151    /* png_set_background handling - deals with the complexity of whether the
   1152     * background color is in the file format or the screen format in the case
   1153     * where an 'expand' will happen.
   1154     */
   1155 
   1156    /* The following code cannot be entered in the alpha pre-multiplication case
   1157     * because PNG_BACKGROUND_EXPAND is cancelled below.
   1158     */
   1159    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
   1160        (png_ptr->transformations & PNG_EXPAND) != 0)
   1161    {
   1162       {
   1163          png_ptr->background.red   =
   1164              png_ptr->palette[png_ptr->background.index].red;
   1165          png_ptr->background.green =
   1166              png_ptr->palette[png_ptr->background.index].green;
   1167          png_ptr->background.blue  =
   1168              png_ptr->palette[png_ptr->background.index].blue;
   1169 
   1170 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   1171         if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
   1172         {
   1173            if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
   1174            {
   1175               /* Invert the alpha channel (in tRNS) unless the pixels are
   1176                * going to be expanded, in which case leave it for later
   1177                */
   1178               int i, istop = png_ptr->num_trans;
   1179 
   1180               for (i=0; i<istop; i++)
   1181                  png_ptr->trans_alpha[i] = (png_byte)(255 -
   1182                     png_ptr->trans_alpha[i]);
   1183            }
   1184         }
   1185 #endif /* READ_INVERT_ALPHA */
   1186       }
   1187    } /* background expand and (therefore) no alpha association. */
   1188 #endif /* READ_EXPAND && READ_BACKGROUND */
   1189 }
   1190 
   1191 static void /* PRIVATE */
   1192 png_init_rgb_transformations(png_structrp png_ptr)
   1193 {
   1194    /* Added to libpng-1.5.4: check the color type to determine whether there
   1195     * is any alpha or transparency in the image and simply cancel the
   1196     * background and alpha mode stuff if there isn't.
   1197     */
   1198    int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
   1199    int input_has_transparency = png_ptr->num_trans > 0;
   1200 
   1201    /* If no alpha we can optimize. */
   1202    if (input_has_alpha == 0)
   1203    {
   1204       /* Any alpha means background and associative alpha processing is
   1205        * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
   1206        * and ENCODE_ALPHA are irrelevant.
   1207        */
   1208 #     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   1209          png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
   1210          png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
   1211 #     endif
   1212 
   1213       if (input_has_transparency == 0)
   1214          png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
   1215    }
   1216 
   1217 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
   1218    /* png_set_background handling - deals with the complexity of whether the
   1219     * background color is in the file format or the screen format in the case
   1220     * where an 'expand' will happen.
   1221     */
   1222 
   1223    /* The following code cannot be entered in the alpha pre-multiplication case
   1224     * because PNG_BACKGROUND_EXPAND is cancelled below.
   1225     */
   1226    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
   1227        (png_ptr->transformations & PNG_EXPAND) != 0 &&
   1228        (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
   1229        /* i.e., GRAY or GRAY_ALPHA */
   1230    {
   1231       {
   1232          /* Expand background and tRNS chunks */
   1233          int gray = png_ptr->background.gray;
   1234          int trans_gray = png_ptr->trans_color.gray;
   1235 
   1236          switch (png_ptr->bit_depth)
   1237          {
   1238             case 1:
   1239                gray *= 0xff;
   1240                trans_gray *= 0xff;
   1241                break;
   1242 
   1243             case 2:
   1244                gray *= 0x55;
   1245                trans_gray *= 0x55;
   1246                break;
   1247 
   1248             case 4:
   1249                gray *= 0x11;
   1250                trans_gray *= 0x11;
   1251                break;
   1252 
   1253             default:
   1254 
   1255             case 8:
   1256                /* FALL THROUGH (Already 8 bits) */
   1257 
   1258             case 16:
   1259                /* Already a full 16 bits */
   1260                break;
   1261          }
   1262 
   1263          png_ptr->background.red = png_ptr->background.green =
   1264             png_ptr->background.blue = (png_uint_16)gray;
   1265 
   1266          if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
   1267          {
   1268             png_ptr->trans_color.red = png_ptr->trans_color.green =
   1269                png_ptr->trans_color.blue = (png_uint_16)trans_gray;
   1270          }
   1271       }
   1272    } /* background expand and (therefore) no alpha association. */
   1273 #endif /* READ_EXPAND && READ_BACKGROUND */
   1274 }
   1275 
   1276 void /* PRIVATE */
   1277 png_init_read_transformations(png_structrp png_ptr)
   1278 {
   1279    png_debug(1, "in png_init_read_transformations");
   1280 
   1281    /* This internal function is called from png_read_start_row in pngrutil.c
   1282     * and it is called before the 'rowbytes' calculation is done, so the code
   1283     * in here can change or update the transformations flags.
   1284     *
   1285     * First do updates that do not depend on the details of the PNG image data
   1286     * being processed.
   1287     */
   1288 
   1289 #ifdef PNG_READ_GAMMA_SUPPORTED
   1290    /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
   1291     * png_set_alpha_mode and this is another source for a default file gamma so
   1292     * the test needs to be performed later - here.  In addition prior to 1.5.4
   1293     * the tests were repeated for the PALETTE color type here - this is no
   1294     * longer necessary (and doesn't seem to have been necessary before.)
   1295     */
   1296    {
   1297       /* The following temporary indicates if overall gamma correction is
   1298        * required.
   1299        */
   1300       int gamma_correction = 0;
   1301 
   1302       if (png_ptr->colorspace.gamma != 0) /* has been set */
   1303       {
   1304          if (png_ptr->screen_gamma != 0) /* screen set too */
   1305             gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
   1306                 png_ptr->screen_gamma);
   1307 
   1308          else
   1309             /* Assume the output matches the input; a long time default behavior
   1310              * of libpng, although the standard has nothing to say about this.
   1311              */
   1312             png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
   1313       }
   1314 
   1315       else if (png_ptr->screen_gamma != 0)
   1316          /* The converse - assume the file matches the screen, note that this
   1317           * perhaps undesireable default can (from 1.5.4) be changed by calling
   1318           * png_set_alpha_mode (even if the alpha handling mode isn't required
   1319           * or isn't changed from the default.)
   1320           */
   1321          png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
   1322 
   1323       else /* neither are set */
   1324          /* Just in case the following prevents any processing - file and screen
   1325           * are both assumed to be linear and there is no way to introduce a
   1326           * third gamma value other than png_set_background with 'UNIQUE', and,
   1327           * prior to 1.5.4
   1328           */
   1329          png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
   1330 
   1331       /* We have a gamma value now. */
   1332       png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
   1333 
   1334       /* Now turn the gamma transformation on or off as appropriate.  Notice
   1335        * that PNG_GAMMA just refers to the file->screen correction.  Alpha
   1336        * composition may independently cause gamma correction because it needs
   1337        * linear data (e.g. if the file has a gAMA chunk but the screen gamma
   1338        * hasn't been specified.)  In any case this flag may get turned off in
   1339        * the code immediately below if the transform can be handled outside the
   1340        * row loop.
   1341        */
   1342       if (gamma_correction != 0)
   1343          png_ptr->transformations |= PNG_GAMMA;
   1344 
   1345       else
   1346          png_ptr->transformations &= ~PNG_GAMMA;
   1347    }
   1348 #endif
   1349 
   1350    /* Certain transformations have the effect of preventing other
   1351     * transformations that happen afterward in png_do_read_transformations;
   1352     * resolve the interdependencies here.  From the code of
   1353     * png_do_read_transformations the order is:
   1354     *
   1355     *  1) PNG_EXPAND (including PNG_EXPAND_tRNS)
   1356     *  2) PNG_STRIP_ALPHA (if no compose)
   1357     *  3) PNG_RGB_TO_GRAY
   1358     *  4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
   1359     *  5) PNG_COMPOSE
   1360     *  6) PNG_GAMMA
   1361     *  7) PNG_STRIP_ALPHA (if compose)
   1362     *  8) PNG_ENCODE_ALPHA
   1363     *  9) PNG_SCALE_16_TO_8
   1364     * 10) PNG_16_TO_8
   1365     * 11) PNG_QUANTIZE (converts to palette)
   1366     * 12) PNG_EXPAND_16
   1367     * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
   1368     * 14) PNG_INVERT_MONO
   1369     * 15) PNG_INVERT_ALPHA
   1370     * 16) PNG_SHIFT
   1371     * 17) PNG_PACK
   1372     * 18) PNG_BGR
   1373     * 19) PNG_PACKSWAP
   1374     * 20) PNG_FILLER (includes PNG_ADD_ALPHA)
   1375     * 21) PNG_SWAP_ALPHA
   1376     * 22) PNG_SWAP_BYTES
   1377     * 23) PNG_USER_TRANSFORM [must be last]
   1378     */
   1379 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   1380    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
   1381        (png_ptr->transformations & PNG_COMPOSE) == 0)
   1382    {
   1383       /* Stripping the alpha channel happens immediately after the 'expand'
   1384        * transformations, before all other transformation, so it cancels out
   1385        * the alpha handling.  It has the side effect negating the effect of
   1386        * PNG_EXPAND_tRNS too:
   1387        */
   1388       png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
   1389          PNG_EXPAND_tRNS);
   1390       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
   1391 
   1392       /* Kill the tRNS chunk itself too.  Prior to 1.5.4 this did not happen
   1393        * so transparency information would remain just so long as it wasn't
   1394        * expanded.  This produces unexpected API changes if the set of things
   1395        * that do PNG_EXPAND_tRNS changes (perfectly possible given the
   1396        * documentation - which says ask for what you want, accept what you
   1397        * get.)  This makes the behavior consistent from 1.5.4:
   1398        */
   1399       png_ptr->num_trans = 0;
   1400    }
   1401 #endif /* STRIP_ALPHA supported, no COMPOSE */
   1402 
   1403 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   1404    /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
   1405     * settings will have no effect.
   1406     */
   1407    if (png_gamma_significant(png_ptr->screen_gamma) == 0)
   1408    {
   1409       png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
   1410       png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
   1411    }
   1412 #endif
   1413 
   1414 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   1415    /* Make sure the coefficients for the rgb to gray conversion are set
   1416     * appropriately.
   1417     */
   1418    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
   1419       png_colorspace_set_rgb_coefficients(png_ptr);
   1420 #endif
   1421 
   1422 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   1423 #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
   1424    /* Detect gray background and attempt to enable optimization for
   1425     * gray --> RGB case.
   1426     *
   1427     * Note:  if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
   1428     * RGB_ALPHA (in which case need_expand is superfluous anyway), the
   1429     * background color might actually be gray yet not be flagged as such.
   1430     * This is not a problem for the current code, which uses
   1431     * PNG_BACKGROUND_IS_GRAY only to decide when to do the
   1432     * png_do_gray_to_rgb() transformation.
   1433     *
   1434     * TODO: this code needs to be revised to avoid the complexity and
   1435     * interdependencies.  The color type of the background should be recorded in
   1436     * png_set_background, along with the bit depth, then the code has a record
   1437     * of exactly what color space the background is currently in.
   1438     */
   1439    if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
   1440    {
   1441       /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
   1442        * the file was grayscale the background value is gray.
   1443        */
   1444       if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
   1445          png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
   1446    }
   1447 
   1448    else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
   1449    {
   1450       /* PNG_COMPOSE: png_set_background was called with need_expand false,
   1451        * so the color is in the color space of the output or png_set_alpha_mode
   1452        * was called and the color is black.  Ignore RGB_TO_GRAY because that
   1453        * happens before GRAY_TO_RGB.
   1454        */
   1455       if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
   1456       {
   1457          if (png_ptr->background.red == png_ptr->background.green &&
   1458              png_ptr->background.red == png_ptr->background.blue)
   1459          {
   1460             png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
   1461             png_ptr->background.gray = png_ptr->background.red;
   1462          }
   1463       }
   1464    }
   1465 #endif /* READ_EXPAND && READ_BACKGROUND */
   1466 #endif /* READ_GRAY_TO_RGB */
   1467 
   1468    /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
   1469     * can be performed directly on the palette, and some (such as rgb to gray)
   1470     * can be optimized inside the palette.  This is particularly true of the
   1471     * composite (background and alpha) stuff, which can be pretty much all done
   1472     * in the palette even if the result is expanded to RGB or gray afterward.
   1473     *
   1474     * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
   1475     * earlier and the palette stuff is actually handled on the first row.  This
   1476     * leads to the reported bug that the palette returned by png_get_PLTE is not
   1477     * updated.
   1478     */
   1479    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1480       png_init_palette_transformations(png_ptr);
   1481 
   1482    else
   1483       png_init_rgb_transformations(png_ptr);
   1484 
   1485 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
   1486    defined(PNG_READ_EXPAND_16_SUPPORTED)
   1487    if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
   1488        (png_ptr->transformations & PNG_COMPOSE) != 0 &&
   1489        (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
   1490        png_ptr->bit_depth != 16)
   1491    {
   1492       /* TODO: fix this.  Because the expand_16 operation is after the compose
   1493        * handling the background color must be 8, not 16, bits deep, but the
   1494        * application will supply a 16-bit value so reduce it here.
   1495        *
   1496        * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
   1497        * present, so that case is ok (until do_expand_16 is moved.)
   1498        *
   1499        * NOTE: this discards the low 16 bits of the user supplied background
   1500        * color, but until expand_16 works properly there is no choice!
   1501        */
   1502 #     define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
   1503       CHOP(png_ptr->background.red);
   1504       CHOP(png_ptr->background.green);
   1505       CHOP(png_ptr->background.blue);
   1506       CHOP(png_ptr->background.gray);
   1507 #     undef CHOP
   1508    }
   1509 #endif /* READ_BACKGROUND && READ_EXPAND_16 */
   1510 
   1511 #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
   1512    (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
   1513    defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
   1514    if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
   1515        (png_ptr->transformations & PNG_COMPOSE) != 0 &&
   1516        (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
   1517        png_ptr->bit_depth == 16)
   1518    {
   1519       /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
   1520        * component this will also happen after PNG_COMPOSE and so the background
   1521        * color must be pre-expanded here.
   1522        *
   1523        * TODO: fix this too.
   1524        */
   1525       png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
   1526       png_ptr->background.green =
   1527          (png_uint_16)(png_ptr->background.green * 257);
   1528       png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
   1529       png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
   1530    }
   1531 #endif
   1532 
   1533    /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
   1534     * background support (see the comments in scripts/pnglibconf.dfa), this
   1535     * allows pre-multiplication of the alpha channel to be implemented as
   1536     * compositing on black.  This is probably sub-optimal and has been done in
   1537     * 1.5.4 betas simply to enable external critique and testing (i.e. to
   1538     * implement the new API quickly, without lots of internal changes.)
   1539     */
   1540 
   1541 #ifdef PNG_READ_GAMMA_SUPPORTED
   1542 #  ifdef PNG_READ_BACKGROUND_SUPPORTED
   1543       /* Includes ALPHA_MODE */
   1544       png_ptr->background_1 = png_ptr->background;
   1545 #  endif
   1546 
   1547    /* This needs to change - in the palette image case a whole set of tables are
   1548     * built when it would be quicker to just calculate the correct value for
   1549     * each palette entry directly.  Also, the test is too tricky - why check
   1550     * PNG_RGB_TO_GRAY if PNG_GAMMA is not set?  The answer seems to be that
   1551     * PNG_GAMMA is cancelled even if the gamma is known?  The test excludes the
   1552     * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
   1553     * the gamma tables will not be built even if composition is required on a
   1554     * gamma encoded value.
   1555     *
   1556     * In 1.5.4 this is addressed below by an additional check on the individual
   1557     * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
   1558     * tables.
   1559     */
   1560    if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
   1561        ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
   1562         (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
   1563          png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
   1564         ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
   1565          (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
   1566           png_gamma_significant(png_ptr->screen_gamma) != 0
   1567 #  ifdef PNG_READ_BACKGROUND_SUPPORTED
   1568          || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
   1569            png_gamma_significant(png_ptr->background_gamma) != 0)
   1570 #  endif
   1571         )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
   1572        png_gamma_significant(png_ptr->screen_gamma) != 0))
   1573    {
   1574       png_build_gamma_table(png_ptr, png_ptr->bit_depth);
   1575 
   1576 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1577       if ((png_ptr->transformations & PNG_COMPOSE) != 0)
   1578       {
   1579          /* Issue a warning about this combination: because RGB_TO_GRAY is
   1580           * optimized to do the gamma transform if present yet do_background has
   1581           * to do the same thing if both options are set a
   1582           * double-gamma-correction happens.  This is true in all versions of
   1583           * libpng to date.
   1584           */
   1585          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
   1586             png_warning(png_ptr,
   1587                 "libpng does not support gamma+background+rgb_to_gray");
   1588 
   1589          if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
   1590          {
   1591             /* We don't get to here unless there is a tRNS chunk with non-opaque
   1592              * entries - see the checking code at the start of this function.
   1593              */
   1594             png_color back, back_1;
   1595             png_colorp palette = png_ptr->palette;
   1596             int num_palette = png_ptr->num_palette;
   1597             int i;
   1598             if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
   1599             {
   1600 
   1601                back.red = png_ptr->gamma_table[png_ptr->background.red];
   1602                back.green = png_ptr->gamma_table[png_ptr->background.green];
   1603                back.blue = png_ptr->gamma_table[png_ptr->background.blue];
   1604 
   1605                back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
   1606                back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
   1607                back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
   1608             }
   1609             else
   1610             {
   1611                png_fixed_point g, gs;
   1612 
   1613                switch (png_ptr->background_gamma_type)
   1614                {
   1615                   case PNG_BACKGROUND_GAMMA_SCREEN:
   1616                      g = (png_ptr->screen_gamma);
   1617                      gs = PNG_FP_1;
   1618                      break;
   1619 
   1620                   case PNG_BACKGROUND_GAMMA_FILE:
   1621                      g = png_reciprocal(png_ptr->colorspace.gamma);
   1622                      gs = png_reciprocal2(png_ptr->colorspace.gamma,
   1623                          png_ptr->screen_gamma);
   1624                      break;
   1625 
   1626                   case PNG_BACKGROUND_GAMMA_UNIQUE:
   1627                      g = png_reciprocal(png_ptr->background_gamma);
   1628                      gs = png_reciprocal2(png_ptr->background_gamma,
   1629                          png_ptr->screen_gamma);
   1630                      break;
   1631                   default:
   1632                      g = PNG_FP_1;    /* back_1 */
   1633                      gs = PNG_FP_1;   /* back */
   1634                      break;
   1635                }
   1636 
   1637                if (png_gamma_significant(gs) != 0)
   1638                {
   1639                   back.red = png_gamma_8bit_correct(png_ptr->background.red,
   1640                       gs);
   1641                   back.green = png_gamma_8bit_correct(png_ptr->background.green,
   1642                       gs);
   1643                   back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
   1644                       gs);
   1645                }
   1646 
   1647                else
   1648                {
   1649                   back.red   = (png_byte)png_ptr->background.red;
   1650                   back.green = (png_byte)png_ptr->background.green;
   1651                   back.blue  = (png_byte)png_ptr->background.blue;
   1652                }
   1653 
   1654                if (png_gamma_significant(g) != 0)
   1655                {
   1656                   back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
   1657                       g);
   1658                   back_1.green = png_gamma_8bit_correct(
   1659                       png_ptr->background.green, g);
   1660                   back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
   1661                       g);
   1662                }
   1663 
   1664                else
   1665                {
   1666                   back_1.red   = (png_byte)png_ptr->background.red;
   1667                   back_1.green = (png_byte)png_ptr->background.green;
   1668                   back_1.blue  = (png_byte)png_ptr->background.blue;
   1669                }
   1670             }
   1671 
   1672             for (i = 0; i < num_palette; i++)
   1673             {
   1674                if (i < (int)png_ptr->num_trans &&
   1675                    png_ptr->trans_alpha[i] != 0xff)
   1676                {
   1677                   if (png_ptr->trans_alpha[i] == 0)
   1678                   {
   1679                      palette[i] = back;
   1680                   }
   1681                   else /* if (png_ptr->trans_alpha[i] != 0xff) */
   1682                   {
   1683                      png_byte v, w;
   1684 
   1685                      v = png_ptr->gamma_to_1[palette[i].red];
   1686                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
   1687                      palette[i].red = png_ptr->gamma_from_1[w];
   1688 
   1689                      v = png_ptr->gamma_to_1[palette[i].green];
   1690                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
   1691                      palette[i].green = png_ptr->gamma_from_1[w];
   1692 
   1693                      v = png_ptr->gamma_to_1[palette[i].blue];
   1694                      png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
   1695                      palette[i].blue = png_ptr->gamma_from_1[w];
   1696                   }
   1697                }
   1698                else
   1699                {
   1700                   palette[i].red = png_ptr->gamma_table[palette[i].red];
   1701                   palette[i].green = png_ptr->gamma_table[palette[i].green];
   1702                   palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   1703                }
   1704             }
   1705 
   1706             /* Prevent the transformations being done again.
   1707              *
   1708              * NOTE: this is highly dubious; it removes the transformations in
   1709              * place.  This seems inconsistent with the general treatment of the
   1710              * transformations elsewhere.
   1711              */
   1712             png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
   1713          } /* color_type == PNG_COLOR_TYPE_PALETTE */
   1714 
   1715          /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
   1716          else /* color_type != PNG_COLOR_TYPE_PALETTE */
   1717          {
   1718             int gs_sig, g_sig;
   1719             png_fixed_point g = PNG_FP_1;  /* Correction to linear */
   1720             png_fixed_point gs = PNG_FP_1; /* Correction to screen */
   1721 
   1722             switch (png_ptr->background_gamma_type)
   1723             {
   1724                case PNG_BACKGROUND_GAMMA_SCREEN:
   1725                   g = png_ptr->screen_gamma;
   1726                   /* gs = PNG_FP_1; */
   1727                   break;
   1728 
   1729                case PNG_BACKGROUND_GAMMA_FILE:
   1730                   g = png_reciprocal(png_ptr->colorspace.gamma);
   1731                   gs = png_reciprocal2(png_ptr->colorspace.gamma,
   1732                       png_ptr->screen_gamma);
   1733                   break;
   1734 
   1735                case PNG_BACKGROUND_GAMMA_UNIQUE:
   1736                   g = png_reciprocal(png_ptr->background_gamma);
   1737                   gs = png_reciprocal2(png_ptr->background_gamma,
   1738                       png_ptr->screen_gamma);
   1739                   break;
   1740 
   1741                default:
   1742                   png_error(png_ptr, "invalid background gamma type");
   1743             }
   1744 
   1745             g_sig = png_gamma_significant(g);
   1746             gs_sig = png_gamma_significant(gs);
   1747 
   1748             if (g_sig != 0)
   1749                png_ptr->background_1.gray = png_gamma_correct(png_ptr,
   1750                    png_ptr->background.gray, g);
   1751 
   1752             if (gs_sig != 0)
   1753                png_ptr->background.gray = png_gamma_correct(png_ptr,
   1754                    png_ptr->background.gray, gs);
   1755 
   1756             if ((png_ptr->background.red != png_ptr->background.green) ||
   1757                 (png_ptr->background.red != png_ptr->background.blue) ||
   1758                 (png_ptr->background.red != png_ptr->background.gray))
   1759             {
   1760                /* RGB or RGBA with color background */
   1761                if (g_sig != 0)
   1762                {
   1763                   png_ptr->background_1.red = png_gamma_correct(png_ptr,
   1764                       png_ptr->background.red, g);
   1765 
   1766                   png_ptr->background_1.green = png_gamma_correct(png_ptr,
   1767                       png_ptr->background.green, g);
   1768 
   1769                   png_ptr->background_1.blue = png_gamma_correct(png_ptr,
   1770                       png_ptr->background.blue, g);
   1771                }
   1772 
   1773                if (gs_sig != 0)
   1774                {
   1775                   png_ptr->background.red = png_gamma_correct(png_ptr,
   1776                       png_ptr->background.red, gs);
   1777 
   1778                   png_ptr->background.green = png_gamma_correct(png_ptr,
   1779                       png_ptr->background.green, gs);
   1780 
   1781                   png_ptr->background.blue = png_gamma_correct(png_ptr,
   1782                       png_ptr->background.blue, gs);
   1783                }
   1784             }
   1785 
   1786             else
   1787             {
   1788                /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
   1789                png_ptr->background_1.red = png_ptr->background_1.green
   1790                    = png_ptr->background_1.blue = png_ptr->background_1.gray;
   1791 
   1792                png_ptr->background.red = png_ptr->background.green
   1793                    = png_ptr->background.blue = png_ptr->background.gray;
   1794             }
   1795 
   1796             /* The background is now in screen gamma: */
   1797             png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
   1798          } /* color_type != PNG_COLOR_TYPE_PALETTE */
   1799       }/* png_ptr->transformations & PNG_BACKGROUND */
   1800 
   1801       else
   1802       /* Transformation does not include PNG_BACKGROUND */
   1803 #endif /* READ_BACKGROUND */
   1804       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
   1805 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   1806          /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
   1807          && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
   1808          (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
   1809 #endif
   1810          )
   1811       {
   1812          png_colorp palette = png_ptr->palette;
   1813          int num_palette = png_ptr->num_palette;
   1814          int i;
   1815 
   1816          /* NOTE: there are other transformations that should probably be in
   1817           * here too.
   1818           */
   1819          for (i = 0; i < num_palette; i++)
   1820          {
   1821             palette[i].red = png_ptr->gamma_table[palette[i].red];
   1822             palette[i].green = png_ptr->gamma_table[palette[i].green];
   1823             palette[i].blue = png_ptr->gamma_table[palette[i].blue];
   1824          }
   1825 
   1826          /* Done the gamma correction. */
   1827          png_ptr->transformations &= ~PNG_GAMMA;
   1828       } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
   1829    }
   1830 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1831    else
   1832 #endif
   1833 #endif /* READ_GAMMA */
   1834 
   1835 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1836    /* No GAMMA transformation (see the hanging else 4 lines above) */
   1837    if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
   1838        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
   1839    {
   1840       int i;
   1841       int istop = (int)png_ptr->num_trans;
   1842       png_color back;
   1843       png_colorp palette = png_ptr->palette;
   1844 
   1845       back.red   = (png_byte)png_ptr->background.red;
   1846       back.green = (png_byte)png_ptr->background.green;
   1847       back.blue  = (png_byte)png_ptr->background.blue;
   1848 
   1849       for (i = 0; i < istop; i++)
   1850       {
   1851          if (png_ptr->trans_alpha[i] == 0)
   1852          {
   1853             palette[i] = back;
   1854          }
   1855 
   1856          else if (png_ptr->trans_alpha[i] != 0xff)
   1857          {
   1858             /* The png_composite() macro is defined in png.h */
   1859             png_composite(palette[i].red, palette[i].red,
   1860                 png_ptr->trans_alpha[i], back.red);
   1861 
   1862             png_composite(palette[i].green, palette[i].green,
   1863                 png_ptr->trans_alpha[i], back.green);
   1864 
   1865             png_composite(palette[i].blue, palette[i].blue,
   1866                 png_ptr->trans_alpha[i], back.blue);
   1867          }
   1868       }
   1869 
   1870       png_ptr->transformations &= ~PNG_COMPOSE;
   1871    }
   1872 #endif /* READ_BACKGROUND */
   1873 
   1874 #ifdef PNG_READ_SHIFT_SUPPORTED
   1875    if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
   1876        (png_ptr->transformations & PNG_EXPAND) == 0 &&
   1877        (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
   1878    {
   1879       int i;
   1880       int istop = png_ptr->num_palette;
   1881       int shift = 8 - png_ptr->sig_bit.red;
   1882 
   1883       png_ptr->transformations &= ~PNG_SHIFT;
   1884 
   1885       /* significant bits can be in the range 1 to 7 for a meaninful result, if
   1886        * the number of significant bits is 0 then no shift is done (this is an
   1887        * error condition which is silently ignored.)
   1888        */
   1889       if (shift > 0 && shift < 8)
   1890          for (i=0; i<istop; ++i)
   1891          {
   1892             int component = png_ptr->palette[i].red;
   1893 
   1894             component >>= shift;
   1895             png_ptr->palette[i].red = (png_byte)component;
   1896          }
   1897 
   1898       shift = 8 - png_ptr->sig_bit.green;
   1899       if (shift > 0 && shift < 8)
   1900          for (i=0; i<istop; ++i)
   1901          {
   1902             int component = png_ptr->palette[i].green;
   1903 
   1904             component >>= shift;
   1905             png_ptr->palette[i].green = (png_byte)component;
   1906          }
   1907 
   1908       shift = 8 - png_ptr->sig_bit.blue;
   1909       if (shift > 0 && shift < 8)
   1910          for (i=0; i<istop; ++i)
   1911          {
   1912             int component = png_ptr->palette[i].blue;
   1913 
   1914             component >>= shift;
   1915             png_ptr->palette[i].blue = (png_byte)component;
   1916          }
   1917    }
   1918 #endif /* READ_SHIFT */
   1919 }
   1920 
   1921 /* Modify the info structure to reflect the transformations.  The
   1922  * info should be updated so a PNG file could be written with it,
   1923  * assuming the transformations result in valid PNG data.
   1924  */
   1925 void /* PRIVATE */
   1926 png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
   1927 {
   1928    png_debug(1, "in png_read_transform_info");
   1929 
   1930 #ifdef PNG_READ_EXPAND_SUPPORTED
   1931    if ((png_ptr->transformations & PNG_EXPAND) != 0)
   1932    {
   1933       if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1934       {
   1935          /* This check must match what actually happens in
   1936           * png_do_expand_palette; if it ever checks the tRNS chunk to see if
   1937           * it is all opaque we must do the same (at present it does not.)
   1938           */
   1939          if (png_ptr->num_trans > 0)
   1940             info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
   1941 
   1942          else
   1943             info_ptr->color_type = PNG_COLOR_TYPE_RGB;
   1944 
   1945          info_ptr->bit_depth = 8;
   1946          info_ptr->num_trans = 0;
   1947 
   1948          if (png_ptr->palette == NULL)
   1949             png_error (png_ptr, "Palette is NULL in indexed image");
   1950       }
   1951       else
   1952       {
   1953          if (png_ptr->num_trans != 0)
   1954          {
   1955             if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
   1956                info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
   1957          }
   1958          if (info_ptr->bit_depth < 8)
   1959             info_ptr->bit_depth = 8;
   1960 
   1961          info_ptr->num_trans = 0;
   1962       }
   1963    }
   1964 #endif
   1965 
   1966 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
   1967    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
   1968    /* The following is almost certainly wrong unless the background value is in
   1969     * the screen space!
   1970     */
   1971    if ((png_ptr->transformations & PNG_COMPOSE) != 0)
   1972       info_ptr->background = png_ptr->background;
   1973 #endif
   1974 
   1975 #ifdef PNG_READ_GAMMA_SUPPORTED
   1976    /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
   1977     * however it seems that the code in png_init_read_transformations, which has
   1978     * been called before this from png_read_update_info->png_read_start_row
   1979     * sometimes does the gamma transform and cancels the flag.
   1980     *
   1981     * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
   1982     * the screen_gamma value.  The following probably results in weirdness if
   1983     * the info_ptr is used by the app after the rows have been read.
   1984     */
   1985    info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
   1986 #endif
   1987 
   1988    if (info_ptr->bit_depth == 16)
   1989    {
   1990 #  ifdef PNG_READ_16BIT_SUPPORTED
   1991 #     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
   1992          if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
   1993             info_ptr->bit_depth = 8;
   1994 #     endif
   1995 
   1996 #     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
   1997          if ((png_ptr->transformations & PNG_16_TO_8) != 0)
   1998             info_ptr->bit_depth = 8;
   1999 #     endif
   2000 
   2001 #  else
   2002       /* No 16-bit support: force chopping 16-bit input down to 8, in this case
   2003        * the app program can chose if both APIs are available by setting the
   2004        * correct scaling to use.
   2005        */
   2006 #     ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
   2007          /* For compatibility with previous versions use the strip method by
   2008           * default.  This code works because if PNG_SCALE_16_TO_8 is already
   2009           * set the code below will do that in preference to the chop.
   2010           */
   2011          png_ptr->transformations |= PNG_16_TO_8;
   2012          info_ptr->bit_depth = 8;
   2013 #     else
   2014 
   2015 #        ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
   2016             png_ptr->transformations |= PNG_SCALE_16_TO_8;
   2017             info_ptr->bit_depth = 8;
   2018 #        else
   2019 
   2020             CONFIGURATION ERROR: you must enable at least one 16 to 8 method
   2021 #        endif
   2022 #    endif
   2023 #endif /* !READ_16BIT */
   2024    }
   2025 
   2026 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   2027    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
   2028       info_ptr->color_type = (png_byte)(info_ptr->color_type |
   2029          PNG_COLOR_MASK_COLOR);
   2030 #endif
   2031 
   2032 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   2033    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
   2034       info_ptr->color_type = (png_byte)(info_ptr->color_type &
   2035          ~PNG_COLOR_MASK_COLOR);
   2036 #endif
   2037 
   2038 #ifdef PNG_READ_QUANTIZE_SUPPORTED
   2039    if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
   2040    {
   2041       if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
   2042           (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
   2043           png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
   2044       {
   2045          info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
   2046       }
   2047    }
   2048 #endif
   2049 
   2050 #ifdef PNG_READ_EXPAND_16_SUPPORTED
   2051    if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
   2052        info_ptr->bit_depth == 8 &&
   2053        info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
   2054    {
   2055       info_ptr->bit_depth = 16;
   2056    }
   2057 #endif
   2058 
   2059 #ifdef PNG_READ_PACK_SUPPORTED
   2060    if ((png_ptr->transformations & PNG_PACK) != 0 &&
   2061        (info_ptr->bit_depth < 8))
   2062       info_ptr->bit_depth = 8;
   2063 #endif
   2064 
   2065    if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   2066       info_ptr->channels = 1;
   2067 
   2068    else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
   2069       info_ptr->channels = 3;
   2070 
   2071    else
   2072       info_ptr->channels = 1;
   2073 
   2074 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   2075    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
   2076    {
   2077       info_ptr->color_type = (png_byte)(info_ptr->color_type &
   2078          ~PNG_COLOR_MASK_ALPHA);
   2079       info_ptr->num_trans = 0;
   2080    }
   2081 #endif
   2082 
   2083    if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
   2084       info_ptr->channels++;
   2085 
   2086 #ifdef PNG_READ_FILLER_SUPPORTED
   2087    /* STRIP_ALPHA and FILLER allowed:  MASK_ALPHA bit stripped above */
   2088    if ((png_ptr->transformations & PNG_FILLER) != 0 &&
   2089        (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
   2090        info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
   2091    {
   2092       info_ptr->channels++;
   2093       /* If adding a true alpha channel not just filler */
   2094       if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
   2095          info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
   2096    }
   2097 #endif
   2098 
   2099 #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
   2100 defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
   2101    if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
   2102    {
   2103       if (png_ptr->user_transform_depth != 0)
   2104          info_ptr->bit_depth = png_ptr->user_transform_depth;
   2105 
   2106       if (png_ptr->user_transform_channels != 0)
   2107          info_ptr->channels = png_ptr->user_transform_channels;
   2108    }
   2109 #endif
   2110 
   2111    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
   2112        info_ptr->bit_depth);
   2113 
   2114    info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
   2115 
   2116    /* Adding in 1.5.4: cache the above value in png_struct so that we can later
   2117     * check in png_rowbytes that the user buffer won't get overwritten.  Note
   2118     * that the field is not always set - if png_read_update_info isn't called
   2119     * the application has to either not do any transforms or get the calculation
   2120     * right itself.
   2121     */
   2122    png_ptr->info_rowbytes = info_ptr->rowbytes;
   2123 
   2124 #ifndef PNG_READ_EXPAND_SUPPORTED
   2125    if (png_ptr != NULL)
   2126       return;
   2127 #endif
   2128 }
   2129 
   2130 #ifdef PNG_READ_PACK_SUPPORTED
   2131 /* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
   2132  * without changing the actual values.  Thus, if you had a row with
   2133  * a bit depth of 1, you would end up with bytes that only contained
   2134  * the numbers 0 or 1.  If you would rather they contain 0 and 255, use
   2135  * png_do_shift() after this.
   2136  */
   2137 static void
   2138 png_do_unpack(png_row_infop row_info, png_bytep row)
   2139 {
   2140    png_debug(1, "in png_do_unpack");
   2141 
   2142    if (row_info->bit_depth < 8)
   2143    {
   2144       png_uint_32 i;
   2145       png_uint_32 row_width=row_info->width;
   2146 
   2147       switch (row_info->bit_depth)
   2148       {
   2149          case 1:
   2150          {
   2151             png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
   2152             png_bytep dp = row + (png_size_t)row_width - 1;
   2153             png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
   2154             for (i = 0; i < row_width; i++)
   2155             {
   2156                *dp = (png_byte)((*sp >> shift) & 0x01);
   2157 
   2158                if (shift == 7)
   2159                {
   2160                   shift = 0;
   2161                   sp--;
   2162                }
   2163 
   2164                else
   2165                   shift++;
   2166 
   2167                dp--;
   2168             }
   2169             break;
   2170          }
   2171 
   2172          case 2:
   2173          {
   2174 
   2175             png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
   2176             png_bytep dp = row + (png_size_t)row_width - 1;
   2177             png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   2178             for (i = 0; i < row_width; i++)
   2179             {
   2180                *dp = (png_byte)((*sp >> shift) & 0x03);
   2181 
   2182                if (shift == 6)
   2183                {
   2184                   shift = 0;
   2185                   sp--;
   2186                }
   2187 
   2188                else
   2189                   shift += 2;
   2190 
   2191                dp--;
   2192             }
   2193             break;
   2194          }
   2195 
   2196          case 4:
   2197          {
   2198             png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
   2199             png_bytep dp = row + (png_size_t)row_width - 1;
   2200             png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
   2201             for (i = 0; i < row_width; i++)
   2202             {
   2203                *dp = (png_byte)((*sp >> shift) & 0x0f);
   2204 
   2205                if (shift == 4)
   2206                {
   2207                   shift = 0;
   2208                   sp--;
   2209                }
   2210 
   2211                else
   2212                   shift = 4;
   2213 
   2214                dp--;
   2215             }
   2216             break;
   2217          }
   2218 
   2219          default:
   2220             break;
   2221       }
   2222       row_info->bit_depth = 8;
   2223       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
   2224       row_info->rowbytes = row_width * row_info->channels;
   2225    }
   2226 }
   2227 #endif
   2228 
   2229 #ifdef PNG_READ_SHIFT_SUPPORTED
   2230 /* Reverse the effects of png_do_shift.  This routine merely shifts the
   2231  * pixels back to their significant bits values.  Thus, if you have
   2232  * a row of bit depth 8, but only 5 are significant, this will shift
   2233  * the values back to 0 through 31.
   2234  */
   2235 static void
   2236 png_do_unshift(png_row_infop row_info, png_bytep row,
   2237     png_const_color_8p sig_bits)
   2238 {
   2239    int color_type;
   2240 
   2241    png_debug(1, "in png_do_unshift");
   2242 
   2243    /* The palette case has already been handled in the _init routine. */
   2244    color_type = row_info->color_type;
   2245 
   2246    if (color_type != PNG_COLOR_TYPE_PALETTE)
   2247    {
   2248       int shift[4];
   2249       int channels = 0;
   2250       int bit_depth = row_info->bit_depth;
   2251 
   2252       if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
   2253       {
   2254          shift[channels++] = bit_depth - sig_bits->red;
   2255          shift[channels++] = bit_depth - sig_bits->green;
   2256          shift[channels++] = bit_depth - sig_bits->blue;
   2257       }
   2258 
   2259       else
   2260       {
   2261          shift[channels++] = bit_depth - sig_bits->gray;
   2262       }
   2263 
   2264       if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
   2265       {
   2266          shift[channels++] = bit_depth - sig_bits->alpha;
   2267       }
   2268 
   2269       {
   2270          int c, have_shift;
   2271 
   2272          for (c = have_shift = 0; c < channels; ++c)
   2273          {
   2274             /* A shift of more than the bit depth is an error condition but it
   2275              * gets ignored here.
   2276              */
   2277             if (shift[c] <= 0 || shift[c] >= bit_depth)
   2278                shift[c] = 0;
   2279 
   2280             else
   2281                have_shift = 1;
   2282          }
   2283 
   2284          if (have_shift == 0)
   2285             return;
   2286       }
   2287 
   2288       switch (bit_depth)
   2289       {
   2290          default:
   2291          /* Must be 1bpp gray: should not be here! */
   2292             /* NOTREACHED */
   2293             break;
   2294 
   2295          case 2:
   2296          /* Must be 2bpp gray */
   2297          /* assert(channels == 1 && shift[0] == 1) */
   2298          {
   2299             png_bytep bp = row;
   2300             png_bytep bp_end = bp + row_info->rowbytes;
   2301 
   2302             while (bp < bp_end)
   2303             {
   2304                int b = (*bp >> 1) & 0x55;
   2305                *bp++ = (png_byte)b;
   2306             }
   2307             break;
   2308          }
   2309 
   2310          case 4:
   2311          /* Must be 4bpp gray */
   2312          /* assert(channels == 1) */
   2313          {
   2314             png_bytep bp = row;
   2315             png_bytep bp_end = bp + row_info->rowbytes;
   2316             int gray_shift = shift[0];
   2317             int mask =  0xf >> gray_shift;
   2318 
   2319             mask |= mask << 4;
   2320 
   2321             while (bp < bp_end)
   2322             {
   2323                int b = (*bp >> gray_shift) & mask;
   2324                *bp++ = (png_byte)b;
   2325             }
   2326             break;
   2327          }
   2328 
   2329          case 8:
   2330          /* Single byte components, G, GA, RGB, RGBA */
   2331          {
   2332             png_bytep bp = row;
   2333             png_bytep bp_end = bp + row_info->rowbytes;
   2334             int channel = 0;
   2335 
   2336             while (bp < bp_end)
   2337             {
   2338                int b = *bp >> shift[channel];
   2339                if (++channel >= channels)
   2340                   channel = 0;
   2341                *bp++ = (png_byte)b;
   2342             }
   2343             break;
   2344          }
   2345 
   2346 #ifdef PNG_READ_16BIT_SUPPORTED
   2347          case 16:
   2348          /* Double byte components, G, GA, RGB, RGBA */
   2349          {
   2350             png_bytep bp = row;
   2351             png_bytep bp_end = bp + row_info->rowbytes;
   2352             int channel = 0;
   2353 
   2354             while (bp < bp_end)
   2355             {
   2356                int value = (bp[0] << 8) + bp[1];
   2357 
   2358                value >>= shift[channel];
   2359                if (++channel >= channels)
   2360                   channel = 0;
   2361                *bp++ = (png_byte)(value >> 8);
   2362                *bp++ = (png_byte)value;
   2363             }
   2364             break;
   2365          }
   2366 #endif
   2367       }
   2368    }
   2369 }
   2370 #endif
   2371 
   2372 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
   2373 /* Scale rows of bit depth 16 down to 8 accurately */
   2374 static void
   2375 png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
   2376 {
   2377    png_debug(1, "in png_do_scale_16_to_8");
   2378 
   2379    if (row_info->bit_depth == 16)
   2380    {
   2381       png_bytep sp = row; /* source */
   2382       png_bytep dp = row; /* destination */
   2383       png_bytep ep = sp + row_info->rowbytes; /* end+1 */
   2384 
   2385       while (sp < ep)
   2386       {
   2387          /* The input is an array of 16-bit components, these must be scaled to
   2388           * 8 bits each.  For a 16-bit value V the required value (from the PNG
   2389           * specification) is:
   2390           *
   2391           *    (V * 255) / 65535
   2392           *
   2393           * This reduces to round(V / 257), or floor((V + 128.5)/257)
   2394           *
   2395           * Represent V as the two byte value vhi.vlo.  Make a guess that the
   2396           * result is the top byte of V, vhi, then the correction to this value
   2397           * is:
   2398           *
   2399           *    error = floor(((V-vhi.vhi) + 128.5) / 257)
   2400           *          = floor(((vlo-vhi) + 128.5) / 257)
   2401           *
   2402           * This can be approximated using integer arithmetic (and a signed
   2403           * shift):
   2404           *
   2405           *    error = (vlo-vhi+128) >> 8;
   2406           *
   2407           * The approximate differs from the exact answer only when (vlo-vhi) is
   2408           * 128; it then gives a correction of +1 when the exact correction is
   2409           * 0.  This gives 128 errors.  The exact answer (correct for all 16-bit
   2410           * input values) is:
   2411           *
   2412           *    error = (vlo-vhi+128)*65535 >> 24;
   2413           *
   2414           * An alternative arithmetic calculation which also gives no errors is:
   2415           *
   2416           *    (V * 255 + 32895) >> 16
   2417           */
   2418 
   2419          png_int_32 tmp = *sp++; /* must be signed! */
   2420          tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
   2421          *dp++ = (png_byte)tmp;
   2422       }
   2423 
   2424       row_info->bit_depth = 8;
   2425       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
   2426       row_info->rowbytes = row_info->width * row_info->channels;
   2427    }
   2428 }
   2429 #endif
   2430 
   2431 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
   2432 static void
   2433 /* Simply discard the low byte.  This was the default behavior prior
   2434  * to libpng-1.5.4.
   2435  */
   2436 png_do_chop(png_row_infop row_info, png_bytep row)
   2437 {
   2438    png_debug(1, "in png_do_chop");
   2439 
   2440    if (row_info->bit_depth == 16)
   2441    {
   2442       png_bytep sp = row; /* source */
   2443       png_bytep dp = row; /* destination */
   2444       png_bytep ep = sp + row_info->rowbytes; /* end+1 */
   2445 
   2446       while (sp < ep)
   2447       {
   2448          *dp++ = *sp;
   2449          sp += 2; /* skip low byte */
   2450       }
   2451 
   2452       row_info->bit_depth = 8;
   2453       row_info->pixel_depth = (png_byte)(8 * row_info->channels);
   2454       row_info->rowbytes = row_info->width * row_info->channels;
   2455    }
   2456 }
   2457 #endif
   2458 
   2459 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   2460 static void
   2461 png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
   2462 {
   2463    png_debug(1, "in png_do_read_swap_alpha");
   2464 
   2465    {
   2466       png_uint_32 row_width = row_info->width;
   2467       if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   2468       {
   2469          /* This converts from RGBA to ARGB */
   2470          if (row_info->bit_depth == 8)
   2471          {
   2472             png_bytep sp = row + row_info->rowbytes;
   2473             png_bytep dp = sp;
   2474             png_byte save;
   2475             png_uint_32 i;
   2476 
   2477             for (i = 0; i < row_width; i++)
   2478             {
   2479                save = *(--sp);
   2480                *(--dp) = *(--sp);
   2481                *(--dp) = *(--sp);
   2482                *(--dp) = *(--sp);
   2483                *(--dp) = save;
   2484             }
   2485          }
   2486 
   2487 #ifdef PNG_READ_16BIT_SUPPORTED
   2488          /* This converts from RRGGBBAA to AARRGGBB */
   2489          else
   2490          {
   2491             png_bytep sp = row + row_info->rowbytes;
   2492             png_bytep dp = sp;
   2493             png_byte save[2];
   2494             png_uint_32 i;
   2495 
   2496             for (i = 0; i < row_width; i++)
   2497             {
   2498                save[0] = *(--sp);
   2499                save[1] = *(--sp);
   2500                *(--dp) = *(--sp);
   2501                *(--dp) = *(--sp);
   2502                *(--dp) = *(--sp);
   2503                *(--dp) = *(--sp);
   2504                *(--dp) = *(--sp);
   2505                *(--dp) = *(--sp);
   2506                *(--dp) = save[0];
   2507                *(--dp) = save[1];
   2508             }
   2509          }
   2510 #endif
   2511       }
   2512 
   2513       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   2514       {
   2515          /* This converts from GA to AG */
   2516          if (row_info->bit_depth == 8)
   2517          {
   2518             png_bytep sp = row + row_info->rowbytes;
   2519             png_bytep dp = sp;
   2520             png_byte save;
   2521             png_uint_32 i;
   2522 
   2523             for (i = 0; i < row_width; i++)
   2524             {
   2525                save = *(--sp);
   2526                *(--dp) = *(--sp);
   2527                *(--dp) = save;
   2528             }
   2529          }
   2530 
   2531 #ifdef PNG_READ_16BIT_SUPPORTED
   2532          /* This converts from GGAA to AAGG */
   2533          else
   2534          {
   2535             png_bytep sp = row + row_info->rowbytes;
   2536             png_bytep dp = sp;
   2537             png_byte save[2];
   2538             png_uint_32 i;
   2539 
   2540             for (i = 0; i < row_width; i++)
   2541             {
   2542                save[0] = *(--sp);
   2543                save[1] = *(--sp);
   2544                *(--dp) = *(--sp);
   2545                *(--dp) = *(--sp);
   2546                *(--dp) = save[0];
   2547                *(--dp) = save[1];
   2548             }
   2549          }
   2550 #endif
   2551       }
   2552    }
   2553 }
   2554 #endif
   2555 
   2556 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   2557 static void
   2558 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
   2559 {
   2560    png_uint_32 row_width;
   2561    png_debug(1, "in png_do_read_invert_alpha");
   2562 
   2563    row_width = row_info->width;
   2564    if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   2565    {
   2566       if (row_info->bit_depth == 8)
   2567       {
   2568          /* This inverts the alpha channel in RGBA */
   2569          png_bytep sp = row + row_info->rowbytes;
   2570          png_bytep dp = sp;
   2571          png_uint_32 i;
   2572 
   2573          for (i = 0; i < row_width; i++)
   2574          {
   2575             *(--dp) = (png_byte)(255 - *(--sp));
   2576 
   2577 /*          This does nothing:
   2578             *(--dp) = *(--sp);
   2579             *(--dp) = *(--sp);
   2580             *(--dp) = *(--sp);
   2581             We can replace it with:
   2582 */
   2583             sp-=3;
   2584             dp=sp;
   2585          }
   2586       }
   2587 
   2588 #ifdef PNG_READ_16BIT_SUPPORTED
   2589       /* This inverts the alpha channel in RRGGBBAA */
   2590       else
   2591       {
   2592          png_bytep sp = row + row_info->rowbytes;
   2593          png_bytep dp = sp;
   2594          png_uint_32 i;
   2595 
   2596          for (i = 0; i < row_width; i++)
   2597          {
   2598             *(--dp) = (png_byte)(255 - *(--sp));
   2599             *(--dp) = (png_byte)(255 - *(--sp));
   2600 
   2601 /*          This does nothing:
   2602             *(--dp) = *(--sp);
   2603             *(--dp) = *(--sp);
   2604             *(--dp) = *(--sp);
   2605             *(--dp) = *(--sp);
   2606             *(--dp) = *(--sp);
   2607             *(--dp) = *(--sp);
   2608             We can replace it with:
   2609 */
   2610             sp-=6;
   2611             dp=sp;
   2612          }
   2613       }
   2614 #endif
   2615    }
   2616    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   2617    {
   2618       if (row_info->bit_depth == 8)
   2619       {
   2620          /* This inverts the alpha channel in GA */
   2621          png_bytep sp = row + row_info->rowbytes;
   2622          png_bytep dp = sp;
   2623          png_uint_32 i;
   2624 
   2625          for (i = 0; i < row_width; i++)
   2626          {
   2627             *(--dp) = (png_byte)(255 - *(--sp));
   2628             *(--dp) = *(--sp);
   2629          }
   2630       }
   2631 
   2632 #ifdef PNG_READ_16BIT_SUPPORTED
   2633       else
   2634       {
   2635          /* This inverts the alpha channel in GGAA */
   2636          png_bytep sp  = row + row_info->rowbytes;
   2637          png_bytep dp = sp;
   2638          png_uint_32 i;
   2639 
   2640          for (i = 0; i < row_width; i++)
   2641          {
   2642             *(--dp) = (png_byte)(255 - *(--sp));
   2643             *(--dp) = (png_byte)(255 - *(--sp));
   2644 /*
   2645             *(--dp) = *(--sp);
   2646             *(--dp) = *(--sp);
   2647 */
   2648             sp-=2;
   2649             dp=sp;
   2650          }
   2651       }
   2652 #endif
   2653    }
   2654 }
   2655 #endif
   2656 
   2657 #ifdef PNG_READ_FILLER_SUPPORTED
   2658 /* Add filler channel if we have RGB color */
   2659 static void
   2660 png_do_read_filler(png_row_infop row_info, png_bytep row,
   2661     png_uint_32 filler, png_uint_32 flags)
   2662 {
   2663    png_uint_32 i;
   2664    png_uint_32 row_width = row_info->width;
   2665 
   2666 #ifdef PNG_READ_16BIT_SUPPORTED
   2667    png_byte hi_filler = (png_byte)(filler>>8);
   2668 #endif
   2669    png_byte lo_filler = (png_byte)filler;
   2670 
   2671    png_debug(1, "in png_do_read_filler");
   2672 
   2673    if (
   2674        row_info->color_type == PNG_COLOR_TYPE_GRAY)
   2675    {
   2676       if (row_info->bit_depth == 8)
   2677       {
   2678          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
   2679          {
   2680             /* This changes the data from G to GX */
   2681             png_bytep sp = row + (png_size_t)row_width;
   2682             png_bytep dp =  sp + (png_size_t)row_width;
   2683             for (i = 1; i < row_width; i++)
   2684             {
   2685                *(--dp) = lo_filler;
   2686                *(--dp) = *(--sp);
   2687             }
   2688             *(--dp) = lo_filler;
   2689             row_info->channels = 2;
   2690             row_info->pixel_depth = 16;
   2691             row_info->rowbytes = row_width * 2;
   2692          }
   2693 
   2694          else
   2695          {
   2696             /* This changes the data from G to XG */
   2697             png_bytep sp = row + (png_size_t)row_width;
   2698             png_bytep dp = sp  + (png_size_t)row_width;
   2699             for (i = 0; i < row_width; i++)
   2700             {
   2701                *(--dp) = *(--sp);
   2702                *(--dp) = lo_filler;
   2703             }
   2704             row_info->channels = 2;
   2705             row_info->pixel_depth = 16;
   2706             row_info->rowbytes = row_width * 2;
   2707          }
   2708       }
   2709 
   2710 #ifdef PNG_READ_16BIT_SUPPORTED
   2711       else if (row_info->bit_depth == 16)
   2712       {
   2713          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
   2714          {
   2715             /* This changes the data from GG to GGXX */
   2716             png_bytep sp = row + (png_size_t)row_width * 2;
   2717             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2718             for (i = 1; i < row_width; i++)
   2719             {
   2720                *(--dp) = lo_filler;
   2721                *(--dp) = hi_filler;
   2722                *(--dp) = *(--sp);
   2723                *(--dp) = *(--sp);
   2724             }
   2725             *(--dp) = lo_filler;
   2726             *(--dp) = hi_filler;
   2727             row_info->channels = 2;
   2728             row_info->pixel_depth = 32;
   2729             row_info->rowbytes = row_width * 4;
   2730          }
   2731 
   2732          else
   2733          {
   2734             /* This changes the data from GG to XXGG */
   2735             png_bytep sp = row + (png_size_t)row_width * 2;
   2736             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2737             for (i = 0; i < row_width; i++)
   2738             {
   2739                *(--dp) = *(--sp);
   2740                *(--dp) = *(--sp);
   2741                *(--dp) = lo_filler;
   2742                *(--dp) = hi_filler;
   2743             }
   2744             row_info->channels = 2;
   2745             row_info->pixel_depth = 32;
   2746             row_info->rowbytes = row_width * 4;
   2747          }
   2748       }
   2749 #endif
   2750    } /* COLOR_TYPE == GRAY */
   2751    else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
   2752    {
   2753       if (row_info->bit_depth == 8)
   2754       {
   2755          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
   2756          {
   2757             /* This changes the data from RGB to RGBX */
   2758             png_bytep sp = row + (png_size_t)row_width * 3;
   2759             png_bytep dp = sp  + (png_size_t)row_width;
   2760             for (i = 1; i < row_width; i++)
   2761             {
   2762                *(--dp) = lo_filler;
   2763                *(--dp) = *(--sp);
   2764                *(--dp) = *(--sp);
   2765                *(--dp) = *(--sp);
   2766             }
   2767             *(--dp) = lo_filler;
   2768             row_info->channels = 4;
   2769             row_info->pixel_depth = 32;
   2770             row_info->rowbytes = row_width * 4;
   2771          }
   2772 
   2773          else
   2774          {
   2775             /* This changes the data from RGB to XRGB */
   2776             png_bytep sp = row + (png_size_t)row_width * 3;
   2777             png_bytep dp = sp + (png_size_t)row_width;
   2778             for (i = 0; i < row_width; i++)
   2779             {
   2780                *(--dp) = *(--sp);
   2781                *(--dp) = *(--sp);
   2782                *(--dp) = *(--sp);
   2783                *(--dp) = lo_filler;
   2784             }
   2785             row_info->channels = 4;
   2786             row_info->pixel_depth = 32;
   2787             row_info->rowbytes = row_width * 4;
   2788          }
   2789       }
   2790 
   2791 #ifdef PNG_READ_16BIT_SUPPORTED
   2792       else if (row_info->bit_depth == 16)
   2793       {
   2794          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
   2795          {
   2796             /* This changes the data from RRGGBB to RRGGBBXX */
   2797             png_bytep sp = row + (png_size_t)row_width * 6;
   2798             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2799             for (i = 1; i < row_width; i++)
   2800             {
   2801                *(--dp) = lo_filler;
   2802                *(--dp) = hi_filler;
   2803                *(--dp) = *(--sp);
   2804                *(--dp) = *(--sp);
   2805                *(--dp) = *(--sp);
   2806                *(--dp) = *(--sp);
   2807                *(--dp) = *(--sp);
   2808                *(--dp) = *(--sp);
   2809             }
   2810             *(--dp) = lo_filler;
   2811             *(--dp) = hi_filler;
   2812             row_info->channels = 4;
   2813             row_info->pixel_depth = 64;
   2814             row_info->rowbytes = row_width * 8;
   2815          }
   2816 
   2817          else
   2818          {
   2819             /* This changes the data from RRGGBB to XXRRGGBB */
   2820             png_bytep sp = row + (png_size_t)row_width * 6;
   2821             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2822             for (i = 0; i < row_width; i++)
   2823             {
   2824                *(--dp) = *(--sp);
   2825                *(--dp) = *(--sp);
   2826                *(--dp) = *(--sp);
   2827                *(--dp) = *(--sp);
   2828                *(--dp) = *(--sp);
   2829                *(--dp) = *(--sp);
   2830                *(--dp) = lo_filler;
   2831                *(--dp) = hi_filler;
   2832             }
   2833 
   2834             row_info->channels = 4;
   2835             row_info->pixel_depth = 64;
   2836             row_info->rowbytes = row_width * 8;
   2837          }
   2838       }
   2839 #endif
   2840    } /* COLOR_TYPE == RGB */
   2841 }
   2842 #endif
   2843 
   2844 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   2845 /* Expand grayscale files to RGB, with or without alpha */
   2846 static void
   2847 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
   2848 {
   2849    png_uint_32 i;
   2850    png_uint_32 row_width = row_info->width;
   2851 
   2852    png_debug(1, "in png_do_gray_to_rgb");
   2853 
   2854    if (row_info->bit_depth >= 8 &&
   2855        (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
   2856    {
   2857       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
   2858       {
   2859          if (row_info->bit_depth == 8)
   2860          {
   2861             /* This changes G to RGB */
   2862             png_bytep sp = row + (png_size_t)row_width - 1;
   2863             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2864             for (i = 0; i < row_width; i++)
   2865             {
   2866                *(dp--) = *sp;
   2867                *(dp--) = *sp;
   2868                *(dp--) = *(sp--);
   2869             }
   2870          }
   2871 
   2872          else
   2873          {
   2874             /* This changes GG to RRGGBB */
   2875             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
   2876             png_bytep dp = sp  + (png_size_t)row_width * 4;
   2877             for (i = 0; i < row_width; i++)
   2878             {
   2879                *(dp--) = *sp;
   2880                *(dp--) = *(sp - 1);
   2881                *(dp--) = *sp;
   2882                *(dp--) = *(sp - 1);
   2883                *(dp--) = *(sp--);
   2884                *(dp--) = *(sp--);
   2885             }
   2886          }
   2887       }
   2888 
   2889       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   2890       {
   2891          if (row_info->bit_depth == 8)
   2892          {
   2893             /* This changes GA to RGBA */
   2894             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
   2895             png_bytep dp = sp  + (png_size_t)row_width * 2;
   2896             for (i = 0; i < row_width; i++)
   2897             {
   2898                *(dp--) = *(sp--);
   2899                *(dp--) = *sp;
   2900                *(dp--) = *sp;
   2901                *(dp--) = *(sp--);
   2902             }
   2903          }
   2904 
   2905          else
   2906          {
   2907             /* This changes GGAA to RRGGBBAA */
   2908             png_bytep sp = row + (png_size_t)row_width * 4 - 1;
   2909             png_bytep dp = sp  + (png_size_t)row_width * 4;
   2910             for (i = 0; i < row_width; i++)
   2911             {
   2912                *(dp--) = *(sp--);
   2913                *(dp--) = *(sp--);
   2914                *(dp--) = *sp;
   2915                *(dp--) = *(sp - 1);
   2916                *(dp--) = *sp;
   2917                *(dp--) = *(sp - 1);
   2918                *(dp--) = *(sp--);
   2919                *(dp--) = *(sp--);
   2920             }
   2921          }
   2922       }
   2923       row_info->channels = (png_byte)(row_info->channels + 2);
   2924       row_info->color_type |= PNG_COLOR_MASK_COLOR;
   2925       row_info->pixel_depth = (png_byte)(row_info->channels *
   2926           row_info->bit_depth);
   2927       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   2928    }
   2929 }
   2930 #endif
   2931 
   2932 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   2933 /* Reduce RGB files to grayscale, with or without alpha
   2934  * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
   2935  * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
   2936  * versions dated 1998 through November 2002 have been archived at
   2937  * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
   2938  * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
   2939  * Charles Poynton poynton at poynton.com
   2940  *
   2941  *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
   2942  *
   2943  *  which can be expressed with integers as
   2944  *
   2945  *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
   2946  *
   2947  * Poynton's current link (as of January 2003 through July 2011):
   2948  * <http://www.poynton.com/notes/colour_and_gamma/>
   2949  * has changed the numbers slightly:
   2950  *
   2951  *     Y = 0.2126*R + 0.7152*G + 0.0722*B
   2952  *
   2953  *  which can be expressed with integers as
   2954  *
   2955  *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
   2956  *
   2957  *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
   2958  *  end point chromaticities and the D65 white point.  Depending on the
   2959  *  precision used for the D65 white point this produces a variety of different
   2960  *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
   2961  *  used (0.3127,0.3290) the Y calculation would be:
   2962  *
   2963  *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
   2964  *
   2965  *  While this is correct the rounding results in an overflow for white, because
   2966  *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
   2967  *  libpng uses, instead, the closest non-overflowing approximation:
   2968  *
   2969  *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
   2970  *
   2971  *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
   2972  *  (including an sRGB chunk) then the chromaticities are used to calculate the
   2973  *  coefficients.  See the chunk handling in pngrutil.c for more information.
   2974  *
   2975  *  In all cases the calculation is to be done in a linear colorspace.  If no
   2976  *  gamma information is available to correct the encoding of the original RGB
   2977  *  values this results in an implicit assumption that the original PNG RGB
   2978  *  values were linear.
   2979  *
   2980  *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
   2981  *  the API takes just red and green coefficients the blue coefficient is
   2982  *  calculated to make the sum 32768.  This will result in different rounding
   2983  *  to that used above.
   2984  */
   2985 static int
   2986 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
   2987 
   2988 {
   2989    int rgb_error = 0;
   2990 
   2991    png_debug(1, "in png_do_rgb_to_gray");
   2992 
   2993    if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
   2994        (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
   2995    {
   2996       PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
   2997       PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
   2998       PNG_CONST png_uint_32 bc = 32768 - rc - gc;
   2999       PNG_CONST png_uint_32 row_width = row_info->width;
   3000       PNG_CONST int have_alpha =
   3001          (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
   3002 
   3003       if (row_info->bit_depth == 8)
   3004       {
   3005 #ifdef PNG_READ_GAMMA_SUPPORTED
   3006          /* Notice that gamma to/from 1 are not necessarily inverses (if
   3007           * there is an overall gamma correction).  Prior to 1.5.5 this code
   3008           * checked the linearized values for equality; this doesn't match
   3009           * the documentation, the original values must be checked.
   3010           */
   3011          if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
   3012          {
   3013             png_bytep sp = row;
   3014             png_bytep dp = row;
   3015             png_uint_32 i;
   3016 
   3017             for (i = 0; i < row_width; i++)
   3018             {
   3019                png_byte red   = *(sp++);
   3020                png_byte green = *(sp++);
   3021                png_byte blue  = *(sp++);
   3022 
   3023                if (red != green || red != blue)
   3024                {
   3025                   red = png_ptr->gamma_to_1[red];
   3026                   green = png_ptr->gamma_to_1[green];
   3027                   blue = png_ptr->gamma_to_1[blue];
   3028 
   3029                   rgb_error |= 1;
   3030                   *(dp++) = png_ptr->gamma_from_1[
   3031                       (rc*red + gc*green + bc*blue + 16384)>>15];
   3032                }
   3033 
   3034                else
   3035                {
   3036                   /* If there is no overall correction the table will not be
   3037                    * set.
   3038                    */
   3039                   if (png_ptr->gamma_table != NULL)
   3040                      red = png_ptr->gamma_table[red];
   3041 
   3042                   *(dp++) = red;
   3043                }
   3044 
   3045                if (have_alpha != 0)
   3046                   *(dp++) = *(sp++);
   3047             }
   3048          }
   3049          else
   3050 #endif
   3051          {
   3052             png_bytep sp = row;
   3053             png_bytep dp = row;
   3054             png_uint_32 i;
   3055 
   3056             for (i = 0; i < row_width; i++)
   3057             {
   3058                png_byte red   = *(sp++);
   3059                png_byte green = *(sp++);
   3060                png_byte blue  = *(sp++);
   3061 
   3062                if (red != green || red != blue)
   3063                {
   3064                   rgb_error |= 1;
   3065                   /* NOTE: this is the historical approach which simply
   3066                    * truncates the results.
   3067                    */
   3068                   *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
   3069                }
   3070 
   3071                else
   3072                   *(dp++) = red;
   3073 
   3074                if (have_alpha != 0)
   3075                   *(dp++) = *(sp++);
   3076             }
   3077          }
   3078       }
   3079 
   3080       else /* RGB bit_depth == 16 */
   3081       {
   3082 #ifdef PNG_READ_GAMMA_SUPPORTED
   3083          if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
   3084          {
   3085             png_bytep sp = row;
   3086             png_bytep dp = row;
   3087             png_uint_32 i;
   3088 
   3089             for (i = 0; i < row_width; i++)
   3090             {
   3091                png_uint_16 red, green, blue, w;
   3092                png_byte hi,lo;
   3093 
   3094                hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
   3095                hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
   3096                hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
   3097 
   3098                if (red == green && red == blue)
   3099                {
   3100                   if (png_ptr->gamma_16_table != NULL)
   3101                      w = png_ptr->gamma_16_table[(red & 0xff)
   3102                          >> png_ptr->gamma_shift][red >> 8];
   3103 
   3104                   else
   3105                      w = red;
   3106                }
   3107 
   3108                else
   3109                {
   3110                   png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red & 0xff)
   3111                       >> png_ptr->gamma_shift][red>>8];
   3112                   png_uint_16 green_1 =
   3113                       png_ptr->gamma_16_to_1[(green & 0xff) >>
   3114                       png_ptr->gamma_shift][green>>8];
   3115                   png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue & 0xff)
   3116                       >> png_ptr->gamma_shift][blue>>8];
   3117                   png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
   3118                       + bc*blue_1 + 16384)>>15);
   3119                   w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
   3120                       png_ptr->gamma_shift][gray16 >> 8];
   3121                   rgb_error |= 1;
   3122                }
   3123 
   3124                *(dp++) = (png_byte)((w>>8) & 0xff);
   3125                *(dp++) = (png_byte)(w & 0xff);
   3126 
   3127                if (have_alpha != 0)
   3128                {
   3129                   *(dp++) = *(sp++);
   3130                   *(dp++) = *(sp++);
   3131                }
   3132             }
   3133          }
   3134          else
   3135 #endif
   3136          {
   3137             png_bytep sp = row;
   3138             png_bytep dp = row;
   3139             png_uint_32 i;
   3140 
   3141             for (i = 0; i < row_width; i++)
   3142             {
   3143                png_uint_16 red, green, blue, gray16;
   3144                png_byte hi,lo;
   3145 
   3146                hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
   3147                hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
   3148                hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
   3149 
   3150                if (red != green || red != blue)
   3151                   rgb_error |= 1;
   3152 
   3153                /* From 1.5.5 in the 16-bit case do the accurate conversion even
   3154                 * in the 'fast' case - this is because this is where the code
   3155                 * ends up when handling linear 16-bit data.
   3156                 */
   3157                gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
   3158                   15);
   3159                *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
   3160                *(dp++) = (png_byte)(gray16 & 0xff);
   3161 
   3162                if (have_alpha != 0)
   3163                {
   3164                   *(dp++) = *(sp++);
   3165                   *(dp++) = *(sp++);
   3166                }
   3167             }
   3168          }
   3169       }
   3170 
   3171       row_info->channels = (png_byte)(row_info->channels - 2);
   3172       row_info->color_type = (png_byte)(row_info->color_type &
   3173           ~PNG_COLOR_MASK_COLOR);
   3174       row_info->pixel_depth = (png_byte)(row_info->channels *
   3175           row_info->bit_depth);
   3176       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   3177    }
   3178    return rgb_error;
   3179 }
   3180 #endif
   3181 
   3182 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
   3183    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
   3184 /* Replace any alpha or transparency with the supplied background color.
   3185  * "background" is already in the screen gamma, while "background_1" is
   3186  * at a gamma of 1.0.  Paletted files have already been taken care of.
   3187  */
   3188 static void
   3189 png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
   3190 {
   3191 #ifdef PNG_READ_GAMMA_SUPPORTED
   3192    png_const_bytep gamma_table = png_ptr->gamma_table;
   3193    png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
   3194    png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
   3195    png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
   3196    png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
   3197    png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
   3198    int gamma_shift = png_ptr->gamma_shift;
   3199    int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
   3200 #endif
   3201 
   3202    png_bytep sp;
   3203    png_uint_32 i;
   3204    png_uint_32 row_width = row_info->width;
   3205    int shift;
   3206 
   3207    png_debug(1, "in png_do_compose");
   3208 
   3209    {
   3210       switch (row_info->color_type)
   3211       {
   3212          case PNG_COLOR_TYPE_GRAY:
   3213          {
   3214             switch (row_info->bit_depth)
   3215             {
   3216                case 1:
   3217                {
   3218                   sp = row;
   3219                   shift = 7;
   3220                   for (i = 0; i < row_width; i++)
   3221                   {
   3222                      if ((png_uint_16)((*sp >> shift) & 0x01)
   3223                         == png_ptr->trans_color.gray)
   3224                      {
   3225                         unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
   3226                         tmp |= png_ptr->background.gray << shift;
   3227                         *sp = (png_byte)(tmp & 0xff);
   3228                      }
   3229 
   3230                      if (shift == 0)
   3231                      {
   3232                         shift = 7;
   3233                         sp++;
   3234                      }
   3235 
   3236                      else
   3237                         shift--;
   3238                   }
   3239                   break;
   3240                }
   3241 
   3242                case 2:
   3243                {
   3244 #ifdef PNG_READ_GAMMA_SUPPORTED
   3245                   if (gamma_table != NULL)
   3246                   {
   3247                      sp = row;
   3248                      shift = 6;
   3249                      for (i = 0; i < row_width; i++)
   3250                      {
   3251                         if ((png_uint_16)((*sp >> shift) & 0x03)
   3252                             == png_ptr->trans_color.gray)
   3253                         {
   3254                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
   3255                            tmp |= png_ptr->background.gray << shift;
   3256                            *sp = (png_byte)(tmp & 0xff);
   3257                         }
   3258 
   3259                         else
   3260                         {
   3261                            unsigned int p = (*sp >> shift) & 0x03;
   3262                            unsigned int g = (gamma_table [p | (p << 2) |
   3263                                (p << 4) | (p << 6)] >> 6) & 0x03;
   3264                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
   3265                            tmp |= g << shift;
   3266                            *sp = (png_byte)(tmp & 0xff);
   3267                         }
   3268 
   3269                         if (shift == 0)
   3270                         {
   3271                            shift = 6;
   3272                            sp++;
   3273                         }
   3274 
   3275                         else
   3276                            shift -= 2;
   3277                      }
   3278                   }
   3279 
   3280                   else
   3281 #endif
   3282                   {
   3283                      sp = row;
   3284                      shift = 6;
   3285                      for (i = 0; i < row_width; i++)
   3286                      {
   3287                         if ((png_uint_16)((*sp >> shift) & 0x03)
   3288                             == png_ptr->trans_color.gray)
   3289                         {
   3290                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
   3291                            tmp |= png_ptr->background.gray << shift;
   3292                            *sp = (png_byte)(tmp & 0xff);
   3293                         }
   3294 
   3295                         if (shift == 0)
   3296                         {
   3297                            shift = 6;
   3298                            sp++;
   3299                         }
   3300 
   3301                         else
   3302                            shift -= 2;
   3303                      }
   3304                   }
   3305                   break;
   3306                }
   3307 
   3308                case 4:
   3309                {
   3310 #ifdef PNG_READ_GAMMA_SUPPORTED
   3311                   if (gamma_table != NULL)
   3312                   {
   3313                      sp = row;
   3314                      shift = 4;
   3315                      for (i = 0; i < row_width; i++)
   3316                      {
   3317                         if ((png_uint_16)((*sp >> shift) & 0x0f)
   3318                             == png_ptr->trans_color.gray)
   3319                         {
   3320                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
   3321                            tmp |= png_ptr->background.gray << shift;
   3322                            *sp = (png_byte)(tmp & 0xff);
   3323                         }
   3324 
   3325                         else
   3326                         {
   3327                            unsigned int p = (*sp >> shift) & 0x0f;
   3328                            unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
   3329                               0x0f;
   3330                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
   3331                            tmp |= g << shift;
   3332                            *sp = (png_byte)(tmp & 0xff);
   3333                         }
   3334 
   3335                         if (shift == 0)
   3336                         {
   3337                            shift = 4;
   3338                            sp++;
   3339                         }
   3340 
   3341                         else
   3342                            shift -= 4;
   3343                      }
   3344                   }
   3345 
   3346                   else
   3347 #endif
   3348                   {
   3349                      sp = row;
   3350                      shift = 4;
   3351                      for (i = 0; i < row_width; i++)
   3352                      {
   3353                         if ((png_uint_16)((*sp >> shift) & 0x0f)
   3354                             == png_ptr->trans_color.gray)
   3355                         {
   3356                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
   3357                            tmp |= png_ptr->background.gray << shift;
   3358                            *sp = (png_byte)(tmp & 0xff);
   3359                         }
   3360 
   3361                         if (shift == 0)
   3362                         {
   3363                            shift = 4;
   3364                            sp++;
   3365                         }
   3366 
   3367                         else
   3368                            shift -= 4;
   3369                      }
   3370                   }
   3371                   break;
   3372                }
   3373 
   3374                case 8:
   3375                {
   3376 #ifdef PNG_READ_GAMMA_SUPPORTED
   3377                   if (gamma_table != NULL)
   3378                   {
   3379                      sp = row;
   3380                      for (i = 0; i < row_width; i++, sp++)
   3381                      {
   3382                         if (*sp == png_ptr->trans_color.gray)
   3383                            *sp = (png_byte)png_ptr->background.gray;
   3384 
   3385                         else
   3386                            *sp = gamma_table[*sp];
   3387                      }
   3388                   }
   3389                   else
   3390 #endif
   3391                   {
   3392                      sp = row;
   3393                      for (i = 0; i < row_width; i++, sp++)
   3394                      {
   3395                         if (*sp == png_ptr->trans_color.gray)
   3396                            *sp = (png_byte)png_ptr->background.gray;
   3397                      }
   3398                   }
   3399                   break;
   3400                }
   3401 
   3402                case 16:
   3403                {
   3404 #ifdef PNG_READ_GAMMA_SUPPORTED
   3405                   if (gamma_16 != NULL)
   3406                   {
   3407                      sp = row;
   3408                      for (i = 0; i < row_width; i++, sp += 2)
   3409                      {
   3410                         png_uint_16 v;
   3411 
   3412                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3413 
   3414                         if (v == png_ptr->trans_color.gray)
   3415                         {
   3416                            /* Background is already in screen gamma */
   3417                            *sp = (png_byte)((png_ptr->background.gray >> 8)
   3418                                 & 0xff);
   3419                            *(sp + 1) = (png_byte)(png_ptr->background.gray
   3420                                 & 0xff);
   3421                         }
   3422 
   3423                         else
   3424                         {
   3425                            v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3426                            *sp = (png_byte)((v >> 8) & 0xff);
   3427                            *(sp + 1) = (png_byte)(v & 0xff);
   3428                         }
   3429                      }
   3430                   }
   3431                   else
   3432 #endif
   3433                   {
   3434                      sp = row;
   3435                      for (i = 0; i < row_width; i++, sp += 2)
   3436                      {
   3437                         png_uint_16 v;
   3438 
   3439                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3440 
   3441                         if (v == png_ptr->trans_color.gray)
   3442                         {
   3443                            *sp = (png_byte)((png_ptr->background.gray >> 8)
   3444                                 & 0xff);
   3445                            *(sp + 1) = (png_byte)(png_ptr->background.gray
   3446                                 & 0xff);
   3447                         }
   3448                      }
   3449                   }
   3450                   break;
   3451                }
   3452 
   3453                default:
   3454                   break;
   3455             }
   3456             break;
   3457          }
   3458 
   3459          case PNG_COLOR_TYPE_RGB:
   3460          {
   3461             if (row_info->bit_depth == 8)
   3462             {
   3463 #ifdef PNG_READ_GAMMA_SUPPORTED
   3464                if (gamma_table != NULL)
   3465                {
   3466                   sp = row;
   3467                   for (i = 0; i < row_width; i++, sp += 3)
   3468                   {
   3469                      if (*sp == png_ptr->trans_color.red &&
   3470                          *(sp + 1) == png_ptr->trans_color.green &&
   3471                          *(sp + 2) == png_ptr->trans_color.blue)
   3472                      {
   3473                         *sp = (png_byte)png_ptr->background.red;
   3474                         *(sp + 1) = (png_byte)png_ptr->background.green;
   3475                         *(sp + 2) = (png_byte)png_ptr->background.blue;
   3476                      }
   3477 
   3478                      else
   3479                      {
   3480                         *sp = gamma_table[*sp];
   3481                         *(sp + 1) = gamma_table[*(sp + 1)];
   3482                         *(sp + 2) = gamma_table[*(sp + 2)];
   3483                      }
   3484                   }
   3485                }
   3486                else
   3487 #endif
   3488                {
   3489                   sp = row;
   3490                   for (i = 0; i < row_width; i++, sp += 3)
   3491                   {
   3492                      if (*sp == png_ptr->trans_color.red &&
   3493                          *(sp + 1) == png_ptr->trans_color.green &&
   3494                          *(sp + 2) == png_ptr->trans_color.blue)
   3495                      {
   3496                         *sp = (png_byte)png_ptr->background.red;
   3497                         *(sp + 1) = (png_byte)png_ptr->background.green;
   3498                         *(sp + 2) = (png_byte)png_ptr->background.blue;
   3499                      }
   3500                   }
   3501                }
   3502             }
   3503             else /* if (row_info->bit_depth == 16) */
   3504             {
   3505 #ifdef PNG_READ_GAMMA_SUPPORTED
   3506                if (gamma_16 != NULL)
   3507                {
   3508                   sp = row;
   3509                   for (i = 0; i < row_width; i++, sp += 6)
   3510                   {
   3511                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3512 
   3513                      png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
   3514                          + *(sp + 3));
   3515 
   3516                      png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
   3517                          + *(sp + 5));
   3518 
   3519                      if (r == png_ptr->trans_color.red &&
   3520                          g == png_ptr->trans_color.green &&
   3521                          b == png_ptr->trans_color.blue)
   3522                      {
   3523                         /* Background is already in screen gamma */
   3524                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
   3525                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
   3526                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
   3527                                 & 0xff);
   3528                         *(sp + 3) = (png_byte)(png_ptr->background.green
   3529                                 & 0xff);
   3530                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
   3531                                 & 0xff);
   3532                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
   3533                      }
   3534 
   3535                      else
   3536                      {
   3537                         png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3538                         *sp = (png_byte)((v >> 8) & 0xff);
   3539                         *(sp + 1) = (png_byte)(v & 0xff);
   3540 
   3541                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3542                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
   3543                         *(sp + 3) = (png_byte)(v & 0xff);
   3544 
   3545                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3546                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
   3547                         *(sp + 5) = (png_byte)(v & 0xff);
   3548                      }
   3549                   }
   3550                }
   3551 
   3552                else
   3553 #endif
   3554                {
   3555                   sp = row;
   3556                   for (i = 0; i < row_width; i++, sp += 6)
   3557                   {
   3558                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3559 
   3560                      png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
   3561                          + *(sp + 3));
   3562 
   3563                      png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
   3564                          + *(sp + 5));
   3565 
   3566                      if (r == png_ptr->trans_color.red &&
   3567                          g == png_ptr->trans_color.green &&
   3568                          b == png_ptr->trans_color.blue)
   3569                      {
   3570                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
   3571                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
   3572                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
   3573                                 & 0xff);
   3574                         *(sp + 3) = (png_byte)(png_ptr->background.green
   3575                                 & 0xff);
   3576                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
   3577                                 & 0xff);
   3578                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
   3579                      }
   3580                   }
   3581                }
   3582             }
   3583             break;
   3584          }
   3585 
   3586          case PNG_COLOR_TYPE_GRAY_ALPHA:
   3587          {
   3588             if (row_info->bit_depth == 8)
   3589             {
   3590 #ifdef PNG_READ_GAMMA_SUPPORTED
   3591                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
   3592                    gamma_table != NULL)
   3593                {
   3594                   sp = row;
   3595                   for (i = 0; i < row_width; i++, sp += 2)
   3596                   {
   3597                      png_uint_16 a = *(sp + 1);
   3598 
   3599                      if (a == 0xff)
   3600                         *sp = gamma_table[*sp];
   3601 
   3602                      else if (a == 0)
   3603                      {
   3604                         /* Background is already in screen gamma */
   3605                         *sp = (png_byte)png_ptr->background.gray;
   3606                      }
   3607 
   3608                      else
   3609                      {
   3610                         png_byte v, w;
   3611 
   3612                         v = gamma_to_1[*sp];
   3613                         png_composite(w, v, a, png_ptr->background_1.gray);
   3614                         if (optimize == 0)
   3615                            w = gamma_from_1[w];
   3616                         *sp = w;
   3617                      }
   3618                   }
   3619                }
   3620                else
   3621 #endif
   3622                {
   3623                   sp = row;
   3624                   for (i = 0; i < row_width; i++, sp += 2)
   3625                   {
   3626                      png_byte a = *(sp + 1);
   3627 
   3628                      if (a == 0)
   3629                         *sp = (png_byte)png_ptr->background.gray;
   3630 
   3631                      else if (a < 0xff)
   3632                         png_composite(*sp, *sp, a, png_ptr->background.gray);
   3633                   }
   3634                }
   3635             }
   3636             else /* if (png_ptr->bit_depth == 16) */
   3637             {
   3638 #ifdef PNG_READ_GAMMA_SUPPORTED
   3639                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
   3640                    gamma_16_to_1 != NULL)
   3641                {
   3642                   sp = row;
   3643                   for (i = 0; i < row_width; i++, sp += 4)
   3644                   {
   3645                      png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
   3646                          + *(sp + 3));
   3647 
   3648                      if (a == (png_uint_16)0xffff)
   3649                      {
   3650                         png_uint_16 v;
   3651 
   3652                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3653                         *sp = (png_byte)((v >> 8) & 0xff);
   3654                         *(sp + 1) = (png_byte)(v & 0xff);
   3655                      }
   3656 
   3657                      else if (a == 0)
   3658                      {
   3659                         /* Background is already in screen gamma */
   3660                         *sp = (png_byte)((png_ptr->background.gray >> 8)
   3661                                 & 0xff);
   3662                         *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
   3663                      }
   3664 
   3665                      else
   3666                      {
   3667                         png_uint_16 g, v, w;
   3668 
   3669                         g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
   3670                         png_composite_16(v, g, a, png_ptr->background_1.gray);
   3671                         if (optimize != 0)
   3672                            w = v;
   3673                         else
   3674                            w = gamma_16_from_1[(v & 0xff) >>
   3675                                gamma_shift][v >> 8];
   3676                         *sp = (png_byte)((w >> 8) & 0xff);
   3677                         *(sp + 1) = (png_byte)(w & 0xff);
   3678                      }
   3679                   }
   3680                }
   3681                else
   3682 #endif
   3683                {
   3684                   sp = row;
   3685                   for (i = 0; i < row_width; i++, sp += 4)
   3686                   {
   3687                      png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
   3688                          + *(sp + 3));
   3689 
   3690                      if (a == 0)
   3691                      {
   3692                         *sp = (png_byte)((png_ptr->background.gray >> 8)
   3693                                 & 0xff);
   3694                         *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
   3695                      }
   3696 
   3697                      else if (a < 0xffff)
   3698                      {
   3699                         png_uint_16 g, v;
   3700 
   3701                         g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3702                         png_composite_16(v, g, a, png_ptr->background.gray);
   3703                         *sp = (png_byte)((v >> 8) & 0xff);
   3704                         *(sp + 1) = (png_byte)(v & 0xff);
   3705                      }
   3706                   }
   3707                }
   3708             }
   3709             break;
   3710          }
   3711 
   3712          case PNG_COLOR_TYPE_RGB_ALPHA:
   3713          {
   3714             if (row_info->bit_depth == 8)
   3715             {
   3716 #ifdef PNG_READ_GAMMA_SUPPORTED
   3717                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
   3718                    gamma_table != NULL)
   3719                {
   3720                   sp = row;
   3721                   for (i = 0; i < row_width; i++, sp += 4)
   3722                   {
   3723                      png_byte a = *(sp + 3);
   3724 
   3725                      if (a == 0xff)
   3726                      {
   3727                         *sp = gamma_table[*sp];
   3728                         *(sp + 1) = gamma_table[*(sp + 1)];
   3729                         *(sp + 2) = gamma_table[*(sp + 2)];
   3730                      }
   3731 
   3732                      else if (a == 0)
   3733                      {
   3734                         /* Background is already in screen gamma */
   3735                         *sp = (png_byte)png_ptr->background.red;
   3736                         *(sp + 1) = (png_byte)png_ptr->background.green;
   3737                         *(sp + 2) = (png_byte)png_ptr->background.blue;
   3738                      }
   3739 
   3740                      else
   3741                      {
   3742                         png_byte v, w;
   3743 
   3744                         v = gamma_to_1[*sp];
   3745                         png_composite(w, v, a, png_ptr->background_1.red);
   3746                         if (optimize == 0) w = gamma_from_1[w];
   3747                         *sp = w;
   3748 
   3749                         v = gamma_to_1[*(sp + 1)];
   3750                         png_composite(w, v, a, png_ptr->background_1.green);
   3751                         if (optimize == 0) w = gamma_from_1[w];
   3752                         *(sp + 1) = w;
   3753 
   3754                         v = gamma_to_1[*(sp + 2)];
   3755                         png_composite(w, v, a, png_ptr->background_1.blue);
   3756                         if (optimize == 0) w = gamma_from_1[w];
   3757                         *(sp + 2) = w;
   3758                      }
   3759                   }
   3760                }
   3761                else
   3762 #endif
   3763                {
   3764                   sp = row;
   3765                   for (i = 0; i < row_width; i++, sp += 4)
   3766                   {
   3767                      png_byte a = *(sp + 3);
   3768 
   3769                      if (a == 0)
   3770                      {
   3771                         *sp = (png_byte)png_ptr->background.red;
   3772                         *(sp + 1) = (png_byte)png_ptr->background.green;
   3773                         *(sp + 2) = (png_byte)png_ptr->background.blue;
   3774                      }
   3775 
   3776                      else if (a < 0xff)
   3777                      {
   3778                         png_composite(*sp, *sp, a, png_ptr->background.red);
   3779 
   3780                         png_composite(*(sp + 1), *(sp + 1), a,
   3781                             png_ptr->background.green);
   3782 
   3783                         png_composite(*(sp + 2), *(sp + 2), a,
   3784                             png_ptr->background.blue);
   3785                      }
   3786                   }
   3787                }
   3788             }
   3789             else /* if (row_info->bit_depth == 16) */
   3790             {
   3791 #ifdef PNG_READ_GAMMA_SUPPORTED
   3792                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
   3793                    gamma_16_to_1 != NULL)
   3794                {
   3795                   sp = row;
   3796                   for (i = 0; i < row_width; i++, sp += 8)
   3797                   {
   3798                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
   3799                          << 8) + (png_uint_16)(*(sp + 7)));
   3800 
   3801                      if (a == (png_uint_16)0xffff)
   3802                      {
   3803                         png_uint_16 v;
   3804 
   3805                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
   3806                         *sp = (png_byte)((v >> 8) & 0xff);
   3807                         *(sp + 1) = (png_byte)(v & 0xff);
   3808 
   3809                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3810                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
   3811                         *(sp + 3) = (png_byte)(v & 0xff);
   3812 
   3813                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3814                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
   3815                         *(sp + 5) = (png_byte)(v & 0xff);
   3816                      }
   3817 
   3818                      else if (a == 0)
   3819                      {
   3820                         /* Background is already in screen gamma */
   3821                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
   3822                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
   3823                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
   3824                                 & 0xff);
   3825                         *(sp + 3) = (png_byte)(png_ptr->background.green
   3826                                 & 0xff);
   3827                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
   3828                                 & 0xff);
   3829                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
   3830                      }
   3831 
   3832                      else
   3833                      {
   3834                         png_uint_16 v, w;
   3835 
   3836                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
   3837                         png_composite_16(w, v, a, png_ptr->background_1.red);
   3838                         if (optimize == 0)
   3839                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
   3840                                 8];
   3841                         *sp = (png_byte)((w >> 8) & 0xff);
   3842                         *(sp + 1) = (png_byte)(w & 0xff);
   3843 
   3844                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
   3845                         png_composite_16(w, v, a, png_ptr->background_1.green);
   3846                         if (optimize == 0)
   3847                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
   3848                                 8];
   3849 
   3850                         *(sp + 2) = (png_byte)((w >> 8) & 0xff);
   3851                         *(sp + 3) = (png_byte)(w & 0xff);
   3852 
   3853                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
   3854                         png_composite_16(w, v, a, png_ptr->background_1.blue);
   3855                         if (optimize == 0)
   3856                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
   3857                                 8];
   3858 
   3859                         *(sp + 4) = (png_byte)((w >> 8) & 0xff);
   3860                         *(sp + 5) = (png_byte)(w & 0xff);
   3861                      }
   3862                   }
   3863                }
   3864 
   3865                else
   3866 #endif
   3867                {
   3868                   sp = row;
   3869                   for (i = 0; i < row_width; i++, sp += 8)
   3870                   {
   3871                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
   3872                          << 8) + (png_uint_16)(*(sp + 7)));
   3873 
   3874                      if (a == 0)
   3875                      {
   3876                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
   3877                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
   3878                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
   3879                                 & 0xff);
   3880                         *(sp + 3) = (png_byte)(png_ptr->background.green
   3881                                 & 0xff);
   3882                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
   3883                                 & 0xff);
   3884                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
   3885                      }
   3886 
   3887                      else if (a < 0xffff)
   3888                      {
   3889                         png_uint_16 v;
   3890 
   3891                         png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
   3892                         png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
   3893                             + *(sp + 3));
   3894                         png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
   3895                             + *(sp + 5));
   3896 
   3897                         png_composite_16(v, r, a, png_ptr->background.red);
   3898                         *sp = (png_byte)((v >> 8) & 0xff);
   3899                         *(sp + 1) = (png_byte)(v & 0xff);
   3900 
   3901                         png_composite_16(v, g, a, png_ptr->background.green);
   3902                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
   3903                         *(sp + 3) = (png_byte)(v & 0xff);
   3904 
   3905                         png_composite_16(v, b, a, png_ptr->background.blue);
   3906                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
   3907                         *(sp + 5) = (png_byte)(v & 0xff);
   3908                      }
   3909                   }
   3910                }
   3911             }
   3912             break;
   3913          }
   3914 
   3915          default:
   3916             break;
   3917       }
   3918    }
   3919 }
   3920 #endif /* READ_BACKGROUND || READ_ALPHA_MODE */
   3921 
   3922 #ifdef PNG_READ_GAMMA_SUPPORTED
   3923 /* Gamma correct the image, avoiding the alpha channel.  Make sure
   3924  * you do this after you deal with the transparency issue on grayscale
   3925  * or RGB images. If your bit depth is 8, use gamma_table, if it
   3926  * is 16, use gamma_16_table and gamma_shift.  Build these with
   3927  * build_gamma_table().
   3928  */
   3929 static void
   3930 png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
   3931 {
   3932    png_const_bytep gamma_table = png_ptr->gamma_table;
   3933    png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
   3934    int gamma_shift = png_ptr->gamma_shift;
   3935 
   3936    png_bytep sp;
   3937    png_uint_32 i;
   3938    png_uint_32 row_width=row_info->width;
   3939 
   3940    png_debug(1, "in png_do_gamma");
   3941 
   3942    if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
   3943        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
   3944    {
   3945       switch (row_info->color_type)
   3946       {
   3947          case PNG_COLOR_TYPE_RGB:
   3948          {
   3949             if (row_info->bit_depth == 8)
   3950             {
   3951                sp = row;
   3952                for (i = 0; i < row_width; i++)
   3953                {
   3954                   *sp = gamma_table[*sp];
   3955                   sp++;
   3956                   *sp = gamma_table[*sp];
   3957                   sp++;
   3958                   *sp = gamma_table[*sp];
   3959                   sp++;
   3960                }
   3961             }
   3962 
   3963             else /* if (row_info->bit_depth == 16) */
   3964             {
   3965                sp = row;
   3966                for (i = 0; i < row_width; i++)
   3967                {
   3968                   png_uint_16 v;
   3969 
   3970                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3971                   *sp = (png_byte)((v >> 8) & 0xff);
   3972                   *(sp + 1) = (png_byte)(v & 0xff);
   3973                   sp += 2;
   3974 
   3975                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3976                   *sp = (png_byte)((v >> 8) & 0xff);
   3977                   *(sp + 1) = (png_byte)(v & 0xff);
   3978                   sp += 2;
   3979 
   3980                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   3981                   *sp = (png_byte)((v >> 8) & 0xff);
   3982                   *(sp + 1) = (png_byte)(v & 0xff);
   3983                   sp += 2;
   3984                }
   3985             }
   3986             break;
   3987          }
   3988 
   3989          case PNG_COLOR_TYPE_RGB_ALPHA:
   3990          {
   3991             if (row_info->bit_depth == 8)
   3992             {
   3993                sp = row;
   3994                for (i = 0; i < row_width; i++)
   3995                {
   3996                   *sp = gamma_table[*sp];
   3997                   sp++;
   3998 
   3999                   *sp = gamma_table[*sp];
   4000                   sp++;
   4001 
   4002                   *sp = gamma_table[*sp];
   4003                   sp++;
   4004 
   4005                   sp++;
   4006                }
   4007             }
   4008 
   4009             else /* if (row_info->bit_depth == 16) */
   4010             {
   4011                sp = row;
   4012                for (i = 0; i < row_width; i++)
   4013                {
   4014                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   4015                   *sp = (png_byte)((v >> 8) & 0xff);
   4016                   *(sp + 1) = (png_byte)(v & 0xff);
   4017                   sp += 2;
   4018 
   4019                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   4020                   *sp = (png_byte)((v >> 8) & 0xff);
   4021                   *(sp + 1) = (png_byte)(v & 0xff);
   4022                   sp += 2;
   4023 
   4024                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   4025                   *sp = (png_byte)((v >> 8) & 0xff);
   4026                   *(sp + 1) = (png_byte)(v & 0xff);
   4027                   sp += 4;
   4028                }
   4029             }
   4030             break;
   4031          }
   4032 
   4033          case PNG_COLOR_TYPE_GRAY_ALPHA:
   4034          {
   4035             if (row_info->bit_depth == 8)
   4036             {
   4037                sp = row;
   4038                for (i = 0; i < row_width; i++)
   4039                {
   4040                   *sp = gamma_table[*sp];
   4041                   sp += 2;
   4042                }
   4043             }
   4044 
   4045             else /* if (row_info->bit_depth == 16) */
   4046             {
   4047                sp = row;
   4048                for (i = 0; i < row_width; i++)
   4049                {
   4050                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   4051                   *sp = (png_byte)((v >> 8) & 0xff);
   4052                   *(sp + 1) = (png_byte)(v & 0xff);
   4053                   sp += 4;
   4054                }
   4055             }
   4056             break;
   4057          }
   4058 
   4059          case PNG_COLOR_TYPE_GRAY:
   4060          {
   4061             if (row_info->bit_depth == 2)
   4062             {
   4063                sp = row;
   4064                for (i = 0; i < row_width; i += 4)
   4065                {
   4066                   int a = *sp & 0xc0;
   4067                   int b = *sp & 0x30;
   4068                   int c = *sp & 0x0c;
   4069                   int d = *sp & 0x03;
   4070 
   4071                   *sp = (png_byte)(
   4072                       ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
   4073                       ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
   4074                       ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
   4075                       ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
   4076                   sp++;
   4077                }
   4078             }
   4079 
   4080             if (row_info->bit_depth == 4)
   4081             {
   4082                sp = row;
   4083                for (i = 0; i < row_width; i += 2)
   4084                {
   4085                   int msb = *sp & 0xf0;
   4086                   int lsb = *sp & 0x0f;
   4087 
   4088                   *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
   4089                       | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
   4090                   sp++;
   4091                }
   4092             }
   4093 
   4094             else if (row_info->bit_depth == 8)
   4095             {
   4096                sp = row;
   4097                for (i = 0; i < row_width; i++)
   4098                {
   4099                   *sp = gamma_table[*sp];
   4100                   sp++;
   4101                }
   4102             }
   4103 
   4104             else if (row_info->bit_depth == 16)
   4105             {
   4106                sp = row;
   4107                for (i = 0; i < row_width; i++)
   4108                {
   4109                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
   4110                   *sp = (png_byte)((v >> 8) & 0xff);
   4111                   *(sp + 1) = (png_byte)(v & 0xff);
   4112                   sp += 2;
   4113                }
   4114             }
   4115             break;
   4116          }
   4117 
   4118          default:
   4119             break;
   4120       }
   4121    }
   4122 }
   4123 #endif
   4124 
   4125 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   4126 /* Encode the alpha channel to the output gamma (the input channel is always
   4127  * linear.)  Called only with color types that have an alpha channel.  Needs the
   4128  * from_1 tables.
   4129  */
   4130 static void
   4131 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
   4132 {
   4133    png_uint_32 row_width = row_info->width;
   4134 
   4135    png_debug(1, "in png_do_encode_alpha");
   4136 
   4137    if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
   4138    {
   4139       if (row_info->bit_depth == 8)
   4140       {
   4141          PNG_CONST png_bytep table = png_ptr->gamma_from_1;
   4142 
   4143          if (table != NULL)
   4144          {
   4145             PNG_CONST int step =
   4146                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
   4147 
   4148             /* The alpha channel is the last component: */
   4149             row += step - 1;
   4150 
   4151             for (; row_width > 0; --row_width, row += step)
   4152                *row = table[*row];
   4153 
   4154             return;
   4155          }
   4156       }
   4157 
   4158       else if (row_info->bit_depth == 16)
   4159       {
   4160          PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
   4161          PNG_CONST int gamma_shift = png_ptr->gamma_shift;
   4162 
   4163          if (table != NULL)
   4164          {
   4165             PNG_CONST int step =
   4166                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
   4167 
   4168             /* The alpha channel is the last component: */
   4169             row += step - 2;
   4170 
   4171             for (; row_width > 0; --row_width, row += step)
   4172             {
   4173                png_uint_16 v;
   4174 
   4175                v = table[*(row + 1) >> gamma_shift][*row];
   4176                *row = (png_byte)((v >> 8) & 0xff);
   4177                *(row + 1) = (png_byte)(v & 0xff);
   4178             }
   4179 
   4180             return;
   4181          }
   4182       }
   4183    }
   4184 
   4185    /* Only get to here if called with a weird row_info; no harm has been done,
   4186     * so just issue a warning.
   4187     */
   4188    png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
   4189 }
   4190 #endif
   4191 
   4192 #ifdef PNG_READ_EXPAND_SUPPORTED
   4193 /* Expands a palette row to an RGB or RGBA row depending
   4194  * upon whether you supply trans and num_trans.
   4195  */
   4196 static void
   4197 png_do_expand_palette(png_row_infop row_info, png_bytep row,
   4198     png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
   4199 {
   4200    int shift, value;
   4201    png_bytep sp, dp;
   4202    png_uint_32 i;
   4203    png_uint_32 row_width=row_info->width;
   4204 
   4205    png_debug(1, "in png_do_expand_palette");
   4206 
   4207    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
   4208    {
   4209       if (row_info->bit_depth < 8)
   4210       {
   4211          switch (row_info->bit_depth)
   4212          {
   4213             case 1:
   4214             {
   4215                sp = row + (png_size_t)((row_width - 1) >> 3);
   4216                dp = row + (png_size_t)row_width - 1;
   4217                shift = 7 - (int)((row_width + 7) & 0x07);
   4218                for (i = 0; i < row_width; i++)
   4219                {
   4220                   if ((*sp >> shift) & 0x01)
   4221                      *dp = 1;
   4222 
   4223                   else
   4224                      *dp = 0;
   4225 
   4226                   if (shift == 7)
   4227                   {
   4228                      shift = 0;
   4229                      sp--;
   4230                   }
   4231 
   4232                   else
   4233                      shift++;
   4234 
   4235                   dp--;
   4236                }
   4237                break;
   4238             }
   4239 
   4240             case 2:
   4241             {
   4242                sp = row + (png_size_t)((row_width - 1) >> 2);
   4243                dp = row + (png_size_t)row_width - 1;
   4244                shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   4245                for (i = 0; i < row_width; i++)
   4246                {
   4247                   value = (*sp >> shift) & 0x03;
   4248                   *dp = (png_byte)value;
   4249                   if (shift == 6)
   4250                   {
   4251                      shift = 0;
   4252                      sp--;
   4253                   }
   4254 
   4255                   else
   4256                      shift += 2;
   4257 
   4258                   dp--;
   4259                }
   4260                break;
   4261             }
   4262 
   4263             case 4:
   4264             {
   4265                sp = row + (png_size_t)((row_width - 1) >> 1);
   4266                dp = row + (png_size_t)row_width - 1;
   4267                shift = (int)((row_width & 0x01) << 2);
   4268                for (i = 0; i < row_width; i++)
   4269                {
   4270                   value = (*sp >> shift) & 0x0f;
   4271                   *dp = (png_byte)value;
   4272                   if (shift == 4)
   4273                   {
   4274                      shift = 0;
   4275                      sp--;
   4276                   }
   4277 
   4278                   else
   4279                      shift += 4;
   4280 
   4281                   dp--;
   4282                }
   4283                break;
   4284             }
   4285 
   4286             default:
   4287                break;
   4288          }
   4289          row_info->bit_depth = 8;
   4290          row_info->pixel_depth = 8;
   4291          row_info->rowbytes = row_width;
   4292       }
   4293 
   4294       if (row_info->bit_depth == 8)
   4295       {
   4296          {
   4297             if (num_trans > 0)
   4298             {
   4299                sp = row + (png_size_t)row_width - 1;
   4300                dp = row + (png_size_t)(row_width << 2) - 1;
   4301 
   4302                for (i = 0; i < row_width; i++)
   4303                {
   4304                   if ((int)(*sp) >= num_trans)
   4305                      *dp-- = 0xff;
   4306 
   4307                   else
   4308                      *dp-- = trans_alpha[*sp];
   4309 
   4310                   *dp-- = palette[*sp].blue;
   4311                   *dp-- = palette[*sp].green;
   4312                   *dp-- = palette[*sp].red;
   4313                   sp--;
   4314                }
   4315                row_info->bit_depth = 8;
   4316                row_info->pixel_depth = 32;
   4317                row_info->rowbytes = row_width * 4;
   4318                row_info->color_type = 6;
   4319                row_info->channels = 4;
   4320             }
   4321 
   4322             else
   4323             {
   4324                sp = row + (png_size_t)row_width - 1;
   4325                dp = row + (png_size_t)(row_width * 3) - 1;
   4326 
   4327                for (i = 0; i < row_width; i++)
   4328                {
   4329                   *dp-- = palette[*sp].blue;
   4330                   *dp-- = palette[*sp].green;
   4331                   *dp-- = palette[*sp].red;
   4332                   sp--;
   4333                }
   4334 
   4335                row_info->bit_depth = 8;
   4336                row_info->pixel_depth = 24;
   4337                row_info->rowbytes = row_width * 3;
   4338                row_info->color_type = 2;
   4339                row_info->channels = 3;
   4340             }
   4341          }
   4342       }
   4343    }
   4344 }
   4345 
   4346 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
   4347  * expanded transparency value is supplied, an alpha channel is built.
   4348  */
   4349 static void
   4350 png_do_expand(png_row_infop row_info, png_bytep row,
   4351     png_const_color_16p trans_color)
   4352 {
   4353    int shift, value;
   4354    png_bytep sp, dp;
   4355    png_uint_32 i;
   4356    png_uint_32 row_width=row_info->width;
   4357 
   4358    png_debug(1, "in png_do_expand");
   4359 
   4360    {
   4361       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
   4362       {
   4363          unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
   4364 
   4365          if (row_info->bit_depth < 8)
   4366          {
   4367             switch (row_info->bit_depth)
   4368             {
   4369                case 1:
   4370                {
   4371                   gray = (gray & 0x01) * 0xff;
   4372                   sp = row + (png_size_t)((row_width - 1) >> 3);
   4373                   dp = row + (png_size_t)row_width - 1;
   4374                   shift = 7 - (int)((row_width + 7) & 0x07);
   4375                   for (i = 0; i < row_width; i++)
   4376                   {
   4377                      if ((*sp >> shift) & 0x01)
   4378                         *dp = 0xff;
   4379 
   4380                      else
   4381                         *dp = 0;
   4382 
   4383                      if (shift == 7)
   4384                      {
   4385                         shift = 0;
   4386                         sp--;
   4387                      }
   4388 
   4389                      else
   4390                         shift++;
   4391 
   4392                      dp--;
   4393                   }
   4394                   break;
   4395                }
   4396 
   4397                case 2:
   4398                {
   4399                   gray = (gray & 0x03) * 0x55;
   4400                   sp = row + (png_size_t)((row_width - 1) >> 2);
   4401                   dp = row + (png_size_t)row_width - 1;
   4402                   shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
   4403                   for (i = 0; i < row_width; i++)
   4404                   {
   4405                      value = (*sp >> shift) & 0x03;
   4406                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
   4407                         (value << 6));
   4408                      if (shift == 6)
   4409                      {
   4410                         shift = 0;
   4411                         sp--;
   4412                      }
   4413 
   4414                      else
   4415                         shift += 2;
   4416 
   4417                      dp--;
   4418                   }
   4419                   break;
   4420                }
   4421 
   4422                case 4:
   4423                {
   4424                   gray = (gray & 0x0f) * 0x11;
   4425                   sp = row + (png_size_t)((row_width - 1) >> 1);
   4426                   dp = row + (png_size_t)row_width - 1;
   4427                   shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
   4428                   for (i = 0; i < row_width; i++)
   4429                   {
   4430                      value = (*sp >> shift) & 0x0f;
   4431                      *dp = (png_byte)(value | (value << 4));
   4432                      if (shift == 4)
   4433                      {
   4434                         shift = 0;
   4435                         sp--;
   4436                      }
   4437 
   4438                      else
   4439                         shift = 4;
   4440 
   4441                      dp--;
   4442                   }
   4443                   break;
   4444                }
   4445 
   4446                default:
   4447                   break;
   4448             }
   4449 
   4450             row_info->bit_depth = 8;
   4451             row_info->pixel_depth = 8;
   4452             row_info->rowbytes = row_width;
   4453          }
   4454 
   4455          if (trans_color != NULL)
   4456          {
   4457             if (row_info->bit_depth == 8)
   4458             {
   4459                gray = gray & 0xff;
   4460                sp = row + (png_size_t)row_width - 1;
   4461                dp = row + (png_size_t)(row_width << 1) - 1;
   4462 
   4463                for (i = 0; i < row_width; i++)
   4464                {
   4465                   if ((*sp & 0xffU) == gray)
   4466                      *dp-- = 0;
   4467 
   4468                   else
   4469                      *dp-- = 0xff;
   4470 
   4471                   *dp-- = *sp--;
   4472                }
   4473             }
   4474 
   4475             else if (row_info->bit_depth == 16)
   4476             {
   4477                unsigned int gray_high = (gray >> 8) & 0xff;
   4478                unsigned int gray_low = gray & 0xff;
   4479                sp = row + row_info->rowbytes - 1;
   4480                dp = row + (row_info->rowbytes << 1) - 1;
   4481                for (i = 0; i < row_width; i++)
   4482                {
   4483                   if ((*(sp - 1) & 0xffU) == gray_high &&
   4484                       (*(sp) & 0xffU) == gray_low)
   4485                   {
   4486                      *dp-- = 0;
   4487                      *dp-- = 0;
   4488                   }
   4489 
   4490                   else
   4491                   {
   4492                      *dp-- = 0xff;
   4493                      *dp-- = 0xff;
   4494                   }
   4495 
   4496                   *dp-- = *sp--;
   4497                   *dp-- = *sp--;
   4498                }
   4499             }
   4500 
   4501             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
   4502             row_info->channels = 2;
   4503             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
   4504             row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
   4505                 row_width);
   4506          }
   4507       }
   4508       else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
   4509           trans_color != NULL)
   4510       {
   4511          if (row_info->bit_depth == 8)
   4512          {
   4513             png_byte red = (png_byte)(trans_color->red & 0xff);
   4514             png_byte green = (png_byte)(trans_color->green & 0xff);
   4515             png_byte blue = (png_byte)(trans_color->blue & 0xff);
   4516             sp = row + (png_size_t)row_info->rowbytes - 1;
   4517             dp = row + (png_size_t)(row_width << 2) - 1;
   4518             for (i = 0; i < row_width; i++)
   4519             {
   4520                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
   4521                   *dp-- = 0;
   4522 
   4523                else
   4524                   *dp-- = 0xff;
   4525 
   4526                *dp-- = *sp--;
   4527                *dp-- = *sp--;
   4528                *dp-- = *sp--;
   4529             }
   4530          }
   4531          else if (row_info->bit_depth == 16)
   4532          {
   4533             png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
   4534             png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
   4535             png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
   4536             png_byte red_low = (png_byte)(trans_color->red & 0xff);
   4537             png_byte green_low = (png_byte)(trans_color->green & 0xff);
   4538             png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
   4539             sp = row + row_info->rowbytes - 1;
   4540             dp = row + (png_size_t)(row_width << 3) - 1;
   4541             for (i = 0; i < row_width; i++)
   4542             {
   4543                if (*(sp - 5) == red_high &&
   4544                    *(sp - 4) == red_low &&
   4545                    *(sp - 3) == green_high &&
   4546                    *(sp - 2) == green_low &&
   4547                    *(sp - 1) == blue_high &&
   4548                    *(sp    ) == blue_low)
   4549                {
   4550                   *dp-- = 0;
   4551                   *dp-- = 0;
   4552                }
   4553 
   4554                else
   4555                {
   4556                   *dp-- = 0xff;
   4557                   *dp-- = 0xff;
   4558                }
   4559 
   4560                *dp-- = *sp--;
   4561                *dp-- = *sp--;
   4562                *dp-- = *sp--;
   4563                *dp-- = *sp--;
   4564                *dp-- = *sp--;
   4565                *dp-- = *sp--;
   4566             }
   4567          }
   4568          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
   4569          row_info->channels = 4;
   4570          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
   4571          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   4572       }
   4573    }
   4574 }
   4575 #endif
   4576 
   4577 #ifdef PNG_READ_EXPAND_16_SUPPORTED
   4578 /* If the bit depth is 8 and the color type is not a palette type expand the
   4579  * whole row to 16 bits.  Has no effect otherwise.
   4580  */
   4581 static void
   4582 png_do_expand_16(png_row_infop row_info, png_bytep row)
   4583 {
   4584    if (row_info->bit_depth == 8 &&
   4585       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
   4586    {
   4587       /* The row have a sequence of bytes containing [0..255] and we need
   4588        * to turn it into another row containing [0..65535], to do this we
   4589        * calculate:
   4590        *
   4591        *  (input / 255) * 65535
   4592        *
   4593        *  Which happens to be exactly input * 257 and this can be achieved
   4594        *  simply by byte replication in place (copying backwards).
   4595        */
   4596       png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
   4597       png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
   4598       while (dp > sp)
   4599          dp[-2] = dp[-1] = *--sp, dp -= 2;
   4600 
   4601       row_info->rowbytes *= 2;
   4602       row_info->bit_depth = 16;
   4603       row_info->pixel_depth = (png_byte)(row_info->channels * 16);
   4604    }
   4605 }
   4606 #endif
   4607 
   4608 #ifdef PNG_READ_QUANTIZE_SUPPORTED
   4609 static void
   4610 png_do_quantize(png_row_infop row_info, png_bytep row,
   4611     png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
   4612 {
   4613    png_bytep sp, dp;
   4614    png_uint_32 i;
   4615    png_uint_32 row_width=row_info->width;
   4616 
   4617    png_debug(1, "in png_do_quantize");
   4618 
   4619    if (row_info->bit_depth == 8)
   4620    {
   4621       if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
   4622       {
   4623          int r, g, b, p;
   4624          sp = row;
   4625          dp = row;
   4626          for (i = 0; i < row_width; i++)
   4627          {
   4628             r = *sp++;
   4629             g = *sp++;
   4630             b = *sp++;
   4631 
   4632             /* This looks real messy, but the compiler will reduce
   4633              * it down to a reasonable formula.  For example, with
   4634              * 5 bits per color, we get:
   4635              * p = (((r >> 3) & 0x1f) << 10) |
   4636              *    (((g >> 3) & 0x1f) << 5) |
   4637              *    ((b >> 3) & 0x1f);
   4638              */
   4639             p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
   4640                 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
   4641                 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
   4642                 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
   4643                 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
   4644                 (PNG_QUANTIZE_BLUE_BITS)) |
   4645                 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
   4646                 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
   4647 
   4648             *dp++ = palette_lookup[p];
   4649          }
   4650 
   4651          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
   4652          row_info->channels = 1;
   4653          row_info->pixel_depth = row_info->bit_depth;
   4654          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   4655       }
   4656 
   4657       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
   4658          palette_lookup != NULL)
   4659       {
   4660          int r, g, b, p;
   4661          sp = row;
   4662          dp = row;
   4663          for (i = 0; i < row_width; i++)
   4664          {
   4665             r = *sp++;
   4666             g = *sp++;
   4667             b = *sp++;
   4668             sp++;
   4669 
   4670             p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
   4671                 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
   4672                 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
   4673                 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
   4674                 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
   4675                 (PNG_QUANTIZE_BLUE_BITS)) |
   4676                 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
   4677                 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
   4678 
   4679             *dp++ = palette_lookup[p];
   4680          }
   4681 
   4682          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
   4683          row_info->channels = 1;
   4684          row_info->pixel_depth = row_info->bit_depth;
   4685          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
   4686       }
   4687 
   4688       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
   4689          quantize_lookup)
   4690       {
   4691          sp = row;
   4692 
   4693          for (i = 0; i < row_width; i++, sp++)
   4694          {
   4695             *sp = quantize_lookup[*sp];
   4696          }
   4697       }
   4698    }
   4699 }
   4700 #endif /* READ_QUANTIZE */
   4701 
   4702 /* Transform the row.  The order of transformations is significant,
   4703  * and is very touchy.  If you add a transformation, take care to
   4704  * decide how it fits in with the other transformations here.
   4705  */
   4706 void /* PRIVATE */
   4707 png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
   4708 {
   4709    png_debug(1, "in png_do_read_transformations");
   4710 
   4711    if (png_ptr->row_buf == NULL)
   4712    {
   4713       /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
   4714        * error is incredibly rare and incredibly easy to debug without this
   4715        * information.
   4716        */
   4717       png_error(png_ptr, "NULL row buffer");
   4718    }
   4719 
   4720    /* The following is debugging; prior to 1.5.4 the code was never compiled in;
   4721     * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
   4722     * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
   4723     * all transformations, however in practice the ROW_INIT always gets done on
   4724     * demand, if necessary.
   4725     */
   4726    if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
   4727        (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
   4728    {
   4729       /* Application has failed to call either png_read_start_image() or
   4730        * png_read_update_info() after setting transforms that expand pixels.
   4731        * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
   4732        */
   4733       png_error(png_ptr, "Uninitialized row");
   4734    }
   4735 
   4736 #ifdef PNG_READ_EXPAND_SUPPORTED
   4737    if ((png_ptr->transformations & PNG_EXPAND) != 0)
   4738    {
   4739       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
   4740       {
   4741          png_do_expand_palette(row_info, png_ptr->row_buf + 1,
   4742              png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
   4743       }
   4744 
   4745       else
   4746       {
   4747          if (png_ptr->num_trans != 0 &&
   4748              (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
   4749             png_do_expand(row_info, png_ptr->row_buf + 1,
   4750                 &(png_ptr->trans_color));
   4751 
   4752          else
   4753             png_do_expand(row_info, png_ptr->row_buf + 1,
   4754                 NULL);
   4755       }
   4756    }
   4757 #endif
   4758 
   4759 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   4760    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
   4761        (png_ptr->transformations & PNG_COMPOSE) == 0 &&
   4762        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
   4763        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
   4764       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
   4765           0 /* at_start == false, because SWAP_ALPHA happens later */);
   4766 #endif
   4767 
   4768 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   4769    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
   4770    {
   4771       int rgb_error =
   4772           png_do_rgb_to_gray(png_ptr, row_info,
   4773               png_ptr->row_buf + 1);
   4774 
   4775       if (rgb_error != 0)
   4776       {
   4777          png_ptr->rgb_to_gray_status=1;
   4778          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
   4779              PNG_RGB_TO_GRAY_WARN)
   4780             png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
   4781 
   4782          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
   4783              PNG_RGB_TO_GRAY_ERR)
   4784             png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
   4785       }
   4786    }
   4787 #endif
   4788 
   4789 /* From Andreas Dilger e-mail to png-implement, 26 March 1998:
   4790  *
   4791  *   In most cases, the "simple transparency" should be done prior to doing
   4792  *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
   4793  *   pixel is transparent.  You would also need to make sure that the
   4794  *   transparency information is upgraded to RGB.
   4795  *
   4796  *   To summarize, the current flow is:
   4797  *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
   4798  *                                   with background "in place" if transparent,
   4799  *                                   convert to RGB if necessary
   4800  *   - Gray + alpha -> composite with gray background and remove alpha bytes,
   4801  *                                   convert to RGB if necessary
   4802  *
   4803  *   To support RGB backgrounds for gray images we need:
   4804  *   - Gray + simple transparency -> convert to RGB + simple transparency,
   4805  *                                   compare 3 or 6 bytes and composite with
   4806  *                                   background "in place" if transparent
   4807  *                                   (3x compare/pixel compared to doing
   4808  *                                   composite with gray bkgrnd)
   4809  *   - Gray + alpha -> convert to RGB + alpha, composite with background and
   4810  *                                   remove alpha bytes (3x float
   4811  *                                   operations/pixel compared with composite
   4812  *                                   on gray background)
   4813  *
   4814  *  Greg's change will do this.  The reason it wasn't done before is for
   4815  *  performance, as this increases the per-pixel operations.  If we would check
   4816  *  in advance if the background was gray or RGB, and position the gray-to-RGB
   4817  *  transform appropriately, then it would save a lot of work/time.
   4818  */
   4819 
   4820 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   4821    /* If gray -> RGB, do so now only if background is non-gray; else do later
   4822     * for performance reasons
   4823     */
   4824    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
   4825        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
   4826       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
   4827 #endif
   4828 
   4829 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
   4830    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
   4831    if ((png_ptr->transformations & PNG_COMPOSE) != 0)
   4832       png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
   4833 #endif
   4834 
   4835 #ifdef PNG_READ_GAMMA_SUPPORTED
   4836    if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
   4837 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   4838       /* Because RGB_TO_GRAY does the gamma transform. */
   4839       (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
   4840 #endif
   4841 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
   4842    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
   4843       /* Because PNG_COMPOSE does the gamma transform if there is something to
   4844        * do (if there is an alpha channel or transparency.)
   4845        */
   4846        !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
   4847        ((png_ptr->num_trans != 0) ||
   4848        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
   4849 #endif
   4850       /* Because png_init_read_transformations transforms the palette, unless
   4851        * RGB_TO_GRAY will do the transform.
   4852        */
   4853        (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
   4854       png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
   4855 #endif
   4856 
   4857 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   4858    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
   4859        (png_ptr->transformations & PNG_COMPOSE) != 0 &&
   4860        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
   4861        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
   4862       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
   4863           0 /* at_start == false, because SWAP_ALPHA happens later */);
   4864 #endif
   4865 
   4866 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   4867    if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
   4868        (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
   4869       png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
   4870 #endif
   4871 
   4872 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
   4873    if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
   4874       png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
   4875 #endif
   4876 
   4877 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
   4878    /* There is no harm in doing both of these because only one has any effect,
   4879     * by putting the 'scale' option first if the app asks for scale (either by
   4880     * calling the API or in a TRANSFORM flag) this is what happens.
   4881     */
   4882    if ((png_ptr->transformations & PNG_16_TO_8) != 0)
   4883       png_do_chop(row_info, png_ptr->row_buf + 1);
   4884 #endif
   4885 
   4886 #ifdef PNG_READ_QUANTIZE_SUPPORTED
   4887    if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
   4888    {
   4889       png_do_quantize(row_info, png_ptr->row_buf + 1,
   4890           png_ptr->palette_lookup, png_ptr->quantize_index);
   4891 
   4892       if (row_info->rowbytes == 0)
   4893          png_error(png_ptr, "png_do_quantize returned rowbytes=0");
   4894    }
   4895 #endif /* READ_QUANTIZE */
   4896 
   4897 #ifdef PNG_READ_EXPAND_16_SUPPORTED
   4898    /* Do the expansion now, after all the arithmetic has been done.  Notice
   4899     * that previous transformations can handle the PNG_EXPAND_16 flag if this
   4900     * is efficient (particularly true in the case of gamma correction, where
   4901     * better accuracy results faster!)
   4902     */
   4903    if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
   4904       png_do_expand_16(row_info, png_ptr->row_buf + 1);
   4905 #endif
   4906 
   4907 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   4908    /* NOTE: moved here in 1.5.4 (from much later in this list.) */
   4909    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
   4910        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
   4911       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
   4912 #endif
   4913 
   4914 #ifdef PNG_READ_INVERT_SUPPORTED
   4915    if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
   4916       png_do_invert(row_info, png_ptr->row_buf + 1);
   4917 #endif
   4918 
   4919 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   4920    if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
   4921       png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
   4922 #endif
   4923 
   4924 #ifdef PNG_READ_SHIFT_SUPPORTED
   4925    if ((png_ptr->transformations & PNG_SHIFT) != 0)
   4926       png_do_unshift(row_info, png_ptr->row_buf + 1,
   4927           &(png_ptr->shift));
   4928 #endif
   4929 
   4930 #ifdef PNG_READ_PACK_SUPPORTED
   4931    if ((png_ptr->transformations & PNG_PACK) != 0)
   4932       png_do_unpack(row_info, png_ptr->row_buf + 1);
   4933 #endif
   4934 
   4935 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
   4936    /* Added at libpng-1.5.10 */
   4937    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
   4938        png_ptr->num_palette_max >= 0)
   4939       png_do_check_palette_indexes(png_ptr, row_info);
   4940 #endif
   4941 
   4942 #ifdef PNG_READ_BGR_SUPPORTED
   4943    if ((png_ptr->transformations & PNG_BGR) != 0)
   4944       png_do_bgr(row_info, png_ptr->row_buf + 1);
   4945 #endif
   4946 
   4947 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   4948    if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
   4949       png_do_packswap(row_info, png_ptr->row_buf + 1);
   4950 #endif
   4951 
   4952 #ifdef PNG_READ_FILLER_SUPPORTED
   4953    if ((png_ptr->transformations & PNG_FILLER) != 0)
   4954       png_do_read_filler(row_info, png_ptr->row_buf + 1,
   4955           (png_uint_32)png_ptr->filler, png_ptr->flags);
   4956 #endif
   4957 
   4958 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   4959    if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
   4960       png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
   4961 #endif
   4962 
   4963 #ifdef PNG_READ_16BIT_SUPPORTED
   4964 #ifdef PNG_READ_SWAP_SUPPORTED
   4965    if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
   4966       png_do_swap(row_info, png_ptr->row_buf + 1);
   4967 #endif
   4968 #endif
   4969 
   4970 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
   4971    if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
   4972    {
   4973       if (png_ptr->read_user_transform_fn != NULL)
   4974          (*(png_ptr->read_user_transform_fn)) /* User read transform function */
   4975              (png_ptr,     /* png_ptr */
   4976              row_info,     /* row_info: */
   4977                 /*  png_uint_32 width;       width of row */
   4978                 /*  png_size_t rowbytes;     number of bytes in row */
   4979                 /*  png_byte color_type;     color type of pixels */
   4980                 /*  png_byte bit_depth;      bit depth of samples */
   4981                 /*  png_byte channels;       number of channels (1-4) */
   4982                 /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
   4983              png_ptr->row_buf + 1);    /* start of pixel data for row */
   4984 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
   4985       if (png_ptr->user_transform_depth != 0)
   4986          row_info->bit_depth = png_ptr->user_transform_depth;
   4987 
   4988       if (png_ptr->user_transform_channels != 0)
   4989          row_info->channels = png_ptr->user_transform_channels;
   4990 #endif
   4991       row_info->pixel_depth = (png_byte)(row_info->bit_depth *
   4992           row_info->channels);
   4993 
   4994       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
   4995    }
   4996 #endif
   4997 }
   4998 
   4999 #endif /* READ_TRANSFORMS */
   5000 #endif /* READ */
   5001