LCOV - code coverage report
Current view: top level - media/libpng - pngread.c (source / functions) Hit Total Coverage
Test: output.info Lines: 40 79 50.6 %
Date: 2017-07-14 16:53:18 Functions: 4 6 66.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13