src/3rdparty/libpng/pngpread.c
changeset 0 1918ee327afb
child 30 5dc02b23752f
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 
       
     2 /* pngpread.c - read a png file in push mode
       
     3  *
       
     4  * Last changed in libpng 1.2.38 [July 16, 2009]
       
     5  * Copyright (c) 1998-2009 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 
       
    14 #define PNG_INTERNAL
       
    15 #include "png.h"
       
    16 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
       
    17 
       
    18 /* Push model modes */
       
    19 #define PNG_READ_SIG_MODE   0
       
    20 #define PNG_READ_CHUNK_MODE 1
       
    21 #define PNG_READ_IDAT_MODE  2
       
    22 #define PNG_SKIP_MODE       3
       
    23 #define PNG_READ_tEXt_MODE  4
       
    24 #define PNG_READ_zTXt_MODE  5
       
    25 #define PNG_READ_DONE_MODE  6
       
    26 #define PNG_READ_iTXt_MODE  7
       
    27 #define PNG_ERROR_MODE      8
       
    28 
       
    29 void PNGAPI
       
    30 png_process_data(png_structp png_ptr, png_infop info_ptr,
       
    31    png_bytep buffer, png_size_t buffer_size)
       
    32 {
       
    33    if (png_ptr == NULL || info_ptr == NULL)
       
    34       return;
       
    35 
       
    36    png_push_restore_buffer(png_ptr, buffer, buffer_size);
       
    37 
       
    38    while (png_ptr->buffer_size)
       
    39    {
       
    40       png_process_some_data(png_ptr, info_ptr);
       
    41    }
       
    42 }
       
    43 
       
    44 /* What we do with the incoming data depends on what we were previously
       
    45  * doing before we ran out of data...
       
    46  */
       
    47 void /* PRIVATE */
       
    48 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
       
    49 {
       
    50    if (png_ptr == NULL)
       
    51       return;
       
    52 
       
    53    switch (png_ptr->process_mode)
       
    54    {
       
    55       case PNG_READ_SIG_MODE:
       
    56       {
       
    57          png_push_read_sig(png_ptr, info_ptr);
       
    58          break;
       
    59       }
       
    60 
       
    61       case PNG_READ_CHUNK_MODE:
       
    62       {
       
    63          png_push_read_chunk(png_ptr, info_ptr);
       
    64          break;
       
    65       }
       
    66 
       
    67       case PNG_READ_IDAT_MODE:
       
    68       {
       
    69          png_push_read_IDAT(png_ptr);
       
    70          break;
       
    71       }
       
    72 
       
    73 #if defined(PNG_READ_tEXt_SUPPORTED)
       
    74       case PNG_READ_tEXt_MODE:
       
    75       {
       
    76          png_push_read_tEXt(png_ptr, info_ptr);
       
    77          break;
       
    78       }
       
    79 
       
    80 #endif
       
    81 #if defined(PNG_READ_zTXt_SUPPORTED)
       
    82       case PNG_READ_zTXt_MODE:
       
    83       {
       
    84          png_push_read_zTXt(png_ptr, info_ptr);
       
    85          break;
       
    86       }
       
    87 
       
    88 #endif
       
    89 #if defined(PNG_READ_iTXt_SUPPORTED)
       
    90       case PNG_READ_iTXt_MODE:
       
    91       {
       
    92          png_push_read_iTXt(png_ptr, info_ptr);
       
    93          break;
       
    94       }
       
    95 
       
    96 #endif
       
    97       case PNG_SKIP_MODE:
       
    98       {
       
    99          png_push_crc_finish(png_ptr);
       
   100          break;
       
   101       }
       
   102 
       
   103       default:
       
   104       {
       
   105          png_ptr->buffer_size = 0;
       
   106          break;
       
   107       }
       
   108    }
       
   109 }
       
   110 
       
   111 /* Read any remaining signature bytes from the stream and compare them with
       
   112  * the correct PNG signature.  It is possible that this routine is called
       
   113  * with bytes already read from the signature, either because they have been
       
   114  * checked by the calling application, or because of multiple calls to this
       
   115  * routine.
       
   116  */
       
   117 void /* PRIVATE */
       
   118 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
       
   119 {
       
   120    png_size_t num_checked = png_ptr->sig_bytes,
       
   121              num_to_check = 8 - num_checked;
       
   122 
       
   123    if (png_ptr->buffer_size < num_to_check)
       
   124    {
       
   125       num_to_check = png_ptr->buffer_size;
       
   126    }
       
   127 
       
   128    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
       
   129       num_to_check);
       
   130    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
       
   131 
       
   132    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
       
   133    {
       
   134       if (num_checked < 4 &&
       
   135           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
       
   136          png_error(png_ptr, "Not a PNG file");
       
   137       else
       
   138          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
       
   139    }
       
   140    else
       
   141    {
       
   142       if (png_ptr->sig_bytes >= 8)
       
   143       {
       
   144          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
       
   145       }
       
   146    }
       
   147 }
       
   148 
       
   149 void /* PRIVATE */
       
   150 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
       
   151 {
       
   152 #ifdef PNG_USE_LOCAL_ARRAYS
       
   153       PNG_CONST PNG_IHDR;
       
   154       PNG_CONST PNG_IDAT;
       
   155       PNG_CONST PNG_IEND;
       
   156       PNG_CONST PNG_PLTE;
       
   157 #if defined(PNG_READ_bKGD_SUPPORTED)
       
   158       PNG_CONST PNG_bKGD;
       
   159 #endif
       
   160 #if defined(PNG_READ_cHRM_SUPPORTED)
       
   161       PNG_CONST PNG_cHRM;
       
   162 #endif
       
   163 #if defined(PNG_READ_gAMA_SUPPORTED)
       
   164       PNG_CONST PNG_gAMA;
       
   165 #endif
       
   166 #if defined(PNG_READ_hIST_SUPPORTED)
       
   167       PNG_CONST PNG_hIST;
       
   168 #endif
       
   169 #if defined(PNG_READ_iCCP_SUPPORTED)
       
   170       PNG_CONST PNG_iCCP;
       
   171 #endif
       
   172 #if defined(PNG_READ_iTXt_SUPPORTED)
       
   173       PNG_CONST PNG_iTXt;
       
   174 #endif
       
   175 #if defined(PNG_READ_oFFs_SUPPORTED)
       
   176       PNG_CONST PNG_oFFs;
       
   177 #endif
       
   178 #if defined(PNG_READ_pCAL_SUPPORTED)
       
   179       PNG_CONST PNG_pCAL;
       
   180 #endif
       
   181 #if defined(PNG_READ_pHYs_SUPPORTED)
       
   182       PNG_CONST PNG_pHYs;
       
   183 #endif
       
   184 #if defined(PNG_READ_sBIT_SUPPORTED)
       
   185       PNG_CONST PNG_sBIT;
       
   186 #endif
       
   187 #if defined(PNG_READ_sCAL_SUPPORTED)
       
   188       PNG_CONST PNG_sCAL;
       
   189 #endif
       
   190 #if defined(PNG_READ_sRGB_SUPPORTED)
       
   191       PNG_CONST PNG_sRGB;
       
   192 #endif
       
   193 #if defined(PNG_READ_sPLT_SUPPORTED)
       
   194       PNG_CONST PNG_sPLT;
       
   195 #endif
       
   196 #if defined(PNG_READ_tEXt_SUPPORTED)
       
   197       PNG_CONST PNG_tEXt;
       
   198 #endif
       
   199 #if defined(PNG_READ_tIME_SUPPORTED)
       
   200       PNG_CONST PNG_tIME;
       
   201 #endif
       
   202 #if defined(PNG_READ_tRNS_SUPPORTED)
       
   203       PNG_CONST PNG_tRNS;
       
   204 #endif
       
   205 #if defined(PNG_READ_zTXt_SUPPORTED)
       
   206       PNG_CONST PNG_zTXt;
       
   207 #endif
       
   208 #endif /* PNG_USE_LOCAL_ARRAYS */
       
   209    /* First we make sure we have enough data for the 4 byte chunk name
       
   210     * and the 4 byte chunk length before proceeding with decoding the
       
   211     * chunk data.  To fully decode each of these chunks, we also make
       
   212     * sure we have enough data in the buffer for the 4 byte CRC at the
       
   213     * end of every chunk (except IDAT, which is handled separately).
       
   214     */
       
   215    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
       
   216    {
       
   217       png_byte chunk_length[4];
       
   218 
       
   219       if (png_ptr->buffer_size < 8)
       
   220       {
       
   221          png_push_save_buffer(png_ptr);
       
   222          return;
       
   223       }
       
   224 
       
   225       png_push_fill_buffer(png_ptr, chunk_length, 4);
       
   226       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
       
   227       png_reset_crc(png_ptr);
       
   228       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
       
   229       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
       
   230       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
       
   231    }
       
   232 
       
   233    if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       
   234      if (png_ptr->mode & PNG_AFTER_IDAT)
       
   235         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
       
   236 
       
   237    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
       
   238    {
       
   239       if (png_ptr->push_length != 13)
       
   240          png_error(png_ptr, "Invalid IHDR length");
       
   241 
       
   242       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   243       {
       
   244          png_push_save_buffer(png_ptr);
       
   245          return;
       
   246       }
       
   247 
       
   248       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
       
   249    }
       
   250 
       
   251    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
       
   252    {
       
   253       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   254       {
       
   255          png_push_save_buffer(png_ptr);
       
   256          return;
       
   257       }
       
   258 
       
   259       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
       
   260 
       
   261       png_ptr->process_mode = PNG_READ_DONE_MODE;
       
   262       png_push_have_end(png_ptr, info_ptr);
       
   263    }
       
   264 
       
   265 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
       
   266    else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
       
   267    {
       
   268       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   269       {
       
   270          png_push_save_buffer(png_ptr);
       
   271          return;
       
   272       }
       
   273 
       
   274       if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       
   275          png_ptr->mode |= PNG_HAVE_IDAT;
       
   276 
       
   277       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
       
   278 
       
   279       if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
       
   280          png_ptr->mode |= PNG_HAVE_PLTE;
       
   281 
       
   282       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       
   283       {
       
   284          if (!(png_ptr->mode & PNG_HAVE_IHDR))
       
   285             png_error(png_ptr, "Missing IHDR before IDAT");
       
   286 
       
   287          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
       
   288                   !(png_ptr->mode & PNG_HAVE_PLTE))
       
   289             png_error(png_ptr, "Missing PLTE before IDAT");
       
   290       }
       
   291    }
       
   292 
       
   293 #endif
       
   294    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
       
   295    {
       
   296       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   297       {
       
   298          png_push_save_buffer(png_ptr);
       
   299          return;
       
   300       }
       
   301       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
       
   302    }
       
   303 
       
   304    else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       
   305    {
       
   306       /* If we reach an IDAT chunk, this means we have read all of the
       
   307        * header chunks, and we can start reading the image (or if this
       
   308        * is called after the image has been read - we have an error).
       
   309        */
       
   310 
       
   311       if (!(png_ptr->mode & PNG_HAVE_IHDR))
       
   312          png_error(png_ptr, "Missing IHDR before IDAT");
       
   313 
       
   314       else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
       
   315           !(png_ptr->mode & PNG_HAVE_PLTE))
       
   316          png_error(png_ptr, "Missing PLTE before IDAT");
       
   317 
       
   318       if (png_ptr->mode & PNG_HAVE_IDAT)
       
   319       {
       
   320          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
       
   321             if (png_ptr->push_length == 0)
       
   322                return;
       
   323 
       
   324          if (png_ptr->mode & PNG_AFTER_IDAT)
       
   325             png_error(png_ptr, "Too many IDAT's found");
       
   326       }
       
   327 
       
   328       png_ptr->idat_size = png_ptr->push_length;
       
   329       png_ptr->mode |= PNG_HAVE_IDAT;
       
   330       png_ptr->process_mode = PNG_READ_IDAT_MODE;
       
   331       png_push_have_info(png_ptr, info_ptr);
       
   332       png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
       
   333       png_ptr->zstream.next_out = png_ptr->row_buf;
       
   334       return;
       
   335    }
       
   336 
       
   337 #if defined(PNG_READ_gAMA_SUPPORTED)
       
   338    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
       
   339    {
       
   340       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   341       {
       
   342          png_push_save_buffer(png_ptr);
       
   343          return;
       
   344       }
       
   345 
       
   346       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
       
   347    }
       
   348 
       
   349 #endif
       
   350 #if defined(PNG_READ_sBIT_SUPPORTED)
       
   351    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
       
   352    {
       
   353       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   354       {
       
   355          png_push_save_buffer(png_ptr);
       
   356          return;
       
   357       }
       
   358 
       
   359       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
       
   360    }
       
   361 
       
   362 #endif
       
   363 #if defined(PNG_READ_cHRM_SUPPORTED)
       
   364    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
       
   365    {
       
   366       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   367       {
       
   368          png_push_save_buffer(png_ptr);
       
   369          return;
       
   370       }
       
   371 
       
   372       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
       
   373    }
       
   374 
       
   375 #endif
       
   376 #if defined(PNG_READ_sRGB_SUPPORTED)
       
   377    else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
       
   378    {
       
   379       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   380       {
       
   381          png_push_save_buffer(png_ptr);
       
   382          return;
       
   383       }
       
   384 
       
   385       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
       
   386    }
       
   387 
       
   388 #endif
       
   389 #if defined(PNG_READ_iCCP_SUPPORTED)
       
   390    else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
       
   391    {
       
   392       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   393       {
       
   394          png_push_save_buffer(png_ptr);
       
   395          return;
       
   396       }
       
   397 
       
   398       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
       
   399    }
       
   400 
       
   401 #endif
       
   402 #if defined(PNG_READ_sPLT_SUPPORTED)
       
   403    else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
       
   404    {
       
   405       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   406       {
       
   407          png_push_save_buffer(png_ptr);
       
   408          return;
       
   409       }
       
   410 
       
   411       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
       
   412    }
       
   413 
       
   414 #endif
       
   415 #if defined(PNG_READ_tRNS_SUPPORTED)
       
   416    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
       
   417    {
       
   418       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   419       {
       
   420          png_push_save_buffer(png_ptr);
       
   421          return;
       
   422       }
       
   423 
       
   424       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
       
   425    }
       
   426 
       
   427 #endif
       
   428 #if defined(PNG_READ_bKGD_SUPPORTED)
       
   429    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
       
   430    {
       
   431       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   432       {
       
   433          png_push_save_buffer(png_ptr);
       
   434          return;
       
   435       }
       
   436 
       
   437       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
       
   438    }
       
   439 
       
   440 #endif
       
   441 #if defined(PNG_READ_hIST_SUPPORTED)
       
   442    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
       
   443    {
       
   444       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   445       {
       
   446          png_push_save_buffer(png_ptr);
       
   447          return;
       
   448       }
       
   449 
       
   450       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
       
   451    }
       
   452 
       
   453 #endif
       
   454 #if defined(PNG_READ_pHYs_SUPPORTED)
       
   455    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
       
   456    {
       
   457       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   458       {
       
   459          png_push_save_buffer(png_ptr);
       
   460          return;
       
   461       }
       
   462 
       
   463       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
       
   464    }
       
   465 
       
   466 #endif
       
   467 #if defined(PNG_READ_oFFs_SUPPORTED)
       
   468    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
       
   469    {
       
   470       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   471       {
       
   472          png_push_save_buffer(png_ptr);
       
   473          return;
       
   474       }
       
   475 
       
   476       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
       
   477    }
       
   478 #endif
       
   479 
       
   480 #if defined(PNG_READ_pCAL_SUPPORTED)
       
   481    else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
       
   482    {
       
   483       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   484       {
       
   485          png_push_save_buffer(png_ptr);
       
   486          return;
       
   487       }
       
   488 
       
   489       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
       
   490    }
       
   491 
       
   492 #endif
       
   493 #if defined(PNG_READ_sCAL_SUPPORTED)
       
   494    else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
       
   495    {
       
   496       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   497       {
       
   498          png_push_save_buffer(png_ptr);
       
   499          return;
       
   500       }
       
   501 
       
   502       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
       
   503    }
       
   504 
       
   505 #endif
       
   506 #if defined(PNG_READ_tIME_SUPPORTED)
       
   507    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
       
   508    {
       
   509       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   510       {
       
   511          png_push_save_buffer(png_ptr);
       
   512          return;
       
   513       }
       
   514 
       
   515       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
       
   516    }
       
   517 
       
   518 #endif
       
   519 #if defined(PNG_READ_tEXt_SUPPORTED)
       
   520    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
       
   521    {
       
   522       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   523       {
       
   524          png_push_save_buffer(png_ptr);
       
   525          return;
       
   526       }
       
   527 
       
   528       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
       
   529    }
       
   530 
       
   531 #endif
       
   532 #if defined(PNG_READ_zTXt_SUPPORTED)
       
   533    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
       
   534    {
       
   535       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   536       {
       
   537          png_push_save_buffer(png_ptr);
       
   538          return;
       
   539       }
       
   540 
       
   541       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
       
   542    }
       
   543 
       
   544 #endif
       
   545 #if defined(PNG_READ_iTXt_SUPPORTED)
       
   546    else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
       
   547    {
       
   548       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   549       {
       
   550          png_push_save_buffer(png_ptr);
       
   551          return;
       
   552       }
       
   553 
       
   554       png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
       
   555    }
       
   556 
       
   557 #endif
       
   558    else
       
   559    {
       
   560       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
       
   561       {
       
   562          png_push_save_buffer(png_ptr);
       
   563          return;
       
   564       }
       
   565       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
       
   566    }
       
   567 
       
   568    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
       
   569 }
       
   570 
       
   571 void /* PRIVATE */
       
   572 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
       
   573 {
       
   574    png_ptr->process_mode = PNG_SKIP_MODE;
       
   575    png_ptr->skip_length = skip;
       
   576 }
       
   577 
       
   578 void /* PRIVATE */
       
   579 png_push_crc_finish(png_structp png_ptr)
       
   580 {
       
   581    if (png_ptr->skip_length && png_ptr->save_buffer_size)
       
   582    {
       
   583       png_size_t save_size;
       
   584 
       
   585       if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
       
   586          save_size = (png_size_t)png_ptr->skip_length;
       
   587       else
       
   588          save_size = png_ptr->save_buffer_size;
       
   589 
       
   590       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
       
   591 
       
   592       png_ptr->skip_length -= save_size;
       
   593       png_ptr->buffer_size -= save_size;
       
   594       png_ptr->save_buffer_size -= save_size;
       
   595       png_ptr->save_buffer_ptr += save_size;
       
   596    }
       
   597    if (png_ptr->skip_length && png_ptr->current_buffer_size)
       
   598    {
       
   599       png_size_t save_size;
       
   600 
       
   601       if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
       
   602          save_size = (png_size_t)png_ptr->skip_length;
       
   603       else
       
   604          save_size = png_ptr->current_buffer_size;
       
   605 
       
   606       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
       
   607 
       
   608       png_ptr->skip_length -= save_size;
       
   609       png_ptr->buffer_size -= save_size;
       
   610       png_ptr->current_buffer_size -= save_size;
       
   611       png_ptr->current_buffer_ptr += save_size;
       
   612    }
       
   613    if (!png_ptr->skip_length)
       
   614    {
       
   615       if (png_ptr->buffer_size < 4)
       
   616       {
       
   617          png_push_save_buffer(png_ptr);
       
   618          return;
       
   619       }
       
   620 
       
   621       png_crc_finish(png_ptr, 0);
       
   622       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
       
   623    }
       
   624 }
       
   625 
       
   626 void PNGAPI
       
   627 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
       
   628 {
       
   629    png_bytep ptr;
       
   630 
       
   631    if (png_ptr == NULL)
       
   632       return;
       
   633 
       
   634    ptr = buffer;
       
   635    if (png_ptr->save_buffer_size)
       
   636    {
       
   637       png_size_t save_size;
       
   638 
       
   639       if (length < png_ptr->save_buffer_size)
       
   640          save_size = length;
       
   641       else
       
   642          save_size = png_ptr->save_buffer_size;
       
   643 
       
   644       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
       
   645       length -= save_size;
       
   646       ptr += save_size;
       
   647       png_ptr->buffer_size -= save_size;
       
   648       png_ptr->save_buffer_size -= save_size;
       
   649       png_ptr->save_buffer_ptr += save_size;
       
   650    }
       
   651    if (length && png_ptr->current_buffer_size)
       
   652    {
       
   653       png_size_t save_size;
       
   654 
       
   655       if (length < png_ptr->current_buffer_size)
       
   656          save_size = length;
       
   657 
       
   658       else
       
   659          save_size = png_ptr->current_buffer_size;
       
   660 
       
   661       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
       
   662       png_ptr->buffer_size -= save_size;
       
   663       png_ptr->current_buffer_size -= save_size;
       
   664       png_ptr->current_buffer_ptr += save_size;
       
   665    }
       
   666 }
       
   667 
       
   668 void /* PRIVATE */
       
   669 png_push_save_buffer(png_structp png_ptr)
       
   670 {
       
   671    if (png_ptr->save_buffer_size)
       
   672    {
       
   673       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
       
   674       {
       
   675          png_size_t i, istop;
       
   676          png_bytep sp;
       
   677          png_bytep dp;
       
   678 
       
   679          istop = png_ptr->save_buffer_size;
       
   680          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
       
   681             i < istop; i++, sp++, dp++)
       
   682          {
       
   683             *dp = *sp;
       
   684          }
       
   685       }
       
   686    }
       
   687    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
       
   688       png_ptr->save_buffer_max)
       
   689    {
       
   690       png_size_t new_max;
       
   691       png_bytep old_buffer;
       
   692 
       
   693       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
       
   694          (png_ptr->current_buffer_size + 256))
       
   695       {
       
   696         png_error(png_ptr, "Potential overflow of save_buffer");
       
   697       }
       
   698 
       
   699       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
       
   700       old_buffer = png_ptr->save_buffer;
       
   701       png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
       
   702          (png_uint_32)new_max);
       
   703       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
       
   704       png_free(png_ptr, old_buffer);
       
   705       png_ptr->save_buffer_max = new_max;
       
   706    }
       
   707    if (png_ptr->current_buffer_size)
       
   708    {
       
   709       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
       
   710          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
       
   711       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
       
   712       png_ptr->current_buffer_size = 0;
       
   713    }
       
   714    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
       
   715    png_ptr->buffer_size = 0;
       
   716 }
       
   717 
       
   718 void /* PRIVATE */
       
   719 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
       
   720    png_size_t buffer_length)
       
   721 {
       
   722    png_ptr->current_buffer = buffer;
       
   723    png_ptr->current_buffer_size = buffer_length;
       
   724    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
       
   725    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
       
   726 }
       
   727 
       
   728 void /* PRIVATE */
       
   729 png_push_read_IDAT(png_structp png_ptr)
       
   730 {
       
   731 #ifdef PNG_USE_LOCAL_ARRAYS
       
   732    PNG_CONST PNG_IDAT;
       
   733 #endif
       
   734    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
       
   735    {
       
   736       png_byte chunk_length[4];
       
   737 
       
   738       if (png_ptr->buffer_size < 8)
       
   739       {
       
   740          png_push_save_buffer(png_ptr);
       
   741          return;
       
   742       }
       
   743 
       
   744       png_push_fill_buffer(png_ptr, chunk_length, 4);
       
   745       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
       
   746       png_reset_crc(png_ptr);
       
   747       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
       
   748       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
       
   749 
       
   750       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
       
   751       {
       
   752          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
       
   753          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
       
   754             png_error(png_ptr, "Not enough compressed data");
       
   755          return;
       
   756       }
       
   757 
       
   758       png_ptr->idat_size = png_ptr->push_length;
       
   759    }
       
   760    if (png_ptr->idat_size && png_ptr->save_buffer_size)
       
   761    {
       
   762       png_size_t save_size;
       
   763 
       
   764       if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
       
   765       {
       
   766          save_size = (png_size_t)png_ptr->idat_size;
       
   767 
       
   768          /* Check for overflow */
       
   769          if ((png_uint_32)save_size != png_ptr->idat_size)
       
   770             png_error(png_ptr, "save_size overflowed in pngpread");
       
   771       }
       
   772       else
       
   773          save_size = png_ptr->save_buffer_size;
       
   774 
       
   775       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
       
   776 
       
   777       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
       
   778          png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
       
   779 
       
   780       png_ptr->idat_size -= save_size;
       
   781       png_ptr->buffer_size -= save_size;
       
   782       png_ptr->save_buffer_size -= save_size;
       
   783       png_ptr->save_buffer_ptr += save_size;
       
   784    }
       
   785    if (png_ptr->idat_size && png_ptr->current_buffer_size)
       
   786    {
       
   787       png_size_t save_size;
       
   788 
       
   789       if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
       
   790       {
       
   791          save_size = (png_size_t)png_ptr->idat_size;
       
   792 
       
   793          /* Check for overflow */
       
   794          if ((png_uint_32)save_size != png_ptr->idat_size)
       
   795             png_error(png_ptr, "save_size overflowed in pngpread");
       
   796       }
       
   797       else
       
   798          save_size = png_ptr->current_buffer_size;
       
   799 
       
   800       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
       
   801       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
       
   802         png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
       
   803 
       
   804       png_ptr->idat_size -= save_size;
       
   805       png_ptr->buffer_size -= save_size;
       
   806       png_ptr->current_buffer_size -= save_size;
       
   807       png_ptr->current_buffer_ptr += save_size;
       
   808    }
       
   809    if (!png_ptr->idat_size)
       
   810    {
       
   811       if (png_ptr->buffer_size < 4)
       
   812       {
       
   813          png_push_save_buffer(png_ptr);
       
   814          return;
       
   815       }
       
   816 
       
   817       png_crc_finish(png_ptr, 0);
       
   818       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
       
   819       png_ptr->mode |= PNG_AFTER_IDAT;
       
   820    }
       
   821 }
       
   822 
       
   823 void /* PRIVATE */
       
   824 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
       
   825    png_size_t buffer_length)
       
   826 {
       
   827    int ret;
       
   828 
       
   829    if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
       
   830       png_error(png_ptr, "Extra compression data");
       
   831 
       
   832    png_ptr->zstream.next_in = buffer;
       
   833    png_ptr->zstream.avail_in = (uInt)buffer_length;
       
   834    for (;;)
       
   835    {
       
   836       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
       
   837       if (ret != Z_OK)
       
   838       {
       
   839          if (ret == Z_STREAM_END)
       
   840          {
       
   841             if (png_ptr->zstream.avail_in)
       
   842                png_error(png_ptr, "Extra compressed data");
       
   843 
       
   844             if (!(png_ptr->zstream.avail_out))
       
   845             {
       
   846                png_push_process_row(png_ptr);
       
   847             }
       
   848 
       
   849             png_ptr->mode |= PNG_AFTER_IDAT;
       
   850             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
       
   851             break;
       
   852          }
       
   853          else if (ret == Z_BUF_ERROR)
       
   854             break;
       
   855 
       
   856          else
       
   857             png_error(png_ptr, "Decompression Error");
       
   858       }
       
   859       if (!(png_ptr->zstream.avail_out))
       
   860       {
       
   861          if ((
       
   862 #if defined(PNG_READ_INTERLACING_SUPPORTED)
       
   863              png_ptr->interlaced && png_ptr->pass > 6) ||
       
   864              (!png_ptr->interlaced &&
       
   865 #endif
       
   866              png_ptr->row_number == png_ptr->num_rows))
       
   867          {
       
   868            if (png_ptr->zstream.avail_in)
       
   869              png_warning(png_ptr, "Too much data in IDAT chunks");
       
   870            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
       
   871            break;
       
   872          }
       
   873          png_push_process_row(png_ptr);
       
   874          png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
       
   875          png_ptr->zstream.next_out = png_ptr->row_buf;
       
   876       }
       
   877 
       
   878       else
       
   879          break;
       
   880    }
       
   881 }
       
   882 
       
   883 void /* PRIVATE */
       
   884 png_push_process_row(png_structp png_ptr)
       
   885 {
       
   886    png_ptr->row_info.color_type = png_ptr->color_type;
       
   887    png_ptr->row_info.width = png_ptr->iwidth;
       
   888    png_ptr->row_info.channels = png_ptr->channels;
       
   889    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
       
   890    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
       
   891 
       
   892    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
       
   893        png_ptr->row_info.width);
       
   894 
       
   895    png_read_filter_row(png_ptr, &(png_ptr->row_info),
       
   896       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
       
   897       (int)(png_ptr->row_buf[0]));
       
   898 
       
   899    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
       
   900       png_ptr->rowbytes + 1);
       
   901 
       
   902    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
       
   903       png_do_read_transformations(png_ptr);
       
   904 
       
   905 #if defined(PNG_READ_INTERLACING_SUPPORTED)
       
   906    /* Blow up interlaced rows to full size */
       
   907    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
       
   908    {
       
   909       if (png_ptr->pass < 6)
       
   910 /*       old interface (pre-1.0.9):
       
   911          png_do_read_interlace(&(png_ptr->row_info),
       
   912             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
       
   913  */
       
   914          png_do_read_interlace(png_ptr);
       
   915 
       
   916     switch (png_ptr->pass)
       
   917     {
       
   918          case 0:
       
   919          {
       
   920             int i;
       
   921             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
       
   922             {
       
   923                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
   924                png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
       
   925             }
       
   926 
       
   927             if (png_ptr->pass == 2) /* Pass 1 might be empty */
       
   928             {
       
   929                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
       
   930                {
       
   931                   png_push_have_row(png_ptr, png_bytep_NULL);
       
   932                   png_read_push_finish_row(png_ptr);
       
   933                }
       
   934             }
       
   935 
       
   936             if (png_ptr->pass == 4 && png_ptr->height <= 4)
       
   937             {
       
   938                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
       
   939                {
       
   940                   png_push_have_row(png_ptr, png_bytep_NULL);
       
   941                   png_read_push_finish_row(png_ptr);
       
   942                }
       
   943             }
       
   944 
       
   945             if (png_ptr->pass == 6 && png_ptr->height <= 4)
       
   946             {
       
   947                 png_push_have_row(png_ptr, png_bytep_NULL);
       
   948                 png_read_push_finish_row(png_ptr);
       
   949             }
       
   950 
       
   951             break;
       
   952          }
       
   953 
       
   954          case 1:
       
   955          {
       
   956             int i;
       
   957             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
       
   958             {
       
   959                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
   960                png_read_push_finish_row(png_ptr);
       
   961             }
       
   962 
       
   963             if (png_ptr->pass == 2) /* Skip top 4 generated rows */
       
   964             {
       
   965                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
       
   966                {
       
   967                   png_push_have_row(png_ptr, png_bytep_NULL);
       
   968                   png_read_push_finish_row(png_ptr);
       
   969                }
       
   970             }
       
   971 
       
   972             break;
       
   973          }
       
   974 
       
   975          case 2:
       
   976          {
       
   977             int i;
       
   978 
       
   979             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
       
   980             {
       
   981                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
   982                png_read_push_finish_row(png_ptr);
       
   983             }
       
   984 
       
   985             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
       
   986             {
       
   987                png_push_have_row(png_ptr, png_bytep_NULL);
       
   988                png_read_push_finish_row(png_ptr);
       
   989             }
       
   990 
       
   991             if (png_ptr->pass == 4) /* Pass 3 might be empty */
       
   992             {
       
   993                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
       
   994                {
       
   995                   png_push_have_row(png_ptr, png_bytep_NULL);
       
   996                   png_read_push_finish_row(png_ptr);
       
   997                }
       
   998             }
       
   999 
       
  1000             break;
       
  1001          }
       
  1002 
       
  1003          case 3:
       
  1004          {
       
  1005             int i;
       
  1006 
       
  1007             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
       
  1008             {
       
  1009                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
  1010                png_read_push_finish_row(png_ptr);
       
  1011             }
       
  1012 
       
  1013             if (png_ptr->pass == 4) /* Skip top two generated rows */
       
  1014             {
       
  1015                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
       
  1016                {
       
  1017                   png_push_have_row(png_ptr, png_bytep_NULL);
       
  1018                   png_read_push_finish_row(png_ptr);
       
  1019                }
       
  1020             }
       
  1021 
       
  1022             break;
       
  1023          }
       
  1024 
       
  1025          case 4:
       
  1026          {
       
  1027             int i;
       
  1028 
       
  1029             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
       
  1030             {
       
  1031                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
  1032                png_read_push_finish_row(png_ptr);
       
  1033             }
       
  1034 
       
  1035             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
       
  1036             {
       
  1037                png_push_have_row(png_ptr, png_bytep_NULL);
       
  1038                png_read_push_finish_row(png_ptr);
       
  1039             }
       
  1040 
       
  1041             if (png_ptr->pass == 6) /* Pass 5 might be empty */
       
  1042             {
       
  1043                png_push_have_row(png_ptr, png_bytep_NULL);
       
  1044                png_read_push_finish_row(png_ptr);
       
  1045             }
       
  1046 
       
  1047             break;
       
  1048          }
       
  1049 
       
  1050          case 5:
       
  1051          {
       
  1052             int i;
       
  1053 
       
  1054             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
       
  1055             {
       
  1056                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
  1057                png_read_push_finish_row(png_ptr);
       
  1058             }
       
  1059 
       
  1060             if (png_ptr->pass == 6) /* Skip top generated row */
       
  1061             {
       
  1062                png_push_have_row(png_ptr, png_bytep_NULL);
       
  1063                png_read_push_finish_row(png_ptr);
       
  1064             }
       
  1065 
       
  1066             break;
       
  1067          }
       
  1068          case 6:
       
  1069          {
       
  1070             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
  1071             png_read_push_finish_row(png_ptr);
       
  1072 
       
  1073             if (png_ptr->pass != 6)
       
  1074                break;
       
  1075 
       
  1076             png_push_have_row(png_ptr, png_bytep_NULL);
       
  1077             png_read_push_finish_row(png_ptr);
       
  1078          }
       
  1079       }
       
  1080    }
       
  1081    else
       
  1082 #endif
       
  1083    {
       
  1084       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
       
  1085       png_read_push_finish_row(png_ptr);
       
  1086    }
       
  1087 }
       
  1088 
       
  1089 void /* PRIVATE */
       
  1090 png_read_push_finish_row(png_structp png_ptr)
       
  1091 {
       
  1092 #ifdef PNG_USE_LOCAL_ARRAYS
       
  1093    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
       
  1094 
       
  1095    /* Start of interlace block */
       
  1096    PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
       
  1097 
       
  1098    /* Offset to next interlace block */
       
  1099    PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
       
  1100 
       
  1101    /* Start of interlace block in the y direction */
       
  1102    PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
       
  1103 
       
  1104    /* Offset to next interlace block in the y direction */
       
  1105    PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
       
  1106 
       
  1107    /* Height of interlace block.  This is not currently used - if you need
       
  1108     * it, uncomment it here and in png.h
       
  1109    PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
       
  1110    */
       
  1111 #endif
       
  1112 
       
  1113    png_ptr->row_number++;
       
  1114    if (png_ptr->row_number < png_ptr->num_rows)
       
  1115       return;
       
  1116 
       
  1117 #if defined(PNG_READ_INTERLACING_SUPPORTED)
       
  1118    if (png_ptr->interlaced)
       
  1119    {
       
  1120       png_ptr->row_number = 0;
       
  1121       png_memset_check(png_ptr, png_ptr->prev_row, 0,
       
  1122          png_ptr->rowbytes + 1);
       
  1123       do
       
  1124       {
       
  1125          png_ptr->pass++;
       
  1126          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
       
  1127              (png_ptr->pass == 3 && png_ptr->width < 3) ||
       
  1128              (png_ptr->pass == 5 && png_ptr->width < 2))
       
  1129            png_ptr->pass++;
       
  1130 
       
  1131          if (png_ptr->pass > 7)
       
  1132             png_ptr->pass--;
       
  1133 
       
  1134          if (png_ptr->pass >= 7)
       
  1135             break;
       
  1136 
       
  1137          png_ptr->iwidth = (png_ptr->width +
       
  1138             png_pass_inc[png_ptr->pass] - 1 -
       
  1139             png_pass_start[png_ptr->pass]) /
       
  1140             png_pass_inc[png_ptr->pass];
       
  1141 
       
  1142          png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
       
  1143             png_ptr->iwidth) + 1;
       
  1144 
       
  1145          if (png_ptr->transformations & PNG_INTERLACE)
       
  1146             break;
       
  1147 
       
  1148          png_ptr->num_rows = (png_ptr->height +
       
  1149             png_pass_yinc[png_ptr->pass] - 1 -
       
  1150             png_pass_ystart[png_ptr->pass]) /
       
  1151             png_pass_yinc[png_ptr->pass];
       
  1152 
       
  1153       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
       
  1154    }
       
  1155 #endif /* PNG_READ_INTERLACING_SUPPORTED */
       
  1156 }
       
  1157 
       
  1158 #if defined(PNG_READ_tEXt_SUPPORTED)
       
  1159 void /* PRIVATE */
       
  1160 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
       
  1161    length)
       
  1162 {
       
  1163    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       
  1164       {
       
  1165          png_error(png_ptr, "Out of place tEXt");
       
  1166          info_ptr = info_ptr; /* To quiet some compiler warnings */
       
  1167       }
       
  1168 
       
  1169 #ifdef PNG_MAX_MALLOC_64K
       
  1170    png_ptr->skip_length = 0;  /* This may not be necessary */
       
  1171 
       
  1172    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
       
  1173    {
       
  1174       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
       
  1175       png_ptr->skip_length = length - (png_uint_32)65535L;
       
  1176       length = (png_uint_32)65535L;
       
  1177    }
       
  1178 #endif
       
  1179 
       
  1180    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
       
  1181       (png_uint_32)(length + 1));
       
  1182    png_ptr->current_text[length] = '\0';
       
  1183    png_ptr->current_text_ptr = png_ptr->current_text;
       
  1184    png_ptr->current_text_size = (png_size_t)length;
       
  1185    png_ptr->current_text_left = (png_size_t)length;
       
  1186    png_ptr->process_mode = PNG_READ_tEXt_MODE;
       
  1187 }
       
  1188 
       
  1189 void /* PRIVATE */
       
  1190 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
       
  1191 {
       
  1192    if (png_ptr->buffer_size && png_ptr->current_text_left)
       
  1193    {
       
  1194       png_size_t text_size;
       
  1195 
       
  1196       if (png_ptr->buffer_size < png_ptr->current_text_left)
       
  1197          text_size = png_ptr->buffer_size;
       
  1198 
       
  1199       else
       
  1200          text_size = png_ptr->current_text_left;
       
  1201 
       
  1202       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
       
  1203       png_ptr->current_text_left -= text_size;
       
  1204       png_ptr->current_text_ptr += text_size;
       
  1205    }
       
  1206    if (!(png_ptr->current_text_left))
       
  1207    {
       
  1208       png_textp text_ptr;
       
  1209       png_charp text;
       
  1210       png_charp key;
       
  1211       int ret;
       
  1212 
       
  1213       if (png_ptr->buffer_size < 4)
       
  1214       {
       
  1215          png_push_save_buffer(png_ptr);
       
  1216          return;
       
  1217       }
       
  1218 
       
  1219       png_push_crc_finish(png_ptr);
       
  1220 
       
  1221 #if defined(PNG_MAX_MALLOC_64K)
       
  1222       if (png_ptr->skip_length)
       
  1223          return;
       
  1224 #endif
       
  1225 
       
  1226       key = png_ptr->current_text;
       
  1227 
       
  1228       for (text = key; *text; text++)
       
  1229          /* Empty loop */ ;
       
  1230 
       
  1231       if (text < key + png_ptr->current_text_size)
       
  1232          text++;
       
  1233 
       
  1234       text_ptr = (png_textp)png_malloc(png_ptr,
       
  1235          (png_uint_32)png_sizeof(png_text));
       
  1236       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
       
  1237       text_ptr->key = key;
       
  1238 #ifdef PNG_iTXt_SUPPORTED
       
  1239       text_ptr->lang = NULL;
       
  1240       text_ptr->lang_key = NULL;
       
  1241 #endif
       
  1242       text_ptr->text = text;
       
  1243 
       
  1244       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
       
  1245 
       
  1246       png_free(png_ptr, key);
       
  1247       png_free(png_ptr, text_ptr);
       
  1248       png_ptr->current_text = NULL;
       
  1249 
       
  1250       if (ret)
       
  1251         png_warning(png_ptr, "Insufficient memory to store text chunk.");
       
  1252    }
       
  1253 }
       
  1254 #endif
       
  1255 
       
  1256 #if defined(PNG_READ_zTXt_SUPPORTED)
       
  1257 void /* PRIVATE */
       
  1258 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
       
  1259    length)
       
  1260 {
       
  1261    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       
  1262       {
       
  1263          png_error(png_ptr, "Out of place zTXt");
       
  1264          info_ptr = info_ptr; /* To quiet some compiler warnings */
       
  1265       }
       
  1266 
       
  1267 #ifdef PNG_MAX_MALLOC_64K
       
  1268    /* We can't handle zTXt chunks > 64K, since we don't have enough space
       
  1269     * to be able to store the uncompressed data.  Actually, the threshold
       
  1270     * is probably around 32K, but it isn't as definite as 64K is.
       
  1271     */
       
  1272    if (length > (png_uint_32)65535L)
       
  1273    {
       
  1274       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
       
  1275       png_push_crc_skip(png_ptr, length);
       
  1276       return;
       
  1277    }
       
  1278 #endif
       
  1279 
       
  1280    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
       
  1281       (png_uint_32)(length + 1));
       
  1282    png_ptr->current_text[length] = '\0';
       
  1283    png_ptr->current_text_ptr = png_ptr->current_text;
       
  1284    png_ptr->current_text_size = (png_size_t)length;
       
  1285    png_ptr->current_text_left = (png_size_t)length;
       
  1286    png_ptr->process_mode = PNG_READ_zTXt_MODE;
       
  1287 }
       
  1288 
       
  1289 void /* PRIVATE */
       
  1290 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
       
  1291 {
       
  1292    if (png_ptr->buffer_size && png_ptr->current_text_left)
       
  1293    {
       
  1294       png_size_t text_size;
       
  1295 
       
  1296       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
       
  1297          text_size = png_ptr->buffer_size;
       
  1298 
       
  1299       else
       
  1300          text_size = png_ptr->current_text_left;
       
  1301 
       
  1302       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
       
  1303       png_ptr->current_text_left -= text_size;
       
  1304       png_ptr->current_text_ptr += text_size;
       
  1305    }
       
  1306    if (!(png_ptr->current_text_left))
       
  1307    {
       
  1308       png_textp text_ptr;
       
  1309       png_charp text;
       
  1310       png_charp key;
       
  1311       int ret;
       
  1312       png_size_t text_size, key_size;
       
  1313 
       
  1314       if (png_ptr->buffer_size < 4)
       
  1315       {
       
  1316          png_push_save_buffer(png_ptr);
       
  1317          return;
       
  1318       }
       
  1319 
       
  1320       png_push_crc_finish(png_ptr);
       
  1321 
       
  1322       key = png_ptr->current_text;
       
  1323 
       
  1324       for (text = key; *text; text++)
       
  1325          /* Empty loop */ ;
       
  1326 
       
  1327       /* zTXt can't have zero text */
       
  1328       if (text >= key + png_ptr->current_text_size)
       
  1329       {
       
  1330          png_ptr->current_text = NULL;
       
  1331          png_free(png_ptr, key);
       
  1332          return;
       
  1333       }
       
  1334 
       
  1335       text++;
       
  1336 
       
  1337       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
       
  1338       {
       
  1339          png_ptr->current_text = NULL;
       
  1340          png_free(png_ptr, key);
       
  1341          return;
       
  1342       }
       
  1343 
       
  1344       text++;
       
  1345 
       
  1346       png_ptr->zstream.next_in = (png_bytep )text;
       
  1347       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
       
  1348          (text - key));
       
  1349       png_ptr->zstream.next_out = png_ptr->zbuf;
       
  1350       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
       
  1351 
       
  1352       key_size = text - key;
       
  1353       text_size = 0;
       
  1354       text = NULL;
       
  1355       ret = Z_STREAM_END;
       
  1356 
       
  1357       while (png_ptr->zstream.avail_in)
       
  1358       {
       
  1359          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
       
  1360          if (ret != Z_OK && ret != Z_STREAM_END)
       
  1361          {
       
  1362             inflateReset(&png_ptr->zstream);
       
  1363             png_ptr->zstream.avail_in = 0;
       
  1364             png_ptr->current_text = NULL;
       
  1365             png_free(png_ptr, key);
       
  1366             png_free(png_ptr, text);
       
  1367             return;
       
  1368          }
       
  1369          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
       
  1370          {
       
  1371             if (text == NULL)
       
  1372             {
       
  1373                text = (png_charp)png_malloc(png_ptr,
       
  1374                      (png_uint_32)(png_ptr->zbuf_size
       
  1375                      - png_ptr->zstream.avail_out + key_size + 1));
       
  1376 
       
  1377                png_memcpy(text + key_size, png_ptr->zbuf,
       
  1378                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
       
  1379 
       
  1380                png_memcpy(text, key, key_size);
       
  1381 
       
  1382                text_size = key_size + png_ptr->zbuf_size -
       
  1383                   png_ptr->zstream.avail_out;
       
  1384 
       
  1385                *(text + text_size) = '\0';
       
  1386             }
       
  1387             else
       
  1388             {
       
  1389                png_charp tmp;
       
  1390 
       
  1391                tmp = text;
       
  1392                text = (png_charp)png_malloc(png_ptr, text_size +
       
  1393                   (png_uint_32)(png_ptr->zbuf_size 
       
  1394                   - png_ptr->zstream.avail_out + 1));
       
  1395 
       
  1396                png_memcpy(text, tmp, text_size);
       
  1397                png_free(png_ptr, tmp);
       
  1398 
       
  1399                png_memcpy(text + text_size, png_ptr->zbuf,
       
  1400                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
       
  1401 
       
  1402                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
       
  1403                *(text + text_size) = '\0';
       
  1404             }
       
  1405             if (ret != Z_STREAM_END)
       
  1406             {
       
  1407                png_ptr->zstream.next_out = png_ptr->zbuf;
       
  1408                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
       
  1409             }
       
  1410          }
       
  1411          else
       
  1412          {
       
  1413             break;
       
  1414          }
       
  1415 
       
  1416          if (ret == Z_STREAM_END)
       
  1417             break;
       
  1418       }
       
  1419 
       
  1420       inflateReset(&png_ptr->zstream);
       
  1421       png_ptr->zstream.avail_in = 0;
       
  1422 
       
  1423       if (ret != Z_STREAM_END)
       
  1424       {
       
  1425          png_ptr->current_text = NULL;
       
  1426          png_free(png_ptr, key);
       
  1427          png_free(png_ptr, text);
       
  1428          return;
       
  1429       }
       
  1430 
       
  1431       png_ptr->current_text = NULL;
       
  1432       png_free(png_ptr, key);
       
  1433       key = text;
       
  1434       text += key_size;
       
  1435 
       
  1436       text_ptr = (png_textp)png_malloc(png_ptr,
       
  1437           (png_uint_32)png_sizeof(png_text));
       
  1438       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
       
  1439       text_ptr->key = key;
       
  1440 #ifdef PNG_iTXt_SUPPORTED
       
  1441       text_ptr->lang = NULL;
       
  1442       text_ptr->lang_key = NULL;
       
  1443 #endif
       
  1444       text_ptr->text = text;
       
  1445 
       
  1446       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
       
  1447 
       
  1448       png_free(png_ptr, key);
       
  1449       png_free(png_ptr, text_ptr);
       
  1450 
       
  1451       if (ret)
       
  1452         png_warning(png_ptr, "Insufficient memory to store text chunk.");
       
  1453    }
       
  1454 }
       
  1455 #endif
       
  1456 
       
  1457 #if defined(PNG_READ_iTXt_SUPPORTED)
       
  1458 void /* PRIVATE */
       
  1459 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
       
  1460    length)
       
  1461 {
       
  1462    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
       
  1463       {
       
  1464          png_error(png_ptr, "Out of place iTXt");
       
  1465          info_ptr = info_ptr; /* To quiet some compiler warnings */
       
  1466       }
       
  1467 
       
  1468 #ifdef PNG_MAX_MALLOC_64K
       
  1469    png_ptr->skip_length = 0;  /* This may not be necessary */
       
  1470 
       
  1471    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
       
  1472    {
       
  1473       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
       
  1474       png_ptr->skip_length = length - (png_uint_32)65535L;
       
  1475       length = (png_uint_32)65535L;
       
  1476    }
       
  1477 #endif
       
  1478 
       
  1479    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
       
  1480       (png_uint_32)(length + 1));
       
  1481    png_ptr->current_text[length] = '\0';
       
  1482    png_ptr->current_text_ptr = png_ptr->current_text;
       
  1483    png_ptr->current_text_size = (png_size_t)length;
       
  1484    png_ptr->current_text_left = (png_size_t)length;
       
  1485    png_ptr->process_mode = PNG_READ_iTXt_MODE;
       
  1486 }
       
  1487 
       
  1488 void /* PRIVATE */
       
  1489 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
       
  1490 {
       
  1491 
       
  1492    if (png_ptr->buffer_size && png_ptr->current_text_left)
       
  1493    {
       
  1494       png_size_t text_size;
       
  1495 
       
  1496       if (png_ptr->buffer_size < png_ptr->current_text_left)
       
  1497          text_size = png_ptr->buffer_size;
       
  1498 
       
  1499       else
       
  1500          text_size = png_ptr->current_text_left;
       
  1501 
       
  1502       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
       
  1503       png_ptr->current_text_left -= text_size;
       
  1504       png_ptr->current_text_ptr += text_size;
       
  1505    }
       
  1506    if (!(png_ptr->current_text_left))
       
  1507    {
       
  1508       png_textp text_ptr;
       
  1509       png_charp key;
       
  1510       int comp_flag;
       
  1511       png_charp lang;
       
  1512       png_charp lang_key;
       
  1513       png_charp text;
       
  1514       int ret;
       
  1515 
       
  1516       if (png_ptr->buffer_size < 4)
       
  1517       {
       
  1518          png_push_save_buffer(png_ptr);
       
  1519          return;
       
  1520       }
       
  1521 
       
  1522       png_push_crc_finish(png_ptr);
       
  1523 
       
  1524 #if defined(PNG_MAX_MALLOC_64K)
       
  1525       if (png_ptr->skip_length)
       
  1526          return;
       
  1527 #endif
       
  1528 
       
  1529       key = png_ptr->current_text;
       
  1530 
       
  1531       for (lang = key; *lang; lang++)
       
  1532          /* Empty loop */ ;
       
  1533 
       
  1534       if (lang < key + png_ptr->current_text_size - 3)
       
  1535          lang++;
       
  1536 
       
  1537       comp_flag = *lang++;
       
  1538       lang++;     /* Skip comp_type, always zero */
       
  1539 
       
  1540       for (lang_key = lang; *lang_key; lang_key++)
       
  1541          /* Empty loop */ ;
       
  1542 
       
  1543       lang_key++;        /* Skip NUL separator */
       
  1544 
       
  1545       text=lang_key;
       
  1546 
       
  1547       if (lang_key < key + png_ptr->current_text_size - 1)
       
  1548       {
       
  1549         for (; *text; text++)
       
  1550            /* Empty loop */ ;
       
  1551       }
       
  1552 
       
  1553       if (text < key + png_ptr->current_text_size)
       
  1554          text++;
       
  1555 
       
  1556       text_ptr = (png_textp)png_malloc(png_ptr,
       
  1557          (png_uint_32)png_sizeof(png_text));
       
  1558 
       
  1559       text_ptr->compression = comp_flag + 2;
       
  1560       text_ptr->key = key;
       
  1561       text_ptr->lang = lang;
       
  1562       text_ptr->lang_key = lang_key;
       
  1563       text_ptr->text = text;
       
  1564       text_ptr->text_length = 0;
       
  1565       text_ptr->itxt_length = png_strlen(text);
       
  1566 
       
  1567       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
       
  1568 
       
  1569       png_ptr->current_text = NULL;
       
  1570 
       
  1571       png_free(png_ptr, text_ptr);
       
  1572       if (ret)
       
  1573         png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
       
  1574    }
       
  1575 }
       
  1576 #endif
       
  1577 
       
  1578 /* This function is called when we haven't found a handler for this
       
  1579  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
       
  1580  * name or a critical chunk), the chunk is (currently) silently ignored.
       
  1581  */
       
  1582 void /* PRIVATE */
       
  1583 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
       
  1584    length)
       
  1585 {
       
  1586    png_uint_32 skip = 0;
       
  1587 
       
  1588    if (!(png_ptr->chunk_name[0] & 0x20))
       
  1589    {
       
  1590 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
       
  1591       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
       
  1592          PNG_HANDLE_CHUNK_ALWAYS
       
  1593 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
       
  1594          && png_ptr->read_user_chunk_fn == NULL
       
  1595 #endif
       
  1596          )
       
  1597 #endif
       
  1598          png_chunk_error(png_ptr, "unknown critical chunk");
       
  1599 
       
  1600       info_ptr = info_ptr; /* To quiet some compiler warnings */
       
  1601    }
       
  1602 
       
  1603 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
       
  1604    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
       
  1605    {
       
  1606 #ifdef PNG_MAX_MALLOC_64K
       
  1607       if (length > (png_uint_32)65535L)
       
  1608       {
       
  1609           png_warning(png_ptr, "unknown chunk too large to fit in memory");
       
  1610           skip = length - (png_uint_32)65535L;
       
  1611           length = (png_uint_32)65535L;
       
  1612       }
       
  1613 #endif
       
  1614       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
       
  1615                  (png_charp)png_ptr->chunk_name, 
       
  1616                  png_sizeof(png_ptr->unknown_chunk.name));
       
  1617       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
       
  1618         = '\0';
       
  1619 
       
  1620       png_ptr->unknown_chunk.size = (png_size_t)length;
       
  1621 
       
  1622       if (length == 0)
       
  1623          png_ptr->unknown_chunk.data = NULL;
       
  1624 
       
  1625       else
       
  1626       {
       
  1627          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
       
  1628        (png_uint_32)length);
       
  1629          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
       
  1630       }
       
  1631 
       
  1632 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
       
  1633       if (png_ptr->read_user_chunk_fn != NULL)
       
  1634       {
       
  1635          /* Callback to user unknown chunk handler */
       
  1636          int ret;
       
  1637          ret = (*(png_ptr->read_user_chunk_fn))
       
  1638            (png_ptr, &png_ptr->unknown_chunk);
       
  1639 
       
  1640          if (ret < 0)
       
  1641             png_chunk_error(png_ptr, "error in user chunk");
       
  1642 
       
  1643          if (ret == 0)
       
  1644          {
       
  1645             if (!(png_ptr->chunk_name[0] & 0x20))
       
  1646                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
       
  1647                     PNG_HANDLE_CHUNK_ALWAYS)
       
  1648                   png_chunk_error(png_ptr, "unknown critical chunk");
       
  1649             png_set_unknown_chunks(png_ptr, info_ptr,
       
  1650                &png_ptr->unknown_chunk, 1);
       
  1651          }
       
  1652       }
       
  1653 
       
  1654       else
       
  1655 #endif
       
  1656         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
       
  1657       png_free(png_ptr, png_ptr->unknown_chunk.data);
       
  1658       png_ptr->unknown_chunk.data = NULL;
       
  1659    }
       
  1660 
       
  1661    else
       
  1662 #endif
       
  1663       skip=length;
       
  1664    png_push_crc_skip(png_ptr, skip);
       
  1665 }
       
  1666 
       
  1667 void /* PRIVATE */
       
  1668 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
       
  1669 {
       
  1670    if (png_ptr->info_fn != NULL)
       
  1671       (*(png_ptr->info_fn))(png_ptr, info_ptr);
       
  1672 }
       
  1673 
       
  1674 void /* PRIVATE */
       
  1675 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
       
  1676 {
       
  1677    if (png_ptr->end_fn != NULL)
       
  1678       (*(png_ptr->end_fn))(png_ptr, info_ptr);
       
  1679 }
       
  1680 
       
  1681 void /* PRIVATE */
       
  1682 png_push_have_row(png_structp png_ptr, png_bytep row)
       
  1683 {
       
  1684    if (png_ptr->row_fn != NULL)
       
  1685       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
       
  1686          (int)png_ptr->pass);
       
  1687 }
       
  1688 
       
  1689 void PNGAPI
       
  1690 png_progressive_combine_row (png_structp png_ptr,
       
  1691    png_bytep old_row, png_bytep new_row)
       
  1692 {
       
  1693 #ifdef PNG_USE_LOCAL_ARRAYS
       
  1694    PNG_CONST int FARDATA png_pass_dsp_mask[7] =
       
  1695       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
       
  1696 #endif
       
  1697    if (png_ptr == NULL)
       
  1698       return;
       
  1699 
       
  1700    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
       
  1701       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
       
  1702 }
       
  1703 
       
  1704 void PNGAPI
       
  1705 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
       
  1706    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
       
  1707    png_progressive_end_ptr end_fn)
       
  1708 {
       
  1709    if (png_ptr == NULL)
       
  1710       return;
       
  1711 
       
  1712    png_ptr->info_fn = info_fn;
       
  1713    png_ptr->row_fn = row_fn;
       
  1714    png_ptr->end_fn = end_fn;
       
  1715 
       
  1716    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
       
  1717 }
       
  1718 
       
  1719 png_voidp PNGAPI
       
  1720 png_get_progressive_ptr(png_structp png_ptr)
       
  1721 {
       
  1722    if (png_ptr == NULL)
       
  1723       return (NULL);
       
  1724 
       
  1725    return png_ptr->io_ptr;
       
  1726 }
       
  1727 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */