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.33 [September 28, 2017]
  33  * Copyright (c) 1998-2002,2004,2006-2017 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 accomodate 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       png_size_t num_entries = ((png_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 undesireable 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 meaninful 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 + (png_size_t)((row_width - 1) >> 3);
2183             png_bytep dp = row + (png_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 + (png_size_t)((row_width - 1) >> 2);
2207             png_bytep dp = row + (png_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 + (png_size_t)((row_width - 1) >> 1);
2230             png_bytep dp = row + (png_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_debug(1, "in png_do_read_swap_alpha");
2495 
2496    {
2497       png_uint_32 row_width = row_info->width;
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 }
2585 #endif
2586 
2587 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
2588 static void
2589 png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
2590 {
2591    png_uint_32 row_width;
2592    png_debug(1, "in png_do_read_invert_alpha");
2593 
2594    row_width = row_info->width;
2595    if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2596    {
2597       if (row_info->bit_depth == 8)
2598       {
2599          /* This inverts the alpha channel in RGBA */
2600          png_bytep sp = row + row_info->rowbytes;
2601          png_bytep dp = sp;
2602          png_uint_32 i;
2603 
2604          for (i = 0; i < row_width; i++)
2605          {
2606             *(--dp) = (png_byte)(255 - *(--sp));
2607 
2608 /*          This does nothing:
2609             *(--dp) = *(--sp);
2610             *(--dp) = *(--sp);
2611             *(--dp) = *(--sp);
2612             We can replace it with:
2613 */
2614             sp-=3;
2615             dp=sp;
2616          }
2617       }
2618 
2619 #ifdef PNG_READ_16BIT_SUPPORTED
2620       /* This inverts the alpha channel in RRGGBBAA */
2621       else
2622       {
2623          png_bytep sp = row + row_info->rowbytes;
2624          png_bytep dp = sp;
2625          png_uint_32 i;
2626 
2627          for (i = 0; i < row_width; i++)
2628          {
2629             *(--dp) = (png_byte)(255 - *(--sp));
2630             *(--dp) = (png_byte)(255 - *(--sp));
2631 
2632 /*          This does nothing:
2633             *(--dp) = *(--sp);
2634             *(--dp) = *(--sp);
2635             *(--dp) = *(--sp);
2636             *(--dp) = *(--sp);
2637             *(--dp) = *(--sp);
2638             *(--dp) = *(--sp);
2639             We can replace it with:
2640 */
2641             sp-=6;
2642             dp=sp;
2643          }
2644       }
2645 #endif
2646    }
2647    else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2648    {
2649       if (row_info->bit_depth == 8)
2650       {
2651          /* This inverts the alpha channel in GA */
2652          png_bytep sp = row + row_info->rowbytes;
2653          png_bytep dp = sp;
2654          png_uint_32 i;
2655 
2656          for (i = 0; i < row_width; i++)
2657          {
2658             *(--dp) = (png_byte)(255 - *(--sp));
2659             *(--dp) = *(--sp);
2660          }
2661       }
2662 
2663 #ifdef PNG_READ_16BIT_SUPPORTED
2664       else
2665       {
2666          /* This inverts the alpha channel in GGAA */
2667          png_bytep sp  = row + row_info->rowbytes;
2668          png_bytep dp = sp;
2669          png_uint_32 i;
2670 
2671          for (i = 0; i < row_width; i++)
2672          {
2673             *(--dp) = (png_byte)(255 - *(--sp));
2674             *(--dp) = (png_byte)(255 - *(--sp));
2675 /*
2676             *(--dp) = *(--sp);
2677             *(--dp) = *(--sp);
2678 */
2679             sp-=2;
2680             dp=sp;
2681          }
2682       }
2683 #endif
2684    }
2685 }
2686 #endif
2687 
2688 #ifdef PNG_READ_FILLER_SUPPORTED
2689 /* Add filler channel if we have RGB color */
2690 static void
2691 png_do_read_filler(png_row_infop row_info, png_bytep row,
2692     png_uint_32 filler, png_uint_32 flags)
2693 {
2694    png_uint_32 i;
2695    png_uint_32 row_width = row_info->width;
2696 
2697 #ifdef PNG_READ_16BIT_SUPPORTED
2698    png_byte hi_filler = (png_byte)(filler>>8);
2699 #endif
2700    png_byte lo_filler = (png_byte)filler;
2701 
2702    png_debug(1, "in png_do_read_filler");
2703 
2704    if (
2705        row_info->color_type == PNG_COLOR_TYPE_GRAY)
2706    {
2707       if (row_info->bit_depth == 8)
2708       {
2709          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2710          {
2711             /* This changes the data from G to GX */
2712             png_bytep sp = row + (png_size_t)row_width;
2713             png_bytep dp =  sp + (png_size_t)row_width;
2714             for (i = 1; i < row_width; i++)
2715             {
2716                *(--dp) = lo_filler;
2717                *(--dp) = *(--sp);
2718             }
2719             *(--dp) = lo_filler;
2720             row_info->channels = 2;
2721             row_info->pixel_depth = 16;
2722             row_info->rowbytes = row_width * 2;
2723          }
2724 
2725          else
2726          {
2727             /* This changes the data from G to XG */
2728             png_bytep sp = row + (png_size_t)row_width;
2729             png_bytep dp = sp  + (png_size_t)row_width;
2730             for (i = 0; i < row_width; i++)
2731             {
2732                *(--dp) = *(--sp);
2733                *(--dp) = lo_filler;
2734             }
2735             row_info->channels = 2;
2736             row_info->pixel_depth = 16;
2737             row_info->rowbytes = row_width * 2;
2738          }
2739       }
2740 
2741 #ifdef PNG_READ_16BIT_SUPPORTED
2742       else if (row_info->bit_depth == 16)
2743       {
2744          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2745          {
2746             /* This changes the data from GG to GGXX */
2747             png_bytep sp = row + (png_size_t)row_width * 2;
2748             png_bytep dp = sp  + (png_size_t)row_width * 2;
2749             for (i = 1; i < row_width; i++)
2750             {
2751                *(--dp) = lo_filler;
2752                *(--dp) = hi_filler;
2753                *(--dp) = *(--sp);
2754                *(--dp) = *(--sp);
2755             }
2756             *(--dp) = lo_filler;
2757             *(--dp) = hi_filler;
2758             row_info->channels = 2;
2759             row_info->pixel_depth = 32;
2760             row_info->rowbytes = row_width * 4;
2761          }
2762 
2763          else
2764          {
2765             /* This changes the data from GG to XXGG */
2766             png_bytep sp = row + (png_size_t)row_width * 2;
2767             png_bytep dp = sp  + (png_size_t)row_width * 2;
2768             for (i = 0; i < row_width; i++)
2769             {
2770                *(--dp) = *(--sp);
2771                *(--dp) = *(--sp);
2772                *(--dp) = lo_filler;
2773                *(--dp) = hi_filler;
2774             }
2775             row_info->channels = 2;
2776             row_info->pixel_depth = 32;
2777             row_info->rowbytes = row_width * 4;
2778          }
2779       }
2780 #endif
2781    } /* COLOR_TYPE == GRAY */
2782    else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
2783    {
2784       if (row_info->bit_depth == 8)
2785       {
2786          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2787          {
2788             /* This changes the data from RGB to RGBX */
2789             png_bytep sp = row + (png_size_t)row_width * 3;
2790             png_bytep dp = sp  + (png_size_t)row_width;
2791             for (i = 1; i < row_width; i++)
2792             {
2793                *(--dp) = lo_filler;
2794                *(--dp) = *(--sp);
2795                *(--dp) = *(--sp);
2796                *(--dp) = *(--sp);
2797             }
2798             *(--dp) = lo_filler;
2799             row_info->channels = 4;
2800             row_info->pixel_depth = 32;
2801             row_info->rowbytes = row_width * 4;
2802          }
2803 
2804          else
2805          {
2806             /* This changes the data from RGB to XRGB */
2807             png_bytep sp = row + (png_size_t)row_width * 3;
2808             png_bytep dp = sp + (png_size_t)row_width;
2809             for (i = 0; i < row_width; i++)
2810             {
2811                *(--dp) = *(--sp);
2812                *(--dp) = *(--sp);
2813                *(--dp) = *(--sp);
2814                *(--dp) = lo_filler;
2815             }
2816             row_info->channels = 4;
2817             row_info->pixel_depth = 32;
2818             row_info->rowbytes = row_width * 4;
2819          }
2820       }
2821 
2822 #ifdef PNG_READ_16BIT_SUPPORTED
2823       else if (row_info->bit_depth == 16)
2824       {
2825          if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
2826          {
2827             /* This changes the data from RRGGBB to RRGGBBXX */
2828             png_bytep sp = row + (png_size_t)row_width * 6;
2829             png_bytep dp = sp  + (png_size_t)row_width * 2;
2830             for (i = 1; i < row_width; i++)
2831             {
2832                *(--dp) = lo_filler;
2833                *(--dp) = hi_filler;
2834                *(--dp) = *(--sp);
2835                *(--dp) = *(--sp);
2836                *(--dp) = *(--sp);
2837                *(--dp) = *(--sp);
2838                *(--dp) = *(--sp);
2839                *(--dp) = *(--sp);
2840             }
2841             *(--dp) = lo_filler;
2842             *(--dp) = hi_filler;
2843             row_info->channels = 4;
2844             row_info->pixel_depth = 64;
2845             row_info->rowbytes = row_width * 8;
2846          }
2847 
2848          else
2849          {
2850             /* This changes the data from RRGGBB to XXRRGGBB */
2851             png_bytep sp = row + (png_size_t)row_width * 6;
2852             png_bytep dp = sp  + (png_size_t)row_width * 2;
2853             for (i = 0; i < row_width; i++)
2854             {
2855                *(--dp) = *(--sp);
2856                *(--dp) = *(--sp);
2857                *(--dp) = *(--sp);
2858                *(--dp) = *(--sp);
2859                *(--dp) = *(--sp);
2860                *(--dp) = *(--sp);
2861                *(--dp) = lo_filler;
2862                *(--dp) = hi_filler;
2863             }
2864 
2865             row_info->channels = 4;
2866             row_info->pixel_depth = 64;
2867             row_info->rowbytes = row_width * 8;
2868          }
2869       }
2870 #endif
2871    } /* COLOR_TYPE == RGB */
2872 }
2873 #endif
2874 
2875 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
2876 /* Expand grayscale files to RGB, with or without alpha */
2877 static void
2878 png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
2879 {
2880    png_uint_32 i;
2881    png_uint_32 row_width = row_info->width;
2882 
2883    png_debug(1, "in png_do_gray_to_rgb");
2884 
2885    if (row_info->bit_depth >= 8 &&
2886        (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
2887    {
2888       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
2889       {
2890          if (row_info->bit_depth == 8)
2891          {
2892             /* This changes G to RGB */
2893             png_bytep sp = row + (png_size_t)row_width - 1;
2894             png_bytep dp = sp  + (png_size_t)row_width * 2;
2895             for (i = 0; i < row_width; i++)
2896             {
2897                *(dp--) = *sp;
2898                *(dp--) = *sp;
2899                *(dp--) = *(sp--);
2900             }
2901          }
2902 
2903          else
2904          {
2905             /* This changes GG to RRGGBB */
2906             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2907             png_bytep dp = sp  + (png_size_t)row_width * 4;
2908             for (i = 0; i < row_width; i++)
2909             {
2910                *(dp--) = *sp;
2911                *(dp--) = *(sp - 1);
2912                *(dp--) = *sp;
2913                *(dp--) = *(sp - 1);
2914                *(dp--) = *(sp--);
2915                *(dp--) = *(sp--);
2916             }
2917          }
2918       }
2919 
2920       else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2921       {
2922          if (row_info->bit_depth == 8)
2923          {
2924             /* This changes GA to RGBA */
2925             png_bytep sp = row + (png_size_t)row_width * 2 - 1;
2926             png_bytep dp = sp  + (png_size_t)row_width * 2;
2927             for (i = 0; i < row_width; i++)
2928             {
2929                *(dp--) = *(sp--);
2930                *(dp--) = *sp;
2931                *(dp--) = *sp;
2932                *(dp--) = *(sp--);
2933             }
2934          }
2935 
2936          else
2937          {
2938             /* This changes GGAA to RRGGBBAA */
2939             png_bytep sp = row + (png_size_t)row_width * 4 - 1;
2940             png_bytep dp = sp  + (png_size_t)row_width * 4;
2941             for (i = 0; i < row_width; i++)
2942             {
2943                *(dp--) = *(sp--);
2944                *(dp--) = *(sp--);
2945                *(dp--) = *sp;
2946                *(dp--) = *(sp - 1);
2947                *(dp--) = *sp;
2948                *(dp--) = *(sp - 1);
2949                *(dp--) = *(sp--);
2950                *(dp--) = *(sp--);
2951             }
2952          }
2953       }
2954       row_info->channels = (png_byte)(row_info->channels + 2);
2955       row_info->color_type |= PNG_COLOR_MASK_COLOR;
2956       row_info->pixel_depth = (png_byte)(row_info->channels *
2957           row_info->bit_depth);
2958       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
2959    }
2960 }
2961 #endif
2962 
2963 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2964 /* Reduce RGB files to grayscale, with or without alpha
2965  * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
2966  * <http://www.inforamp.net/~poynton/>  (THIS LINK IS DEAD June 2008 but
2967  * versions dated 1998 through November 2002 have been archived at
2968  * https://web.archive.org/web/20000816232553/www.inforamp.net/
2969  * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
2970  * Charles Poynton poynton at poynton.com
2971  *
2972  *     Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
2973  *
2974  *  which can be expressed with integers as
2975  *
2976  *     Y = (6969 * R + 23434 * G + 2365 * B)/32768
2977  *
2978  * Poynton's current link (as of January 2003 through July 2011):
2979  * <http://www.poynton.com/notes/colour_and_gamma/>
2980  * has changed the numbers slightly:
2981  *
2982  *     Y = 0.2126*R + 0.7152*G + 0.0722*B
2983  *
2984  *  which can be expressed with integers as
2985  *
2986  *     Y = (6966 * R + 23436 * G + 2366 * B)/32768
2987  *
2988  *  Historically, however, libpng uses numbers derived from the ITU-R Rec 709
2989  *  end point chromaticities and the D65 white point.  Depending on the
2990  *  precision used for the D65 white point this produces a variety of different
2991  *  numbers, however if the four decimal place value used in ITU-R Rec 709 is
2992  *  used (0.3127,0.3290) the Y calculation would be:
2993  *
2994  *     Y = (6968 * R + 23435 * G + 2366 * B)/32768
2995  *
2996  *  While this is correct the rounding results in an overflow for white, because
2997  *  the sum of the rounded coefficients is 32769, not 32768.  Consequently
2998  *  libpng uses, instead, the closest non-overflowing approximation:
2999  *
3000  *     Y = (6968 * R + 23434 * G + 2366 * B)/32768
3001  *
3002  *  Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
3003  *  (including an sRGB chunk) then the chromaticities are used to calculate the
3004  *  coefficients.  See the chunk handling in pngrutil.c for more information.
3005  *
3006  *  In all cases the calculation is to be done in a linear colorspace.  If no
3007  *  gamma information is available to correct the encoding of the original RGB
3008  *  values this results in an implicit assumption that the original PNG RGB
3009  *  values were linear.
3010  *
3011  *  Other integer coefficents can be used via png_set_rgb_to_gray().  Because
3012  *  the API takes just red and green coefficients the blue coefficient is
3013  *  calculated to make the sum 32768.  This will result in different rounding
3014  *  to that used above.
3015  */
3016 static int
3017 png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
3018 
3019 {
3020    int rgb_error = 0;
3021 
3022    png_debug(1, "in png_do_rgb_to_gray");
3023 
3024    if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
3025        (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
3026    {
3027       PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
3028       PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
3029       PNG_CONST png_uint_32 bc = 32768 - rc - gc;
3030       PNG_CONST png_uint_32 row_width = row_info->width;
3031       PNG_CONST int have_alpha =
3032          (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
3033 
3034       if (row_info->bit_depth == 8)
3035       {
3036 #ifdef PNG_READ_GAMMA_SUPPORTED
3037          /* Notice that gamma to/from 1 are not necessarily inverses (if
3038           * there is an overall gamma correction).  Prior to 1.5.5 this code
3039           * checked the linearized values for equality; this doesn't match
3040           * the documentation, the original values must be checked.
3041           */
3042          if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
3043          {
3044             png_bytep sp = row;
3045             png_bytep dp = row;
3046             png_uint_32 i;
3047 
3048             for (i = 0; i < row_width; i++)
3049             {
3050                png_byte red   = *(sp++);
3051                png_byte green = *(sp++);
3052                png_byte blue  = *(sp++);
3053 
3054                if (red != green || red != blue)
3055                {
3056                   red = png_ptr->gamma_to_1[red];
3057                   green = png_ptr->gamma_to_1[green];
3058                   blue = png_ptr->gamma_to_1[blue];
3059 
3060                   rgb_error |= 1;
3061                   *(dp++) = png_ptr->gamma_from_1[
3062                       (rc*red + gc*green + bc*blue + 16384)>>15];
3063                }
3064 
3065                else
3066                {
3067                   /* If there is no overall correction the table will not be
3068                    * set.
3069                    */
3070                   if (png_ptr->gamma_table != NULL)
3071                      red = png_ptr->gamma_table[red];
3072 
3073                   *(dp++) = red;
3074                }
3075 
3076                if (have_alpha != 0)
3077                   *(dp++) = *(sp++);
3078             }
3079          }
3080          else
3081 #endif
3082          {
3083             png_bytep sp = row;
3084             png_bytep dp = row;
3085             png_uint_32 i;
3086 
3087             for (i = 0; i < row_width; i++)
3088             {
3089                png_byte red   = *(sp++);
3090                png_byte green = *(sp++);
3091                png_byte blue  = *(sp++);
3092 
3093                if (red != green || red != blue)
3094                {
3095                   rgb_error |= 1;
3096                   /* NOTE: this is the historical approach which simply
3097                    * truncates the results.
3098                    */
3099                   *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
3100                }
3101 
3102                else
3103                   *(dp++) = red;
3104 
3105                if (have_alpha != 0)
3106                   *(dp++) = *(sp++);
3107             }
3108          }
3109       }
3110 
3111       else /* RGB bit_depth == 16 */
3112       {
3113 #ifdef PNG_READ_GAMMA_SUPPORTED
3114          if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
3115          {
3116             png_bytep sp = row;
3117             png_bytep dp = row;
3118             png_uint_32 i;
3119 
3120             for (i = 0; i < row_width; i++)
3121             {
3122                png_uint_16 red, green, blue, w;
3123                png_byte hi,lo;
3124 
3125                hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
3126                hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3127                hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
3128 
3129                if (red == green && red == blue)
3130                {
3131                   if (png_ptr->gamma_16_table != NULL)
3132                      w = png_ptr->gamma_16_table[(red & 0xff)
3133                          >> png_ptr->gamma_shift][red >> 8];
3134 
3135                   else
3136                      w = red;
3137                }
3138 
3139                else
3140                {
3141                   png_uint_16 red_1   = png_ptr->gamma_16_to_1[(red & 0xff)
3142                       >> png_ptr->gamma_shift][red>>8];
3143                   png_uint_16 green_1 =
3144                       png_ptr->gamma_16_to_1[(green & 0xff) >>
3145                       png_ptr->gamma_shift][green>>8];
3146                   png_uint_16 blue_1  = png_ptr->gamma_16_to_1[(blue & 0xff)
3147                       >> png_ptr->gamma_shift][blue>>8];
3148                   png_uint_16 gray16  = (png_uint_16)((rc*red_1 + gc*green_1
3149                       + bc*blue_1 + 16384)>>15);
3150                   w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
3151                       png_ptr->gamma_shift][gray16 >> 8];
3152                   rgb_error |= 1;
3153                }
3154 
3155                *(dp++) = (png_byte)((w>>8) & 0xff);
3156                *(dp++) = (png_byte)(w & 0xff);
3157 
3158                if (have_alpha != 0)
3159                {
3160                   *(dp++) = *(sp++);
3161                   *(dp++) = *(sp++);
3162                }
3163             }
3164          }
3165          else
3166 #endif
3167          {
3168             png_bytep sp = row;
3169             png_bytep dp = row;
3170             png_uint_32 i;
3171 
3172             for (i = 0; i < row_width; i++)
3173             {
3174                png_uint_16 red, green, blue, gray16;
3175                png_byte hi,lo;
3176 
3177                hi=*(sp)++; lo=*(sp)++; red   = (png_uint_16)((hi << 8) | (lo));
3178                hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
3179                hi=*(sp)++; lo=*(sp)++; blue  = (png_uint_16)((hi << 8) | (lo));
3180 
3181                if (red != green || red != blue)
3182                   rgb_error |= 1;
3183 
3184                /* From 1.5.5 in the 16-bit case do the accurate conversion even
3185                 * in the 'fast' case - this is because this is where the code
3186                 * ends up when handling linear 16-bit data.
3187                 */
3188                gray16  = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
3189                   15);
3190                *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
3191                *(dp++) = (png_byte)(gray16 & 0xff);
3192 
3193                if (have_alpha != 0)
3194                {
3195                   *(dp++) = *(sp++);
3196                   *(dp++) = *(sp++);
3197                }
3198             }
3199          }
3200       }
3201 
3202       row_info->channels = (png_byte)(row_info->channels - 2);
3203       row_info->color_type = (png_byte)(row_info->color_type &
3204           ~PNG_COLOR_MASK_COLOR);
3205       row_info->pixel_depth = (png_byte)(row_info->channels *
3206           row_info->bit_depth);
3207       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
3208    }
3209    return rgb_error;
3210 }
3211 #endif
3212 
3213 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
3214    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
3215 /* Replace any alpha or transparency with the supplied background color.
3216  * "background" is already in the screen gamma, while "background_1" is
3217  * at a gamma of 1.0.  Paletted files have already been taken care of.
3218  */
3219 static void
3220 png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3221 {
3222 #ifdef PNG_READ_GAMMA_SUPPORTED
3223    png_const_bytep gamma_table = png_ptr->gamma_table;
3224    png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
3225    png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
3226    png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
3227    png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
3228    png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
3229    int gamma_shift = png_ptr->gamma_shift;
3230    int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
3231 #endif
3232 
3233    png_bytep sp;
3234    png_uint_32 i;
3235    png_uint_32 row_width = row_info->width;
3236    int shift;
3237 
3238    png_debug(1, "in png_do_compose");
3239 
3240    {
3241       switch (row_info->color_type)
3242       {
3243          case PNG_COLOR_TYPE_GRAY:
3244          {
3245             switch (row_info->bit_depth)
3246             {
3247                case 1:
3248                {
3249                   sp = row;
3250                   shift = 7;
3251                   for (i = 0; i < row_width; i++)
3252                   {
3253                      if ((png_uint_16)((*sp >> shift) & 0x01)
3254                         == png_ptr->trans_color.gray)
3255                      {
3256                         unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
3257                         tmp |=
3258                             (unsigned int)(png_ptr->background.gray << shift);
3259                         *sp = (png_byte)(tmp & 0xff);
3260                      }
3261 
3262                      if (shift == 0)
3263                      {
3264                         shift = 7;
3265                         sp++;
3266                      }
3267 
3268                      else
3269                         shift--;
3270                   }
3271                   break;
3272                }
3273 
3274                case 2:
3275                {
3276 #ifdef PNG_READ_GAMMA_SUPPORTED
3277                   if (gamma_table != NULL)
3278                   {
3279                      sp = row;
3280                      shift = 6;
3281                      for (i = 0; i < row_width; i++)
3282                      {
3283                         if ((png_uint_16)((*sp >> shift) & 0x03)
3284                             == png_ptr->trans_color.gray)
3285                         {
3286                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3287                            tmp |=
3288                               (unsigned int)png_ptr->background.gray << shift;
3289                            *sp = (png_byte)(tmp & 0xff);
3290                         }
3291 
3292                         else
3293                         {
3294                            unsigned int p = (*sp >> shift) & 0x03;
3295                            unsigned int g = (gamma_table [p | (p << 2) |
3296                                (p << 4) | (p << 6)] >> 6) & 0x03;
3297                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3298                            tmp |= (unsigned int)(g << shift);
3299                            *sp = (png_byte)(tmp & 0xff);
3300                         }
3301 
3302                         if (shift == 0)
3303                         {
3304                            shift = 6;
3305                            sp++;
3306                         }
3307 
3308                         else
3309                            shift -= 2;
3310                      }
3311                   }
3312 
3313                   else
3314 #endif
3315                   {
3316                      sp = row;
3317                      shift = 6;
3318                      for (i = 0; i < row_width; i++)
3319                      {
3320                         if ((png_uint_16)((*sp >> shift) & 0x03)
3321                             == png_ptr->trans_color.gray)
3322                         {
3323                            unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
3324                            tmp |=
3325                                (unsigned int)png_ptr->background.gray << shift;
3326                            *sp = (png_byte)(tmp & 0xff);
3327                         }
3328 
3329                         if (shift == 0)
3330                         {
3331                            shift = 6;
3332                            sp++;
3333                         }
3334 
3335                         else
3336                            shift -= 2;
3337                      }
3338                   }
3339                   break;
3340                }
3341 
3342                case 4:
3343                {
3344 #ifdef PNG_READ_GAMMA_SUPPORTED
3345                   if (gamma_table != NULL)
3346                   {
3347                      sp = row;
3348                      shift = 4;
3349                      for (i = 0; i < row_width; i++)
3350                      {
3351                         if ((png_uint_16)((*sp >> shift) & 0x0f)
3352                             == png_ptr->trans_color.gray)
3353                         {
3354                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3355                            tmp |=
3356                               (unsigned int)(png_ptr->background.gray << shift);
3357                            *sp = (png_byte)(tmp & 0xff);
3358                         }
3359 
3360                         else
3361                         {
3362                            unsigned int p = (*sp >> shift) & 0x0f;
3363                            unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
3364                               0x0f;
3365                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3366                            tmp |= (unsigned int)(g << shift);
3367                            *sp = (png_byte)(tmp & 0xff);
3368                         }
3369 
3370                         if (shift == 0)
3371                         {
3372                            shift = 4;
3373                            sp++;
3374                         }
3375 
3376                         else
3377                            shift -= 4;
3378                      }
3379                   }
3380 
3381                   else
3382 #endif
3383                   {
3384                      sp = row;
3385                      shift = 4;
3386                      for (i = 0; i < row_width; i++)
3387                      {
3388                         if ((png_uint_16)((*sp >> shift) & 0x0f)
3389                             == png_ptr->trans_color.gray)
3390                         {
3391                            unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
3392                            tmp |=
3393                               (unsigned int)(png_ptr->background.gray << shift);
3394                            *sp = (png_byte)(tmp & 0xff);
3395                         }
3396 
3397                         if (shift == 0)
3398                         {
3399                            shift = 4;
3400                            sp++;
3401                         }
3402 
3403                         else
3404                            shift -= 4;
3405                      }
3406                   }
3407                   break;
3408                }
3409 
3410                case 8:
3411                {
3412 #ifdef PNG_READ_GAMMA_SUPPORTED
3413                   if (gamma_table != NULL)
3414                   {
3415                      sp = row;
3416                      for (i = 0; i < row_width; i++, sp++)
3417                      {
3418                         if (*sp == png_ptr->trans_color.gray)
3419                            *sp = (png_byte)png_ptr->background.gray;
3420 
3421                         else
3422                            *sp = gamma_table[*sp];
3423                      }
3424                   }
3425                   else
3426 #endif
3427                   {
3428                      sp = row;
3429                      for (i = 0; i < row_width; i++, sp++)
3430                      {
3431                         if (*sp == png_ptr->trans_color.gray)
3432                            *sp = (png_byte)png_ptr->background.gray;
3433                      }
3434                   }
3435                   break;
3436                }
3437 
3438                case 16:
3439                {
3440 #ifdef PNG_READ_GAMMA_SUPPORTED
3441                   if (gamma_16 != NULL)
3442                   {
3443                      sp = row;
3444                      for (i = 0; i < row_width; i++, sp += 2)
3445                      {
3446                         png_uint_16 v;
3447 
3448                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3449 
3450                         if (v == png_ptr->trans_color.gray)
3451                         {
3452                            /* Background is already in screen gamma */
3453                            *sp = (png_byte)((png_ptr->background.gray >> 8)
3454                                 & 0xff);
3455                            *(sp + 1) = (png_byte)(png_ptr->background.gray
3456                                 & 0xff);
3457                         }
3458 
3459                         else
3460                         {
3461                            v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3462                            *sp = (png_byte)((v >> 8) & 0xff);
3463                            *(sp + 1) = (png_byte)(v & 0xff);
3464                         }
3465                      }
3466                   }
3467                   else
3468 #endif
3469                   {
3470                      sp = row;
3471                      for (i = 0; i < row_width; i++, sp += 2)
3472                      {
3473                         png_uint_16 v;
3474 
3475                         v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3476 
3477                         if (v == png_ptr->trans_color.gray)
3478                         {
3479                            *sp = (png_byte)((png_ptr->background.gray >> 8)
3480                                 & 0xff);
3481                            *(sp + 1) = (png_byte)(png_ptr->background.gray
3482                                 & 0xff);
3483                         }
3484                      }
3485                   }
3486                   break;
3487                }
3488 
3489                default:
3490                   break;
3491             }
3492             break;
3493          }
3494 
3495          case PNG_COLOR_TYPE_RGB:
3496          {
3497             if (row_info->bit_depth == 8)
3498             {
3499 #ifdef PNG_READ_GAMMA_SUPPORTED
3500                if (gamma_table != NULL)
3501                {
3502                   sp = row;
3503                   for (i = 0; i < row_width; i++, sp += 3)
3504                   {
3505                      if (*sp == png_ptr->trans_color.red &&
3506                          *(sp + 1) == png_ptr->trans_color.green &&
3507                          *(sp + 2) == png_ptr->trans_color.blue)
3508                      {
3509                         *sp = (png_byte)png_ptr->background.red;
3510                         *(sp + 1) = (png_byte)png_ptr->background.green;
3511                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3512                      }
3513 
3514                      else
3515                      {
3516                         *sp = gamma_table[*sp];
3517                         *(sp + 1) = gamma_table[*(sp + 1)];
3518                         *(sp + 2) = gamma_table[*(sp + 2)];
3519                      }
3520                   }
3521                }
3522                else
3523 #endif
3524                {
3525                   sp = row;
3526                   for (i = 0; i < row_width; i++, sp += 3)
3527                   {
3528                      if (*sp == png_ptr->trans_color.red &&
3529                          *(sp + 1) == png_ptr->trans_color.green &&
3530                          *(sp + 2) == png_ptr->trans_color.blue)
3531                      {
3532                         *sp = (png_byte)png_ptr->background.red;
3533                         *(sp + 1) = (png_byte)png_ptr->background.green;
3534                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3535                      }
3536                   }
3537                }
3538             }
3539             else /* if (row_info->bit_depth == 16) */
3540             {
3541 #ifdef PNG_READ_GAMMA_SUPPORTED
3542                if (gamma_16 != NULL)
3543                {
3544                   sp = row;
3545                   for (i = 0; i < row_width; i++, sp += 6)
3546                   {
3547                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3548 
3549                      png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3550                          + *(sp + 3));
3551 
3552                      png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3553                          + *(sp + 5));
3554 
3555                      if (r == png_ptr->trans_color.red &&
3556                          g == png_ptr->trans_color.green &&
3557                          b == png_ptr->trans_color.blue)
3558                      {
3559                         /* Background is already in screen gamma */
3560                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3561                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3562                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3563                                 & 0xff);
3564                         *(sp + 3) = (png_byte)(png_ptr->background.green
3565                                 & 0xff);
3566                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3567                                 & 0xff);
3568                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3569                      }
3570 
3571                      else
3572                      {
3573                         png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3574                         *sp = (png_byte)((v >> 8) & 0xff);
3575                         *(sp + 1) = (png_byte)(v & 0xff);
3576 
3577                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3578                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3579                         *(sp + 3) = (png_byte)(v & 0xff);
3580 
3581                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3582                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3583                         *(sp + 5) = (png_byte)(v & 0xff);
3584                      }
3585                   }
3586                }
3587 
3588                else
3589 #endif
3590                {
3591                   sp = row;
3592                   for (i = 0; i < row_width; i++, sp += 6)
3593                   {
3594                      png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3595 
3596                      png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3597                          + *(sp + 3));
3598 
3599                      png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3600                          + *(sp + 5));
3601 
3602                      if (r == png_ptr->trans_color.red &&
3603                          g == png_ptr->trans_color.green &&
3604                          b == png_ptr->trans_color.blue)
3605                      {
3606                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3607                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3608                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3609                                 & 0xff);
3610                         *(sp + 3) = (png_byte)(png_ptr->background.green
3611                                 & 0xff);
3612                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3613                                 & 0xff);
3614                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3615                      }
3616                   }
3617                }
3618             }
3619             break;
3620          }
3621 
3622          case PNG_COLOR_TYPE_GRAY_ALPHA:
3623          {
3624             if (row_info->bit_depth == 8)
3625             {
3626 #ifdef PNG_READ_GAMMA_SUPPORTED
3627                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3628                    gamma_table != NULL)
3629                {
3630                   sp = row;
3631                   for (i = 0; i < row_width; i++, sp += 2)
3632                   {
3633                      png_uint_16 a = *(sp + 1);
3634 
3635                      if (a == 0xff)
3636                         *sp = gamma_table[*sp];
3637 
3638                      else if (a == 0)
3639                      {
3640                         /* Background is already in screen gamma */
3641                         *sp = (png_byte)png_ptr->background.gray;
3642                      }
3643 
3644                      else
3645                      {
3646                         png_byte v, w;
3647 
3648                         v = gamma_to_1[*sp];
3649                         png_composite(w, v, a, png_ptr->background_1.gray);
3650                         if (optimize == 0)
3651                            w = gamma_from_1[w];
3652                         *sp = w;
3653                      }
3654                   }
3655                }
3656                else
3657 #endif
3658                {
3659                   sp = row;
3660                   for (i = 0; i < row_width; i++, sp += 2)
3661                   {
3662                      png_byte a = *(sp + 1);
3663 
3664                      if (a == 0)
3665                         *sp = (png_byte)png_ptr->background.gray;
3666 
3667                      else if (a < 0xff)
3668                         png_composite(*sp, *sp, a, png_ptr->background.gray);
3669                   }
3670                }
3671             }
3672             else /* if (png_ptr->bit_depth == 16) */
3673             {
3674 #ifdef PNG_READ_GAMMA_SUPPORTED
3675                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3676                    gamma_16_to_1 != NULL)
3677                {
3678                   sp = row;
3679                   for (i = 0; i < row_width; i++, sp += 4)
3680                   {
3681                      png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3682                          + *(sp + 3));
3683 
3684                      if (a == (png_uint_16)0xffff)
3685                      {
3686                         png_uint_16 v;
3687 
3688                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3689                         *sp = (png_byte)((v >> 8) & 0xff);
3690                         *(sp + 1) = (png_byte)(v & 0xff);
3691                      }
3692 
3693                      else if (a == 0)
3694                      {
3695                         /* Background is already in screen gamma */
3696                         *sp = (png_byte)((png_ptr->background.gray >> 8)
3697                                 & 0xff);
3698                         *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3699                      }
3700 
3701                      else
3702                      {
3703                         png_uint_16 g, v, w;
3704 
3705                         g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3706                         png_composite_16(v, g, a, png_ptr->background_1.gray);
3707                         if (optimize != 0)
3708                            w = v;
3709                         else
3710                            w = gamma_16_from_1[(v & 0xff) >>
3711                                gamma_shift][v >> 8];
3712                         *sp = (png_byte)((w >> 8) & 0xff);
3713                         *(sp + 1) = (png_byte)(w & 0xff);
3714                      }
3715                   }
3716                }
3717                else
3718 #endif
3719                {
3720                   sp = row;
3721                   for (i = 0; i < row_width; i++, sp += 4)
3722                   {
3723                      png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
3724                          + *(sp + 3));
3725 
3726                      if (a == 0)
3727                      {
3728                         *sp = (png_byte)((png_ptr->background.gray >> 8)
3729                                 & 0xff);
3730                         *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
3731                      }
3732 
3733                      else if (a < 0xffff)
3734                      {
3735                         png_uint_16 g, v;
3736 
3737                         g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3738                         png_composite_16(v, g, a, png_ptr->background.gray);
3739                         *sp = (png_byte)((v >> 8) & 0xff);
3740                         *(sp + 1) = (png_byte)(v & 0xff);
3741                      }
3742                   }
3743                }
3744             }
3745             break;
3746          }
3747 
3748          case PNG_COLOR_TYPE_RGB_ALPHA:
3749          {
3750             if (row_info->bit_depth == 8)
3751             {
3752 #ifdef PNG_READ_GAMMA_SUPPORTED
3753                if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
3754                    gamma_table != NULL)
3755                {
3756                   sp = row;
3757                   for (i = 0; i < row_width; i++, sp += 4)
3758                   {
3759                      png_byte a = *(sp + 3);
3760 
3761                      if (a == 0xff)
3762                      {
3763                         *sp = gamma_table[*sp];
3764                         *(sp + 1) = gamma_table[*(sp + 1)];
3765                         *(sp + 2) = gamma_table[*(sp + 2)];
3766                      }
3767 
3768                      else if (a == 0)
3769                      {
3770                         /* Background is already in screen gamma */
3771                         *sp = (png_byte)png_ptr->background.red;
3772                         *(sp + 1) = (png_byte)png_ptr->background.green;
3773                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3774                      }
3775 
3776                      else
3777                      {
3778                         png_byte v, w;
3779 
3780                         v = gamma_to_1[*sp];
3781                         png_composite(w, v, a, png_ptr->background_1.red);
3782                         if (optimize == 0) w = gamma_from_1[w];
3783                         *sp = w;
3784 
3785                         v = gamma_to_1[*(sp + 1)];
3786                         png_composite(w, v, a, png_ptr->background_1.green);
3787                         if (optimize == 0) w = gamma_from_1[w];
3788                         *(sp + 1) = w;
3789 
3790                         v = gamma_to_1[*(sp + 2)];
3791                         png_composite(w, v, a, png_ptr->background_1.blue);
3792                         if (optimize == 0) w = gamma_from_1[w];
3793                         *(sp + 2) = w;
3794                      }
3795                   }
3796                }
3797                else
3798 #endif
3799                {
3800                   sp = row;
3801                   for (i = 0; i < row_width; i++, sp += 4)
3802                   {
3803                      png_byte a = *(sp + 3);
3804 
3805                      if (a == 0)
3806                      {
3807                         *sp = (png_byte)png_ptr->background.red;
3808                         *(sp + 1) = (png_byte)png_ptr->background.green;
3809                         *(sp + 2) = (png_byte)png_ptr->background.blue;
3810                      }
3811 
3812                      else if (a < 0xff)
3813                      {
3814                         png_composite(*sp, *sp, a, png_ptr->background.red);
3815 
3816                         png_composite(*(sp + 1), *(sp + 1), a,
3817                             png_ptr->background.green);
3818 
3819                         png_composite(*(sp + 2), *(sp + 2), a,
3820                             png_ptr->background.blue);
3821                      }
3822                   }
3823                }
3824             }
3825             else /* if (row_info->bit_depth == 16) */
3826             {
3827 #ifdef PNG_READ_GAMMA_SUPPORTED
3828                if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
3829                    gamma_16_to_1 != NULL)
3830                {
3831                   sp = row;
3832                   for (i = 0; i < row_width; i++, sp += 8)
3833                   {
3834                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3835                          << 8) + (png_uint_16)(*(sp + 7)));
3836 
3837                      if (a == (png_uint_16)0xffff)
3838                      {
3839                         png_uint_16 v;
3840 
3841                         v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
3842                         *sp = (png_byte)((v >> 8) & 0xff);
3843                         *(sp + 1) = (png_byte)(v & 0xff);
3844 
3845                         v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
3846                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3847                         *(sp + 3) = (png_byte)(v & 0xff);
3848 
3849                         v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
3850                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3851                         *(sp + 5) = (png_byte)(v & 0xff);
3852                      }
3853 
3854                      else if (a == 0)
3855                      {
3856                         /* Background is already in screen gamma */
3857                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3858                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3859                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3860                                 & 0xff);
3861                         *(sp + 3) = (png_byte)(png_ptr->background.green
3862                                 & 0xff);
3863                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3864                                 & 0xff);
3865                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3866                      }
3867 
3868                      else
3869                      {
3870                         png_uint_16 v, w;
3871 
3872                         v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
3873                         png_composite_16(w, v, a, png_ptr->background_1.red);
3874                         if (optimize == 0)
3875                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3876                                 8];
3877                         *sp = (png_byte)((w >> 8) & 0xff);
3878                         *(sp + 1) = (png_byte)(w & 0xff);
3879 
3880                         v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
3881                         png_composite_16(w, v, a, png_ptr->background_1.green);
3882                         if (optimize == 0)
3883                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3884                                 8];
3885 
3886                         *(sp + 2) = (png_byte)((w >> 8) & 0xff);
3887                         *(sp + 3) = (png_byte)(w & 0xff);
3888 
3889                         v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
3890                         png_composite_16(w, v, a, png_ptr->background_1.blue);
3891                         if (optimize == 0)
3892                            w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
3893                                 8];
3894 
3895                         *(sp + 4) = (png_byte)((w >> 8) & 0xff);
3896                         *(sp + 5) = (png_byte)(w & 0xff);
3897                      }
3898                   }
3899                }
3900 
3901                else
3902 #endif
3903                {
3904                   sp = row;
3905                   for (i = 0; i < row_width; i++, sp += 8)
3906                   {
3907                      png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
3908                          << 8) + (png_uint_16)(*(sp + 7)));
3909 
3910                      if (a == 0)
3911                      {
3912                         *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
3913                         *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
3914                         *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
3915                                 & 0xff);
3916                         *(sp + 3) = (png_byte)(png_ptr->background.green
3917                                 & 0xff);
3918                         *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
3919                                 & 0xff);
3920                         *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
3921                      }
3922 
3923                      else if (a < 0xffff)
3924                      {
3925                         png_uint_16 v;
3926 
3927                         png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
3928                         png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
3929                             + *(sp + 3));
3930                         png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
3931                             + *(sp + 5));
3932 
3933                         png_composite_16(v, r, a, png_ptr->background.red);
3934                         *sp = (png_byte)((v >> 8) & 0xff);
3935                         *(sp + 1) = (png_byte)(v & 0xff);
3936 
3937                         png_composite_16(v, g, a, png_ptr->background.green);
3938                         *(sp + 2) = (png_byte)((v >> 8) & 0xff);
3939                         *(sp + 3) = (png_byte)(v & 0xff);
3940 
3941                         png_composite_16(v, b, a, png_ptr->background.blue);
3942                         *(sp + 4) = (png_byte)((v >> 8) & 0xff);
3943                         *(sp + 5) = (png_byte)(v & 0xff);
3944                      }
3945                   }
3946                }
3947             }
3948             break;
3949          }
3950 
3951          default:
3952             break;
3953       }
3954    }
3955 }
3956 #endif /* READ_BACKGROUND || READ_ALPHA_MODE */
3957 
3958 #ifdef PNG_READ_GAMMA_SUPPORTED
3959 /* Gamma correct the image, avoiding the alpha channel.  Make sure
3960  * you do this after you deal with the transparency issue on grayscale
3961  * or RGB images. If your bit depth is 8, use gamma_table, if it
3962  * is 16, use gamma_16_table and gamma_shift.  Build these with
3963  * build_gamma_table().
3964  */
3965 static void
3966 png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
3967 {
3968    png_const_bytep gamma_table = png_ptr->gamma_table;
3969    png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
3970    int gamma_shift = png_ptr->gamma_shift;
3971 
3972    png_bytep sp;
3973    png_uint_32 i;
3974    png_uint_32 row_width=row_info->width;
3975 
3976    png_debug(1, "in png_do_gamma");
3977 
3978    if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
3979        (row_info->bit_depth == 16 && gamma_16_table != NULL)))
3980    {
3981       switch (row_info->color_type)
3982       {
3983          case PNG_COLOR_TYPE_RGB:
3984          {
3985             if (row_info->bit_depth == 8)
3986             {
3987                sp = row;
3988                for (i = 0; i < row_width; i++)
3989                {
3990                   *sp = gamma_table[*sp];
3991                   sp++;
3992                   *sp = gamma_table[*sp];
3993                   sp++;
3994                   *sp = gamma_table[*sp];
3995                   sp++;
3996                }
3997             }
3998 
3999             else /* if (row_info->bit_depth == 16) */
4000             {
4001                sp = row;
4002                for (i = 0; i < row_width; i++)
4003                {
4004                   png_uint_16 v;
4005 
4006                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4007                   *sp = (png_byte)((v >> 8) & 0xff);
4008                   *(sp + 1) = (png_byte)(v & 0xff);
4009                   sp += 2;
4010 
4011                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4012                   *sp = (png_byte)((v >> 8) & 0xff);
4013                   *(sp + 1) = (png_byte)(v & 0xff);
4014                   sp += 2;
4015 
4016                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4017                   *sp = (png_byte)((v >> 8) & 0xff);
4018                   *(sp + 1) = (png_byte)(v & 0xff);
4019                   sp += 2;
4020                }
4021             }
4022             break;
4023          }
4024 
4025          case PNG_COLOR_TYPE_RGB_ALPHA:
4026          {
4027             if (row_info->bit_depth == 8)
4028             {
4029                sp = row;
4030                for (i = 0; i < row_width; i++)
4031                {
4032                   *sp = gamma_table[*sp];
4033                   sp++;
4034 
4035                   *sp = gamma_table[*sp];
4036                   sp++;
4037 
4038                   *sp = gamma_table[*sp];
4039                   sp++;
4040 
4041                   sp++;
4042                }
4043             }
4044 
4045             else /* if (row_info->bit_depth == 16) */
4046             {
4047                sp = row;
4048                for (i = 0; i < row_width; i++)
4049                {
4050                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4051                   *sp = (png_byte)((v >> 8) & 0xff);
4052                   *(sp + 1) = (png_byte)(v & 0xff);
4053                   sp += 2;
4054 
4055                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4056                   *sp = (png_byte)((v >> 8) & 0xff);
4057                   *(sp + 1) = (png_byte)(v & 0xff);
4058                   sp += 2;
4059 
4060                   v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4061                   *sp = (png_byte)((v >> 8) & 0xff);
4062                   *(sp + 1) = (png_byte)(v & 0xff);
4063                   sp += 4;
4064                }
4065             }
4066             break;
4067          }
4068 
4069          case PNG_COLOR_TYPE_GRAY_ALPHA:
4070          {
4071             if (row_info->bit_depth == 8)
4072             {
4073                sp = row;
4074                for (i = 0; i < row_width; i++)
4075                {
4076                   *sp = gamma_table[*sp];
4077                   sp += 2;
4078                }
4079             }
4080 
4081             else /* if (row_info->bit_depth == 16) */
4082             {
4083                sp = row;
4084                for (i = 0; i < row_width; i++)
4085                {
4086                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4087                   *sp = (png_byte)((v >> 8) & 0xff);
4088                   *(sp + 1) = (png_byte)(v & 0xff);
4089                   sp += 4;
4090                }
4091             }
4092             break;
4093          }
4094 
4095          case PNG_COLOR_TYPE_GRAY:
4096          {
4097             if (row_info->bit_depth == 2)
4098             {
4099                sp = row;
4100                for (i = 0; i < row_width; i += 4)
4101                {
4102                   int a = *sp & 0xc0;
4103                   int b = *sp & 0x30;
4104                   int c = *sp & 0x0c;
4105                   int d = *sp & 0x03;
4106 
4107                   *sp = (png_byte)(
4108                       ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)])   ) & 0xc0)|
4109                       ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
4110                       ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
4111                       ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
4112                   sp++;
4113                }
4114             }
4115 
4116             if (row_info->bit_depth == 4)
4117             {
4118                sp = row;
4119                for (i = 0; i < row_width; i += 2)
4120                {
4121                   int msb = *sp & 0xf0;
4122                   int lsb = *sp & 0x0f;
4123 
4124                   *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
4125                       | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
4126                   sp++;
4127                }
4128             }
4129 
4130             else if (row_info->bit_depth == 8)
4131             {
4132                sp = row;
4133                for (i = 0; i < row_width; i++)
4134                {
4135                   *sp = gamma_table[*sp];
4136                   sp++;
4137                }
4138             }
4139 
4140             else if (row_info->bit_depth == 16)
4141             {
4142                sp = row;
4143                for (i = 0; i < row_width; i++)
4144                {
4145                   png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
4146                   *sp = (png_byte)((v >> 8) & 0xff);
4147                   *(sp + 1) = (png_byte)(v & 0xff);
4148                   sp += 2;
4149                }
4150             }
4151             break;
4152          }
4153 
4154          default:
4155             break;
4156       }
4157    }
4158 }
4159 #endif
4160 
4161 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4162 /* Encode the alpha channel to the output gamma (the input channel is always
4163  * linear.)  Called only with color types that have an alpha channel.  Needs the
4164  * from_1 tables.
4165  */
4166 static void
4167 png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
4168 {
4169    png_uint_32 row_width = row_info->width;
4170 
4171    png_debug(1, "in png_do_encode_alpha");
4172 
4173    if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4174    {
4175       if (row_info->bit_depth == 8)
4176       {
4177          PNG_CONST png_bytep table = png_ptr->gamma_from_1;
4178 
4179          if (table != NULL)
4180          {
4181             PNG_CONST int step =
4182                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
4183 
4184             /* The alpha channel is the last component: */
4185             row += step - 1;
4186 
4187             for (; row_width > 0; --row_width, row += step)
4188                *row = table[*row];
4189 
4190             return;
4191          }
4192       }
4193 
4194       else if (row_info->bit_depth == 16)
4195       {
4196          PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
4197          PNG_CONST int gamma_shift = png_ptr->gamma_shift;
4198 
4199          if (table != NULL)
4200          {
4201             PNG_CONST int step =
4202                (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
4203 
4204             /* The alpha channel is the last component: */
4205             row += step - 2;
4206 
4207             for (; row_width > 0; --row_width, row += step)
4208             {
4209                png_uint_16 v;
4210 
4211                v = table[*(row + 1) >> gamma_shift][*row];
4212                *row = (png_byte)((v >> 8) & 0xff);
4213                *(row + 1) = (png_byte)(v & 0xff);
4214             }
4215 
4216             return;
4217          }
4218       }
4219    }
4220 
4221    /* Only get to here if called with a weird row_info; no harm has been done,
4222     * so just issue a warning.
4223     */
4224    png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
4225 }
4226 #endif
4227 
4228 #ifdef PNG_READ_EXPAND_SUPPORTED
4229 /* Expands a palette row to an RGB or RGBA row depending
4230  * upon whether you supply trans and num_trans.
4231  */
4232 static void
4233 png_do_expand_palette(png_row_infop row_info, png_bytep row,
4234     png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
4235 {
4236    int shift, value;
4237    png_bytep sp, dp;
4238    png_uint_32 i;
4239    png_uint_32 row_width=row_info->width;
4240 
4241    png_debug(1, "in png_do_expand_palette");
4242 
4243    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4244    {
4245       if (row_info->bit_depth < 8)
4246       {
4247          switch (row_info->bit_depth)
4248          {
4249             case 1:
4250             {
4251                sp = row + (png_size_t)((row_width - 1) >> 3);
4252                dp = row + (png_size_t)row_width - 1;
4253                shift = 7 - (int)((row_width + 7) & 0x07);
4254                for (i = 0; i < row_width; i++)
4255                {
4256                   if ((*sp >> shift) & 0x01)
4257                      *dp = 1;
4258 
4259                   else
4260                      *dp = 0;
4261 
4262                   if (shift == 7)
4263                   {
4264                      shift = 0;
4265                      sp--;
4266                   }
4267 
4268                   else
4269                      shift++;
4270 
4271                   dp--;
4272                }
4273                break;
4274             }
4275 
4276             case 2:
4277             {
4278                sp = row + (png_size_t)((row_width - 1) >> 2);
4279                dp = row + (png_size_t)row_width - 1;
4280                shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4281                for (i = 0; i < row_width; i++)
4282                {
4283                   value = (*sp >> shift) & 0x03;
4284                   *dp = (png_byte)value;
4285                   if (shift == 6)
4286                   {
4287                      shift = 0;
4288                      sp--;
4289                   }
4290 
4291                   else
4292                      shift += 2;
4293 
4294                   dp--;
4295                }
4296                break;
4297             }
4298 
4299             case 4:
4300             {
4301                sp = row + (png_size_t)((row_width - 1) >> 1);
4302                dp = row + (png_size_t)row_width - 1;
4303                shift = (int)((row_width & 0x01) << 2);
4304                for (i = 0; i < row_width; i++)
4305                {
4306                   value = (*sp >> shift) & 0x0f;
4307                   *dp = (png_byte)value;
4308                   if (shift == 4)
4309                   {
4310                      shift = 0;
4311                      sp--;
4312                   }
4313 
4314                   else
4315                      shift += 4;
4316 
4317                   dp--;
4318                }
4319                break;
4320             }
4321 
4322             default:
4323                break;
4324          }
4325          row_info->bit_depth = 8;
4326          row_info->pixel_depth = 8;
4327          row_info->rowbytes = row_width;
4328       }
4329 
4330       if (row_info->bit_depth == 8)
4331       {
4332          {
4333             if (num_trans > 0)
4334             {
4335                sp = row + (png_size_t)row_width - 1;
4336                dp = row + ((png_size_t)row_width << 2) - 1;
4337 
4338                for (i = 0; i < row_width; i++)
4339                {
4340                   if ((int)(*sp) >= num_trans)
4341                      *dp-- = 0xff;
4342 
4343                   else
4344                      *dp-- = trans_alpha[*sp];
4345 
4346                   *dp-- = palette[*sp].blue;
4347                   *dp-- = palette[*sp].green;
4348                   *dp-- = palette[*sp].red;
4349                   sp--;
4350                }
4351                row_info->bit_depth = 8;
4352                row_info->pixel_depth = 32;
4353                row_info->rowbytes = row_width * 4;
4354                row_info->color_type = 6;
4355                row_info->channels = 4;
4356             }
4357 
4358             else
4359             {
4360                sp = row + (png_size_t)row_width - 1;
4361                dp = row + (png_size_t)(row_width * 3) - 1;
4362 
4363                for (i = 0; i < row_width; i++)
4364                {
4365                   *dp-- = palette[*sp].blue;
4366                   *dp-- = palette[*sp].green;
4367                   *dp-- = palette[*sp].red;
4368                   sp--;
4369                }
4370 
4371                row_info->bit_depth = 8;
4372                row_info->pixel_depth = 24;
4373                row_info->rowbytes = row_width * 3;
4374                row_info->color_type = 2;
4375                row_info->channels = 3;
4376             }
4377          }
4378       }
4379    }
4380 }
4381 
4382 /* If the bit depth < 8, it is expanded to 8.  Also, if the already
4383  * expanded transparency value is supplied, an alpha channel is built.
4384  */
4385 static void
4386 png_do_expand(png_row_infop row_info, png_bytep row,
4387     png_const_color_16p trans_color)
4388 {
4389    int shift, value;
4390    png_bytep sp, dp;
4391    png_uint_32 i;
4392    png_uint_32 row_width=row_info->width;
4393 
4394    png_debug(1, "in png_do_expand");
4395 
4396    {
4397       if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
4398       {
4399          unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
4400 
4401          if (row_info->bit_depth < 8)
4402          {
4403             switch (row_info->bit_depth)
4404             {
4405                case 1:
4406                {
4407                   gray = (gray & 0x01) * 0xff;
4408                   sp = row + (png_size_t)((row_width - 1) >> 3);
4409                   dp = row + (png_size_t)row_width - 1;
4410                   shift = 7 - (int)((row_width + 7) & 0x07);
4411                   for (i = 0; i < row_width; i++)
4412                   {
4413                      if ((*sp >> shift) & 0x01)
4414                         *dp = 0xff;
4415 
4416                      else
4417                         *dp = 0;
4418 
4419                      if (shift == 7)
4420                      {
4421                         shift = 0;
4422                         sp--;
4423                      }
4424 
4425                      else
4426                         shift++;
4427 
4428                      dp--;
4429                   }
4430                   break;
4431                }
4432 
4433                case 2:
4434                {
4435                   gray = (gray & 0x03) * 0x55;
4436                   sp = row + (png_size_t)((row_width - 1) >> 2);
4437                   dp = row + (png_size_t)row_width - 1;
4438                   shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
4439                   for (i = 0; i < row_width; i++)
4440                   {
4441                      value = (*sp >> shift) & 0x03;
4442                      *dp = (png_byte)(value | (value << 2) | (value << 4) |
4443                         (value << 6));
4444                      if (shift == 6)
4445                      {
4446                         shift = 0;
4447                         sp--;
4448                      }
4449 
4450                      else
4451                         shift += 2;
4452 
4453                      dp--;
4454                   }
4455                   break;
4456                }
4457 
4458                case 4:
4459                {
4460                   gray = (gray & 0x0f) * 0x11;
4461                   sp = row + (png_size_t)((row_width - 1) >> 1);
4462                   dp = row + (png_size_t)row_width - 1;
4463                   shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
4464                   for (i = 0; i < row_width; i++)
4465                   {
4466                      value = (*sp >> shift) & 0x0f;
4467                      *dp = (png_byte)(value | (value << 4));
4468                      if (shift == 4)
4469                      {
4470                         shift = 0;
4471                         sp--;
4472                      }
4473 
4474                      else
4475                         shift = 4;
4476 
4477                      dp--;
4478                   }
4479                   break;
4480                }
4481 
4482                default:
4483                   break;
4484             }
4485 
4486             row_info->bit_depth = 8;
4487             row_info->pixel_depth = 8;
4488             row_info->rowbytes = row_width;
4489          }
4490 
4491          if (trans_color != NULL)
4492          {
4493             if (row_info->bit_depth == 8)
4494             {
4495                gray = gray & 0xff;
4496                sp = row + (png_size_t)row_width - 1;
4497                dp = row + ((png_size_t)row_width << 1) - 1;
4498 
4499                for (i = 0; i < row_width; i++)
4500                {
4501                   if ((*sp & 0xffU) == gray)
4502                      *dp-- = 0;
4503 
4504                   else
4505                      *dp-- = 0xff;
4506 
4507                   *dp-- = *sp--;
4508                }
4509             }
4510 
4511             else if (row_info->bit_depth == 16)
4512             {
4513                unsigned int gray_high = (gray >> 8) & 0xff;
4514                unsigned int gray_low = gray & 0xff;
4515                sp = row + row_info->rowbytes - 1;
4516                dp = row + (row_info->rowbytes << 1) - 1;
4517                for (i = 0; i < row_width; i++)
4518                {
4519                   if ((*(sp - 1) & 0xffU) == gray_high &&
4520                       (*(sp) & 0xffU) == gray_low)
4521                   {
4522                      *dp-- = 0;
4523                      *dp-- = 0;
4524                   }
4525 
4526                   else
4527                   {
4528                      *dp-- = 0xff;
4529                      *dp-- = 0xff;
4530                   }
4531 
4532                   *dp-- = *sp--;
4533                   *dp-- = *sp--;
4534                }
4535             }
4536 
4537             row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
4538             row_info->channels = 2;
4539             row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
4540             row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
4541                 row_width);
4542          }
4543       }
4544       else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
4545           trans_color != NULL)
4546       {
4547          if (row_info->bit_depth == 8)
4548          {
4549             png_byte red = (png_byte)(trans_color->red & 0xff);
4550             png_byte green = (png_byte)(trans_color->green & 0xff);
4551             png_byte blue = (png_byte)(trans_color->blue & 0xff);
4552             sp = row + (png_size_t)row_info->rowbytes - 1;
4553             dp = row + ((png_size_t)row_width << 2) - 1;
4554             for (i = 0; i < row_width; i++)
4555             {
4556                if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
4557                   *dp-- = 0;
4558 
4559                else
4560                   *dp-- = 0xff;
4561 
4562                *dp-- = *sp--;
4563                *dp-- = *sp--;
4564                *dp-- = *sp--;
4565             }
4566          }
4567          else if (row_info->bit_depth == 16)
4568          {
4569             png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
4570             png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
4571             png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
4572             png_byte red_low = (png_byte)(trans_color->red & 0xff);
4573             png_byte green_low = (png_byte)(trans_color->green & 0xff);
4574             png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
4575             sp = row + row_info->rowbytes - 1;
4576             dp = row + ((png_size_t)row_width << 3) - 1;
4577             for (i = 0; i < row_width; i++)
4578             {
4579                if (*(sp - 5) == red_high &&
4580                    *(sp - 4) == red_low &&
4581                    *(sp - 3) == green_high &&
4582                    *(sp - 2) == green_low &&
4583                    *(sp - 1) == blue_high &&
4584                    *(sp    ) == blue_low)
4585                {
4586                   *dp-- = 0;
4587                   *dp-- = 0;
4588                }
4589 
4590                else
4591                {
4592                   *dp-- = 0xff;
4593                   *dp-- = 0xff;
4594                }
4595 
4596                *dp-- = *sp--;
4597                *dp-- = *sp--;
4598                *dp-- = *sp--;
4599                *dp-- = *sp--;
4600                *dp-- = *sp--;
4601                *dp-- = *sp--;
4602             }
4603          }
4604          row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
4605          row_info->channels = 4;
4606          row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
4607          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4608       }
4609    }
4610 }
4611 #endif
4612 
4613 #ifdef PNG_READ_EXPAND_16_SUPPORTED
4614 /* If the bit depth is 8 and the color type is not a palette type expand the
4615  * whole row to 16 bits.  Has no effect otherwise.
4616  */
4617 static void
4618 png_do_expand_16(png_row_infop row_info, png_bytep row)
4619 {
4620    if (row_info->bit_depth == 8 &&
4621       row_info->color_type != PNG_COLOR_TYPE_PALETTE)
4622    {
4623       /* The row have a sequence of bytes containing [0..255] and we need
4624        * to turn it into another row containing [0..65535], to do this we
4625        * calculate:
4626        *
4627        *  (input / 255) * 65535
4628        *
4629        *  Which happens to be exactly input * 257 and this can be achieved
4630        *  simply by byte replication in place (copying backwards).
4631        */
4632       png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
4633       png_byte *dp = sp + row_info->rowbytes;  /* destination, end + 1 */
4634       while (dp > sp)
4635       {
4636          dp[-2] = dp[-1] = *--sp; dp -= 2;
4637       }
4638 
4639       row_info->rowbytes *= 2;
4640       row_info->bit_depth = 16;
4641       row_info->pixel_depth = (png_byte)(row_info->channels * 16);
4642    }
4643 }
4644 #endif
4645 
4646 #ifdef PNG_READ_QUANTIZE_SUPPORTED
4647 static void
4648 png_do_quantize(png_row_infop row_info, png_bytep row,
4649     png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
4650 {
4651    png_bytep sp, dp;
4652    png_uint_32 i;
4653    png_uint_32 row_width=row_info->width;
4654 
4655    png_debug(1, "in png_do_quantize");
4656 
4657    if (row_info->bit_depth == 8)
4658    {
4659       if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
4660       {
4661          int r, g, b, p;
4662          sp = row;
4663          dp = row;
4664          for (i = 0; i < row_width; i++)
4665          {
4666             r = *sp++;
4667             g = *sp++;
4668             b = *sp++;
4669 
4670             /* This looks real messy, but the compiler will reduce
4671              * it down to a reasonable formula.  For example, with
4672              * 5 bits per color, we get:
4673              * p = (((r >> 3) & 0x1f) << 10) |
4674              *    (((g >> 3) & 0x1f) << 5) |
4675              *    ((b >> 3) & 0x1f);
4676              */
4677             p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4678                 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4679                 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4680                 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4681                 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4682                 (PNG_QUANTIZE_BLUE_BITS)) |
4683                 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4684                 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4685 
4686             *dp++ = palette_lookup[p];
4687          }
4688 
4689          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4690          row_info->channels = 1;
4691          row_info->pixel_depth = row_info->bit_depth;
4692          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4693       }
4694 
4695       else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
4696          palette_lookup != NULL)
4697       {
4698          int r, g, b, p;
4699          sp = row;
4700          dp = row;
4701          for (i = 0; i < row_width; i++)
4702          {
4703             r = *sp++;
4704             g = *sp++;
4705             b = *sp++;
4706             sp++;
4707 
4708             p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
4709                 ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
4710                 (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
4711                 (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
4712                 ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
4713                 (PNG_QUANTIZE_BLUE_BITS)) |
4714                 ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
4715                 ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
4716 
4717             *dp++ = palette_lookup[p];
4718          }
4719 
4720          row_info->color_type = PNG_COLOR_TYPE_PALETTE;
4721          row_info->channels = 1;
4722          row_info->pixel_depth = row_info->bit_depth;
4723          row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
4724       }
4725 
4726       else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4727          quantize_lookup)
4728       {
4729          sp = row;
4730 
4731          for (i = 0; i < row_width; i++, sp++)
4732          {
4733             *sp = quantize_lookup[*sp];
4734          }
4735       }
4736    }
4737 }
4738 #endif /* READ_QUANTIZE */
4739 
4740 /* Transform the row.  The order of transformations is significant,
4741  * and is very touchy.  If you add a transformation, take care to
4742  * decide how it fits in with the other transformations here.
4743  */
4744 void /* PRIVATE */
4745 png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
4746 {
4747    png_debug(1, "in png_do_read_transformations");
4748 
4749    if (png_ptr->row_buf == NULL)
4750    {
4751       /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
4752        * error is incredibly rare and incredibly easy to debug without this
4753        * information.
4754        */
4755       png_error(png_ptr, "NULL row buffer");
4756    }
4757 
4758    /* The following is debugging; prior to 1.5.4 the code was never compiled in;
4759     * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
4760     * PNG_WARN_UNINITIALIZED_ROW removed.  In 1.6 the new flag is set only for
4761     * all transformations, however in practice the ROW_INIT always gets done on
4762     * demand, if necessary.
4763     */
4764    if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
4765        (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
4766    {
4767       /* Application has failed to call either png_read_start_image() or
4768        * png_read_update_info() after setting transforms that expand pixels.
4769        * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
4770        */
4771       png_error(png_ptr, "Uninitialized row");
4772    }
4773 
4774 #ifdef PNG_READ_EXPAND_SUPPORTED
4775    if ((png_ptr->transformations & PNG_EXPAND) != 0)
4776    {
4777       if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
4778       {
4779          png_do_expand_palette(row_info, png_ptr->row_buf + 1,
4780              png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
4781       }
4782 
4783       else
4784       {
4785          if (png_ptr->num_trans != 0 &&
4786              (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
4787             png_do_expand(row_info, png_ptr->row_buf + 1,
4788                 &(png_ptr->trans_color));
4789 
4790          else
4791             png_do_expand(row_info, png_ptr->row_buf + 1,
4792                 NULL);
4793       }
4794    }
4795 #endif
4796 
4797 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4798    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4799        (png_ptr->transformations & PNG_COMPOSE) == 0 &&
4800        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
4801        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
4802       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
4803           0 /* at_start == false, because SWAP_ALPHA happens later */);
4804 #endif
4805 
4806 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
4807    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
4808    {
4809       int rgb_error =
4810           png_do_rgb_to_gray(png_ptr, row_info,
4811               png_ptr->row_buf + 1);
4812 
4813       if (rgb_error != 0)
4814       {
4815          png_ptr->rgb_to_gray_status=1;
4816          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4817              PNG_RGB_TO_GRAY_WARN)
4818             png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
4819 
4820          if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
4821              PNG_RGB_TO_GRAY_ERR)
4822             png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
4823       }
4824    }
4825 #endif
4826 
4827 /* From Andreas Dilger e-mail to png-implement, 26 March 1998:
4828  *
4829  *   In most cases, the "simple transparency" should be done prior to doing
4830  *   gray-to-RGB, or you will have to test 3x as many bytes to check if a
4831  *   pixel is transparent.  You would also need to make sure that the
4832  *   transparency information is upgraded to RGB.
4833  *
4834  *   To summarize, the current flow is:
4835  *   - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
4836  *                                   with background "in place" if transparent,
4837  *                                   convert to RGB if necessary
4838  *   - Gray + alpha -> composite with gray background and remove alpha bytes,
4839  *                                   convert to RGB if necessary
4840  *
4841  *   To support RGB backgrounds for gray images we need:
4842  *   - Gray + simple transparency -> convert to RGB + simple transparency,
4843  *                                   compare 3 or 6 bytes and composite with
4844  *                                   background "in place" if transparent
4845  *                                   (3x compare/pixel compared to doing
4846  *                                   composite with gray bkgrnd)
4847  *   - Gray + alpha -> convert to RGB + alpha, composite with background and
4848  *                                   remove alpha bytes (3x float
4849  *                                   operations/pixel compared with composite
4850  *                                   on gray background)
4851  *
4852  *  Greg's change will do this.  The reason it wasn't done before is for
4853  *  performance, as this increases the per-pixel operations.  If we would check
4854  *  in advance if the background was gray or RGB, and position the gray-to-RGB
4855  *  transform appropriately, then it would save a lot of work/time.
4856  */
4857 
4858 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4859    /* If gray -> RGB, do so now only if background is non-gray; else do later
4860     * for performance reasons
4861     */
4862    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
4863        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
4864       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
4865 #endif
4866 
4867 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
4868    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
4869    if ((png_ptr->transformations & PNG_COMPOSE) != 0)
4870       png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
4871 #endif
4872 
4873 #ifdef PNG_READ_GAMMA_SUPPORTED
4874    if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
4875 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
4876       /* Because RGB_TO_GRAY does the gamma transform. */
4877       (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
4878 #endif
4879 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
4880    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
4881       /* Because PNG_COMPOSE does the gamma transform if there is something to
4882        * do (if there is an alpha channel or transparency.)
4883        */
4884        !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
4885        ((png_ptr->num_trans != 0) ||
4886        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
4887 #endif
4888       /* Because png_init_read_transformations transforms the palette, unless
4889        * RGB_TO_GRAY will do the transform.
4890        */
4891        (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
4892       png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
4893 #endif
4894 
4895 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
4896    if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
4897        (png_ptr->transformations & PNG_COMPOSE) != 0 &&
4898        (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
4899        row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
4900       png_do_strip_channel(row_info, png_ptr->row_buf + 1,
4901           0 /* at_start == false, because SWAP_ALPHA happens later */);
4902 #endif
4903 
4904 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
4905    if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
4906        (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
4907       png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
4908 #endif
4909 
4910 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
4911    if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
4912       png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
4913 #endif
4914 
4915 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
4916    /* There is no harm in doing both of these because only one has any effect,
4917     * by putting the 'scale' option first if the app asks for scale (either by
4918     * calling the API or in a TRANSFORM flag) this is what happens.
4919     */
4920    if ((png_ptr->transformations & PNG_16_TO_8) != 0)
4921       png_do_chop(row_info, png_ptr->row_buf + 1);
4922 #endif
4923 
4924 #ifdef PNG_READ_QUANTIZE_SUPPORTED
4925    if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
4926    {
4927       png_do_quantize(row_info, png_ptr->row_buf + 1,
4928           png_ptr->palette_lookup, png_ptr->quantize_index);
4929 
4930       if (row_info->rowbytes == 0)
4931          png_error(png_ptr, "png_do_quantize returned rowbytes=0");
4932    }
4933 #endif /* READ_QUANTIZE */
4934 
4935 #ifdef PNG_READ_EXPAND_16_SUPPORTED
4936    /* Do the expansion now, after all the arithmetic has been done.  Notice
4937     * that previous transformations can handle the PNG_EXPAND_16 flag if this
4938     * is efficient (particularly true in the case of gamma correction, where
4939     * better accuracy results faster!)
4940     */
4941    if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
4942       png_do_expand_16(row_info, png_ptr->row_buf + 1);
4943 #endif
4944 
4945 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4946    /* NOTE: moved here in 1.5.4 (from much later in this list.) */
4947    if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
4948        (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
4949       png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
4950 #endif
4951 
4952 #ifdef PNG_READ_INVERT_SUPPORTED
4953    if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
4954       png_do_invert(row_info, png_ptr->row_buf + 1);
4955 #endif
4956 
4957 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
4958    if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
4959       png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
4960 #endif
4961 
4962 #ifdef PNG_READ_SHIFT_SUPPORTED
4963    if ((png_ptr->transformations & PNG_SHIFT) != 0)
4964       png_do_unshift(row_info, png_ptr->row_buf + 1,
4965           &(png_ptr->shift));
4966 #endif
4967 
4968 #ifdef PNG_READ_PACK_SUPPORTED
4969    if ((png_ptr->transformations & PNG_PACK) != 0)
4970       png_do_unpack(row_info, png_ptr->row_buf + 1);
4971 #endif
4972 
4973 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
4974    /* Added at libpng-1.5.10 */
4975    if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
4976        png_ptr->num_palette_max >= 0)
4977       png_do_check_palette_indexes(png_ptr, row_info);
4978 #endif
4979 
4980 #ifdef PNG_READ_BGR_SUPPORTED
4981    if ((png_ptr->transformations & PNG_BGR) != 0)
4982       png_do_bgr(row_info, png_ptr->row_buf + 1);
4983 #endif
4984 
4985 #ifdef PNG_READ_PACKSWAP_SUPPORTED
4986    if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
4987       png_do_packswap(row_info, png_ptr->row_buf + 1);
4988 #endif
4989 
4990 #ifdef PNG_READ_FILLER_SUPPORTED
4991    if ((png_ptr->transformations & PNG_FILLER) != 0)
4992       png_do_read_filler(row_info, png_ptr->row_buf + 1,
4993           (png_uint_32)png_ptr->filler, png_ptr->flags);
4994 #endif
4995 
4996 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
4997    if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
4998       png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
4999 #endif
5000 
5001 #ifdef PNG_READ_16BIT_SUPPORTED
5002 #ifdef PNG_READ_SWAP_SUPPORTED
5003    if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
5004       png_do_swap(row_info, png_ptr->row_buf + 1);
5005 #endif
5006 #endif
5007 
5008 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
5009    if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
5010    {
5011       if (png_ptr->read_user_transform_fn != NULL)
5012          (*(png_ptr->read_user_transform_fn)) /* User read transform function */
5013              (png_ptr,     /* png_ptr */
5014              row_info,     /* row_info: */
5015                 /*  png_uint_32 width;       width of row */
5016                 /*  png_size_t rowbytes;     number of bytes in row */
5017                 /*  png_byte color_type;     color type of pixels */
5018                 /*  png_byte bit_depth;      bit depth of samples */
5019                 /*  png_byte channels;       number of channels (1-4) */
5020                 /*  png_byte pixel_depth;    bits per pixel (depth*channels) */
5021              png_ptr->row_buf + 1);    /* start of pixel data for row */
5022 #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
5023       if (png_ptr->user_transform_depth != 0)
5024          row_info->bit_depth = png_ptr->user_transform_depth;
5025 
5026       if (png_ptr->user_transform_channels != 0)
5027          row_info->channels = png_ptr->user_transform_channels;
5028 #endif
5029       row_info->pixel_depth = (png_byte)(row_info->bit_depth *
5030           row_info->channels);
5031 
5032       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
5033    }
5034 #endif
5035 }
5036 
5037 #endif /* READ_TRANSFORMS */
5038 #endif /* READ */