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 /* pngread.c - read a PNG file
  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.17 [March 26, 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 routines that an application calls directly to
  42  * read a PNG file or stream.
  43  */
  44 
  45 #include "pngpriv.h"
  46 #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
  47 #  include <errno.h>
  48 #endif
  49 
  50 #ifdef PNG_READ_SUPPORTED
  51 
  52 /* Create a PNG structure for reading, and allocate any memory needed. */
  53 PNG_FUNCTION(png_structp,PNGAPI
  54 png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
  55     png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
  56 {
  57 #ifndef PNG_USER_MEM_SUPPORTED
  58    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
  59       error_fn, warn_fn, NULL, NULL, NULL);
  60 #else
  61    return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
  62        warn_fn, NULL, NULL, NULL);
  63 }
  64 
  65 /* Alternate create PNG structure for reading, and allocate any memory
  66  * needed.
  67  */
  68 PNG_FUNCTION(png_structp,PNGAPI
  69 png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
  70     png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
  71     png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
  72 {
  73    png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
  74       error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
  75 #endif /* USER_MEM */
  76 
  77    if (png_ptr != NULL)
  78    {
  79       png_ptr->mode = PNG_IS_READ_STRUCT;
  80 
  81       /* Added in libpng-1.6.0; this can be used to detect a read structure if
  82        * required (it will be zero in a write structure.)
  83        */
  84 #     ifdef PNG_SEQUENTIAL_READ_SUPPORTED
  85          png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;
  86 #     endif
  87 
  88 #     ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED
  89          png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
  90 
  91          /* In stable builds only warn if an application error can be completely
  92           * handled.
  93           */
  94 #        if PNG_RELEASE_BUILD
  95             png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
  96 #        endif
  97 #     endif
  98 
  99       /* TODO: delay this, it can be done in png_init_io (if the app doesn't
 100        * do it itself) avoiding setting the default function if it is not
 101        * required.
 102        */
 103       png_set_read_fn(png_ptr, NULL, NULL);
 104    }
 105 
 106    return png_ptr;
 107 }
 108 
 109 
 110 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 111 /* Read the information before the actual image data.  This has been
 112  * changed in v0.90 to allow reading a file that already has the magic
 113  * bytes read from the stream.  You can tell libpng how many bytes have
 114  * been read from the beginning of the stream (up to the maximum of 8)
 115  * via png_set_sig_bytes(), and we will only check the remaining bytes
 116  * here.  The application can then have access to the signature bytes we
 117  * read if it is determined that this isn't a valid PNG file.
 118  */
 119 void PNGAPI
 120 png_read_info(png_structrp png_ptr, png_inforp info_ptr)
 121 {
 122 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 123    int keep;
 124 #endif
 125 
 126    png_debug(1, "in png_read_info");
 127 
 128    if (png_ptr == NULL || info_ptr == NULL)
 129       return;
 130 
 131    /* Read and check the PNG file signature. */
 132    png_read_sig(png_ptr, info_ptr);
 133 
 134    for (;;)
 135    {
 136       png_uint_32 length = png_read_chunk_header(png_ptr);
 137       png_uint_32 chunk_name = png_ptr->chunk_name;
 138 
 139       /* IDAT logic needs to happen here to simplify getting the two flags
 140        * right.
 141        */
 142       if (chunk_name == png_IDAT)
 143       {
 144          if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
 145             png_chunk_error(png_ptr, "Missing IHDR before IDAT");
 146 
 147          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
 148              (png_ptr->mode & PNG_HAVE_PLTE) == 0)
 149             png_chunk_error(png_ptr, "Missing PLTE before IDAT");
 150 
 151          else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
 152             png_chunk_benign_error(png_ptr, "Too many IDATs found");
 153 
 154          png_ptr->mode |= PNG_HAVE_IDAT;
 155       }
 156 
 157       else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
 158          png_ptr->mode |= PNG_AFTER_IDAT;
 159 
 160       /* This should be a binary subdivision search or a hash for
 161        * matching the chunk name rather than a linear search.
 162        */
 163       if (chunk_name == png_IHDR)
 164          png_handle_IHDR(png_ptr, info_ptr, length);
 165 
 166       else if (chunk_name == png_IEND)
 167          png_handle_IEND(png_ptr, info_ptr, length);
 168 
 169 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 170       else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
 171       {
 172          png_handle_unknown(png_ptr, info_ptr, length, keep);
 173 
 174          if (chunk_name == png_PLTE)
 175             png_ptr->mode |= PNG_HAVE_PLTE;
 176 
 177          else if (chunk_name == png_IDAT)
 178          {
 179             png_ptr->idat_size = 0; /* It has been consumed */
 180             break;
 181          }
 182       }
 183 #endif
 184       else if (chunk_name == png_PLTE)
 185          png_handle_PLTE(png_ptr, info_ptr, length);
 186 
 187       else if (chunk_name == png_IDAT)
 188       {
 189          png_ptr->idat_size = length;
 190          break;
 191       }
 192 
 193 #ifdef PNG_READ_bKGD_SUPPORTED
 194       else if (chunk_name == png_bKGD)
 195          png_handle_bKGD(png_ptr, info_ptr, length);
 196 #endif
 197 
 198 #ifdef PNG_READ_cHRM_SUPPORTED
 199       else if (chunk_name == png_cHRM)
 200          png_handle_cHRM(png_ptr, info_ptr, length);
 201 #endif
 202 
 203 #ifdef PNG_READ_gAMA_SUPPORTED
 204       else if (chunk_name == png_gAMA)
 205          png_handle_gAMA(png_ptr, info_ptr, length);
 206 #endif
 207 
 208 #ifdef PNG_READ_hIST_SUPPORTED
 209       else if (chunk_name == png_hIST)
 210          png_handle_hIST(png_ptr, info_ptr, length);
 211 #endif
 212 
 213 #ifdef PNG_READ_oFFs_SUPPORTED
 214       else if (chunk_name == png_oFFs)
 215          png_handle_oFFs(png_ptr, info_ptr, length);
 216 #endif
 217 
 218 #ifdef PNG_READ_pCAL_SUPPORTED
 219       else if (chunk_name == png_pCAL)
 220          png_handle_pCAL(png_ptr, info_ptr, length);
 221 #endif
 222 
 223 #ifdef PNG_READ_sCAL_SUPPORTED
 224       else if (chunk_name == png_sCAL)
 225          png_handle_sCAL(png_ptr, info_ptr, length);
 226 #endif
 227 
 228 #ifdef PNG_READ_pHYs_SUPPORTED
 229       else if (chunk_name == png_pHYs)
 230          png_handle_pHYs(png_ptr, info_ptr, length);
 231 #endif
 232 
 233 #ifdef PNG_READ_sBIT_SUPPORTED
 234       else if (chunk_name == png_sBIT)
 235          png_handle_sBIT(png_ptr, info_ptr, length);
 236 #endif
 237 
 238 #ifdef PNG_READ_sRGB_SUPPORTED
 239       else if (chunk_name == png_sRGB)
 240          png_handle_sRGB(png_ptr, info_ptr, length);
 241 #endif
 242 
 243 #ifdef PNG_READ_iCCP_SUPPORTED
 244       else if (chunk_name == png_iCCP)
 245          png_handle_iCCP(png_ptr, info_ptr, length);
 246 #endif
 247 
 248 #ifdef PNG_READ_sPLT_SUPPORTED
 249       else if (chunk_name == png_sPLT)
 250          png_handle_sPLT(png_ptr, info_ptr, length);
 251 #endif
 252 
 253 #ifdef PNG_READ_tEXt_SUPPORTED
 254       else if (chunk_name == png_tEXt)
 255          png_handle_tEXt(png_ptr, info_ptr, length);
 256 #endif
 257 
 258 #ifdef PNG_READ_tIME_SUPPORTED
 259       else if (chunk_name == png_tIME)
 260          png_handle_tIME(png_ptr, info_ptr, length);
 261 #endif
 262 
 263 #ifdef PNG_READ_tRNS_SUPPORTED
 264       else if (chunk_name == png_tRNS)
 265          png_handle_tRNS(png_ptr, info_ptr, length);
 266 #endif
 267 
 268 #ifdef PNG_READ_zTXt_SUPPORTED
 269       else if (chunk_name == png_zTXt)
 270          png_handle_zTXt(png_ptr, info_ptr, length);
 271 #endif
 272 
 273 #ifdef PNG_READ_iTXt_SUPPORTED
 274       else if (chunk_name == png_iTXt)
 275          png_handle_iTXt(png_ptr, info_ptr, length);
 276 #endif
 277 
 278       else
 279          png_handle_unknown(png_ptr, info_ptr, length,
 280             PNG_HANDLE_CHUNK_AS_DEFAULT);
 281    }
 282 }
 283 #endif /* SEQUENTIAL_READ */
 284 
 285 /* Optional call to update the users info_ptr structure */
 286 void PNGAPI
 287 png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
 288 {
 289    png_debug(1, "in png_read_update_info");
 290 
 291    if (png_ptr != NULL)
 292    {
 293       if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
 294       {
 295          png_read_start_row(png_ptr);
 296 
 297 #        ifdef PNG_READ_TRANSFORMS_SUPPORTED
 298             png_read_transform_info(png_ptr, info_ptr);
 299 #        else
 300             PNG_UNUSED(info_ptr)
 301 #        endif
 302       }
 303 
 304       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
 305       else
 306          png_app_error(png_ptr,
 307             "png_read_update_info/png_start_read_image: duplicate call");
 308    }
 309 }
 310 
 311 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 312 /* Initialize palette, background, etc, after transformations
 313  * are set, but before any reading takes place.  This allows
 314  * the user to obtain a gamma-corrected palette, for example.
 315  * If the user doesn't call this, we will do it ourselves.
 316  */
 317 void PNGAPI
 318 png_start_read_image(png_structrp png_ptr)
 319 {
 320    png_debug(1, "in png_start_read_image");
 321 
 322    if (png_ptr != NULL)
 323    {
 324       if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
 325          png_read_start_row(png_ptr);
 326 
 327       /* New in 1.6.0 this avoids the bug of doing the initializations twice */
 328       else
 329          png_app_error(png_ptr,
 330             "png_start_read_image/png_read_update_info: duplicate call");
 331    }
 332 }
 333 #endif /* SEQUENTIAL_READ */
 334 
 335 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 336 #ifdef PNG_MNG_FEATURES_SUPPORTED
 337 /* Undoes intrapixel differencing,
 338  * NOTE: this is apparently only supported in the 'sequential' reader.
 339  */
 340 static void
 341 png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
 342 {
 343    png_debug(1, "in png_do_read_intrapixel");
 344 
 345    if (
 346        (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
 347    {
 348       int bytes_per_pixel;
 349       png_uint_32 row_width = row_info->width;
 350 
 351       if (row_info->bit_depth == 8)
 352       {
 353          png_bytep rp;
 354          png_uint_32 i;
 355 
 356          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 357             bytes_per_pixel = 3;
 358 
 359          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 360             bytes_per_pixel = 4;
 361 
 362          else
 363             return;
 364 
 365          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
 366          {
 367             *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
 368             *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
 369          }
 370       }
 371       else if (row_info->bit_depth == 16)
 372       {
 373          png_bytep rp;
 374          png_uint_32 i;
 375 
 376          if (row_info->color_type == PNG_COLOR_TYPE_RGB)
 377             bytes_per_pixel = 6;
 378 
 379          else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 380             bytes_per_pixel = 8;
 381 
 382          else
 383             return;
 384 
 385          for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
 386          {
 387             png_uint_32 s0   = (*(rp    ) << 8) | *(rp + 1);
 388             png_uint_32 s1   = (*(rp + 2) << 8) | *(rp + 3);
 389             png_uint_32 s2   = (*(rp + 4) << 8) | *(rp + 5);
 390             png_uint_32 red  = (s0 + s1 + 65536) & 0xffff;
 391             png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
 392             *(rp    ) = (png_byte)((red >> 8) & 0xff);
 393             *(rp + 1) = (png_byte)(red & 0xff);
 394             *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
 395             *(rp + 5) = (png_byte)(blue & 0xff);
 396          }
 397       }
 398    }
 399 }
 400 #endif /* MNG_FEATURES */
 401 
 402 void PNGAPI
 403 png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
 404 {
 405    png_row_info row_info;
 406 
 407    if (png_ptr == NULL)
 408       return;
 409 
 410    png_debug2(1, "in png_read_row (row %lu, pass %d)",
 411        (unsigned long)png_ptr->row_number, png_ptr->pass);
 412 
 413    /* png_read_start_row sets the information (in particular iwidth) for this
 414     * interlace pass.
 415     */
 416    if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
 417       png_read_start_row(png_ptr);
 418 
 419    /* 1.5.6: row_info moved out of png_struct to a local here. */
 420    row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
 421    row_info.color_type = png_ptr->color_type;
 422    row_info.bit_depth = png_ptr->bit_depth;
 423    row_info.channels = png_ptr->channels;
 424    row_info.pixel_depth = png_ptr->pixel_depth;
 425    row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
 426 
 427 #ifdef PNG_WARNINGS_SUPPORTED
 428    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
 429    {
 430    /* Check for transforms that have been set but were defined out */
 431 #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
 432    if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
 433       png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
 434 #endif
 435 
 436 #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
 437    if ((png_ptr->transformations & PNG_FILLER) != 0)
 438       png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
 439 #endif
 440 
 441 #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
 442     !defined(PNG_READ_PACKSWAP_SUPPORTED)
 443    if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
 444       png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
 445 #endif
 446 
 447 #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
 448    if ((png_ptr->transformations & PNG_PACK) != 0)
 449       png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
 450 #endif
 451 
 452 #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
 453    if ((png_ptr->transformations & PNG_SHIFT) != 0)
 454       png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
 455 #endif
 456 
 457 #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
 458    if ((png_ptr->transformations & PNG_BGR) != 0)
 459       png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
 460 #endif
 461 
 462 #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
 463    if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
 464       png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
 465 #endif
 466    }
 467 #endif /* WARNINGS */
 468 
 469 #ifdef PNG_READ_INTERLACING_SUPPORTED
 470    /* If interlaced and we do not need a new row, combine row and return.
 471     * Notice that the pixels we have from previous rows have been transformed
 472     * already; we can only combine like with like (transformed or
 473     * untransformed) and, because of the libpng API for interlaced images, this
 474     * means we must transform before de-interlacing.
 475     */
 476    if (png_ptr->interlaced != 0 &&
 477        (png_ptr->transformations & PNG_INTERLACE) != 0)
 478    {
 479       switch (png_ptr->pass)
 480       {
 481          case 0:
 482             if (png_ptr->row_number & 0x07)
 483             {
 484                if (dsp_row != NULL)
 485                   png_combine_row(png_ptr, dsp_row, 1/*display*/);
 486                png_read_finish_row(png_ptr);
 487                return;
 488             }
 489             break;
 490 
 491          case 1:
 492             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
 493             {
 494                if (dsp_row != NULL)
 495                   png_combine_row(png_ptr, dsp_row, 1/*display*/);
 496 
 497                png_read_finish_row(png_ptr);
 498                return;
 499             }
 500             break;
 501 
 502          case 2:
 503             if ((png_ptr->row_number & 0x07) != 4)
 504             {
 505                if (dsp_row != NULL && (png_ptr->row_number & 4))
 506                   png_combine_row(png_ptr, dsp_row, 1/*display*/);
 507 
 508                png_read_finish_row(png_ptr);
 509                return;
 510             }
 511             break;
 512 
 513          case 3:
 514             if ((png_ptr->row_number & 3) || png_ptr->width < 3)
 515             {
 516                if (dsp_row != NULL)
 517                   png_combine_row(png_ptr, dsp_row, 1/*display*/);
 518 
 519                png_read_finish_row(png_ptr);
 520                return;
 521             }
 522             break;
 523 
 524          case 4:
 525             if ((png_ptr->row_number & 3) != 2)
 526             {
 527                if (dsp_row != NULL && (png_ptr->row_number & 2))
 528                   png_combine_row(png_ptr, dsp_row, 1/*display*/);
 529 
 530                png_read_finish_row(png_ptr);
 531                return;
 532             }
 533             break;
 534 
 535          case 5:
 536             if ((png_ptr->row_number & 1) || png_ptr->width < 2)
 537             {
 538                if (dsp_row != NULL)
 539                   png_combine_row(png_ptr, dsp_row, 1/*display*/);
 540 
 541                png_read_finish_row(png_ptr);
 542                return;
 543             }
 544             break;
 545 
 546          default:
 547          case 6:
 548             if ((png_ptr->row_number & 1) == 0)
 549             {
 550                png_read_finish_row(png_ptr);
 551                return;
 552             }
 553             break;
 554       }
 555    }
 556 #endif
 557 
 558    if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
 559       png_error(png_ptr, "Invalid attempt to read row data");
 560 
 561    /* Fill the row with IDAT data: */
 562    png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
 563 
 564    if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
 565    {
 566       if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
 567          png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
 568             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
 569       else
 570          png_error(png_ptr, "bad adaptive filter value");
 571    }
 572 
 573    /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
 574     * 1.5.6, while the buffer really is this big in current versions of libpng
 575     * it may not be in the future, so this was changed just to copy the
 576     * interlaced count:
 577     */
 578    memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
 579 
 580 #ifdef PNG_MNG_FEATURES_SUPPORTED
 581    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
 582        (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
 583    {
 584       /* Intrapixel differencing */
 585       png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
 586    }
 587 #endif
 588 
 589 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
 590    if (png_ptr->transformations)
 591       png_do_read_transformations(png_ptr, &row_info);
 592 #endif
 593 
 594    /* The transformed pixel depth should match the depth now in row_info. */
 595    if (png_ptr->transformed_pixel_depth == 0)
 596    {
 597       png_ptr->transformed_pixel_depth = row_info.pixel_depth;
 598       if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
 599          png_error(png_ptr, "sequential row overflow");
 600    }
 601 
 602    else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
 603       png_error(png_ptr, "internal sequential row size calculation error");
 604 
 605 #ifdef PNG_READ_INTERLACING_SUPPORTED
 606    /* Expand interlaced rows to full size */
 607    if (png_ptr->interlaced != 0 &&
 608       (png_ptr->transformations & PNG_INTERLACE) != 0)
 609    {
 610       if (png_ptr->pass < 6)
 611          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
 612             png_ptr->transformations);
 613 
 614       if (dsp_row != NULL)
 615          png_combine_row(png_ptr, dsp_row, 1/*display*/);
 616 
 617       if (row != NULL)
 618          png_combine_row(png_ptr, row, 0/*row*/);
 619    }
 620 
 621    else
 622 #endif
 623    {
 624       if (row != NULL)
 625          png_combine_row(png_ptr, row, -1/*ignored*/);
 626 
 627       if (dsp_row != NULL)
 628          png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
 629    }
 630    png_read_finish_row(png_ptr);
 631 
 632    if (png_ptr->read_row_fn != NULL)
 633       (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
 634 
 635 }
 636 #endif /* SEQUENTIAL_READ */
 637 
 638 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 639 /* Read one or more rows of image data.  If the image is interlaced,
 640  * and png_set_interlace_handling() has been called, the rows need to
 641  * contain the contents of the rows from the previous pass.  If the
 642  * image has alpha or transparency, and png_handle_alpha()[*] has been
 643  * called, the rows contents must be initialized to the contents of the
 644  * screen.
 645  *
 646  * "row" holds the actual image, and pixels are placed in it
 647  * as they arrive.  If the image is displayed after each pass, it will
 648  * appear to "sparkle" in.  "display_row" can be used to display a
 649  * "chunky" progressive image, with finer detail added as it becomes
 650  * available.  If you do not want this "chunky" display, you may pass
 651  * NULL for display_row.  If you do not want the sparkle display, and
 652  * you have not called png_handle_alpha(), you may pass NULL for rows.
 653  * If you have called png_handle_alpha(), and the image has either an
 654  * alpha channel or a transparency chunk, you must provide a buffer for
 655  * rows.  In this case, you do not have to provide a display_row buffer
 656  * also, but you may.  If the image is not interlaced, or if you have
 657  * not called png_set_interlace_handling(), the display_row buffer will
 658  * be ignored, so pass NULL to it.
 659  *
 660  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
 661  */
 662 
 663 void PNGAPI
 664 png_read_rows(png_structrp png_ptr, png_bytepp row,
 665     png_bytepp display_row, png_uint_32 num_rows)
 666 {
 667    png_uint_32 i;
 668    png_bytepp rp;
 669    png_bytepp dp;
 670 
 671    png_debug(1, "in png_read_rows");
 672 
 673    if (png_ptr == NULL)
 674       return;
 675 
 676    rp = row;
 677    dp = display_row;
 678    if (rp != NULL && dp != NULL)
 679       for (i = 0; i < num_rows; i++)
 680       {
 681          png_bytep rptr = *rp++;
 682          png_bytep dptr = *dp++;
 683 
 684          png_read_row(png_ptr, rptr, dptr);
 685       }
 686 
 687    else if (rp != NULL)
 688       for (i = 0; i < num_rows; i++)
 689       {
 690          png_bytep rptr = *rp;
 691          png_read_row(png_ptr, rptr, NULL);
 692          rp++;
 693       }
 694 
 695    else if (dp != NULL)
 696       for (i = 0; i < num_rows; i++)
 697       {
 698          png_bytep dptr = *dp;
 699          png_read_row(png_ptr, NULL, dptr);
 700          dp++;
 701       }
 702 }
 703 #endif /* SEQUENTIAL_READ */
 704 
 705 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 706 /* Read the entire image.  If the image has an alpha channel or a tRNS
 707  * chunk, and you have called png_handle_alpha()[*], you will need to
 708  * initialize the image to the current image that PNG will be overlaying.
 709  * We set the num_rows again here, in case it was incorrectly set in
 710  * png_read_start_row() by a call to png_read_update_info() or
 711  * png_start_read_image() if png_set_interlace_handling() wasn't called
 712  * prior to either of these functions like it should have been.  You can
 713  * only call this function once.  If you desire to have an image for
 714  * each pass of a interlaced image, use png_read_rows() instead.
 715  *
 716  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
 717  */
 718 void PNGAPI
 719 png_read_image(png_structrp png_ptr, png_bytepp image)
 720 {
 721    png_uint_32 i, image_height;
 722    int pass, j;
 723    png_bytepp rp;
 724 
 725    png_debug(1, "in png_read_image");
 726 
 727    if (png_ptr == NULL)
 728       return;
 729 
 730 #ifdef PNG_READ_INTERLACING_SUPPORTED
 731    if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
 732    {
 733       pass = png_set_interlace_handling(png_ptr);
 734       /* And make sure transforms are initialized. */
 735       png_start_read_image(png_ptr);
 736    }
 737    else
 738    {
 739       if (png_ptr->interlaced != 0 &&
 740           (png_ptr->transformations & PNG_INTERLACE) == 0)
 741       {
 742          /* Caller called png_start_read_image or png_read_update_info without
 743           * first turning on the PNG_INTERLACE transform.  We can fix this here,
 744           * but the caller should do it!
 745           */
 746          png_warning(png_ptr, "Interlace handling should be turned on when "
 747             "using png_read_image");
 748          /* Make sure this is set correctly */
 749          png_ptr->num_rows = png_ptr->height;
 750       }
 751 
 752       /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
 753        * the above error case.
 754        */
 755       pass = png_set_interlace_handling(png_ptr);
 756    }
 757 #else
 758    if (png_ptr->interlaced)
 759       png_error(png_ptr,
 760           "Cannot read interlaced image -- interlace handler disabled");
 761 
 762    pass = 1;
 763 #endif
 764 
 765    image_height=png_ptr->height;
 766 
 767    for (j = 0; j < pass; j++)
 768    {
 769       rp = image;
 770       for (i = 0; i < image_height; i++)
 771       {
 772          png_read_row(png_ptr, *rp, NULL);
 773          rp++;
 774       }
 775    }
 776 }
 777 #endif /* SEQUENTIAL_READ */
 778 
 779 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 780 /* Read the end of the PNG file.  Will not read past the end of the
 781  * file, will verify the end is accurate, and will read any comments
 782  * or time information at the end of the file, if info is not NULL.
 783  */
 784 void PNGAPI
 785 png_read_end(png_structrp png_ptr, png_inforp info_ptr)
 786 {
 787 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 788    int keep;
 789 #endif
 790 
 791    png_debug(1, "in png_read_end");
 792 
 793    if (png_ptr == NULL)
 794       return;
 795 
 796    /* If png_read_end is called in the middle of reading the rows there may
 797     * still be pending IDAT data and an owned zstream.  Deal with this here.
 798     */
 799 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 800    if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0)
 801 #endif
 802       png_read_finish_IDAT(png_ptr);
 803 
 804 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
 805    /* Report invalid palette index; added at libng-1.5.10 */
 806    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
 807       png_ptr->num_palette_max > png_ptr->num_palette)
 808      png_benign_error(png_ptr, "Read palette index exceeding num_palette");
 809 #endif
 810 
 811    do
 812    {
 813       png_uint_32 length = png_read_chunk_header(png_ptr);
 814       png_uint_32 chunk_name = png_ptr->chunk_name;
 815 
 816       if (chunk_name == png_IEND)
 817          png_handle_IEND(png_ptr, info_ptr, length);
 818 
 819       else if (chunk_name == png_IHDR)
 820          png_handle_IHDR(png_ptr, info_ptr, length);
 821 
 822       else if (info_ptr == NULL)
 823          png_crc_finish(png_ptr, length);
 824 
 825 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 826       else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
 827       {
 828          if (chunk_name == png_IDAT)
 829          {
 830             if ((length > 0) ||
 831                 (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
 832                png_benign_error(png_ptr, "Too many IDATs found");
 833          }
 834          png_handle_unknown(png_ptr, info_ptr, length, keep);
 835          if (chunk_name == png_PLTE)
 836             png_ptr->mode |= PNG_HAVE_PLTE;
 837       }
 838 #endif
 839 
 840       else if (chunk_name == png_IDAT)
 841       {
 842          /* Zero length IDATs are legal after the last IDAT has been
 843           * read, but not after other chunks have been read.
 844           */
 845          if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
 846             png_benign_error(png_ptr, "Too many IDATs found");
 847 
 848          png_crc_finish(png_ptr, length);
 849       }
 850       else if (chunk_name == png_PLTE)
 851          png_handle_PLTE(png_ptr, info_ptr, length);
 852 
 853 #ifdef PNG_READ_bKGD_SUPPORTED
 854       else if (chunk_name == png_bKGD)
 855          png_handle_bKGD(png_ptr, info_ptr, length);
 856 #endif
 857 
 858 #ifdef PNG_READ_cHRM_SUPPORTED
 859       else if (chunk_name == png_cHRM)
 860          png_handle_cHRM(png_ptr, info_ptr, length);
 861 #endif
 862 
 863 #ifdef PNG_READ_gAMA_SUPPORTED
 864       else if (chunk_name == png_gAMA)
 865          png_handle_gAMA(png_ptr, info_ptr, length);
 866 #endif
 867 
 868 #ifdef PNG_READ_hIST_SUPPORTED
 869       else if (chunk_name == png_hIST)
 870          png_handle_hIST(png_ptr, info_ptr, length);
 871 #endif
 872 
 873 #ifdef PNG_READ_oFFs_SUPPORTED
 874       else if (chunk_name == png_oFFs)
 875          png_handle_oFFs(png_ptr, info_ptr, length);
 876 #endif
 877 
 878 #ifdef PNG_READ_pCAL_SUPPORTED
 879       else if (chunk_name == png_pCAL)
 880          png_handle_pCAL(png_ptr, info_ptr, length);
 881 #endif
 882 
 883 #ifdef PNG_READ_sCAL_SUPPORTED
 884       else if (chunk_name == png_sCAL)
 885          png_handle_sCAL(png_ptr, info_ptr, length);
 886 #endif
 887 
 888 #ifdef PNG_READ_pHYs_SUPPORTED
 889       else if (chunk_name == png_pHYs)
 890          png_handle_pHYs(png_ptr, info_ptr, length);
 891 #endif
 892 
 893 #ifdef PNG_READ_sBIT_SUPPORTED
 894       else if (chunk_name == png_sBIT)
 895          png_handle_sBIT(png_ptr, info_ptr, length);
 896 #endif
 897 
 898 #ifdef PNG_READ_sRGB_SUPPORTED
 899       else if (chunk_name == png_sRGB)
 900          png_handle_sRGB(png_ptr, info_ptr, length);
 901 #endif
 902 
 903 #ifdef PNG_READ_iCCP_SUPPORTED
 904       else if (chunk_name == png_iCCP)
 905          png_handle_iCCP(png_ptr, info_ptr, length);
 906 #endif
 907 
 908 #ifdef PNG_READ_sPLT_SUPPORTED
 909       else if (chunk_name == png_sPLT)
 910          png_handle_sPLT(png_ptr, info_ptr, length);
 911 #endif
 912 
 913 #ifdef PNG_READ_tEXt_SUPPORTED
 914       else if (chunk_name == png_tEXt)
 915          png_handle_tEXt(png_ptr, info_ptr, length);
 916 #endif
 917 
 918 #ifdef PNG_READ_tIME_SUPPORTED
 919       else if (chunk_name == png_tIME)
 920          png_handle_tIME(png_ptr, info_ptr, length);
 921 #endif
 922 
 923 #ifdef PNG_READ_tRNS_SUPPORTED
 924       else if (chunk_name == png_tRNS)
 925          png_handle_tRNS(png_ptr, info_ptr, length);
 926 #endif
 927 
 928 #ifdef PNG_READ_zTXt_SUPPORTED
 929       else if (chunk_name == png_zTXt)
 930          png_handle_zTXt(png_ptr, info_ptr, length);
 931 #endif
 932 
 933 #ifdef PNG_READ_iTXt_SUPPORTED
 934       else if (chunk_name == png_iTXt)
 935          png_handle_iTXt(png_ptr, info_ptr, length);
 936 #endif
 937 
 938       else
 939          png_handle_unknown(png_ptr, info_ptr, length,
 940             PNG_HANDLE_CHUNK_AS_DEFAULT);
 941    } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
 942 }
 943 #endif /* SEQUENTIAL_READ */
 944 
 945 /* Free all memory used in the read struct */
 946 static void
 947 png_read_destroy(png_structrp png_ptr)
 948 {
 949    png_debug(1, "in png_read_destroy");
 950 
 951 #ifdef PNG_READ_GAMMA_SUPPORTED
 952    png_destroy_gamma_table(png_ptr);
 953 #endif
 954 
 955    png_free(png_ptr, png_ptr->big_row_buf);
 956    png_ptr->big_row_buf = NULL;
 957    png_free(png_ptr, png_ptr->big_prev_row);
 958    png_ptr->big_prev_row = NULL;
 959    png_free(png_ptr, png_ptr->read_buffer);
 960    png_ptr->read_buffer = NULL;
 961 
 962 #ifdef PNG_READ_QUANTIZE_SUPPORTED
 963    png_free(png_ptr, png_ptr->palette_lookup);
 964    png_ptr->palette_lookup = NULL;
 965    png_free(png_ptr, png_ptr->quantize_index);
 966    png_ptr->quantize_index = NULL;
 967 #endif
 968 
 969    if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)
 970    {
 971       png_zfree(png_ptr, png_ptr->palette);
 972       png_ptr->palette = NULL;
 973    }
 974    png_ptr->free_me &= ~PNG_FREE_PLTE;
 975 
 976 #if defined(PNG_tRNS_SUPPORTED) || \
 977     defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
 978    if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)
 979    {
 980       png_free(png_ptr, png_ptr->trans_alpha);
 981       png_ptr->trans_alpha = NULL;
 982    }
 983    png_ptr->free_me &= ~PNG_FREE_TRNS;
 984 #endif
 985 
 986    inflateEnd(&png_ptr->zstream);
 987 
 988 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 989    png_free(png_ptr, png_ptr->save_buffer);
 990    png_ptr->save_buffer = NULL;
 991 #endif
 992 
 993 #if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \
 994    defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
 995    png_free(png_ptr, png_ptr->unknown_chunk.data);
 996    png_ptr->unknown_chunk.data = NULL;
 997 #endif
 998 
 999 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
1000    png_free(png_ptr, png_ptr->chunk_list);
1001    png_ptr->chunk_list = NULL;
1002 #endif
1003 
1004    /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error
1005     * callbacks are still set at this point.  They are required to complete the
1006     * destruction of the png_struct itself.
1007     */
1008 }
1009 
1010 /* Free all memory used by the read */
1011 void PNGAPI
1012 png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
1013     png_infopp end_info_ptr_ptr)
1014 {
1015    png_structrp png_ptr = NULL;
1016 
1017    png_debug(1, "in png_destroy_read_struct");
1018 
1019    if (png_ptr_ptr != NULL)
1020       png_ptr = *png_ptr_ptr;
1021 
1022    if (png_ptr == NULL)
1023       return;
1024 
1025    /* libpng 1.6.0: use the API to destroy info structs to ensure consistent
1026     * behavior.  Prior to 1.6.0 libpng did extra 'info' destruction in this API.
1027     * The extra was, apparently, unnecessary yet this hides memory leak bugs.
1028     */
1029    png_destroy_info_struct(png_ptr, end_info_ptr_ptr);
1030    png_destroy_info_struct(png_ptr, info_ptr_ptr);
1031 
1032    *png_ptr_ptr = NULL;
1033    png_read_destroy(png_ptr);
1034    png_destroy_png_struct(png_ptr);
1035 }
1036 
1037 void PNGAPI
1038 png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
1039 {
1040    if (png_ptr == NULL)
1041       return;
1042 
1043    png_ptr->read_row_fn = read_row_fn;
1044 }
1045 
1046 
1047 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1048 #ifdef PNG_INFO_IMAGE_SUPPORTED
1049 void PNGAPI
1050 png_read_png(png_structrp png_ptr, png_inforp info_ptr,
1051                            int transforms,
1052                            voidp params)
1053 {
1054    if (png_ptr == NULL || info_ptr == NULL)
1055       return;
1056 
1057    /* png_read_info() gives us all of the information from the
1058     * PNG file before the first IDAT (image data chunk).
1059     */
1060    png_read_info(png_ptr, info_ptr);
1061    if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
1062       png_error(png_ptr, "Image is too high to process with png_read_png()");
1063 
1064    /* -------------- image transformations start here ------------------- */
1065    /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM
1066     * is not implemented.  This will only happen in de-configured (non-default)
1067     * libpng builds.  The results can be unexpected - png_read_png may return
1068     * short or mal-formed rows because the transform is skipped.
1069     */
1070 
1071    /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
1072     */
1073    if ((transforms & PNG_TRANSFORM_SCALE_16) != 0)
1074       /* Added at libpng-1.5.4. "strip_16" produces the same result that it
1075        * did in earlier versions, while "scale_16" is now more accurate.
1076        */
1077 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1078       png_set_scale_16(png_ptr);
1079 #else
1080       png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");
1081 #endif
1082 
1083    /* If both SCALE and STRIP are required pngrtran will effectively cancel the
1084     * latter by doing SCALE first.  This is ok and allows apps not to check for
1085     * which is supported to get the right answer.
1086     */
1087    if ((transforms & PNG_TRANSFORM_STRIP_16) != 0)
1088 #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1089       png_set_strip_16(png_ptr);
1090 #else
1091       png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");
1092 #endif
1093 
1094    /* Strip alpha bytes from the input data without combining with
1095     * the background (not recommended).
1096     */
1097    if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0)
1098 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1099       png_set_strip_alpha(png_ptr);
1100 #else
1101       png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");
1102 #endif
1103 
1104    /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1105     * byte into separate bytes (useful for paletted and grayscale images).
1106     */
1107    if ((transforms & PNG_TRANSFORM_PACKING) != 0)
1108 #ifdef PNG_READ_PACK_SUPPORTED
1109       png_set_packing(png_ptr);
1110 #else
1111       png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
1112 #endif
1113 
1114    /* Change the order of packed pixels to least significant bit first
1115     * (not useful if you are using png_set_packing).
1116     */
1117    if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
1118 #ifdef PNG_READ_PACKSWAP_SUPPORTED
1119       png_set_packswap(png_ptr);
1120 #else
1121       png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
1122 #endif
1123 
1124    /* Expand paletted colors into true RGB triplets
1125     * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
1126     * Expand paletted or RGB images with transparency to full alpha
1127     * channels so the data will be available as RGBA quartets.
1128     */
1129    if ((transforms & PNG_TRANSFORM_EXPAND) != 0)
1130 #ifdef PNG_READ_EXPAND_SUPPORTED
1131       png_set_expand(png_ptr);
1132 #else
1133       png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");
1134 #endif
1135 
1136    /* We don't handle background color or gamma transformation or quantizing.
1137     */
1138 
1139    /* Invert monochrome files to have 0 as white and 1 as black
1140     */
1141    if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
1142 #ifdef PNG_READ_INVERT_SUPPORTED
1143       png_set_invert_mono(png_ptr);
1144 #else
1145       png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
1146 #endif
1147 
1148    /* If you want to shift the pixel values from the range [0,255] or
1149     * [0,65535] to the original [0,7] or [0,31], or whatever range the
1150     * colors were originally in:
1151     */
1152    if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
1153 #ifdef PNG_READ_SHIFT_SUPPORTED
1154       if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
1155          png_set_shift(png_ptr, &info_ptr->sig_bit);
1156 #else
1157       png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
1158 #endif
1159 
1160    /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
1161    if ((transforms & PNG_TRANSFORM_BGR) != 0)
1162 #ifdef PNG_READ_BGR_SUPPORTED
1163       png_set_bgr(png_ptr);
1164 #else
1165       png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
1166 #endif
1167 
1168    /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
1169    if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
1170 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1171       png_set_swap_alpha(png_ptr);
1172 #else
1173       png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
1174 #endif
1175 
1176    /* Swap bytes of 16-bit files to least significant byte first */
1177    if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
1178 #ifdef PNG_READ_SWAP_SUPPORTED
1179       png_set_swap(png_ptr);
1180 #else
1181       png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
1182 #endif
1183 
1184 /* Added at libpng-1.2.41 */
1185    /* Invert the alpha channel from opacity to transparency */
1186    if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
1187 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1188       png_set_invert_alpha(png_ptr);
1189 #else
1190       png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
1191 #endif
1192 
1193 /* Added at libpng-1.2.41 */
1194    /* Expand grayscale image to RGB */
1195    if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0)
1196 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1197       png_set_gray_to_rgb(png_ptr);
1198 #else
1199       png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");
1200 #endif
1201 
1202 /* Added at libpng-1.5.4 */
1203    if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0)
1204 #ifdef PNG_READ_EXPAND_16_SUPPORTED
1205       png_set_expand_16(png_ptr);
1206 #else
1207       png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");
1208 #endif
1209 
1210    /* We don't handle adding filler bytes */
1211 
1212    /* We use png_read_image and rely on that for interlace handling, but we also
1213     * call png_read_update_info therefore must turn on interlace handling now:
1214     */
1215    (void)png_set_interlace_handling(png_ptr);
1216 
1217    /* Optional call to gamma correct and add the background to the palette
1218     * and update info structure.  REQUIRED if you are expecting libpng to
1219     * update the palette for you (i.e., you selected such a transform above).
1220     */
1221    png_read_update_info(png_ptr, info_ptr);
1222 
1223    /* -------------- image transformations end here ------------------- */
1224 
1225    png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1226    if (info_ptr->row_pointers == NULL)
1227    {
1228       png_uint_32 iptr;
1229 
1230       info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
1231           info_ptr->height * (sizeof (png_bytep))));
1232 
1233       for (iptr=0; iptr<info_ptr->height; iptr++)
1234          info_ptr->row_pointers[iptr] = NULL;
1235 
1236       info_ptr->free_me |= PNG_FREE_ROWS;
1237 
1238       for (iptr = 0; iptr < info_ptr->height; iptr++)
1239          info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,
1240              png_malloc(png_ptr, info_ptr->rowbytes));
1241    }
1242 
1243    png_read_image(png_ptr, info_ptr->row_pointers);
1244    info_ptr->valid |= PNG_INFO_IDAT;
1245 
1246    /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
1247    png_read_end(png_ptr, info_ptr);
1248 
1249    PNG_UNUSED(params)
1250 }
1251 #endif /* INFO_IMAGE */
1252 #endif /* SEQUENTIAL_READ */
1253 
1254 #ifdef PNG_SIMPLIFIED_READ_SUPPORTED
1255 /* SIMPLIFIED READ
1256  *
1257  * This code currently relies on the sequential reader, though it could easily
1258  * be made to work with the progressive one.
1259  */
1260 /* Arguments to png_image_finish_read: */
1261 
1262 /* Encoding of PNG data (used by the color-map code) */
1263 #  define P_NOTSET  0 /* File encoding not yet known */
1264 #  define P_sRGB    1 /* 8-bit encoded to sRGB gamma */
1265 #  define P_LINEAR  2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
1266 #  define P_FILE    3 /* 8-bit encoded to file gamma, not sRGB or linear */
1267 #  define P_LINEAR8 4 /* 8-bit linear: only from a file value */
1268 
1269 /* Color-map processing: after libpng has run on the PNG image further
1270  * processing may be needed to convert the data to color-map indices.
1271  */
1272 #define PNG_CMAP_NONE      0
1273 #define PNG_CMAP_GA        1 /* Process GA data to a color-map with alpha */
1274 #define PNG_CMAP_TRANS     2 /* Process GA data to a background index */
1275 #define PNG_CMAP_RGB       3 /* Process RGB data */
1276 #define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */
1277 
1278 /* The following document where the background is for each processing case. */
1279 #define PNG_CMAP_NONE_BACKGROUND      256
1280 #define PNG_CMAP_GA_BACKGROUND        231
1281 #define PNG_CMAP_TRANS_BACKGROUND     254
1282 #define PNG_CMAP_RGB_BACKGROUND       256
1283 #define PNG_CMAP_RGB_ALPHA_BACKGROUND 216
1284 
1285 typedef struct
1286 {
1287    /* Arguments: */
1288    png_imagep image;
1289    png_voidp  buffer;
1290    png_int_32 row_stride;
1291    png_voidp  colormap;
1292    png_const_colorp background;
1293    /* Local variables: */
1294    png_voidp       local_row;
1295    png_voidp       first_row;
1296    ptrdiff_t       row_bytes;           /* step between rows */
1297    int             file_encoding;       /* E_ values above */
1298    png_fixed_point gamma_to_linear;     /* For P_FILE, reciprocal of gamma */
1299    int             colormap_processing; /* PNG_CMAP_ values above */
1300 } png_image_read_control;
1301 
1302 /* Do all the *safe* initialization - 'safe' means that png_error won't be
1303  * called, so setting up the jmp_buf is not required.  This means that anything
1304  * called from here must *not* call png_malloc - it has to call png_malloc_warn
1305  * instead so that control is returned safely back to this routine.
1306  */
1307 static int
1308 png_image_read_init(png_imagep image)
1309 {
1310    if (image->opaque == NULL)
1311    {
1312       png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,
1313           png_safe_error, png_safe_warning);
1314 
1315       /* And set the rest of the structure to NULL to ensure that the various
1316        * fields are consistent.
1317        */
1318       memset(image, 0, (sizeof *image));
1319       image->version = PNG_IMAGE_VERSION;
1320 
1321       if (png_ptr != NULL)
1322       {
1323          png_infop info_ptr = png_create_info_struct(png_ptr);
1324 
1325          if (info_ptr != NULL)
1326          {
1327             png_controlp control = png_voidcast(png_controlp,
1328                png_malloc_warn(png_ptr, (sizeof *control)));
1329 
1330             if (control != NULL)
1331             {
1332                memset(control, 0, (sizeof *control));
1333 
1334                control->png_ptr = png_ptr;
1335                control->info_ptr = info_ptr;
1336                control->for_write = 0;
1337 
1338                image->opaque = control;
1339                return 1;
1340             }
1341 
1342             /* Error clean up */
1343             png_destroy_info_struct(png_ptr, &info_ptr);
1344          }
1345 
1346          png_destroy_read_struct(&png_ptr, NULL, NULL);
1347       }
1348 
1349       return png_image_error(image, "png_image_read: out of memory");
1350    }
1351 
1352    return png_image_error(image, "png_image_read: opaque pointer not NULL");
1353 }
1354 
1355 /* Utility to find the base format of a PNG file from a png_struct. */
1356 static png_uint_32
1357 png_image_format(png_structrp png_ptr)
1358 {
1359    png_uint_32 format = 0;
1360 
1361    if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
1362       format |= PNG_FORMAT_FLAG_COLOR;
1363 
1364    if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
1365       format |= PNG_FORMAT_FLAG_ALPHA;
1366 
1367    /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS
1368     * sets the png_struct fields; that's all we are interested in here.  The
1369     * precise interaction with an app call to png_set_tRNS and PNG file reading
1370     * is unclear.
1371     */
1372    else if (png_ptr->num_trans > 0)
1373       format |= PNG_FORMAT_FLAG_ALPHA;
1374 
1375    if (png_ptr->bit_depth == 16)
1376       format |= PNG_FORMAT_FLAG_LINEAR;
1377 
1378    if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0)
1379       format |= PNG_FORMAT_FLAG_COLORMAP;
1380 
1381    return format;
1382 }
1383 
1384 /* Is the given gamma significantly different from sRGB?  The test is the same
1385  * one used in pngrtran.c when deciding whether to do gamma correction.  The
1386  * arithmetic optimizes the division by using the fact that the inverse of the
1387  * file sRGB gamma is 2.2
1388  */
1389 static int
1390 png_gamma_not_sRGB(png_fixed_point g)
1391 {
1392    if (g < PNG_FP_1)
1393    {
1394       /* An uninitialized gamma is assumed to be sRGB for the simplified API. */
1395       if (g == 0)
1396          return 0;
1397 
1398       return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
1399    }
1400 
1401    return 1;
1402 }
1403 
1404 /* Do the main body of a 'png_image_begin_read' function; read the PNG file
1405  * header and fill in all the information.  This is executed in a safe context,
1406  * unlike the init routine above.
1407  */
1408 static int
1409 png_image_read_header(png_voidp argument)
1410 {
1411    png_imagep image = png_voidcast(png_imagep, argument);
1412    png_structrp png_ptr = image->opaque->png_ptr;
1413    png_inforp info_ptr = image->opaque->info_ptr;
1414 
1415    png_set_benign_errors(png_ptr, 1/*warn*/);
1416    png_read_info(png_ptr, info_ptr);
1417 
1418    /* Do this the fast way; just read directly out of png_struct. */
1419    image->width = png_ptr->width;
1420    image->height = png_ptr->height;
1421 
1422    {
1423       png_uint_32 format = png_image_format(png_ptr);
1424 
1425       image->format = format;
1426 
1427 #ifdef PNG_COLORSPACE_SUPPORTED
1428       /* Does the colorspace match sRGB?  If there is no color endpoint
1429        * (colorant) information assume yes, otherwise require the
1430        * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set.  If the
1431        * colorspace has been determined to be invalid ignore it.
1432        */
1433       if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
1434          & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
1435             PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
1436          image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
1437 #endif
1438    }
1439 
1440    /* We need the maximum number of entries regardless of the format the
1441     * application sets here.
1442     */
1443    {
1444       png_uint_32 cmap_entries;
1445 
1446       switch (png_ptr->color_type)
1447       {
1448          case PNG_COLOR_TYPE_GRAY:
1449             cmap_entries = 1U << png_ptr->bit_depth;
1450             break;
1451 
1452          case PNG_COLOR_TYPE_PALETTE:
1453             cmap_entries = png_ptr->num_palette;
1454             break;
1455 
1456          default:
1457             cmap_entries = 256;
1458             break;
1459       }
1460 
1461       if (cmap_entries > 256)
1462          cmap_entries = 256;
1463 
1464       image->colormap_entries = cmap_entries;
1465    }
1466 
1467    return 1;
1468 }
1469 
1470 #ifdef PNG_STDIO_SUPPORTED
1471 int PNGAPI
1472 png_image_begin_read_from_stdio(png_imagep image, FILE* file)
1473 {
1474    if (image != NULL && image->version == PNG_IMAGE_VERSION)
1475    {
1476       if (file != NULL)
1477       {
1478          if (png_image_read_init(image) != 0)
1479          {
1480             /* This is slightly evil, but png_init_io doesn't do anything other
1481              * than this and we haven't changed the standard IO functions so
1482              * this saves a 'safe' function.
1483              */
1484             image->opaque->png_ptr->io_ptr = file;
1485             return png_safe_execute(image, png_image_read_header, image);
1486          }
1487       }
1488 
1489       else
1490          return png_image_error(image,
1491             "png_image_begin_read_from_stdio: invalid argument");
1492    }
1493 
1494    else if (image != NULL)
1495       return png_image_error(image,
1496          "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
1497 
1498    return 0;
1499 }
1500 
1501 int PNGAPI
1502 png_image_begin_read_from_file(png_imagep image, const char *file_name)
1503 {
1504    if (image != NULL && image->version == PNG_IMAGE_VERSION)
1505    {
1506       if (file_name != NULL)
1507       {
1508          FILE *fp = fopen(file_name, "rb");
1509 
1510          if (fp != NULL)
1511          {
1512             if (png_image_read_init(image) != 0)
1513             {
1514                image->opaque->png_ptr->io_ptr = fp;
1515                image->opaque->owned_file = 1;
1516                return png_safe_execute(image, png_image_read_header, image);
1517             }
1518 
1519             /* Clean up: just the opened file. */
1520             (void)fclose(fp);
1521          }
1522 
1523          else
1524             return png_image_error(image, strerror(errno));
1525       }
1526 
1527       else
1528          return png_image_error(image,
1529             "png_image_begin_read_from_file: invalid argument");
1530    }
1531 
1532    else if (image != NULL)
1533       return png_image_error(image,
1534          "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
1535 
1536    return 0;
1537 }
1538 #endif /* STDIO */
1539 
1540 static void PNGCBAPI
1541 png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
1542 {
1543    if (png_ptr != NULL)
1544    {
1545       png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
1546       if (image != NULL)
1547       {
1548          png_controlp cp = image->opaque;
1549          if (cp != NULL)
1550          {
1551             png_const_bytep memory = cp->memory;
1552             png_size_t size = cp->size;
1553 
1554             if (memory != NULL && size >= need)
1555             {
1556                memcpy(out, memory, need);
1557                cp->memory = memory + need;
1558                cp->size = size - need;
1559                return;
1560             }
1561 
1562             png_error(png_ptr, "read beyond end of data");
1563          }
1564       }
1565 
1566       png_error(png_ptr, "invalid memory read");
1567    }
1568 }
1569 
1570 int PNGAPI png_image_begin_read_from_memory(png_imagep image,
1571    png_const_voidp memory, png_size_t size)
1572 {
1573    if (image != NULL && image->version == PNG_IMAGE_VERSION)
1574    {
1575       if (memory != NULL && size > 0)
1576       {
1577          if (png_image_read_init(image) != 0)
1578          {
1579             /* Now set the IO functions to read from the memory buffer and
1580              * store it into io_ptr.  Again do this in-place to avoid calling a
1581              * libpng function that requires error handling.
1582              */
1583             image->opaque->memory = png_voidcast(png_const_bytep, memory);
1584             image->opaque->size = size;
1585             image->opaque->png_ptr->io_ptr = image;
1586             image->opaque->png_ptr->read_data_fn = png_image_memory_read;
1587 
1588             return png_safe_execute(image, png_image_read_header, image);
1589          }
1590       }
1591 
1592       else
1593          return png_image_error(image,
1594             "png_image_begin_read_from_memory: invalid argument");
1595    }
1596 
1597    else if (image != NULL)
1598       return png_image_error(image,
1599          "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
1600 
1601    return 0;
1602 }
1603 
1604 /* Utility function to skip chunks that are not used by the simplified image
1605  * read functions and an appropriate macro to call it.
1606  */
1607 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
1608 static void
1609 png_image_skip_unused_chunks(png_structrp png_ptr)
1610 {
1611    /* Prepare the reader to ignore all recognized chunks whose data will not
1612     * be used, i.e., all chunks recognized by libpng except for those
1613     * involved in basic image reading:
1614     *
1615     *    IHDR, PLTE, IDAT, IEND
1616     *
1617     * Or image data handling:
1618     *
1619     *    tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.
1620     *
1621     * This provides a small performance improvement and eliminates any
1622     * potential vulnerability to security problems in the unused chunks.
1623     *
1624     * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
1625     * too.  This allows the simplified API to be compiled without iCCP support,
1626     * however if the support is there the chunk is still checked to detect
1627     * errors (which are unfortunately quite common.)
1628     */
1629    {
1630          static PNG_CONST png_byte chunks_to_process[] = {
1631             98,  75,  71,  68, '\0',  /* bKGD */
1632             99,  72,  82,  77, '\0',  /* cHRM */
1633            103,  65,  77,  65, '\0',  /* gAMA */
1634 #        ifdef PNG_READ_iCCP_SUPPORTED
1635            105,  67,  67,  80, '\0',  /* iCCP */
1636 #        endif
1637            115,  66,  73,  84, '\0',  /* sBIT */
1638            115,  82,  71,  66, '\0',  /* sRGB */
1639            };
1640 
1641        /* Ignore unknown chunks and all other chunks except for the
1642         * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
1643         */
1644        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
1645          NULL, -1);
1646 
1647        /* But do not ignore image data handling chunks */
1648        png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
1649          chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
1650     }
1651 }
1652 
1653 #  define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
1654 #else
1655 #  define PNG_SKIP_CHUNKS(p) ((void)0)
1656 #endif /* HANDLE_AS_UNKNOWN */
1657 
1658 /* The following macro gives the exact rounded answer for all values in the
1659  * range 0..255 (it actually divides by 51.2, but the rounding still generates
1660  * the correct numbers 0..5
1661  */
1662 #define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)
1663 
1664 /* Utility functions to make particular color-maps */
1665 static void
1666 set_file_encoding(png_image_read_control *display)
1667 {
1668    png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
1669    if (png_gamma_significant(g) != 0)
1670    {
1671       if (png_gamma_not_sRGB(g) != 0)
1672       {
1673          display->file_encoding = P_FILE;
1674          display->gamma_to_linear = png_reciprocal(g);
1675       }
1676 
1677       else
1678          display->file_encoding = P_sRGB;
1679    }
1680 
1681    else
1682       display->file_encoding = P_LINEAR8;
1683 }
1684 
1685 static unsigned int
1686 decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
1687 {
1688    if (encoding == P_FILE) /* double check */
1689       encoding = display->file_encoding;
1690 
1691    if (encoding == P_NOTSET) /* must be the file encoding */
1692    {
1693       set_file_encoding(display);
1694       encoding = display->file_encoding;
1695    }
1696 
1697    switch (encoding)
1698    {
1699       case P_FILE:
1700          value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
1701          break;
1702 
1703       case P_sRGB:
1704          value = png_sRGB_table[value];
1705          break;
1706 
1707       case P_LINEAR:
1708          break;
1709 
1710       case P_LINEAR8:
1711          value *= 257;
1712          break;
1713 
1714 #ifdef __GNUC__
1715       default:
1716          png_error(display->image->opaque->png_ptr,
1717             "unexpected encoding (internal error)");
1718 #endif
1719    }
1720 
1721    return value;
1722 }
1723 
1724 static png_uint_32
1725 png_colormap_compose(png_image_read_control *display,
1726    png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
1727    png_uint_32 background, int encoding)
1728 {
1729    /* The file value is composed on the background, the background has the given
1730     * encoding and so does the result, the file is encoded with P_FILE and the
1731     * file and alpha are 8-bit values.  The (output) encoding will always be
1732     * P_LINEAR or P_sRGB.
1733     */
1734    png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
1735    png_uint_32 b = decode_gamma(display, background, encoding);
1736 
1737    /* The alpha is always an 8-bit value (it comes from the palette), the value
1738     * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
1739     */
1740    f = f * alpha + b * (255-alpha);
1741 
1742    if (encoding == P_LINEAR)
1743    {
1744       /* Scale to 65535; divide by 255, approximately (in fact this is extremely
1745        * accurate, it divides by 255.00000005937181414556, with no overflow.)
1746        */
1747       f *= 257; /* Now scaled by 65535 */
1748       f += f >> 16;
1749       f = (f+32768) >> 16;
1750    }
1751 
1752    else /* P_sRGB */
1753       f = PNG_sRGB_FROM_LINEAR(f);
1754 
1755    return f;
1756 }
1757 
1758 /* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must
1759  * be 8-bit.
1760  */
1761 static void
1762 png_create_colormap_entry(png_image_read_control *display,
1763    png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
1764    png_uint_32 alpha, int encoding)
1765 {
1766    png_imagep image = display->image;
1767    const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
1768       P_LINEAR : P_sRGB;
1769    const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
1770       (red != green || green != blue);
1771 
1772    if (ip > 255)
1773       png_error(image->opaque->png_ptr, "color-map index out of range");
1774 
1775    /* Update the cache with whether the file gamma is significantly different
1776     * from sRGB.
1777     */
1778    if (encoding == P_FILE)
1779    {
1780       if (display->file_encoding == P_NOTSET)
1781          set_file_encoding(display);
1782 
1783       /* Note that the cached value may be P_FILE too, but if it is then the
1784        * gamma_to_linear member has been set.
1785        */
1786       encoding = display->file_encoding;
1787    }
1788 
1789    if (encoding == P_FILE)
1790    {
1791       png_fixed_point g = display->gamma_to_linear;
1792 
1793       red = png_gamma_16bit_correct(red*257, g);
1794       green = png_gamma_16bit_correct(green*257, g);
1795       blue = png_gamma_16bit_correct(blue*257, g);
1796 
1797       if (convert_to_Y != 0 || output_encoding == P_LINEAR)
1798       {
1799          alpha *= 257;
1800          encoding = P_LINEAR;
1801       }
1802 
1803       else
1804       {
1805          red = PNG_sRGB_FROM_LINEAR(red * 255);
1806          green = PNG_sRGB_FROM_LINEAR(green * 255);
1807          blue = PNG_sRGB_FROM_LINEAR(blue * 255);
1808          encoding = P_sRGB;
1809       }
1810    }
1811 
1812    else if (encoding == P_LINEAR8)
1813    {
1814       /* This encoding occurs quite frequently in test cases because PngSuite
1815        * includes a gAMA 1.0 chunk with most images.
1816        */
1817       red *= 257;
1818       green *= 257;
1819       blue *= 257;
1820       alpha *= 257;
1821       encoding = P_LINEAR;
1822    }
1823 
1824    else if (encoding == P_sRGB &&
1825        (convert_to_Y  != 0 || output_encoding == P_LINEAR))
1826    {
1827       /* The values are 8-bit sRGB values, but must be converted to 16-bit
1828        * linear.
1829        */
1830       red = png_sRGB_table[red];
1831       green = png_sRGB_table[green];
1832       blue = png_sRGB_table[blue];
1833       alpha *= 257;
1834       encoding = P_LINEAR;
1835    }
1836 
1837    /* This is set if the color isn't gray but the output is. */
1838    if (encoding == P_LINEAR)
1839    {
1840       if (convert_to_Y != 0)
1841       {
1842          /* NOTE: these values are copied from png_do_rgb_to_gray */
1843          png_uint_32 y = (png_uint_32)6968 * red  + (png_uint_32)23434 * green +
1844             (png_uint_32)2366 * blue;
1845 
1846          if (output_encoding == P_LINEAR)
1847             y = (y + 16384) >> 15;
1848 
1849          else
1850          {
1851             /* y is scaled by 32768, we need it scaled by 255: */
1852             y = (y + 128) >> 8;
1853             y *= 255;
1854             y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
1855             alpha = PNG_DIV257(alpha);
1856             encoding = P_sRGB;
1857          }
1858 
1859          blue = red = green = y;
1860       }
1861 
1862       else if (output_encoding == P_sRGB)
1863       {
1864          red = PNG_sRGB_FROM_LINEAR(red * 255);
1865          green = PNG_sRGB_FROM_LINEAR(green * 255);
1866          blue = PNG_sRGB_FROM_LINEAR(blue * 255);
1867          alpha = PNG_DIV257(alpha);
1868          encoding = P_sRGB;
1869       }
1870    }
1871 
1872    if (encoding != output_encoding)
1873       png_error(image->opaque->png_ptr, "bad encoding (internal error)");
1874 
1875    /* Store the value. */
1876    {
1877 #     ifdef PNG_FORMAT_AFIRST_SUPPORTED
1878          const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
1879             (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
1880 #     else
1881 #        define afirst 0
1882 #     endif
1883 #     ifdef PNG_FORMAT_BGR_SUPPORTED
1884          const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
1885 #     else
1886 #        define bgr 0
1887 #     endif
1888 
1889       if (output_encoding == P_LINEAR)
1890       {
1891          png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
1892 
1893          entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
1894 
1895          /* The linear 16-bit values must be pre-multiplied by the alpha channel
1896           * value, if less than 65535 (this is, effectively, composite on black
1897           * if the alpha channel is removed.)
1898           */
1899          switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
1900          {
1901             case 4:
1902                entry[afirst ? 0 : 3] = (png_uint_16)alpha;
1903                /* FALL THROUGH */
1904 
1905             case 3:
1906                if (alpha < 65535)
1907                {
1908                   if (alpha > 0)
1909                   {
1910                      blue = (blue * alpha + 32767U)/65535U;
1911                      green = (green * alpha + 32767U)/65535U;
1912                      red = (red * alpha + 32767U)/65535U;
1913                   }
1914 
1915                   else
1916                      red = green = blue = 0;
1917                }
1918                entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;
1919                entry[afirst + 1] = (png_uint_16)green;
1920                entry[afirst + bgr] = (png_uint_16)red;
1921                break;
1922 
1923             case 2:
1924                entry[1 ^ afirst] = (png_uint_16)alpha;
1925                /* FALL THROUGH */
1926 
1927             case 1:
1928                if (alpha < 65535)
1929                {
1930                   if (alpha > 0)
1931                      green = (green * alpha + 32767U)/65535U;
1932 
1933                   else
1934                      green = 0;
1935                }
1936                entry[afirst] = (png_uint_16)green;
1937                break;
1938 
1939             default:
1940                break;
1941          }
1942       }
1943 
1944       else /* output encoding is P_sRGB */
1945       {
1946          png_bytep entry = png_voidcast(png_bytep, display->colormap);
1947 
1948          entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
1949 
1950          switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
1951          {
1952             case 4:
1953                entry[afirst ? 0 : 3] = (png_byte)alpha;
1954             case 3:
1955                entry[afirst + (2 ^ bgr)] = (png_byte)blue;
1956                entry[afirst + 1] = (png_byte)green;
1957                entry[afirst + bgr] = (png_byte)red;
1958                break;
1959 
1960             case 2:
1961                entry[1 ^ afirst] = (png_byte)alpha;
1962             case 1:
1963                entry[afirst] = (png_byte)green;
1964                break;
1965 
1966             default:
1967                break;
1968          }
1969       }
1970 
1971 #     ifdef afirst
1972 #        undef afirst
1973 #     endif
1974 #     ifdef bgr
1975 #        undef bgr
1976 #     endif
1977    }
1978 }
1979 
1980 static int
1981 make_gray_file_colormap(png_image_read_control *display)
1982 {
1983    unsigned int i;
1984 
1985    for (i=0; i<256; ++i)
1986       png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
1987 
1988    return i;
1989 }
1990 
1991 static int
1992 make_gray_colormap(png_image_read_control *display)
1993 {
1994    unsigned int i;
1995 
1996    for (i=0; i<256; ++i)
1997       png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
1998 
1999    return i;
2000 }
2001 #define PNG_GRAY_COLORMAP_ENTRIES 256
2002 
2003 static int
2004 make_ga_colormap(png_image_read_control *display)
2005 {
2006    unsigned int i, a;
2007 
2008    /* Alpha is retained, the output will be a color-map with entries
2009     * selected by six levels of alpha.  One transparent entry, 6 gray
2010     * levels for all the intermediate alpha values, leaving 230 entries
2011     * for the opaque grays.  The color-map entries are the six values
2012     * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the
2013     * relevant entry.
2014     *
2015     * if (alpha > 229) // opaque
2016     * {
2017     *    // The 231 entries are selected to make the math below work:
2018     *    base = 0;
2019     *    entry = (231 * gray + 128) >> 8;
2020     * }
2021     * else if (alpha < 26) // transparent
2022     * {
2023     *    base = 231;
2024     *    entry = 0;
2025     * }
2026     * else // partially opaque
2027     * {
2028     *    base = 226 + 6 * PNG_DIV51(alpha);
2029     *    entry = PNG_DIV51(gray);
2030     * }
2031     */
2032    i = 0;
2033    while (i < 231)
2034    {
2035       unsigned int gray = (i * 256 + 115) / 231;
2036       png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);
2037    }
2038 
2039    /* 255 is used here for the component values for consistency with the code
2040     * that undoes premultiplication in pngwrite.c.
2041     */
2042    png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);
2043 
2044    for (a=1; a<5; ++a)
2045    {
2046       unsigned int g;
2047 
2048       for (g=0; g<6; ++g)
2049          png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
2050             P_sRGB);
2051    }
2052 
2053    return i;
2054 }
2055 
2056 #define PNG_GA_COLORMAP_ENTRIES 256
2057 
2058 static int
2059 make_rgb_colormap(png_image_read_control *display)
2060 {
2061    unsigned int i, r;
2062 
2063    /* Build a 6x6x6 opaque RGB cube */
2064    for (i=r=0; r<6; ++r)
2065    {
2066       unsigned int g;
2067 
2068       for (g=0; g<6; ++g)
2069       {
2070          unsigned int b;
2071 
2072          for (b=0; b<6; ++b)
2073             png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
2074                P_sRGB);
2075       }
2076    }
2077 
2078    return i;
2079 }
2080 
2081 #define PNG_RGB_COLORMAP_ENTRIES 216
2082 
2083 /* Return a palette index to the above palette given three 8-bit sRGB values. */
2084 #define PNG_RGB_INDEX(r,g,b) \
2085    ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))
2086 
2087 static int
2088 png_image_read_colormap(png_voidp argument)
2089 {
2090    png_image_read_control *display =
2091       png_voidcast(png_image_read_control*, argument);
2092    const png_imagep image = display->image;
2093 
2094    const png_structrp png_ptr = image->opaque->png_ptr;
2095    const png_uint_32 output_format = image->format;
2096    const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
2097       P_LINEAR : P_sRGB;
2098 
2099    unsigned int cmap_entries;
2100    unsigned int output_processing;        /* Output processing option */
2101    unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */
2102 
2103    /* Background information; the background color and the index of this color
2104     * in the color-map if it exists (else 256).
2105     */
2106    unsigned int background_index = 256;
2107    png_uint_32 back_r, back_g, back_b;
2108 
2109    /* Flags to accumulate things that need to be done to the input. */
2110    int expand_tRNS = 0;
2111 
2112    /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is
2113     * very difficult to do, the results look awful, and it is difficult to see
2114     * what possible use it is because the application can't control the
2115     * color-map.
2116     */
2117    if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||
2118          png_ptr->num_trans > 0) /* alpha in input */ &&
2119       ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
2120    {
2121       if (output_encoding == P_LINEAR) /* compose on black */
2122          back_b = back_g = back_r = 0;
2123 
2124       else if (display->background == NULL /* no way to remove it */)
2125          png_error(png_ptr,
2126             "a background color must be supplied to remove alpha/transparency");
2127 
2128       /* Get a copy of the background color (this avoids repeating the checks
2129        * below.)  The encoding is 8-bit sRGB or 16-bit linear, depending on the
2130        * output format.
2131        */
2132       else
2133       {
2134          back_g = display->background->green;
2135          if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0)
2136          {
2137             back_r = display->background->red;
2138             back_b = display->background->blue;
2139          }
2140          else
2141             back_b = back_r = back_g;
2142       }
2143    }
2144 
2145    else if (output_encoding == P_LINEAR)
2146       back_b = back_r = back_g = 65535;
2147 
2148    else
2149       back_b = back_r = back_g = 255;
2150 
2151    /* Default the input file gamma if required - this is necessary because
2152     * libpng assumes that if no gamma information is present the data is in the
2153     * output format, but the simplified API deduces the gamma from the input
2154     * format.
2155     */
2156    if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)
2157    {
2158       /* Do this directly, not using the png_colorspace functions, to ensure
2159        * that it happens even if the colorspace is invalid (though probably if
2160        * it is the setting will be ignored)  Note that the same thing can be
2161        * achieved at the application interface with png_set_gAMA.
2162        */
2163       if (png_ptr->bit_depth == 16 &&
2164          (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
2165          png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;
2166 
2167       else
2168          png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;
2169 
2170       png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
2171    }
2172 
2173    /* Decide what to do based on the PNG color type of the input data.  The
2174     * utility function png_create_colormap_entry deals with most aspects of the
2175     * output transformations; this code works out how to produce bytes of
2176     * color-map entries from the original format.
2177     */
2178    switch (png_ptr->color_type)
2179    {
2180       case PNG_COLOR_TYPE_GRAY:
2181          if (png_ptr->bit_depth <= 8)
2182          {
2183             /* There at most 256 colors in the output, regardless of
2184              * transparency.
2185              */
2186             unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;
2187 
2188             cmap_entries = 1U << png_ptr->bit_depth;
2189             if (cmap_entries > image->colormap_entries)
2190                png_error(png_ptr, "gray[8] color-map: too few entries");
2191 
2192             step = 255 / (cmap_entries - 1);
2193             output_processing = PNG_CMAP_NONE;
2194 
2195             /* If there is a tRNS chunk then this either selects a transparent
2196              * value or, if the output has no alpha, the background color.
2197              */
2198             if (png_ptr->num_trans > 0)
2199             {
2200                trans = png_ptr->trans_color.gray;
2201 
2202                if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
2203                   back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
2204             }
2205 
2206             /* png_create_colormap_entry just takes an RGBA and writes the
2207              * corresponding color-map entry using the format from 'image',
2208              * including the required conversion to sRGB or linear as
2209              * appropriate.  The input values are always either sRGB (if the
2210              * gamma correction flag is 0) or 0..255 scaled file encoded values
2211              * (if the function must gamma correct them).
2212              */
2213             for (i=val=0; i<cmap_entries; ++i, val += step)
2214             {
2215                /* 'i' is a file value.  While this will result in duplicated
2216                 * entries for 8-bit non-sRGB encoded files it is necessary to
2217                 * have non-gamma corrected values to do tRNS handling.
2218                 */
2219                if (i != trans)
2220                   png_create_colormap_entry(display, i, val, val, val, 255,
2221                      P_FILE/*8-bit with file gamma*/);
2222 
2223                /* Else this entry is transparent.  The colors don't matter if
2224                 * there is an alpha channel (back_alpha == 0), but it does no
2225                 * harm to pass them in; the values are not set above so this
2226                 * passes in white.
2227                 *
2228                 * NOTE: this preserves the full precision of the application
2229                 * supplied background color when it is used.
2230                 */
2231                else
2232                   png_create_colormap_entry(display, i, back_r, back_g, back_b,
2233                      back_alpha, output_encoding);
2234             }
2235 
2236             /* We need libpng to preserve the original encoding. */
2237             data_encoding = P_FILE;
2238 
2239             /* The rows from libpng, while technically gray values, are now also
2240              * color-map indices; however, they may need to be expanded to 1
2241              * byte per pixel.  This is what png_set_packing does (i.e., it
2242              * unpacks the bit values into bytes.)
2243              */
2244             if (png_ptr->bit_depth < 8)
2245                png_set_packing(png_ptr);
2246          }
2247 
2248          else /* bit depth is 16 */
2249          {
2250             /* The 16-bit input values can be converted directly to 8-bit gamma
2251              * encoded values; however, if a tRNS chunk is present 257 color-map
2252              * entries are required.  This means that the extra entry requires
2253              * special processing; add an alpha channel, sacrifice gray level
2254              * 254 and convert transparent (alpha==0) entries to that.
2255              *
2256              * Use libpng to chop the data to 8 bits.  Convert it to sRGB at the
2257              * same time to minimize quality loss.  If a tRNS chunk is present
2258              * this means libpng must handle it too; otherwise it is impossible
2259              * to do the exact match on the 16-bit value.
2260              *
2261              * If the output has no alpha channel *and* the background color is
2262              * gray then it is possible to let libpng handle the substitution by
2263              * ensuring that the corresponding gray level matches the background
2264              * color exactly.
2265              */
2266             data_encoding = P_sRGB;
2267 
2268             if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2269                png_error(png_ptr, "gray[16] color-map: too few entries");
2270 
2271             cmap_entries = make_gray_colormap(display);
2272 
2273             if (png_ptr->num_trans > 0)
2274             {
2275                unsigned int back_alpha;
2276 
2277                if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2278                   back_alpha = 0;
2279 
2280                else
2281                {
2282                   if (back_r == back_g && back_g == back_b)
2283                   {
2284                      /* Background is gray; no special processing will be
2285                       * required.
2286                       */
2287                      png_color_16 c;
2288                      png_uint_32 gray = back_g;
2289 
2290                      if (output_encoding == P_LINEAR)
2291                      {
2292                         gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2293 
2294                         /* And make sure the corresponding palette entry
2295                          * matches.
2296                          */
2297                         png_create_colormap_entry(display, gray, back_g, back_g,
2298                            back_g, 65535, P_LINEAR);
2299                      }
2300 
2301                      /* The background passed to libpng, however, must be the
2302                       * sRGB value.
2303                       */
2304                      c.index = 0; /*unused*/
2305                      c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2306 
2307                      /* NOTE: does this work without expanding tRNS to alpha?
2308                       * It should be the color->gray case below apparently
2309                       * doesn't.
2310                       */
2311                      png_set_background_fixed(png_ptr, &c,
2312                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2313                         0/*gamma: not used*/);
2314 
2315                      output_processing = PNG_CMAP_NONE;
2316                      break;
2317                   }
2318 #ifdef __COVERITY__
2319                  /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
2320                   * here.
2321                   */
2322                   back_alpha = 255;
2323 #else
2324                   back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
2325 #endif
2326                }
2327 
2328                /* output_processing means that the libpng-processed row will be
2329                 * 8-bit GA and it has to be processing to single byte color-map
2330                 * values.  Entry 254 is replaced by either a completely
2331                 * transparent entry or by the background color at full
2332                 * precision (and the background color is not a simple gray
2333                 * level in this case.)
2334                 */
2335                expand_tRNS = 1;
2336                output_processing = PNG_CMAP_TRANS;
2337                background_index = 254;
2338 
2339                /* And set (overwrite) color-map entry 254 to the actual
2340                 * background color at full precision.
2341                 */
2342                png_create_colormap_entry(display, 254, back_r, back_g, back_b,
2343                   back_alpha, output_encoding);
2344             }
2345 
2346             else
2347                output_processing = PNG_CMAP_NONE;
2348          }
2349          break;
2350 
2351       case PNG_COLOR_TYPE_GRAY_ALPHA:
2352          /* 8-bit or 16-bit PNG with two channels - gray and alpha.  A minimum
2353           * of 65536 combinations.  If, however, the alpha channel is to be
2354           * removed there are only 256 possibilities if the background is gray.
2355           * (Otherwise there is a subset of the 65536 possibilities defined by
2356           * the triangle between black, white and the background color.)
2357           *
2358           * Reduce 16-bit files to 8-bit and sRGB encode the result.  No need to
2359           * worry about tRNS matching - tRNS is ignored if there is an alpha
2360           * channel.
2361           */
2362          data_encoding = P_sRGB;
2363 
2364          if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2365          {
2366             if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2367                png_error(png_ptr, "gray+alpha color-map: too few entries");
2368 
2369             cmap_entries = make_ga_colormap(display);
2370 
2371             background_index = PNG_CMAP_GA_BACKGROUND;
2372             output_processing = PNG_CMAP_GA;
2373          }
2374 
2375          else /* alpha is removed */
2376          {
2377             /* Alpha must be removed as the PNG data is processed when the
2378              * background is a color because the G and A channels are
2379              * independent and the vector addition (non-parallel vectors) is a
2380              * 2-D problem.
2381              *
2382              * This can be reduced to the same algorithm as above by making a
2383              * colormap containing gray levels (for the opaque grays), a
2384              * background entry (for a transparent pixel) and a set of four six
2385              * level color values, one set for each intermediate alpha value.
2386              * See the comments in make_ga_colormap for how this works in the
2387              * per-pixel processing.
2388              *
2389              * If the background is gray, however, we only need a 256 entry gray
2390              * level color map.  It is sufficient to make the entry generated
2391              * for the background color be exactly the color specified.
2392              */
2393             if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||
2394                (back_r == back_g && back_g == back_b))
2395             {
2396                /* Background is gray; no special processing will be required. */
2397                png_color_16 c;
2398                png_uint_32 gray = back_g;
2399 
2400                if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2401                   png_error(png_ptr, "gray-alpha color-map: too few entries");
2402 
2403                cmap_entries = make_gray_colormap(display);
2404 
2405                if (output_encoding == P_LINEAR)
2406                {
2407                   gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2408 
2409                   /* And make sure the corresponding palette entry matches. */
2410                   png_create_colormap_entry(display, gray, back_g, back_g,
2411                      back_g, 65535, P_LINEAR);
2412                }
2413 
2414                /* The background passed to libpng, however, must be the sRGB
2415                 * value.
2416                 */
2417                c.index = 0; /*unused*/
2418                c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2419 
2420                png_set_background_fixed(png_ptr, &c,
2421                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2422                   0/*gamma: not used*/);
2423 
2424                output_processing = PNG_CMAP_NONE;
2425             }
2426 
2427             else
2428             {
2429                png_uint_32 i, a;
2430 
2431                /* This is the same as png_make_ga_colormap, above, except that
2432                 * the entries are all opaque.
2433                 */
2434                if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2435                   png_error(png_ptr, "ga-alpha color-map: too few entries");
2436 
2437                i = 0;
2438                while (i < 231)
2439                {
2440                   png_uint_32 gray = (i * 256 + 115) / 231;
2441                   png_create_colormap_entry(display, i++, gray, gray, gray,
2442                      255, P_sRGB);
2443                }
2444 
2445                /* NOTE: this preserves the full precision of the application
2446                 * background color.
2447                 */
2448                background_index = i;
2449                png_create_colormap_entry(display, i++, back_r, back_g, back_b,
2450 #ifdef __COVERITY__
2451                  /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
2452                   * here.
2453                   */ 255U,
2454 #else
2455                   output_encoding == P_LINEAR ? 65535U : 255U,
2456 #endif
2457                   output_encoding);
2458 
2459                /* For non-opaque input composite on the sRGB background - this
2460                 * requires inverting the encoding for each component.  The input
2461                 * is still converted to the sRGB encoding because this is a
2462                 * reasonable approximate to the logarithmic curve of human
2463                 * visual sensitivity, at least over the narrow range which PNG
2464                 * represents.  Consequently 'G' is always sRGB encoded, while
2465                 * 'A' is linear.  We need the linear background colors.
2466                 */
2467                if (output_encoding == P_sRGB) /* else already linear */
2468                {
2469                   /* This may produce a value not exactly matching the
2470                    * background, but that's ok because these numbers are only
2471                    * used when alpha != 0
2472                    */
2473                   back_r = png_sRGB_table[back_r];
2474                   back_g = png_sRGB_table[back_g];
2475                   back_b = png_sRGB_table[back_b];
2476                }
2477 
2478                for (a=1; a<5; ++a)
2479                {
2480                   unsigned int g;
2481 
2482                   /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled
2483                    * by an 8-bit alpha value (0..255).
2484                    */
2485                   png_uint_32 alpha = 51 * a;
2486                   png_uint_32 back_rx = (255-alpha) * back_r;
2487                   png_uint_32 back_gx = (255-alpha) * back_g;
2488                   png_uint_32 back_bx = (255-alpha) * back_b;
2489 
2490                   for (g=0; g<6; ++g)
2491                   {
2492                      png_uint_32 gray = png_sRGB_table[g*51] * alpha;
2493 
2494                      png_create_colormap_entry(display, i++,
2495                         PNG_sRGB_FROM_LINEAR(gray + back_rx),
2496                         PNG_sRGB_FROM_LINEAR(gray + back_gx),
2497                         PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
2498                   }
2499                }
2500 
2501                cmap_entries = i;
2502                output_processing = PNG_CMAP_GA;
2503             }
2504          }
2505          break;
2506 
2507       case PNG_COLOR_TYPE_RGB:
2508       case PNG_COLOR_TYPE_RGB_ALPHA:
2509          /* Exclude the case where the output is gray; we can always handle this
2510           * with the cases above.
2511           */
2512          if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)
2513          {
2514             /* The color-map will be grayscale, so we may as well convert the
2515              * input RGB values to a simple grayscale and use the grayscale
2516              * code above.
2517              *
2518              * NOTE: calling this apparently damages the recognition of the
2519              * transparent color in background color handling; call
2520              * png_set_tRNS_to_alpha before png_set_background_fixed.
2521              */
2522             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
2523                -1);
2524             data_encoding = P_sRGB;
2525 
2526             /* The output will now be one or two 8-bit gray or gray+alpha
2527              * channels.  The more complex case arises when the input has alpha.
2528              */
2529             if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2530                png_ptr->num_trans > 0) &&
2531                (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2532             {
2533                /* Both input and output have an alpha channel, so no background
2534                 * processing is required; just map the GA bytes to the right
2535                 * color-map entry.
2536                 */
2537                expand_tRNS = 1;
2538 
2539                if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
2540                   png_error(png_ptr, "rgb[ga] color-map: too few entries");
2541 
2542                cmap_entries = make_ga_colormap(display);
2543                background_index = PNG_CMAP_GA_BACKGROUND;
2544                output_processing = PNG_CMAP_GA;
2545             }
2546 
2547             else
2548             {
2549                /* Either the input or the output has no alpha channel, so there
2550                 * will be no non-opaque pixels in the color-map; it will just be
2551                 * grayscale.
2552                 */
2553                if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
2554                   png_error(png_ptr, "rgb[gray] color-map: too few entries");
2555 
2556                /* Ideally this code would use libpng to do the gamma correction,
2557                 * but if an input alpha channel is to be removed we will hit the
2558                 * libpng bug in gamma+compose+rgb-to-gray (the double gamma
2559                 * correction bug).  Fix this by dropping the gamma correction in
2560                 * this case and doing it in the palette; this will result in
2561                 * duplicate palette entries, but that's better than the
2562                 * alternative of double gamma correction.
2563                 */
2564                if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2565                   png_ptr->num_trans > 0) &&
2566                   png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)
2567                {
2568                   cmap_entries = make_gray_file_colormap(display);
2569                   data_encoding = P_FILE;
2570                }
2571 
2572                else
2573                   cmap_entries = make_gray_colormap(display);
2574 
2575                /* But if the input has alpha or transparency it must be removed
2576                 */
2577                if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2578                   png_ptr->num_trans > 0)
2579                {
2580                   png_color_16 c;
2581                   png_uint_32 gray = back_g;
2582 
2583                   /* We need to ensure that the application background exists in
2584                    * the colormap and that completely transparent pixels map to
2585                    * it.  Achieve this simply by ensuring that the entry
2586                    * selected for the background really is the background color.
2587                    */
2588                   if (data_encoding == P_FILE) /* from the fixup above */
2589                   {
2590                      /* The app supplied a gray which is in output_encoding, we
2591                       * need to convert it to a value of the input (P_FILE)
2592                       * encoding then set this palette entry to the required
2593                       * output encoding.
2594                       */
2595                      if (output_encoding == P_sRGB)
2596                         gray = png_sRGB_table[gray]; /* now P_LINEAR */
2597 
2598                      gray = PNG_DIV257(png_gamma_16bit_correct(gray,
2599                         png_ptr->colorspace.gamma)); /* now P_FILE */
2600 
2601                      /* And make sure the corresponding palette entry contains
2602                       * exactly the required sRGB value.
2603                       */
2604                      png_create_colormap_entry(display, gray, back_g, back_g,
2605                         back_g, 0/*unused*/, output_encoding);
2606                   }
2607 
2608                   else if (output_encoding == P_LINEAR)
2609                   {
2610                      gray = PNG_sRGB_FROM_LINEAR(gray * 255);
2611 
2612                      /* And make sure the corresponding palette entry matches.
2613                       */
2614                      png_create_colormap_entry(display, gray, back_g, back_g,
2615                         back_g, 0/*unused*/, P_LINEAR);
2616                   }
2617 
2618                   /* The background passed to libpng, however, must be the
2619                    * output (normally sRGB) value.
2620                    */
2621                   c.index = 0; /*unused*/
2622                   c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
2623 
2624                   /* NOTE: the following is apparently a bug in libpng. Without
2625                    * it the transparent color recognition in
2626                    * png_set_background_fixed seems to go wrong.
2627                    */
2628                   expand_tRNS = 1;
2629                   png_set_background_fixed(png_ptr, &c,
2630                      PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2631                      0/*gamma: not used*/);
2632                }
2633 
2634                output_processing = PNG_CMAP_NONE;
2635             }
2636          }
2637 
2638          else /* output is color */
2639          {
2640             /* We could use png_quantize here so long as there is no transparent
2641              * color or alpha; png_quantize ignores alpha.  Easier overall just
2642              * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
2643              * Consequently we always want libpng to produce sRGB data.
2644              */
2645             data_encoding = P_sRGB;
2646 
2647             /* Is there any transparency or alpha? */
2648             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
2649                png_ptr->num_trans > 0)
2650             {
2651                /* Is there alpha in the output too?  If so all four channels are
2652                 * processed into a special RGB cube with alpha support.
2653                 */
2654                if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
2655                {
2656                   png_uint_32 r;
2657 
2658                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
2659                      png_error(png_ptr, "rgb+alpha color-map: too few entries");
2660 
2661                   cmap_entries = make_rgb_colormap(display);
2662 
2663                   /* Add a transparent entry. */
2664                   png_create_colormap_entry(display, cmap_entries, 255, 255,
2665                      255, 0, P_sRGB);
2666 
2667                   /* This is stored as the background index for the processing
2668                    * algorithm.
2669                    */
2670                   background_index = cmap_entries++;
2671 
2672                   /* Add 27 r,g,b entries each with alpha 0.5. */
2673                   for (r=0; r<256; r = (r << 1) | 0x7f)
2674                   {
2675                      png_uint_32 g;
2676 
2677                      for (g=0; g<256; g = (g << 1) | 0x7f)
2678                      {
2679                         png_uint_32 b;
2680 
2681                         /* This generates components with the values 0, 127 and
2682                          * 255
2683                          */
2684                         for (b=0; b<256; b = (b << 1) | 0x7f)
2685                            png_create_colormap_entry(display, cmap_entries++,
2686                               r, g, b, 128, P_sRGB);
2687                      }
2688                   }
2689 
2690                   expand_tRNS = 1;
2691                   output_processing = PNG_CMAP_RGB_ALPHA;
2692                }
2693 
2694                else
2695                {
2696                   /* Alpha/transparency must be removed.  The background must
2697                    * exist in the color map (achieved by setting adding it after
2698                    * the 666 color-map).  If the standard processing code will
2699                    * pick up this entry automatically that's all that is
2700                    * required; libpng can be called to do the background
2701                    * processing.
2702                    */
2703                   unsigned int sample_size =
2704                      PNG_IMAGE_SAMPLE_SIZE(output_format);
2705                   png_uint_32 r, g, b; /* sRGB background */
2706 
2707                   if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
2708                      png_error(png_ptr, "rgb-alpha color-map: too few entries");
2709 
2710                   cmap_entries = make_rgb_colormap(display);
2711 
2712                   png_create_colormap_entry(display, cmap_entries, back_r,
2713                         back_g, back_b, 0/*unused*/, output_encoding);
2714 
2715                   if (output_encoding == P_LINEAR)
2716                   {
2717                      r = PNG_sRGB_FROM_LINEAR(back_r * 255);
2718                      g = PNG_sRGB_FROM_LINEAR(back_g * 255);
2719                      b = PNG_sRGB_FROM_LINEAR(back_b * 255);
2720                   }
2721 
2722                   else
2723                   {
2724                      r = back_r;
2725                      g = back_g;
2726                      b = back_g;
2727                   }
2728 
2729                   /* Compare the newly-created color-map entry with the one the
2730                    * PNG_CMAP_RGB algorithm will use.  If the two entries don't
2731                    * match, add the new one and set this as the background
2732                    * index.
2733                    */
2734                   if (memcmp((png_const_bytep)display->colormap +
2735                         sample_size * cmap_entries,
2736                      (png_const_bytep)display->colormap +
2737                         sample_size * PNG_RGB_INDEX(r,g,b),
2738                      sample_size) != 0)
2739                   {
2740                      /* The background color must be added. */
2741                      background_index = cmap_entries++;
2742 
2743                      /* Add 27 r,g,b entries each with created by composing with
2744                       * the background at alpha 0.5.
2745                       */
2746                      for (r=0; r<256; r = (r << 1) | 0x7f)
2747                      {
2748                         for (g=0; g<256; g = (g << 1) | 0x7f)
2749                         {
2750                            /* This generates components with the values 0, 127
2751                             * and 255
2752                             */
2753                            for (b=0; b<256; b = (b << 1) | 0x7f)
2754                               png_create_colormap_entry(display, cmap_entries++,
2755                                  png_colormap_compose(display, r, P_sRGB, 128,
2756                                     back_r, output_encoding),
2757                                  png_colormap_compose(display, g, P_sRGB, 128,
2758                                     back_g, output_encoding),
2759                                  png_colormap_compose(display, b, P_sRGB, 128,
2760                                     back_b, output_encoding),
2761                                  0/*unused*/, output_encoding);
2762                         }
2763                      }
2764 
2765                      expand_tRNS = 1;
2766                      output_processing = PNG_CMAP_RGB_ALPHA;
2767                   }
2768 
2769                   else /* background color is in the standard color-map */
2770                   {
2771                      png_color_16 c;
2772 
2773                      c.index = 0; /*unused*/
2774                      c.red = (png_uint_16)back_r;
2775                      c.gray = c.green = (png_uint_16)back_g;
2776                      c.blue = (png_uint_16)back_b;
2777 
2778                      png_set_background_fixed(png_ptr, &c,
2779                         PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
2780                         0/*gamma: not used*/);
2781 
2782                      output_processing = PNG_CMAP_RGB;
2783                   }
2784                }
2785             }
2786 
2787             else /* no alpha or transparency in the input */
2788             {
2789                /* Alpha in the output is irrelevant, simply map the opaque input
2790                 * pixels to the 6x6x6 color-map.
2791                 */
2792                if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
2793                   png_error(png_ptr, "rgb color-map: too few entries");
2794 
2795                cmap_entries = make_rgb_colormap(display);
2796                output_processing = PNG_CMAP_RGB;
2797             }
2798          }
2799          break;
2800 
2801       case PNG_COLOR_TYPE_PALETTE:
2802          /* It's already got a color-map.  It may be necessary to eliminate the
2803           * tRNS entries though.
2804           */
2805          {
2806             unsigned int num_trans = png_ptr->num_trans;
2807             png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
2808             png_const_colorp colormap = png_ptr->palette;
2809             const int do_background = trans != NULL &&
2810                (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
2811             unsigned int i;
2812 
2813             /* Just in case: */
2814             if (trans == NULL)
2815                num_trans = 0;
2816 
2817             output_processing = PNG_CMAP_NONE;
2818             data_encoding = P_FILE; /* Don't change from color-map indices */
2819             cmap_entries = png_ptr->num_palette;
2820             if (cmap_entries > 256)
2821                cmap_entries = 256;
2822 
2823             if (cmap_entries > image->colormap_entries)
2824                png_error(png_ptr, "palette color-map: too few entries");
2825 
2826             for (i=0; i < cmap_entries; ++i)
2827             {
2828                if (do_background != 0 && i < num_trans && trans[i] < 255)
2829                {
2830                   if (trans[i] == 0)
2831                      png_create_colormap_entry(display, i, back_r, back_g,
2832                         back_b, 0, output_encoding);
2833 
2834                   else
2835                   {
2836                      /* Must compose the PNG file color in the color-map entry
2837                       * on the sRGB color in 'back'.
2838                       */
2839                      png_create_colormap_entry(display, i,
2840                         png_colormap_compose(display, colormap[i].red, P_FILE,
2841                            trans[i], back_r, output_encoding),
2842                         png_colormap_compose(display, colormap[i].green, P_FILE,
2843                            trans[i], back_g, output_encoding),
2844                         png_colormap_compose(display, colormap[i].blue, P_FILE,
2845                            trans[i], back_b, output_encoding),
2846                         output_encoding == P_LINEAR ? trans[i] * 257U :
2847                            trans[i],
2848                         output_encoding);
2849                   }
2850                }
2851 
2852                else
2853                   png_create_colormap_entry(display, i, colormap[i].red,
2854                      colormap[i].green, colormap[i].blue,
2855                      i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
2856             }
2857 
2858             /* The PNG data may have indices packed in fewer than 8 bits, it
2859              * must be expanded if so.
2860              */
2861             if (png_ptr->bit_depth < 8)
2862                png_set_packing(png_ptr);
2863          }
2864          break;
2865 
2866       default:
2867          png_error(png_ptr, "invalid PNG color type");
2868          /*NOT REACHED*/
2869    }
2870 
2871    /* Now deal with the output processing */
2872    if (expand_tRNS != 0 && png_ptr->num_trans > 0 &&
2873        (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
2874       png_set_tRNS_to_alpha(png_ptr);
2875 
2876    switch (data_encoding)
2877    {
2878       case P_sRGB:
2879          /* Change to 8-bit sRGB */
2880          png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
2881          /* FALL THROUGH */
2882 
2883       case P_FILE:
2884          if (png_ptr->bit_depth > 8)
2885             png_set_scale_16(png_ptr);
2886          break;
2887 
2888 #ifdef __GNUC__
2889       default:
2890          png_error(png_ptr, "bad data option (internal error)");
2891 #endif
2892    }
2893 
2894    if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
2895       png_error(png_ptr, "color map overflow (BAD internal error)");
2896 
2897    image->colormap_entries = cmap_entries;
2898 
2899    /* Double check using the recorded background index */
2900    switch (output_processing)
2901    {
2902       case PNG_CMAP_NONE:
2903          if (background_index != PNG_CMAP_NONE_BACKGROUND)
2904             goto bad_background;
2905          break;
2906 
2907       case PNG_CMAP_GA:
2908          if (background_index != PNG_CMAP_GA_BACKGROUND)
2909             goto bad_background;
2910          break;
2911 
2912       case PNG_CMAP_TRANS:
2913          if (background_index >= cmap_entries ||
2914             background_index != PNG_CMAP_TRANS_BACKGROUND)
2915             goto bad_background;
2916          break;
2917 
2918       case PNG_CMAP_RGB:
2919          if (background_index != PNG_CMAP_RGB_BACKGROUND)
2920             goto bad_background;
2921          break;
2922 
2923       case PNG_CMAP_RGB_ALPHA:
2924          if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)
2925             goto bad_background;
2926          break;
2927 
2928       default:
2929          png_error(png_ptr, "bad processing option (internal error)");
2930 
2931       bad_background:
2932          png_error(png_ptr, "bad background index (internal error)");
2933    }
2934 
2935    display->colormap_processing = output_processing;
2936 
2937    return 1/*ok*/;
2938 }
2939 
2940 /* The final part of the color-map read called from png_image_finish_read. */
2941 static int
2942 png_image_read_and_map(png_voidp argument)
2943 {
2944    png_image_read_control *display = png_voidcast(png_image_read_control*,
2945       argument);
2946    png_imagep image = display->image;
2947    png_structrp png_ptr = image->opaque->png_ptr;
2948    int passes;
2949 
2950    /* Called when the libpng data must be transformed into the color-mapped
2951     * form.  There is a local row buffer in display->local and this routine must
2952     * do the interlace handling.
2953     */
2954    switch (png_ptr->interlaced)
2955    {
2956       case PNG_INTERLACE_NONE:
2957          passes = 1;
2958          break;
2959 
2960       case PNG_INTERLACE_ADAM7:
2961          passes = PNG_INTERLACE_ADAM7_PASSES;
2962          break;
2963 
2964       default:
2965          png_error(png_ptr, "unknown interlace type");
2966    }
2967 
2968    {
2969       png_uint_32  height = image->height;
2970       png_uint_32  width = image->width;
2971       int          proc = display->colormap_processing;
2972       png_bytep    first_row = png_voidcast(png_bytep, display->first_row);
2973       ptrdiff_t    step_row = display->row_bytes;
2974       int pass;
2975 
2976       for (pass = 0; pass < passes; ++pass)
2977       {
2978          unsigned int     startx, stepx, stepy;
2979          png_uint_32      y;
2980 
2981          if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
2982          {
2983             /* The row may be empty for a short image: */
2984             if (PNG_PASS_COLS(width, pass) == 0)
2985                continue;
2986 
2987             startx = PNG_PASS_START_COL(pass);
2988             stepx = PNG_PASS_COL_OFFSET(pass);
2989             y = PNG_PASS_START_ROW(pass);
2990             stepy = PNG_PASS_ROW_OFFSET(pass);
2991          }
2992 
2993          else
2994          {
2995             y = 0;
2996             startx = 0;
2997             stepx = stepy = 1;
2998          }
2999 
3000          for (; y<height; y += stepy)
3001          {
3002             png_bytep inrow = png_voidcast(png_bytep, display->local_row);
3003             png_bytep outrow = first_row + y * step_row;
3004             png_const_bytep end_row = outrow + width;
3005 
3006             /* Read read the libpng data into the temporary buffer. */
3007             png_read_row(png_ptr, inrow, NULL);
3008 
3009             /* Now process the row according to the processing option, note
3010              * that the caller verifies that the format of the libpng output
3011              * data is as required.
3012              */
3013             outrow += startx;
3014             switch (proc)
3015             {
3016                case PNG_CMAP_GA:
3017                   for (; outrow < end_row; outrow += stepx)
3018                   {
3019                      /* The data is always in the PNG order */
3020                      unsigned int gray = *inrow++;
3021                      unsigned int alpha = *inrow++;
3022                      unsigned int entry;
3023 
3024                      /* NOTE: this code is copied as a comment in
3025                       * make_ga_colormap above.  Please update the
3026                       * comment if you change this code!
3027                       */
3028                      if (alpha > 229) /* opaque */
3029                      {
3030                         entry = (231 * gray + 128) >> 8;
3031                      }
3032                      else if (alpha < 26) /* transparent */
3033                      {
3034                         entry = 231;
3035                      }
3036                      else /* partially opaque */
3037                      {
3038                         entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
3039                      }
3040 
3041                      *outrow = (png_byte)entry;
3042                   }
3043                   break;
3044 
3045                case PNG_CMAP_TRANS:
3046                   for (; outrow < end_row; outrow += stepx)
3047                   {
3048                      png_byte gray = *inrow++;
3049                      png_byte alpha = *inrow++;
3050 
3051                      if (alpha == 0)
3052                         *outrow = PNG_CMAP_TRANS_BACKGROUND;
3053 
3054                      else if (gray != PNG_CMAP_TRANS_BACKGROUND)
3055                         *outrow = gray;
3056 
3057                      else
3058                         *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1);
3059                   }
3060                   break;
3061 
3062                case PNG_CMAP_RGB:
3063                   for (; outrow < end_row; outrow += stepx)
3064                   {
3065                      *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);
3066                      inrow += 3;
3067                   }
3068                   break;
3069 
3070                case PNG_CMAP_RGB_ALPHA:
3071                   for (; outrow < end_row; outrow += stepx)
3072                   {
3073                      unsigned int alpha = inrow[3];
3074 
3075                      /* Because the alpha entries only hold alpha==0.5 values
3076                       * split the processing at alpha==0.25 (64) and 0.75
3077                       * (196).
3078                       */
3079 
3080                      if (alpha >= 196)
3081                         *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
3082                            inrow[2]);
3083 
3084                      else if (alpha < 64)
3085                         *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
3086 
3087                      else
3088                      {
3089                         /* Likewise there are three entries for each of r, g
3090                          * and b.  We could select the entry by popcount on
3091                          * the top two bits on those architectures that
3092                          * support it, this is what the code below does,
3093                          * crudely.
3094                          */
3095                         unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;
3096 
3097                         /* Here are how the values map:
3098                          *
3099                          * 0x00 .. 0x3f -> 0
3100                          * 0x40 .. 0xbf -> 1
3101                          * 0xc0 .. 0xff -> 2
3102                          *
3103                          * So, as above with the explicit alpha checks, the
3104                          * breakpoints are at 64 and 196.
3105                          */
3106                         if (inrow[0] & 0x80) back_i += 9; /* red */
3107                         if (inrow[0] & 0x40) back_i += 9;
3108                         if (inrow[0] & 0x80) back_i += 3; /* green */
3109                         if (inrow[0] & 0x40) back_i += 3;
3110                         if (inrow[0] & 0x80) back_i += 1; /* blue */
3111                         if (inrow[0] & 0x40) back_i += 1;
3112 
3113                         *outrow = (png_byte)back_i;
3114                      }
3115 
3116                      inrow += 4;
3117                   }
3118                   break;
3119 
3120                default:
3121                   break;
3122             }
3123          }
3124       }
3125    }
3126 
3127    return 1;
3128 }
3129 
3130 static int
3131 png_image_read_colormapped(png_voidp argument)
3132 {
3133    png_image_read_control *display = png_voidcast(png_image_read_control*,
3134       argument);
3135    png_imagep image = display->image;
3136    png_controlp control = image->opaque;
3137    png_structrp png_ptr = control->png_ptr;
3138    png_inforp info_ptr = control->info_ptr;
3139 
3140    int passes = 0; /* As a flag */
3141 
3142    PNG_SKIP_CHUNKS(png_ptr);
3143 
3144    /* Update the 'info' structure and make sure the result is as required; first
3145     * make sure to turn on the interlace handling if it will be required
3146     * (because it can't be turned on *after* the call to png_read_update_info!)
3147     */
3148    if (display->colormap_processing == PNG_CMAP_NONE)
3149       passes = png_set_interlace_handling(png_ptr);
3150 
3151    png_read_update_info(png_ptr, info_ptr);
3152 
3153    /* The expected output can be deduced from the colormap_processing option. */
3154    switch (display->colormap_processing)
3155    {
3156       case PNG_CMAP_NONE:
3157          /* Output must be one channel and one byte per pixel, the output
3158           * encoding can be anything.
3159           */
3160          if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
3161             info_ptr->color_type == PNG_COLOR_TYPE_GRAY) &&
3162             info_ptr->bit_depth == 8)
3163             break;
3164 
3165          goto bad_output;
3166 
3167       case PNG_CMAP_TRANS:
3168       case PNG_CMAP_GA:
3169          /* Output must be two channels and the 'G' one must be sRGB, the latter
3170           * can be checked with an exact number because it should have been set
3171           * to this number above!
3172           */
3173          if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
3174             info_ptr->bit_depth == 8 &&
3175             png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3176             image->colormap_entries == 256)
3177             break;
3178 
3179          goto bad_output;
3180 
3181       case PNG_CMAP_RGB:
3182          /* Output must be 8-bit sRGB encoded RGB */
3183          if (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
3184             info_ptr->bit_depth == 8 &&
3185             png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3186             image->colormap_entries == 216)
3187             break;
3188 
3189          goto bad_output;
3190 
3191       case PNG_CMAP_RGB_ALPHA:
3192          /* Output must be 8-bit sRGB encoded RGBA */
3193          if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
3194             info_ptr->bit_depth == 8 &&
3195             png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
3196             image->colormap_entries == 244 /* 216 + 1 + 27 */)
3197             break;
3198 
3199          /* goto bad_output; */
3200          /* FALL THROUGH */
3201 
3202       default:
3203       bad_output:
3204          png_error(png_ptr, "bad color-map processing (internal error)");
3205    }
3206 
3207    /* Now read the rows.  Do this here if it is possible to read directly into
3208     * the output buffer, otherwise allocate a local row buffer of the maximum
3209     * size libpng requires and call the relevant processing routine safely.
3210     */
3211    {
3212       png_voidp first_row = display->buffer;
3213       ptrdiff_t row_bytes = display->row_stride;
3214 
3215       /* The following expression is designed to work correctly whether it gives
3216        * a signed or an unsigned result.
3217        */
3218       if (row_bytes < 0)
3219       {
3220          char *ptr = png_voidcast(char*, first_row);
3221          ptr += (image->height-1) * (-row_bytes);
3222          first_row = png_voidcast(png_voidp, ptr);
3223       }
3224 
3225       display->first_row = first_row;
3226       display->row_bytes = row_bytes;
3227    }
3228 
3229    if (passes == 0)
3230    {
3231       int result;
3232       png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
3233 
3234       display->local_row = row;
3235       result = png_safe_execute(image, png_image_read_and_map, display);
3236       display->local_row = NULL;
3237       png_free(png_ptr, row);
3238 
3239       return result;
3240    }
3241 
3242    else
3243    {
3244       png_alloc_size_t row_bytes = display->row_bytes;
3245 
3246       while (--passes >= 0)
3247       {
3248          png_uint_32      y = image->height;
3249          png_bytep        row = png_voidcast(png_bytep, display->first_row);
3250 
3251          while (y-- > 0)
3252          {
3253             png_read_row(png_ptr, row, NULL);
3254             row += row_bytes;
3255          }
3256       }
3257 
3258       return 1;
3259    }
3260 }
3261 
3262 /* Just the row reading part of png_image_read. */
3263 static int
3264 png_image_read_composite(png_voidp argument)
3265 {
3266    png_image_read_control *display = png_voidcast(png_image_read_control*,
3267       argument);
3268    png_imagep image = display->image;
3269    png_structrp png_ptr = image->opaque->png_ptr;
3270    int passes;
3271 
3272    switch (png_ptr->interlaced)
3273    {
3274       case PNG_INTERLACE_NONE:
3275          passes = 1;
3276          break;
3277 
3278       case PNG_INTERLACE_ADAM7:
3279          passes = PNG_INTERLACE_ADAM7_PASSES;
3280          break;
3281 
3282       default:
3283          png_error(png_ptr, "unknown interlace type");
3284    }
3285 
3286    {
3287       png_uint_32  height = image->height;
3288       png_uint_32  width = image->width;
3289       ptrdiff_t    step_row = display->row_bytes;
3290       unsigned int channels =
3291           (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
3292       int pass;
3293 
3294       for (pass = 0; pass < passes; ++pass)
3295       {
3296          unsigned int     startx, stepx, stepy;
3297          png_uint_32      y;
3298 
3299          if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3300          {
3301             /* The row may be empty for a short image: */
3302             if (PNG_PASS_COLS(width, pass) == 0)
3303                continue;
3304 
3305             startx = PNG_PASS_START_COL(pass) * channels;
3306             stepx = PNG_PASS_COL_OFFSET(pass) * channels;
3307             y = PNG_PASS_START_ROW(pass);
3308             stepy = PNG_PASS_ROW_OFFSET(pass);
3309          }
3310 
3311          else
3312          {
3313             y = 0;
3314             startx = 0;
3315             stepx = channels;
3316             stepy = 1;
3317          }
3318 
3319          for (; y<height; y += stepy)
3320          {
3321             png_bytep inrow = png_voidcast(png_bytep, display->local_row);
3322             png_bytep outrow;
3323             png_const_bytep end_row;
3324 
3325             /* Read the row, which is packed: */
3326             png_read_row(png_ptr, inrow, NULL);
3327 
3328             outrow = png_voidcast(png_bytep, display->first_row);
3329             outrow += y * step_row;
3330             end_row = outrow + width * channels;
3331 
3332             /* Now do the composition on each pixel in this row. */
3333             outrow += startx;
3334             for (; outrow < end_row; outrow += stepx)
3335             {
3336                png_byte alpha = inrow[channels];
3337 
3338                if (alpha > 0) /* else no change to the output */
3339                {
3340                   unsigned int c;
3341 
3342                   for (c=0; c<channels; ++c)
3343                   {
3344                      png_uint_32 component = inrow[c];
3345 
3346                      if (alpha < 255) /* else just use component */
3347                      {
3348                         /* This is PNG_OPTIMIZED_ALPHA, the component value
3349                          * is a linear 8-bit value.  Combine this with the
3350                          * current outrow[c] value which is sRGB encoded.
3351                          * Arithmetic here is 16-bits to preserve the output
3352                          * values correctly.
3353                          */
3354                         component *= 257*255; /* =65535 */
3355                         component += (255-alpha)*png_sRGB_table[outrow[c]];
3356 
3357                         /* So 'component' is scaled by 255*65535 and is
3358                          * therefore appropriate for the sRGB to linear
3359                          * conversion table.
3360                          */
3361                         component = PNG_sRGB_FROM_LINEAR(component);
3362                      }
3363 
3364                      outrow[c] = (png_byte)component;
3365                   }
3366                }
3367 
3368                inrow += channels+1; /* components and alpha channel */
3369             }
3370          }
3371       }
3372    }
3373 
3374    return 1;
3375 }
3376 
3377 /* The do_local_background case; called when all the following transforms are to
3378  * be done:
3379  *
3380  * PNG_RGB_TO_GRAY
3381  * PNG_COMPOSITE
3382  * PNG_GAMMA
3383  *
3384  * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and
3385  * PNG_COMPOSITE code performs gamma correction, so we get double gamma
3386  * correction.  The fix-up is to prevent the PNG_COMPOSITE operation from
3387  * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha
3388  * row and handles the removal or pre-multiplication of the alpha channel.
3389  */
3390 static int
3391 png_image_read_background(png_voidp argument)
3392 {
3393    png_image_read_control *display = png_voidcast(png_image_read_control*,
3394       argument);
3395    png_imagep image = display->image;
3396    png_structrp png_ptr = image->opaque->png_ptr;
3397    png_inforp info_ptr = image->opaque->info_ptr;
3398    png_uint_32 height = image->height;
3399    png_uint_32 width = image->width;
3400    int pass, passes;
3401 
3402    /* Double check the convoluted logic below.  We expect to get here with
3403     * libpng doing rgb to gray and gamma correction but background processing
3404     * left to the png_image_read_background function.  The rows libpng produce
3405     * might be 8 or 16-bit but should always have two channels; gray plus alpha.
3406     */
3407    if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
3408       png_error(png_ptr, "lost rgb to gray");
3409 
3410    if ((png_ptr->transformations & PNG_COMPOSE) != 0)
3411       png_error(png_ptr, "unexpected compose");
3412 
3413    if (png_get_channels(png_ptr, info_ptr) != 2)
3414       png_error(png_ptr, "lost/gained channels");
3415 
3416    /* Expect the 8-bit case to always remove the alpha channel */
3417    if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&
3418       (image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
3419       png_error(png_ptr, "unexpected 8-bit transformation");
3420 
3421    switch (png_ptr->interlaced)
3422    {
3423       case PNG_INTERLACE_NONE:
3424          passes = 1;
3425          break;
3426 
3427       case PNG_INTERLACE_ADAM7:
3428          passes = PNG_INTERLACE_ADAM7_PASSES;
3429          break;
3430 
3431       default:
3432          png_error(png_ptr, "unknown interlace type");
3433    }
3434 
3435    /* Use direct access to info_ptr here because otherwise the simplified API
3436     * would require PNG_EASY_ACCESS_SUPPORTED (just for this.)  Note this is
3437     * checking the value after libpng expansions, not the original value in the
3438     * PNG.
3439     */
3440    switch (info_ptr->bit_depth)
3441    {
3442       case 8:
3443          /* 8-bit sRGB gray values with an alpha channel; the alpha channel is
3444           * to be removed by composing on a background: either the row if
3445           * display->background is NULL or display->background->green if not.
3446           * Unlike the code above ALPHA_OPTIMIZED has *not* been done.
3447           */
3448          {
3449             png_bytep first_row = png_voidcast(png_bytep, display->first_row);
3450             ptrdiff_t step_row = display->row_bytes;
3451 
3452             for (pass = 0; pass < passes; ++pass)
3453             {
3454                png_bytep        row = png_voidcast(png_bytep,
3455                                                    display->first_row);
3456                unsigned int     startx, stepx, stepy;
3457                png_uint_32      y;
3458 
3459                if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3460                {
3461                   /* The row may be empty for a short image: */
3462                   if (PNG_PASS_COLS(width, pass) == 0)
3463                      continue;
3464 
3465                   startx = PNG_PASS_START_COL(pass);
3466                   stepx = PNG_PASS_COL_OFFSET(pass);
3467                   y = PNG_PASS_START_ROW(pass);
3468                   stepy = PNG_PASS_ROW_OFFSET(pass);
3469                }
3470 
3471                else
3472                {
3473                   y = 0;
3474                   startx = 0;
3475                   stepx = stepy = 1;
3476                }
3477 
3478                if (display->background == NULL)
3479                {
3480                   for (; y<height; y += stepy)
3481                   {
3482                      png_bytep inrow = png_voidcast(png_bytep,
3483                         display->local_row);
3484                      png_bytep outrow = first_row + y * step_row;
3485                      png_const_bytep end_row = outrow + width;
3486 
3487                      /* Read the row, which is packed: */
3488                      png_read_row(png_ptr, inrow, NULL);
3489 
3490                      /* Now do the composition on each pixel in this row. */
3491                      outrow += startx;
3492                      for (; outrow < end_row; outrow += stepx)
3493                      {
3494                         png_byte alpha = inrow[1];
3495 
3496                         if (alpha > 0) /* else no change to the output */
3497                         {
3498                            png_uint_32 component = inrow[0];
3499 
3500                            if (alpha < 255) /* else just use component */
3501                            {
3502                               /* Since PNG_OPTIMIZED_ALPHA was not set it is
3503                                * necessary to invert the sRGB transfer
3504                                * function and multiply the alpha out.
3505                                */
3506                               component = png_sRGB_table[component] * alpha;
3507                               component += png_sRGB_table[outrow[0]] *
3508                                  (255-alpha);
3509                               component = PNG_sRGB_FROM_LINEAR(component);
3510                            }
3511 
3512                            outrow[0] = (png_byte)component;
3513                         }
3514 
3515                         inrow += 2; /* gray and alpha channel */
3516                      }
3517                   }
3518                }
3519 
3520                else /* constant background value */
3521                {
3522                   png_byte background8 = display->background->green;
3523                   png_uint_16 background = png_sRGB_table[background8];
3524 
3525                   for (; y<height; y += stepy)
3526                   {
3527                      png_bytep inrow = png_voidcast(png_bytep,
3528                         display->local_row);
3529                      png_bytep outrow = first_row + y * step_row;
3530                      png_const_bytep end_row = outrow + width;
3531 
3532                      /* Read the row, which is packed: */
3533                      png_read_row(png_ptr, inrow, NULL);
3534 
3535                      /* Now do the composition on each pixel in this row. */
3536                      outrow += startx;
3537                      for (; outrow < end_row; outrow += stepx)
3538                      {
3539                         png_byte alpha = inrow[1];
3540 
3541                         if (alpha > 0) /* else use background */
3542                         {
3543                            png_uint_32 component = inrow[0];
3544 
3545                            if (alpha < 255) /* else just use component */
3546                            {
3547                               component = png_sRGB_table[component] * alpha;
3548                               component += background * (255-alpha);
3549                               component = PNG_sRGB_FROM_LINEAR(component);
3550                            }
3551 
3552                            outrow[0] = (png_byte)component;
3553                         }
3554 
3555                         else
3556                            outrow[0] = background8;
3557 
3558                         inrow += 2; /* gray and alpha channel */
3559                      }
3560 
3561                      row += display->row_bytes;
3562                   }
3563                }
3564             }
3565          }
3566          break;
3567 
3568       case 16:
3569          /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must
3570           * still be done and, maybe, the alpha channel removed.  This code also
3571           * handles the alpha-first option.
3572           */
3573          {
3574             png_uint_16p first_row = png_voidcast(png_uint_16p,
3575                display->first_row);
3576             /* The division by two is safe because the caller passed in a
3577              * stride which was multiplied by 2 (below) to get row_bytes.
3578              */
3579             ptrdiff_t    step_row = display->row_bytes / 2;
3580             int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
3581             unsigned int outchannels = 1+preserve_alpha;
3582             int swap_alpha = 0;
3583 
3584 #           ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
3585                if (preserve_alpha != 0 &&
3586                    (image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
3587                   swap_alpha = 1;
3588 #           endif
3589 
3590             for (pass = 0; pass < passes; ++pass)
3591             {
3592                unsigned int     startx, stepx, stepy;
3593                png_uint_32      y;
3594 
3595                /* The 'x' start and step are adjusted to output components here.
3596                 */
3597                if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
3598                {
3599                   /* The row may be empty for a short image: */
3600                   if (PNG_PASS_COLS(width, pass) == 0)
3601                      continue;
3602 
3603                   startx = PNG_PASS_START_COL(pass) * outchannels;
3604                   stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;
3605                   y = PNG_PASS_START_ROW(pass);
3606                   stepy = PNG_PASS_ROW_OFFSET(pass);
3607                }
3608 
3609                else
3610                {
3611                   y = 0;
3612                   startx = 0;
3613                   stepx = outchannels;
3614                   stepy = 1;
3615                }
3616 
3617                for (; y<height; y += stepy)
3618                {
3619                   png_const_uint_16p inrow;
3620                   png_uint_16p outrow = first_row + y*step_row;
3621                   png_uint_16p end_row = outrow + width * outchannels;
3622 
3623                   /* Read the row, which is packed: */
3624                   png_read_row(png_ptr, png_voidcast(png_bytep,
3625                      display->local_row), NULL);
3626                   inrow = png_voidcast(png_const_uint_16p, display->local_row);
3627 
3628                   /* Now do the pre-multiplication on each pixel in this row.
3629                    */
3630                   outrow += startx;
3631                   for (; outrow < end_row; outrow += stepx)
3632                   {
3633                      png_uint_32 component = inrow[0];
3634                      png_uint_16 alpha = inrow[1];
3635 
3636                      if (alpha > 0) /* else 0 */
3637                      {
3638                         if (alpha < 65535) /* else just use component */
3639                         {
3640                            component *= alpha;
3641                            component += 32767;
3642                            component /= 65535;
3643                         }
3644                      }
3645 
3646                      else
3647                         component = 0;
3648 
3649                      outrow[swap_alpha] = (png_uint_16)component;
3650                      if (preserve_alpha != 0)
3651                         outrow[1 ^ swap_alpha] = alpha;
3652 
3653                      inrow += 2; /* components and alpha channel */
3654                   }
3655                }
3656             }
3657          }
3658          break;
3659 
3660 #ifdef __GNUC__
3661       default:
3662          png_error(png_ptr, "unexpected bit depth");
3663 #endif
3664    }
3665 
3666    return 1;
3667 }
3668 
3669 /* The guts of png_image_finish_read as a png_safe_execute callback. */
3670 static int
3671 png_image_read_direct(png_voidp argument)
3672 {
3673    png_image_read_control *display = png_voidcast(png_image_read_control*,
3674       argument);
3675    png_imagep image = display->image;
3676    png_structrp png_ptr = image->opaque->png_ptr;
3677    png_inforp info_ptr = image->opaque->info_ptr;
3678 
3679    png_uint_32 format = image->format;
3680    int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
3681    int do_local_compose = 0;
3682    int do_local_background = 0; /* to avoid double gamma correction bug */
3683    int passes = 0;
3684 
3685    /* Add transforms to ensure the correct output format is produced then check
3686     * that the required implementation support is there.  Always expand; always
3687     * need 8 bits minimum, no palette and expanded tRNS.
3688     */
3689    png_set_expand(png_ptr);
3690 
3691    /* Now check the format to see if it was modified. */
3692    {
3693       png_uint_32 base_format = png_image_format(png_ptr) &
3694          ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */;
3695       png_uint_32 change = format ^ base_format;
3696       png_fixed_point output_gamma;
3697       int mode; /* alpha mode */
3698 
3699       /* Do this first so that we have a record if rgb to gray is happening. */
3700       if ((change & PNG_FORMAT_FLAG_COLOR) != 0)
3701       {
3702          /* gray<->color transformation required. */
3703          if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
3704             png_set_gray_to_rgb(png_ptr);
3705 
3706          else
3707          {
3708             /* libpng can't do both rgb to gray and
3709              * background/pre-multiplication if there is also significant gamma
3710              * correction, because both operations require linear colors and
3711              * the code only supports one transform doing the gamma correction.
3712              * Handle this by doing the pre-multiplication or background
3713              * operation in this code, if necessary.
3714              *
3715              * TODO: fix this by rewriting pngrtran.c (!)
3716              *
3717              * For the moment (given that fixing this in pngrtran.c is an
3718              * enormous change) 'do_local_background' is used to indicate that
3719              * the problem exists.
3720              */
3721             if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
3722                do_local_background = 1/*maybe*/;
3723 
3724             png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
3725                PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
3726          }
3727 
3728          change &= ~PNG_FORMAT_FLAG_COLOR;
3729       }
3730 
3731       /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
3732        */
3733       {
3734          png_fixed_point input_gamma_default;
3735 
3736          if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
3737              (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
3738             input_gamma_default = PNG_GAMMA_LINEAR;
3739          else
3740             input_gamma_default = PNG_DEFAULT_sRGB;
3741 
3742          /* Call png_set_alpha_mode to set the default for the input gamma; the
3743           * output gamma is set by a second call below.
3744           */
3745          png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);
3746       }
3747 
3748       if (linear != 0)
3749       {
3750          /* If there *is* an alpha channel in the input it must be multiplied
3751           * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.
3752           */
3753          if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
3754             mode = PNG_ALPHA_STANDARD; /* associated alpha */
3755 
3756          else
3757             mode = PNG_ALPHA_PNG;
3758 
3759          output_gamma = PNG_GAMMA_LINEAR;
3760       }
3761 
3762       else
3763       {
3764          mode = PNG_ALPHA_PNG;
3765          output_gamma = PNG_DEFAULT_sRGB;
3766       }
3767 
3768       /* If 'do_local_background' is set check for the presence of gamma
3769        * correction; this is part of the work-round for the libpng bug
3770        * described above.
3771        *
3772        * TODO: fix libpng and remove this.
3773        */
3774       if (do_local_background != 0)
3775       {
3776          png_fixed_point gtest;
3777 
3778          /* This is 'png_gamma_threshold' from pngrtran.c; the test used for
3779           * gamma correction, the screen gamma hasn't been set on png_struct
3780           * yet; it's set below.  png_struct::gamma, however, is set to the
3781           * final value.
3782           */
3783          if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
3784                PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
3785             do_local_background = 0;
3786 
3787          else if (mode == PNG_ALPHA_STANDARD)
3788          {
3789             do_local_background = 2/*required*/;
3790             mode = PNG_ALPHA_PNG; /* prevent libpng doing it */
3791          }
3792 
3793          /* else leave as 1 for the checks below */
3794       }
3795 
3796       /* If the bit-depth changes then handle that here. */
3797       if ((change & PNG_FORMAT_FLAG_LINEAR) != 0)
3798       {
3799          if (linear != 0 /*16-bit output*/)
3800             png_set_expand_16(png_ptr);
3801 
3802          else /* 8-bit output */
3803             png_set_scale_16(png_ptr);
3804 
3805          change &= ~PNG_FORMAT_FLAG_LINEAR;
3806       }
3807 
3808       /* Now the background/alpha channel changes. */
3809       if ((change & PNG_FORMAT_FLAG_ALPHA) != 0)
3810       {
3811          /* Removing an alpha channel requires composition for the 8-bit
3812           * formats; for the 16-bit it is already done, above, by the
3813           * pre-multiplication and the channel just needs to be stripped.
3814           */
3815          if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
3816          {
3817             /* If RGB->gray is happening the alpha channel must be left and the
3818              * operation completed locally.
3819              *
3820              * TODO: fix libpng and remove this.
3821              */
3822             if (do_local_background != 0)
3823                do_local_background = 2/*required*/;
3824 
3825             /* 16-bit output: just remove the channel */
3826             else if (linear != 0) /* compose on black (well, pre-multiply) */
3827                png_set_strip_alpha(png_ptr);
3828 
3829             /* 8-bit output: do an appropriate compose */
3830             else if (display->background != NULL)
3831             {
3832                png_color_16 c;
3833 
3834                c.index = 0; /*unused*/
3835                c.red = display->background->red;
3836                c.green = display->background->green;
3837                c.blue = display->background->blue;
3838                c.gray = display->background->green;
3839 
3840                /* This is always an 8-bit sRGB value, using the 'green' channel
3841                 * for gray is much better than calculating the luminance here;
3842                 * we can get off-by-one errors in that calculation relative to
3843                 * the app expectations and that will show up in transparent
3844                 * pixels.
3845                 */
3846                png_set_background_fixed(png_ptr, &c,
3847                   PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
3848                   0/*gamma: not used*/);
3849             }
3850 
3851             else /* compose on row: implemented below. */
3852             {
3853                do_local_compose = 1;
3854                /* This leaves the alpha channel in the output, so it has to be
3855                 * removed by the code below.  Set the encoding to the 'OPTIMIZE'
3856                 * one so the code only has to hack on the pixels that require
3857                 * composition.
3858                 */
3859                mode = PNG_ALPHA_OPTIMIZED;
3860             }
3861          }
3862 
3863          else /* output needs an alpha channel */
3864          {
3865             /* This is tricky because it happens before the swap operation has
3866              * been accomplished; however, the swap does *not* swap the added
3867              * alpha channel (weird API), so it must be added in the correct
3868              * place.
3869              */
3870             png_uint_32 filler; /* opaque filler */
3871             int where;
3872 
3873             if (linear != 0)
3874                filler = 65535;
3875 
3876             else
3877                filler = 255;
3878 
3879 #           ifdef PNG_FORMAT_AFIRST_SUPPORTED
3880                if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
3881                {
3882                   where = PNG_FILLER_BEFORE;
3883                   change &= ~PNG_FORMAT_FLAG_AFIRST;
3884                }
3885 
3886                else
3887 #           endif
3888                where = PNG_FILLER_AFTER;
3889 
3890             png_set_add_alpha(png_ptr, filler, where);
3891          }
3892 
3893          /* This stops the (irrelevant) call to swap_alpha below. */
3894          change &= ~PNG_FORMAT_FLAG_ALPHA;
3895       }
3896 
3897       /* Now set the alpha mode correctly; this is always done, even if there is
3898        * no alpha channel in either the input or the output because it correctly
3899        * sets the output gamma.
3900        */
3901       png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);
3902 
3903 #     ifdef PNG_FORMAT_BGR_SUPPORTED
3904          if ((change & PNG_FORMAT_FLAG_BGR) != 0)
3905          {
3906             /* Check only the output format; PNG is never BGR; don't do this if
3907              * the output is gray, but fix up the 'format' value in that case.
3908              */
3909             if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
3910                png_set_bgr(png_ptr);
3911 
3912             else
3913                format &= ~PNG_FORMAT_FLAG_BGR;
3914 
3915             change &= ~PNG_FORMAT_FLAG_BGR;
3916          }
3917 #     endif
3918 
3919 #     ifdef PNG_FORMAT_AFIRST_SUPPORTED
3920          if ((change & PNG_FORMAT_FLAG_AFIRST) != 0)
3921          {
3922             /* Only relevant if there is an alpha channel - it's particularly
3923              * important to handle this correctly because do_local_compose may
3924              * be set above and then libpng will keep the alpha channel for this
3925              * code to remove.
3926              */
3927             if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)
3928             {
3929                /* Disable this if doing a local background,
3930                 * TODO: remove this when local background is no longer required.
3931                 */
3932                if (do_local_background != 2)
3933                   png_set_swap_alpha(png_ptr);
3934             }
3935 
3936             else
3937                format &= ~PNG_FORMAT_FLAG_AFIRST;
3938 
3939             change &= ~PNG_FORMAT_FLAG_AFIRST;
3940          }
3941 #     endif
3942 
3943       /* If the *output* is 16-bit then we need to check for a byte-swap on this
3944        * architecture.
3945        */
3946       if (linear != 0)
3947       {
3948          PNG_CONST png_uint_16 le = 0x0001;
3949 
3950          if ((*(png_const_bytep) & le) != 0)
3951             png_set_swap(png_ptr);
3952       }
3953 
3954       /* If change is not now 0 some transformation is missing - error out. */
3955       if (change != 0)
3956          png_error(png_ptr, "png_read_image: unsupported transformation");
3957    }
3958 
3959    PNG_SKIP_CHUNKS(png_ptr);
3960 
3961    /* Update the 'info' structure and make sure the result is as required; first
3962     * make sure to turn on the interlace handling if it will be required
3963     * (because it can't be turned on *after* the call to png_read_update_info!)
3964     *
3965     * TODO: remove the do_local_background fixup below.
3966     */
3967    if (do_local_compose == 0 && do_local_background != 2)
3968       passes = png_set_interlace_handling(png_ptr);
3969 
3970    png_read_update_info(png_ptr, info_ptr);
3971 
3972    {
3973       png_uint_32 info_format = 0;
3974 
3975       if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
3976          info_format |= PNG_FORMAT_FLAG_COLOR;
3977 
3978       if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
3979       {
3980          /* do_local_compose removes this channel below. */
3981          if (do_local_compose == 0)
3982          {
3983             /* do_local_background does the same if required. */
3984             if (do_local_background != 2 ||
3985                (format & PNG_FORMAT_FLAG_ALPHA) != 0)
3986                info_format |= PNG_FORMAT_FLAG_ALPHA;
3987          }
3988       }
3989 
3990       else if (do_local_compose != 0) /* internal error */
3991          png_error(png_ptr, "png_image_read: alpha channel lost");
3992 
3993       if (info_ptr->bit_depth == 16)
3994          info_format |= PNG_FORMAT_FLAG_LINEAR;
3995 
3996 #     ifdef PNG_FORMAT_BGR_SUPPORTED
3997          if ((png_ptr->transformations & PNG_BGR) != 0)
3998             info_format |= PNG_FORMAT_FLAG_BGR;
3999 #     endif
4000 
4001 #     ifdef PNG_FORMAT_AFIRST_SUPPORTED
4002          if (do_local_background == 2)
4003          {
4004             if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
4005                info_format |= PNG_FORMAT_FLAG_AFIRST;
4006          }
4007 
4008          if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 ||
4009             ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
4010             (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
4011          {
4012             if (do_local_background == 2)
4013                png_error(png_ptr, "unexpected alpha swap transformation");
4014 
4015             info_format |= PNG_FORMAT_FLAG_AFIRST;
4016          }
4017 #     endif
4018 
4019       /* This is actually an internal error. */
4020       if (info_format != format)
4021          png_error(png_ptr, "png_read_image: invalid transformations");
4022    }
4023 
4024    /* Now read the rows.  If do_local_compose is set then it is necessary to use
4025     * a local row buffer.  The output will be GA, RGBA or BGRA and must be
4026     * converted to G, RGB or BGR as appropriate.  The 'local_row' member of the
4027     * display acts as a flag.
4028     */
4029    {
4030       png_voidp first_row = display->buffer;
4031       ptrdiff_t row_bytes = display->row_stride;
4032 
4033       if (linear != 0)
4034          row_bytes *= 2;
4035 
4036       /* The following expression is designed to work correctly whether it gives
4037        * a signed or an unsigned result.
4038        */
4039       if (row_bytes < 0)
4040       {
4041          char *ptr = png_voidcast(char*, first_row);
4042          ptr += (image->height-1) * (-row_bytes);
4043          first_row = png_voidcast(png_voidp, ptr);
4044       }
4045 
4046       display->first_row = first_row;
4047       display->row_bytes = row_bytes;
4048    }
4049 
4050    if (do_local_compose != 0)
4051    {
4052       int result;
4053       png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
4054 
4055       display->local_row = row;
4056       result = png_safe_execute(image, png_image_read_composite, display);
4057       display->local_row = NULL;
4058       png_free(png_ptr, row);
4059 
4060       return result;
4061    }
4062 
4063    else if (do_local_background == 2)
4064    {
4065       int result;
4066       png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
4067 
4068       display->local_row = row;
4069       result = png_safe_execute(image, png_image_read_background, display);
4070       display->local_row = NULL;
4071       png_free(png_ptr, row);
4072 
4073       return result;
4074    }
4075 
4076    else
4077    {
4078       png_alloc_size_t row_bytes = display->row_bytes;
4079 
4080       while (--passes >= 0)
4081       {
4082          png_uint_32      y = image->height;
4083          png_bytep        row = png_voidcast(png_bytep, display->first_row);
4084 
4085          while (y-- > 0)
4086          {
4087             png_read_row(png_ptr, row, NULL);
4088             row += row_bytes;
4089          }
4090       }
4091 
4092       return 1;
4093    }
4094 }
4095 
4096 int PNGAPI
4097 png_image_finish_read(png_imagep image, png_const_colorp background,
4098    void *buffer, png_int_32 row_stride, void *colormap)
4099 {
4100    if (image != NULL && image->version == PNG_IMAGE_VERSION)
4101    {
4102       png_uint_32 check;
4103 
4104       if (row_stride == 0)
4105          row_stride = PNG_IMAGE_ROW_STRIDE(*image);
4106 
4107       if (row_stride < 0)
4108          check = -row_stride;
4109 
4110       else
4111          check = row_stride;
4112 
4113       if (image->opaque != NULL && buffer != NULL &&
4114          check >= PNG_IMAGE_ROW_STRIDE(*image))
4115       {
4116          if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
4117             (image->colormap_entries > 0 && colormap != NULL))
4118          {
4119             int result;
4120             png_image_read_control display;
4121 
4122             memset(&display, 0, (sizeof display));
4123             display.image = image;
4124             display.buffer = buffer;
4125             display.row_stride = row_stride;
4126             display.colormap = colormap;
4127             display.background = background;
4128             display.local_row = NULL;
4129 
4130             /* Choose the correct 'end' routine; for the color-map case all the
4131              * setup has already been done.
4132              */
4133             if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
4134                result =
4135                   png_safe_execute(image, png_image_read_colormap, &display) &&
4136                   png_safe_execute(image, png_image_read_colormapped, &display);
4137 
4138             else
4139                result =
4140                   png_safe_execute(image, png_image_read_direct, &display);
4141 
4142             png_image_free(image);
4143             return result;
4144          }
4145 
4146          else
4147             return png_image_error(image,
4148                "png_image_finish_read[color-map]: no color-map");
4149       }
4150 
4151       else
4152          return png_image_error(image,
4153             "png_image_finish_read: invalid argument");
4154    }
4155 
4156    else if (image != NULL)
4157       return png_image_error(image,
4158          "png_image_finish_read: damaged PNG_IMAGE_VERSION");
4159 
4160    return 0;
4161 }
4162 
4163 #endif /* SIMPLIFIED_READ */
4164 #endif /* READ */