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