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