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