Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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