LCOV - code coverage report
Current view: top level - media/libpng - pngrtran.c (source / functions) Hit Total Coverage
Test: output.info Lines: 167 583 28.6 %
Date: 2017-07-14 16:53:18 Functions: 17 23 73.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13