176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* pngpread.c - read a png file in push mode
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Last changed in libpng 1.2.44 [June 26, 2010]
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright (c) 1998-2010 Glenn Randers-Pehrson
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * This code is released under the libpng license.
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * For conditions of distribution and use, see the disclaimer
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and license in png.h
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_INTERNAL
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_NO_PEDANTIC_WARNINGS
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "png.h"
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Push model modes */
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_READ_SIG_MODE   0
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_READ_CHUNK_MODE 1
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_READ_IDAT_MODE  2
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_SKIP_MODE       3
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_READ_tEXt_MODE  4
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_READ_zTXt_MODE  5
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_READ_DONE_MODE  6
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_READ_iTXt_MODE  7
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PNG_ERROR_MODE      8
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid PNGAPI
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_process_data(png_structp png_ptr, png_infop info_ptr,
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_bytep buffer, png_size_t buffer_size)
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr == NULL || info_ptr == NULL)
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_push_restore_buffer(png_ptr, buffer, buffer_size);
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   while (png_ptr->buffer_size)
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_process_some_data(png_ptr, info_ptr);
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* What we do with the incoming data depends on what we were previously
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * doing before we ran out of data...
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_process_some_data(png_structp png_ptr, png_infop info_ptr)
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr == NULL)
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   switch (png_ptr->process_mode)
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      case PNG_READ_SIG_MODE:
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_read_sig(png_ptr, info_ptr);
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      case PNG_READ_CHUNK_MODE:
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_read_chunk(png_ptr, info_ptr);
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      case PNG_READ_IDAT_MODE:
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_read_IDAT(png_ptr);
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tEXt_SUPPORTED
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      case PNG_READ_tEXt_MODE:
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_read_tEXt(png_ptr, info_ptr);
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_zTXt_SUPPORTED
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      case PNG_READ_zTXt_MODE:
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_read_zTXt(png_ptr, info_ptr);
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_iTXt_SUPPORTED
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      case PNG_READ_iTXt_MODE:
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_read_iTXt(png_ptr, info_ptr);
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      case PNG_SKIP_MODE:
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_crc_finish(png_ptr);
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      default:
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->buffer_size = 0;
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         break;
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Read any remaining signature bytes from the stream and compare them with
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the correct PNG signature.  It is possible that this routine is called
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * with bytes already read from the signature, either because they have been
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * checked by the calling application, or because of multiple calls to this
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * routine.
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_read_sig(png_structp png_ptr, png_infop info_ptr)
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_size_t num_checked = png_ptr->sig_bytes,
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             num_to_check = 8 - num_checked;
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->buffer_size < num_to_check)
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      num_to_check = png_ptr->buffer_size;
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      num_to_check);
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (num_checked < 4 &&
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "Not a PNG file");
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "PNG file corrupted by ASCII conversion");
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->sig_bytes >= 8)
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USE_LOCAL_ARRAYS
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_IHDR;
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_IDAT;
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_IEND;
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_PLTE;
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_bKGD_SUPPORTED
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_bKGD;
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_cHRM_SUPPORTED
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_cHRM;
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_gAMA_SUPPORTED
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_gAMA;
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_hIST_SUPPORTED
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_hIST;
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_iCCP_SUPPORTED
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_iCCP;
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_iTXt_SUPPORTED
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_iTXt;
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_oFFs_SUPPORTED
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_oFFs;
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_pCAL_SUPPORTED
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_pCAL;
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_pHYs_SUPPORTED
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_pHYs;
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sBIT_SUPPORTED
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_sBIT;
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sCAL_SUPPORTED
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_sCAL;
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sRGB_SUPPORTED
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_sRGB;
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sPLT_SUPPORTED
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_sPLT;
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tEXt_SUPPORTED
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_tEXt;
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tIME_SUPPORTED
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_tIME;
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tRNS_SUPPORTED
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_tRNS;
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_zTXt_SUPPORTED
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      PNG_CONST PNG_zTXt;
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PNG_USE_LOCAL_ARRAYS */
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* First we make sure we have enough data for the 4 byte chunk name
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * and the 4 byte chunk length before proceeding with decoding the
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * chunk data.  To fully decode each of these chunks, we also make
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * sure we have enough data in the buffer for the 4 byte CRC at the
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * end of every chunk (except IDAT, which is handled separately).
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    */
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_byte chunk_length[4];
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < 8)
22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_fill_buffer(png_ptr, chunk_length, 4);
22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_reset_crc(png_ptr);
23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_check_chunk_name(png_ptr, png_ptr->chunk_name);
23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman     if (png_ptr->mode & PNG_AFTER_IDAT)
23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length != 13)
24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "Invalid IHDR length");
24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->process_mode = PNG_READ_DONE_MODE;
26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_have_end(png_ptr, info_ptr);
26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->mode |= PNG_HAVE_IDAT;
27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
28076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
28276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->mode |= PNG_HAVE_PLTE;
28376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
28576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
28676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (!(png_ptr->mode & PNG_HAVE_IHDR))
28776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_error(png_ptr, "Missing IHDR before IDAT");
28876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
28976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
29076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  !(png_ptr->mode & PNG_HAVE_PLTE))
29176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_error(png_ptr, "Missing PLTE before IDAT");
29276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
29376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
29476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
29576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
29676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
29776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
29876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
29976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
30076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
30176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
30276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
30376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
30476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
30576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
30676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
30776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
30876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* If we reach an IDAT chunk, this means we have read all of the
30976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * header chunks, and we can start reading the image (or if this
31076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * is called after the image has been read - we have an error).
31176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       */
31276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (!(png_ptr->mode & PNG_HAVE_IHDR))
31476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "Missing IHDR before IDAT");
31576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
31676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
31776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          !(png_ptr->mode & PNG_HAVE_PLTE))
31876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "Missing PLTE before IDAT");
31976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->mode & PNG_HAVE_IDAT)
32176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
32276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
32376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->push_length == 0)
32476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               return;
32576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
32676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (png_ptr->mode & PNG_AFTER_IDAT)
32776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_error(png_ptr, "Too many IDAT's found");
32876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
32976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
33076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->idat_size = png_ptr->push_length;
33176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->mode |= PNG_HAVE_IDAT;
33276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->process_mode = PNG_READ_IDAT_MODE;
33376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_have_info(png_ptr, info_ptr);
33476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->zstream.avail_out =
33576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
33676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          png_ptr->iwidth) + 1;
33776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->zstream.next_out = png_ptr->row_buf;
33876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
33976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
34076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
34176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_gAMA_SUPPORTED
34276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
34376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
34476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
34576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
34676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
34776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
34876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
34976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
35176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
35276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
35376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
35476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sBIT_SUPPORTED
35576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
35676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
35776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
35876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
35976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
36076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
36176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
36276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
36476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
36576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
36676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
36776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_cHRM_SUPPORTED
36876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
36976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
37076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
37176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
37276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
37376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
37476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
37576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
37776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
37876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
37976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
38076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sRGB_SUPPORTED
38176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
38276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
38376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
38476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
38576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
38676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
38776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
38876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
38976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
39076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
39176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
39276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
39376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_iCCP_SUPPORTED
39476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
39576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
39676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
39776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
39876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
39976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
40076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
40176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
40276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
40376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
40476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
40576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
40676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sPLT_SUPPORTED
40776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
40876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
40976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
41076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
41176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
41276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
41376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
41476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
41676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
41776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
41876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
41976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tRNS_SUPPORTED
42076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
42176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
42276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
42376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
42476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
42576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
42676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
42776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
42876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
42976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
43076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
43176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
43276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_bKGD_SUPPORTED
43376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
43476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
43576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
43676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
43776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
43876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
43976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
44076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
44176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
44276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
44376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
44476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
44576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_hIST_SUPPORTED
44676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
44776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
44876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
44976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
45076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
45176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
45276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
45376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
45576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
45676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
45776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
45876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_pHYs_SUPPORTED
45976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
46076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
46176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
46276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
46376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
46476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
46576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
46676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
46776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
46876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
46976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
47076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
47176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_oFFs_SUPPORTED
47276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
47376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
47476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
47576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
47676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
47776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
47876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
47976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
48076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
48176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
48276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
48376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
48476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_pCAL_SUPPORTED
48576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
48676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
48776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
48876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
48976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
49076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
49176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
49276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
49376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
49476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
49576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
49676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
49776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_sCAL_SUPPORTED
49876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
49976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
50076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
50176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
50276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
50376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
50476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
50576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
50776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
50876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
50976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
51076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tIME_SUPPORTED
51176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
51276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
51376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
51476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
51576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
51676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
51776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
51876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
51976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
52076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
52176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
52276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
52376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tEXt_SUPPORTED
52476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
52576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
52676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
52776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
52876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
52976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
53076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
53176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
53376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
53476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
53576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
53676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_zTXt_SUPPORTED
53776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
53876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
53976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
54076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
54176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
54276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
54376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
54476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
54676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
54776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
54876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
54976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_iTXt_SUPPORTED
55076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
55176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
55276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
55376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
55476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
55576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
55676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
55776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
55876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
55976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
56076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
56176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
56276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else
56376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
56476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
56576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
56676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
56776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
56876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
56976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
57076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
57176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
57276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
57376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
57476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
57576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
57676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
57776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
57876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->process_mode = PNG_SKIP_MODE;
57976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->skip_length = skip;
58076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
58176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
58276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
58376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_crc_finish(png_structp png_ptr)
58476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
58576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->skip_length && png_ptr->save_buffer_size)
58676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
58776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t save_size;
58876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
58976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
59076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = (png_size_t)png_ptr->skip_length;
59176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
59276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = png_ptr->save_buffer_size;
59376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
59476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
59576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
59676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->skip_length -= save_size;
59776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->buffer_size -= save_size;
59876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_size -= save_size;
59976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_ptr += save_size;
60076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
60176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->skip_length && png_ptr->current_buffer_size)
60276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
60376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t save_size;
60476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
60576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
60676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = (png_size_t)png_ptr->skip_length;
60776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
60876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = png_ptr->current_buffer_size;
60976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
61076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
61176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
61276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->skip_length -= save_size;
61376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->buffer_size -= save_size;
61476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_buffer_size -= save_size;
61576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_buffer_ptr += save_size;
61676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
61776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!png_ptr->skip_length)
61876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
61976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < 4)
62076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
62176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
62276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
62376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
62476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
62576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_crc_finish(png_ptr, 0);
62676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->process_mode = PNG_READ_CHUNK_MODE;
62776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
62876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
62976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid PNGAPI
63176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
63276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
63376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_bytep ptr;
63476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr == NULL)
63676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
63776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
63876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   ptr = buffer;
63976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->save_buffer_size)
64076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
64176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t save_size;
64276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
64376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (length < png_ptr->save_buffer_size)
64476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = length;
64576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
64676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = png_ptr->save_buffer_size;
64776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
64876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
64976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      length -= save_size;
65076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      ptr += save_size;
65176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->buffer_size -= save_size;
65276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_size -= save_size;
65376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_ptr += save_size;
65476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
65576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (length && png_ptr->current_buffer_size)
65676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
65776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t save_size;
65876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
65976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (length < png_ptr->current_buffer_size)
66076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = length;
66176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
66276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
66376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = png_ptr->current_buffer_size;
66476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
66576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
66676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->buffer_size -= save_size;
66776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_buffer_size -= save_size;
66876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_buffer_ptr += save_size;
66976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
67076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
67176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
67276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
67376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_save_buffer(png_structp png_ptr)
67476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
67576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->save_buffer_size)
67676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
67776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
67876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
67976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_size_t i, istop;
68076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_bytep sp;
68176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_bytep dp;
68276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
68376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         istop = png_ptr->save_buffer_size;
68476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
68576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            i < istop; i++, sp++, dp++)
68676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
68776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            *dp = *sp;
68876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
68976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
69076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
69176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
69276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_max)
69376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
69476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t new_max;
69576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_bytep old_buffer;
69676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
69776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
69876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         (png_ptr->current_buffer_size + 256))
69976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
70076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        png_error(png_ptr, "Potential overflow of save_buffer");
70176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
70276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
70376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
70476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      old_buffer = png_ptr->save_buffer;
70576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
70676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         (png_uint_32)new_max);
70776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->save_buffer == NULL)
70876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
70976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        png_free(png_ptr, old_buffer);
71076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        png_error(png_ptr, "Insufficient memory for save_buffer");
71176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
71276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
71376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, old_buffer);
71476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_max = new_max;
71576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
71676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->current_buffer_size)
71776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
71876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
71976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
72076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_size += png_ptr->current_buffer_size;
72176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_buffer_size = 0;
72276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
72376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->save_buffer_ptr = png_ptr->save_buffer;
72476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->buffer_size = 0;
72576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
72676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
72776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
72876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
72976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_size_t buffer_length)
73076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
73176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_buffer = buffer;
73276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_buffer_size = buffer_length;
73376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
73476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_buffer_ptr = png_ptr->current_buffer;
73576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
73676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
73776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
73876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_read_IDAT(png_structp png_ptr)
73976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
74076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USE_LOCAL_ARRAYS
74176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   PNG_CONST PNG_IDAT;
74276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
74376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
74476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
74576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_byte chunk_length[4];
74676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
74776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < 8)
74876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
74976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
75076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
75176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
75276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
75376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_fill_buffer(png_ptr, chunk_length, 4);
75476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
75576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_reset_crc(png_ptr);
75676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_crc_read(png_ptr, png_ptr->chunk_name, 4);
75776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
75876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
75976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
76076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
76176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->process_mode = PNG_READ_CHUNK_MODE;
76276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
76376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_error(png_ptr, "Not enough compressed data");
76476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
76576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
76676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
76776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->idat_size = png_ptr->push_length;
76876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
76976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->idat_size && png_ptr->save_buffer_size)
77076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
77176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t save_size;
77276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
77376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
77476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
77576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = (png_size_t)png_ptr->idat_size;
77676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
77776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* Check for overflow */
77876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if ((png_uint_32)save_size != png_ptr->idat_size)
77976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_error(png_ptr, "save_size overflowed in pngpread");
78076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
78176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
78276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = png_ptr->save_buffer_size;
78376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
78476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
78576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
78676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
78776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
78876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->idat_size -= save_size;
78976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->buffer_size -= save_size;
79076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_size -= save_size;
79176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->save_buffer_ptr += save_size;
79276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
79376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->idat_size && png_ptr->current_buffer_size)
79476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
79576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t save_size;
79676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
79776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
79876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
79976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = (png_size_t)png_ptr->idat_size;
80076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
80176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* Check for overflow */
80276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if ((png_uint_32)save_size != png_ptr->idat_size)
80376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_error(png_ptr, "save_size overflowed in pngpread");
80476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
80576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
80676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         save_size = png_ptr->current_buffer_size;
80776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
80876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
80976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
81076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
81176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
81276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->idat_size -= save_size;
81376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->buffer_size -= save_size;
81476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_buffer_size -= save_size;
81576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_buffer_ptr += save_size;
81676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
81776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!png_ptr->idat_size)
81876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
81976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < 4)
82076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
82176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
82276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
82376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
82476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
82576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_crc_finish(png_ptr, 0);
82676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
82776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->mode |= PNG_AFTER_IDAT;
82876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
82976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
83076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
83176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
83276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
83376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_size_t buffer_length)
83476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
83576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* The caller checks for a non-zero buffer length. */
83676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(buffer_length > 0) || buffer == NULL)
83776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_error(png_ptr, "No IDAT data (internal error)");
83876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
83976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* This routine must process all the data it has been given
84076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * before returning, calling the row callback as required to
84176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * handle the uncompressed results.
84276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    */
84376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->zstream.next_in = buffer;
84476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->zstream.avail_in = (uInt)buffer_length;
84576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
84676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Keep going until the decompressed data is all processed
84776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * or the stream marked as finished.
84876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    */
84976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   while (png_ptr->zstream.avail_in > 0 &&
85076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
85176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
85276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int ret;
85376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
85476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* We have data for zlib, but we must check that zlib
85576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * has somewhere to put the results.  It doesn't matter
85676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * if we don't expect any results -- it may be the input
85776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * data is just the LZ end code.
85876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       */
85976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (!(png_ptr->zstream.avail_out > 0))
86076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
86176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->zstream.avail_out =
86276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
86376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             png_ptr->iwidth) + 1;
86476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->zstream.next_out = png_ptr->row_buf;
86576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
86676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
86776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* Using Z_SYNC_FLUSH here means that an unterminated
86876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * LZ stream can still be handled (a stream with a missing
86976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * end code), otherwise (Z_NO_FLUSH) a future zlib
87076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * implementation might defer output and, therefore,
87176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * change the current behavior.  (See comments in inflate.c
87276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       * for why this doesn't happen at present with zlib 1.2.5.)
87376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       */
87476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
87576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
87676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* Check for any failure before proceeding. */
87776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (ret != Z_OK && ret != Z_STREAM_END)
87876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
87976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 /* Terminate the decompression. */
88076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
88176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
88276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* This may be a truncated stream (missing or
88376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  * damaged end code).  Treat that as a warning.
88476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  */
88576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (png_ptr->row_number >= png_ptr->num_rows ||
88676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     png_ptr->pass > 6)
88776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    png_warning(png_ptr, "Truncated compressed data in IDAT");
88876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 else
88976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    png_error(png_ptr, "Decompression error in IDAT");
89076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
89176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 /* Skip the check on unprocessed input */
89276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
89376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
89476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
89576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* Did inflate output any data? */
89676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->zstream.next_out != png_ptr->row_buf)
89776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
89876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 /* Is this unexpected data after the last row?
89976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  * If it is, artificially terminate the LZ output
90076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  * here.
90176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	  */
90276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (png_ptr->row_number >= png_ptr->num_rows ||
90376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     png_ptr->pass > 6)
90476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
90576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    /* Extra data. */
90676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    png_warning(png_ptr, "Extra compressed data in IDAT");
90776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
90876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    /* Do no more processing; skip the unprocessed
90976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     * input check below.
91076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	     */
91176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            return;
91276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 }
91376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
91476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 /* Do we have a complete row? */
91576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 if (png_ptr->zstream.avail_out == 0)
91676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    png_push_process_row(png_ptr);
91776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
91876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
91976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* And check for the end of the stream. */
92076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (ret == Z_STREAM_END)
92176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
92276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
92376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
92476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* All the data should have been processed, if anything
92576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * is left at this point we have bytes of IDAT data
92676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * after the zlib end code.
92776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    */
92876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->zstream.avail_in > 0)
92976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_warning(png_ptr, "Extra compression data");
93076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
93176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
93276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
93376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_process_row(png_structp png_ptr)
93476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
93576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_info.color_type = png_ptr->color_type;
93676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_info.width = png_ptr->iwidth;
93776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_info.channels = png_ptr->channels;
93876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_info.bit_depth = png_ptr->bit_depth;
93976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
94076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
94176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
94276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       png_ptr->row_info.width);
94376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
94476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_read_filter_row(png_ptr, &(png_ptr->row_info),
94576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
94676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman       (int)(png_ptr->row_buf[0]));
94776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
94876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
94976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->rowbytes + 1);
95076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
95176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
95276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_do_read_transformations(png_ptr);
95376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
95476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_INTERLACING_SUPPORTED
95576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Blow up interlaced rows to full size */
95676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
95776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
95876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->pass < 6)
95976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/*       old interface (pre-1.0.9):
96076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_do_read_interlace(&(png_ptr->row_info),
96176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
96276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
96376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_do_read_interlace(png_ptr);
96476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
96576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    switch (png_ptr->pass)
96676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    {
96776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 0:
96876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
96976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int i;
97076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 8 && png_ptr->pass == 0; i++)
97176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
97276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
97376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
97476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
97576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
97676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 2) /* Pass 1 might be empty */
97776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
97876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
97976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
98076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
98176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_read_push_finish_row(png_ptr);
98276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
98376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
98476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
98576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 4 && png_ptr->height <= 4)
98676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
98776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
98876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
98976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
99076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_read_push_finish_row(png_ptr);
99176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
99276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
99376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
99476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 6 && png_ptr->height <= 4)
99576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
99676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
99776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                png_read_push_finish_row(png_ptr);
99876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
99976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
100076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
100176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
100276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
100376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 1:
100476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
100576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int i;
100676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 8 && png_ptr->pass == 1; i++)
100776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
100876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
100976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
101076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
101176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
101276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 2) /* Skip top 4 generated rows */
101376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
101476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               for (i = 0; i < 4 && png_ptr->pass == 2; i++)
101576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
101676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
101776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_read_push_finish_row(png_ptr);
101876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
101976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
102076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
102176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
102276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
102376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
102476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 2:
102576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
102676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int i;
102776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
102876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
102976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
103076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
103176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
103276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
103376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
103476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 4 && png_ptr->pass == 2; i++)
103576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
103676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
103776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
103876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
103976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
104076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 4) /* Pass 3 might be empty */
104176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
104276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
104376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
104476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
104576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_read_push_finish_row(png_ptr);
104676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
104776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
104876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
104976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
105076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
105176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
105276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 3:
105376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
105476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int i;
105576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
105676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 4 && png_ptr->pass == 3; i++)
105776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
105876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
105976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
106076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
106176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
106276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 4) /* Skip top two generated rows */
106376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
106476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               for (i = 0; i < 2 && png_ptr->pass == 4; i++)
106576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               {
106676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
106776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_read_push_finish_row(png_ptr);
106876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               }
106976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
107076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
107176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
107276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
107376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
107476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 4:
107576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
107676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int i;
107776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
107876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
107976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
108076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
108176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
108276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
108376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
108476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 2 && png_ptr->pass == 4; i++)
108576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
108676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
108776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
108876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
108976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
109076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 6) /* Pass 5 might be empty */
109176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
109276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
109376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
109476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
109576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
109676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
109776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
109876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
109976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 5:
110076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
110176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            int i;
110276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
110376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            for (i = 0; i < 2 && png_ptr->pass == 5; i++)
110476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
110576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_push_have_row(png_ptr, png_ptr->row_buf + 1);
110676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
110776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
110876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
110976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass == 6) /* Skip top generated row */
111076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
111176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
111276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_read_push_finish_row(png_ptr);
111376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
111476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
111576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
111676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
111776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         case 6:
111876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
111976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_push_have_row(png_ptr, png_ptr->row_buf + 1);
112076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_read_push_finish_row(png_ptr);
112176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
112276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (png_ptr->pass != 6)
112376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               break;
112476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
112576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_push_have_row(png_ptr, png_bytep_NULL);
112676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_read_push_finish_row(png_ptr);
112776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
112876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
112976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
113076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else
113176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
113276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
113376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_have_row(png_ptr, png_ptr->row_buf + 1);
113476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_read_push_finish_row(png_ptr);
113576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
113676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
113776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
113876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
113976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_read_push_finish_row(png_structp png_ptr)
114076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
114176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USE_LOCAL_ARRAYS
114276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
114376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
114476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Start of interlace block */
114576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
114676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
114776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Offset to next interlace block */
114876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
114976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
115076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Start of interlace block in the y direction */
115176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
115276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
115376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Offset to next interlace block in the y direction */
115476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
115576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
115676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* Height of interlace block.  This is not currently used - if you need
115776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * it, uncomment it here and in png.h
115876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
115976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   */
116076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
116176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
116276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_number++;
116376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->row_number < png_ptr->num_rows)
116476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
116576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
116676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_INTERLACING_SUPPORTED
116776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->interlaced)
116876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
116976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->row_number = 0;
117076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_memset_check(png_ptr, png_ptr->prev_row, 0,
117176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->rowbytes + 1);
117276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      do
117376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
117476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->pass++;
117576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
117676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             (png_ptr->pass == 3 && png_ptr->width < 3) ||
117776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman             (png_ptr->pass == 5 && png_ptr->width < 2))
117876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman           png_ptr->pass++;
117976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
118076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (png_ptr->pass > 7)
118176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_ptr->pass--;
118276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
118376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (png_ptr->pass >= 7)
118476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
118576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
118676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->iwidth = (png_ptr->width +
118776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_pass_inc[png_ptr->pass] - 1 -
118876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_pass_start[png_ptr->pass]) /
118976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_pass_inc[png_ptr->pass];
119076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
119176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (png_ptr->transformations & PNG_INTERLACE)
119276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
119376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
119476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->num_rows = (png_ptr->height +
119576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_pass_yinc[png_ptr->pass] - 1 -
119676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_pass_ystart[png_ptr->pass]) /
119776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_pass_yinc[png_ptr->pass];
119876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
119976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
120076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
120176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PNG_READ_INTERLACING_SUPPORTED */
120276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
120376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
120476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_tEXt_SUPPORTED
120576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
120676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
120776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   length)
120876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
120976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
121076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
121176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "Out of place tEXt");
121276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         info_ptr = info_ptr; /* To quiet some compiler warnings */
121376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
121476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
121576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MAX_MALLOC_64K
121676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->skip_length = 0;  /* This may not be necessary */
121776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
121876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
121976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
122076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
122176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->skip_length = length - (png_uint_32)65535L;
122276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      length = (png_uint_32)65535L;
122376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
122476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
122576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
122676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
122776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      (png_uint_32)(length + 1));
122876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text[length] = '\0';
122976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_ptr = png_ptr->current_text;
123076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_size = (png_size_t)length;
123176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_left = (png_size_t)length;
123276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->process_mode = PNG_READ_tEXt_MODE;
123376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
123476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
123576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
123676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
123776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
123876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->buffer_size && png_ptr->current_text_left)
123976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
124076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t text_size;
124176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
124276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < png_ptr->current_text_left)
124376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text_size = png_ptr->buffer_size;
124476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
124576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
124676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text_size = png_ptr->current_text_left;
124776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
124876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
124976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text_left -= text_size;
125076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text_ptr += text_size;
125176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
125276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->current_text_left))
125376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
125476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_textp text_ptr;
125576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp text;
125676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp key;
125776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int ret;
125876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
125976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < 4)
126076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
126176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
126276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
126376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
126476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
126576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_crc_finish(png_ptr);
126676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
126776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MAX_MALLOC_64K
126876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->skip_length)
126976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
127076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
127176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
127276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      key = png_ptr->current_text;
127376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
127476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      for (text = key; *text; text++)
127576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* Empty loop */ ;
127676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
127776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (text < key + png_ptr->current_text_size)
127876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text++;
127976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
128076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr = (png_textp)png_malloc(png_ptr,
128176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         (png_uint_32)png_sizeof(png_text));
128276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
128376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->key = key;
128476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_iTXt_SUPPORTED
128576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->lang = NULL;
128676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->lang_key = NULL;
128776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
128876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->text = text;
128976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
129076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
129176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
129276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, key);
129376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, text_ptr);
129476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text = NULL;
129576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
129676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (ret)
129776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        png_warning(png_ptr, "Insufficient memory to store text chunk.");
129876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
129976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
130076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
130176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
130276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_zTXt_SUPPORTED
130376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
130476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
130576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   length)
130676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
130776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
130876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
130976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "Out of place zTXt");
131076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         info_ptr = info_ptr; /* To quiet some compiler warnings */
131176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
131276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
131376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MAX_MALLOC_64K
131476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   /* We can't handle zTXt chunks > 64K, since we don't have enough space
131576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * to be able to store the uncompressed data.  Actually, the threshold
131676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    * is probably around 32K, but it isn't as definite as 64K is.
131776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    */
131876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (length > (png_uint_32)65535L)
131976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
132076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
132176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_crc_skip(png_ptr, length);
132276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
132376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
132476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
132576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
132676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
132776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      (png_uint_32)(length + 1));
132876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text[length] = '\0';
132976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_ptr = png_ptr->current_text;
133076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_size = (png_size_t)length;
133176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_left = (png_size_t)length;
133276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->process_mode = PNG_READ_zTXt_MODE;
133376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
133476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
133576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
133676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
133776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
133876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->buffer_size && png_ptr->current_text_left)
133976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
134076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t text_size;
134176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
134276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
134376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text_size = png_ptr->buffer_size;
134476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
134576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
134676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text_size = png_ptr->current_text_left;
134776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
134876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
134976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text_left -= text_size;
135076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text_ptr += text_size;
135176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
135276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->current_text_left))
135376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
135476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_textp text_ptr;
135576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp text;
135676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp key;
135776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int ret;
135876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t text_size, key_size;
135976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
136076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < 4)
136176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
136276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
136376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
136476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
136576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
136676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_crc_finish(png_ptr);
136776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
136876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      key = png_ptr->current_text;
136976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
137076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      for (text = key; *text; text++)
137176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* Empty loop */ ;
137276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
137376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      /* zTXt can't have zero text */
137476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (text >= key + png_ptr->current_text_size)
137576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
137676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->current_text = NULL;
137776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_free(png_ptr, key);
137876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
137976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
138076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
138176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text++;
138276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
138376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
138476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
138576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->current_text = NULL;
138676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_free(png_ptr, key);
138776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
138876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
138976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
139076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text++;
139176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
139276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->zstream.next_in = (png_bytep )text;
139376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
139476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         (text - key));
139576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->zstream.next_out = png_ptr->zbuf;
139676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
139776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
139876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      key_size = text - key;
139976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_size = 0;
140076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text = NULL;
140176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      ret = Z_STREAM_END;
140276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
140376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      while (png_ptr->zstream.avail_in)
140476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
140576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
140676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (ret != Z_OK && ret != Z_STREAM_END)
140776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
140876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            inflateReset(&png_ptr->zstream);
140976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_ptr->zstream.avail_in = 0;
141076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_ptr->current_text = NULL;
141176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_free(png_ptr, key);
141276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_free(png_ptr, text);
141376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            return;
141476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
141576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
141676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
141776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (text == NULL)
141876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
141976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               text = (png_charp)png_malloc(png_ptr,
142076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                     (png_uint_32)(png_ptr->zbuf_size
142176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                     - png_ptr->zstream.avail_out + key_size + 1));
142276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
142376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_memcpy(text + key_size, png_ptr->zbuf,
142476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
142576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
142676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_memcpy(text, key, key_size);
142776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
142876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               text_size = key_size + png_ptr->zbuf_size -
142976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_ptr->zstream.avail_out;
143076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
143176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(text + text_size) = '\0';
143276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
143376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            else
143476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
143576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_charp tmp;
143676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
143776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               tmp = text;
143876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               text = (png_charp)png_malloc(png_ptr, text_size +
143976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  (png_uint_32)(png_ptr->zbuf_size
144076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  - png_ptr->zstream.avail_out + 1));
144176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_memcpy(text, tmp, text_size);
144376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_free(png_ptr, tmp);
144476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_memcpy(text + text_size, png_ptr->zbuf,
144676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
144776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
144876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
144976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               *(text + text_size) = '\0';
145076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
145176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (ret != Z_STREAM_END)
145276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            {
145376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_ptr->zstream.next_out = png_ptr->zbuf;
145476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
145576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            }
145676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
145776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         else
145876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
145976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
146076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
146176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
146276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (ret == Z_STREAM_END)
146376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            break;
146476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
146576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
146676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      inflateReset(&png_ptr->zstream);
146776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->zstream.avail_in = 0;
146876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
146976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (ret != Z_STREAM_END)
147076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
147176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->current_text = NULL;
147276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_free(png_ptr, key);
147376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_free(png_ptr, text);
147476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
147576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
147676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
147776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text = NULL;
147876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, key);
147976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      key = text;
148076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text += key_size;
148176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
148276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr = (png_textp)png_malloc(png_ptr,
148376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          (png_uint_32)png_sizeof(png_text));
148476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
148576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->key = key;
148676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_iTXt_SUPPORTED
148776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->lang = NULL;
148876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->lang_key = NULL;
148976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
149076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->text = text;
149176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
149276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
149376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
149476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, key);
149576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, text_ptr);
149676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
149776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (ret)
149876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        png_warning(png_ptr, "Insufficient memory to store text chunk.");
149976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
150076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
150176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
150276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
150376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_iTXt_SUPPORTED
150476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
150576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
150676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   length)
150776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
150876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
150976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
151076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_error(png_ptr, "Out of place iTXt");
151176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         info_ptr = info_ptr; /* To quiet some compiler warnings */
151276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
151376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
151476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MAX_MALLOC_64K
151576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->skip_length = 0;  /* This may not be necessary */
151676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
151776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
151876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
151976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
152076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->skip_length = length - (png_uint_32)65535L;
152176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      length = (png_uint_32)65535L;
152276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
152376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
152476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
152576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
152676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      (png_uint_32)(length + 1));
152776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text[length] = '\0';
152876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_ptr = png_ptr->current_text;
152976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_size = (png_size_t)length;
153076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->current_text_left = (png_size_t)length;
153176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->process_mode = PNG_READ_iTXt_MODE;
153276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
153376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
153476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
153576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
153676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
153776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
153876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->buffer_size && png_ptr->current_text_left)
153976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
154076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_size_t text_size;
154176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
154276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < png_ptr->current_text_left)
154376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text_size = png_ptr->buffer_size;
154476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
154576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
154676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text_size = png_ptr->current_text_left;
154776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
154876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
154976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text_left -= text_size;
155076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text_ptr += text_size;
155176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
155276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->current_text_left))
155376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
155476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_textp text_ptr;
155576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp key;
155676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int comp_flag;
155776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp lang;
155876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp lang_key;
155976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_charp text;
156076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      int ret;
156176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
156276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->buffer_size < 4)
156376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
156476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_push_save_buffer(png_ptr);
156576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
156676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
156776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
156876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_push_crc_finish(png_ptr);
156976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
157076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MAX_MALLOC_64K
157176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->skip_length)
157276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         return;
157376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
157476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
157576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      key = png_ptr->current_text;
157676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
157776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      for (lang = key; *lang; lang++)
157876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* Empty loop */ ;
157976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
158076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (lang < key + png_ptr->current_text_size - 3)
158176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         lang++;
158276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
158376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      comp_flag = *lang++;
158476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      lang++;     /* Skip comp_type, always zero */
158576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
158676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      for (lang_key = lang; *lang_key; lang_key++)
158776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* Empty loop */ ;
158876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
158976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      lang_key++;        /* Skip NUL separator */
159076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
159176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text=lang_key;
159276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
159376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (lang_key < key + png_ptr->current_text_size - 1)
159476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
159576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        for (; *text; text++)
159676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman           /* Empty loop */ ;
159776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
159876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
159976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (text < key + png_ptr->current_text_size)
160076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         text++;
160176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
160276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr = (png_textp)png_malloc(png_ptr,
160376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         (png_uint_32)png_sizeof(png_text));
160476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
160576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->compression = comp_flag + 2;
160676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->key = key;
160776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->lang = lang;
160876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->lang_key = lang_key;
160976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->text = text;
161076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->text_length = 0;
161176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      text_ptr->itxt_length = png_strlen(text);
161276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
161376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
161476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
161576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->current_text = NULL;
161676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
161776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, text_ptr);
161876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (ret)
161976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
162076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
162176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
162276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
162376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
162476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* This function is called when we haven't found a handler for this
162576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
162676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * name or a critical chunk), the chunk is (currently) silently ignored.
162776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */
162876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
162976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
163076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   length)
163176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
163276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_uint_32 skip = 0;
163376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
163476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (!(png_ptr->chunk_name[0] & 0x20))
163576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
163676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
163776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
163876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         PNG_HANDLE_CHUNK_ALWAYS
163976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
164076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         && png_ptr->read_user_chunk_fn == NULL
164176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
164276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         )
164376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
164476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_chunk_error(png_ptr, "unknown critical chunk");
164576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
164676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      info_ptr = info_ptr; /* To quiet some compiler warnings */
164776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
164876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
164976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
165076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
165176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   {
165276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_MAX_MALLOC_64K
165376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (length > (png_uint_32)65535L)
165476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
165576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          png_warning(png_ptr, "unknown chunk too large to fit in memory");
165676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          skip = length - (png_uint_32)65535L;
165776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman          length = (png_uint_32)65535L;
165876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
165976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
166076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_memcpy((png_charp)png_ptr->unknown_chunk.name,
166176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                 (png_charp)png_ptr->chunk_name,
166276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                 png_sizeof(png_ptr->unknown_chunk.name));
166376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
166476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        = '\0';
166576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
166676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->unknown_chunk.size = (png_size_t)length;
166776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
166876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (length == 0)
166976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->unknown_chunk.data = NULL;
167076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
167176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
167276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
167376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
167476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            (png_uint_32)length);
167576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
167676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
167776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
167876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
167976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      if (png_ptr->read_user_chunk_fn != NULL)
168076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {
168176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         /* Callback to user unknown chunk handler */
168276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         int ret;
168376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         ret = (*(png_ptr->read_user_chunk_fn))
168476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman           (png_ptr, &png_ptr->unknown_chunk);
168576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
168676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (ret < 0)
168776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_chunk_error(png_ptr, "error in user chunk");
168876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
168976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         if (ret == 0)
169076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         {
169176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            if (!(png_ptr->chunk_name[0] & 0x20))
169276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
169376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                    PNG_HANDLE_CHUNK_ALWAYS)
169476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman                  png_chunk_error(png_ptr, "unknown critical chunk");
169576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman            png_set_unknown_chunks(png_ptr, info_ptr,
169676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman               &png_ptr->unknown_chunk, 1);
169776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         }
169876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      }
169976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
170076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      else
170176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
170276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
170376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_free(png_ptr, png_ptr->unknown_chunk.data);
170476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_ptr->unknown_chunk.data = NULL;
170576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   }
170676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
170776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   else
170876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
170976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      skip=length;
171076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_push_crc_skip(png_ptr, skip);
171176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
171276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
171376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
171476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_have_info(png_structp png_ptr, png_infop info_ptr)
171576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
171676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->info_fn != NULL)
171776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      (*(png_ptr->info_fn))(png_ptr, info_ptr);
171876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
171976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
172076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
172176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_have_end(png_structp png_ptr, png_infop info_ptr)
172276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
172376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->end_fn != NULL)
172476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      (*(png_ptr->end_fn))(png_ptr, info_ptr);
172576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
172676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
172776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid /* PRIVATE */
172876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_push_have_row(png_structp png_ptr, png_bytep row)
172976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
173076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr->row_fn != NULL)
173176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
173276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman         (int)png_ptr->pass);
173376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
173476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
173576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid PNGAPI
173676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_progressive_combine_row (png_structp png_ptr,
173776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_bytep old_row, png_bytep new_row)
173876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
173976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef PNG_USE_LOCAL_ARRAYS
174076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   PNG_CONST int FARDATA png_pass_dsp_mask[7] =
174176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
174276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif
174376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
174476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr == NULL)
174576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
174676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
174776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
174876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
174976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
175076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
175176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid PNGAPI
175276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
175376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
175476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_progressive_end_ptr end_fn)
175576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
175676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr == NULL)
175776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return;
175876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
175976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->info_fn = info_fn;
176076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->row_fn = row_fn;
176176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_ptr->end_fn = end_fn;
176276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
176376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
176476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
176576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
176676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_voidp PNGAPI
176776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanpng_get_progressive_ptr(png_structp png_ptr)
176876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
176976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   if (png_ptr == NULL)
177076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman      return (NULL);
177176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
177276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman   return png_ptr->io_ptr;
177376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
177476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
1775