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