tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pngrtran.c (171613B)


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