tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pngread.c (145542B)


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