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