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