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