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