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