"Fossies" - the Fresh Open Source Software Archive

Member "pngcrush-1.8.13/pngread.c" (29 Aug 2017, 142502 Bytes) of package /linux/privat/pngcrush-1.8.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pngread.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.8.12_vs_1.8.13.

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