blob: e7af70c49182deb02e093aa2d34b490ad974d0c9 [file] [log] [blame]
Guy Schalnat6d764711995-12-19 03:22:19 -06001
2/* pngpread.c - read a png file in push mode
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06003 *
Glenn Randers-Pehrson glennrp@comcast.net11a3c7b2009-05-15 20:33:24 -05004 * Last changed in libpng 1.4.0 [May 15, 2009]
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06005 * For conditions of distribution and use, see copyright notice in png.h
Glenn Randers-Pehrson79134c62009-02-14 10:32:18 -06006 * Copyright (c) 1998-2009 Glenn Randers-Pehrson
Glenn Randers-Pehrsond4366722000-06-04 14:29:29 -05007 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06009 */
Guy Schalnat6d764711995-12-19 03:22:19 -060010
Guy Schalnat6d764711995-12-19 03:22:19 -060011#include "png.h"
Guy Schalnat4ee97b01996-01-16 01:51:56 -060012#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -050013#include "pngpriv.h"
Guy Schalnat4ee97b01996-01-16 01:51:56 -060014
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060015/* push model modes */
16#define PNG_READ_SIG_MODE 0
17#define PNG_READ_CHUNK_MODE 1
18#define PNG_READ_IDAT_MODE 2
19#define PNG_SKIP_MODE 3
20#define PNG_READ_tEXt_MODE 4
21#define PNG_READ_zTXt_MODE 5
22#define PNG_READ_DONE_MODE 6
23#define PNG_READ_iTXt_MODE 7
24#define PNG_ERROR_MODE 8
25
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050026void PNGAPI
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060027png_process_data(png_structp png_ptr, png_infop info_ptr,
Andreas Dilger47a0c421997-05-16 02:46:07 -050028 png_bytep buffer, png_size_t buffer_size)
Guy Schalnat6d764711995-12-19 03:22:19 -060029{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050030 if (png_ptr == NULL || info_ptr == NULL)
31 return;
32
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060033 png_push_restore_buffer(png_ptr, buffer, buffer_size);
Guy Schalnat6d764711995-12-19 03:22:19 -060034
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060035 while (png_ptr->buffer_size)
36 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060037 png_process_some_data(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060038 }
Guy Schalnat6d764711995-12-19 03:22:19 -060039}
40
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060041/* What we do with the incoming data depends on what we were previously
42 * doing before we ran out of data...
43 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050044void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060045png_process_some_data(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -060046{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050047 if (png_ptr == NULL)
48 return;
49
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060050 switch (png_ptr->process_mode)
51 {
52 case PNG_READ_SIG_MODE:
53 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060054 png_push_read_sig(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060055 break;
56 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050057
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060058 case PNG_READ_CHUNK_MODE:
59 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060060 png_push_read_chunk(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060061 break;
62 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050063
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060064 case PNG_READ_IDAT_MODE:
65 {
Guy Schalnate5a37791996-06-05 15:50:50 -050066 png_push_read_IDAT(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060067 break;
68 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050069
Guy Schalnat6d764711995-12-19 03:22:19 -060070#if defined(PNG_READ_tEXt_SUPPORTED)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060071 case PNG_READ_tEXt_MODE:
72 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060073 png_push_read_tEXt(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060074 break;
75 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050076
Guy Schalnat6d764711995-12-19 03:22:19 -060077#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060078#if defined(PNG_READ_zTXt_SUPPORTED)
79 case PNG_READ_zTXt_MODE:
80 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060081 png_push_read_zTXt(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060082 break;
83 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050084
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060085#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060086#if defined(PNG_READ_iTXt_SUPPORTED)
87 case PNG_READ_iTXt_MODE:
88 {
89 png_push_read_iTXt(png_ptr, info_ptr);
90 break;
91 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050092
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060093#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060094 case PNG_SKIP_MODE:
95 {
Andreas Dilger47a0c421997-05-16 02:46:07 -050096 png_push_crc_finish(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060097 break;
98 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050099
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600100 default:
101 {
102 png_ptr->buffer_size = 0;
103 break;
104 }
105 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600106}
107
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600108/* Read any remaining signature bytes from the stream and compare them with
109 * the correct PNG signature. It is possible that this routine is called
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -0500110 * with bytes already read from the signature, either because they have been
111 * checked by the calling application, or because of multiple calls to this
112 * routine.
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600113 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500114void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600115png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600116{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500117 png_size_t num_checked = png_ptr->sig_bytes,
118 num_to_check = 8 - num_checked;
Guy Schalnat6d764711995-12-19 03:22:19 -0600119
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600120 if (png_ptr->buffer_size < num_to_check)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600121 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600122 num_to_check = png_ptr->buffer_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600123 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600124
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600125 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
Andreas Dilger47a0c421997-05-16 02:46:07 -0500126 num_to_check);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500127 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
Guy Schalnat6d764711995-12-19 03:22:19 -0600128
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600129 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600130 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600131 if (num_checked < 4 &&
132 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
133 png_error(png_ptr, "Not a PNG file");
134 else
135 png_error(png_ptr, "PNG file corrupted by ASCII conversion");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600136 }
137 else
138 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600139 if (png_ptr->sig_bytes >= 8)
140 {
141 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
142 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600143 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600144}
145
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500146void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600147png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600148{
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600149#ifdef PNG_USE_LOCAL_ARRAYS
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500150 PNG_CONST PNG_IHDR;
151 PNG_CONST PNG_IDAT;
152 PNG_CONST PNG_IEND;
153 PNG_CONST PNG_PLTE;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600154#if defined(PNG_READ_bKGD_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500155 PNG_CONST PNG_bKGD;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600156#endif
157#if defined(PNG_READ_cHRM_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500158 PNG_CONST PNG_cHRM;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600159#endif
160#if defined(PNG_READ_gAMA_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500161 PNG_CONST PNG_gAMA;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600162#endif
163#if defined(PNG_READ_hIST_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500164 PNG_CONST PNG_hIST;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600165#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600166#if defined(PNG_READ_iCCP_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500167 PNG_CONST PNG_iCCP;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600168#endif
169#if defined(PNG_READ_iTXt_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500170 PNG_CONST PNG_iTXt;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600171#endif
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600172#if defined(PNG_READ_oFFs_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500173 PNG_CONST PNG_oFFs;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600174#endif
175#if defined(PNG_READ_pCAL_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500176 PNG_CONST PNG_pCAL;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600177#endif
178#if defined(PNG_READ_pHYs_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500179 PNG_CONST PNG_pHYs;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600180#endif
181#if defined(PNG_READ_sBIT_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500182 PNG_CONST PNG_sBIT;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600183#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600184#if defined(PNG_READ_sCAL_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500185 PNG_CONST PNG_sCAL;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600186#endif
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600187#if defined(PNG_READ_sRGB_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500188 PNG_CONST PNG_sRGB;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600189#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600190#if defined(PNG_READ_sPLT_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500191 PNG_CONST PNG_sPLT;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600192#endif
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600193#if defined(PNG_READ_tEXt_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500194 PNG_CONST PNG_tEXt;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600195#endif
196#if defined(PNG_READ_tIME_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500197 PNG_CONST PNG_tIME;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600198#endif
199#if defined(PNG_READ_tRNS_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500200 PNG_CONST PNG_tRNS;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600201#endif
202#if defined(PNG_READ_zTXt_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500203 PNG_CONST PNG_zTXt;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600204#endif
205#endif /* PNG_USE_LOCAL_ARRAYS */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600206 /* First we make sure we have enough data for the 4 byte chunk name
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600207 * and the 4 byte chunk length before proceeding with decoding the
208 * chunk data. To fully decode each of these chunks, we also make
209 * sure we have enough data in the buffer for the 4 byte CRC at the
210 * end of every chunk (except IDAT, which is handled separately).
211 */
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600212 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600213 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600214 png_byte chunk_length[4];
Guy Schalnat6d764711995-12-19 03:22:19 -0600215
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600216 if (png_ptr->buffer_size < 8)
217 {
218 png_push_save_buffer(png_ptr);
219 return;
220 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600221
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600222 png_push_fill_buffer(png_ptr, chunk_length, 4);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500223 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600224 png_reset_crc(png_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500225 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
Glenn Randers-Pehrsoneb580912008-07-30 14:47:09 -0500226 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600227 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600228 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600229
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500230 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500231 if (png_ptr->mode & PNG_AFTER_IDAT)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500232 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
233
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600234 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600235 {
Glenn Randers-Pehrsoneb580912008-07-30 14:47:09 -0500236 if (png_ptr->push_length != 13)
237 png_error(png_ptr, "Invalid IHDR length");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500238
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500239 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
240 {
241 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600242 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500243 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500244
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600245 png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600246 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500247
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500248 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
249 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500250 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
251 {
252 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500253 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500254 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500255
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500256 png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
257
258 png_ptr->process_mode = PNG_READ_DONE_MODE;
259 png_push_have_end(png_ptr, info_ptr);
260 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500261
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500262#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
263 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
264 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500265 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
266 {
267 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500268 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500269 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500270
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500271 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
272 png_ptr->mode |= PNG_HAVE_IDAT;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500273
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500274 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500275
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500276 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
277 png_ptr->mode |= PNG_HAVE_PLTE;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500278
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500279 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
280 {
281 if (!(png_ptr->mode & PNG_HAVE_IHDR))
282 png_error(png_ptr, "Missing IHDR before IDAT");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500283
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500284 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
285 !(png_ptr->mode & PNG_HAVE_PLTE))
286 png_error(png_ptr, "Missing PLTE before IDAT");
287 }
288 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500289
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500290#endif
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600291 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600292 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500293 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
294 {
295 png_push_save_buffer(png_ptr);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600296 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500297 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600298 png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600299 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500300
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500301 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600302 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600303 /* If we reach an IDAT chunk, this means we have read all of the
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600304 * header chunks, and we can start reading the image (or if this
305 * is called after the image has been read - we have an error).
306 */
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500307
308 if (!(png_ptr->mode & PNG_HAVE_IHDR))
309 png_error(png_ptr, "Missing IHDR before IDAT");
310
311 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
312 !(png_ptr->mode & PNG_HAVE_PLTE))
313 png_error(png_ptr, "Missing PLTE before IDAT");
Glenn Randers-Pehrson73d57cb2002-03-25 18:49:08 -0600314
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600315 if (png_ptr->mode & PNG_HAVE_IDAT)
316 {
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500317 if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500318 if (png_ptr->push_length == 0)
319 return;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600320
321 if (png_ptr->mode & PNG_AFTER_IDAT)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500322 png_benign_error(png_ptr, "Too many IDATs found");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600323 }
324
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600325 png_ptr->idat_size = png_ptr->push_length;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600326 png_ptr->mode |= PNG_HAVE_IDAT;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600327 png_ptr->process_mode = PNG_READ_IDAT_MODE;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600328 png_push_have_info(png_ptr, info_ptr);
329 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
330 png_ptr->zstream.next_out = png_ptr->row_buf;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600331 return;
332 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500333
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600334#if defined(PNG_READ_gAMA_SUPPORTED)
335 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
336 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500337 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
338 {
339 png_push_save_buffer(png_ptr);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600340 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500341 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500342
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600343 png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600344 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500345
Guy Schalnat6d764711995-12-19 03:22:19 -0600346#endif
347#if defined(PNG_READ_sBIT_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600348 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600349 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500350 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
351 {
352 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600353 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500354 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500355
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600356 png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600357 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500358
Guy Schalnat6d764711995-12-19 03:22:19 -0600359#endif
360#if defined(PNG_READ_cHRM_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600361 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600362 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500363 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
364 {
365 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600366 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500367 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500368
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600369 png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600370 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500371
Guy Schalnat6d764711995-12-19 03:22:19 -0600372#endif
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600373#if defined(PNG_READ_sRGB_SUPPORTED)
374 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
375 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500376 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
377 {
378 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600379 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500380 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500381
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600382 png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
383 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500384
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600385#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600386#if defined(PNG_READ_iCCP_SUPPORTED)
387 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
388 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500389 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
390 {
391 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600392 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500393 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500394
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600395 png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
396 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500397
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600398#endif
399#if defined(PNG_READ_sPLT_SUPPORTED)
400 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
401 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500402 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
403 {
404 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600405 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500406 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500407
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600408 png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
409 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500410
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600411#endif
Guy Schalnat6d764711995-12-19 03:22:19 -0600412#if defined(PNG_READ_tRNS_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600413 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600414 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500415 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
416 {
417 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600418 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500419 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500420
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600421 png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600422 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500423
Guy Schalnat6d764711995-12-19 03:22:19 -0600424#endif
425#if defined(PNG_READ_bKGD_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600426 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600427 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500428 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
429 {
430 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600431 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500432 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500433
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600434 png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600435 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500436
Guy Schalnat6d764711995-12-19 03:22:19 -0600437#endif
438#if defined(PNG_READ_hIST_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600439 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600440 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500441 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
442 {
443 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600444 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500445 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500446
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600447 png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600448 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500449
Guy Schalnat6d764711995-12-19 03:22:19 -0600450#endif
451#if defined(PNG_READ_pHYs_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600452 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600453 {
454 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
455 {
456 png_push_save_buffer(png_ptr);
457 return;
458 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500459
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600460 png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600461 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500462
Guy Schalnat6d764711995-12-19 03:22:19 -0600463#endif
464#if defined(PNG_READ_oFFs_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600465 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600466 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500467 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
468 {
469 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600470 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500471 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500472
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600473 png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600474 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600475#endif
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500476
Andreas Dilger47a0c421997-05-16 02:46:07 -0500477#if defined(PNG_READ_pCAL_SUPPORTED)
478 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
479 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500480 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
481 {
482 png_push_save_buffer(png_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500483 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500484 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500485
Andreas Dilger47a0c421997-05-16 02:46:07 -0500486 png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
487 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500488
Andreas Dilger47a0c421997-05-16 02:46:07 -0500489#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600490#if defined(PNG_READ_sCAL_SUPPORTED)
491 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
492 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500493 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
494 {
495 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600496 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500497 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500498
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600499 png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
500 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500501
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600502#endif
Guy Schalnat6d764711995-12-19 03:22:19 -0600503#if defined(PNG_READ_tIME_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600504 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600505 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500506 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
507 {
508 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600509 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500510 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500511
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600512 png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600513 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500514
Guy Schalnat6d764711995-12-19 03:22:19 -0600515#endif
516#if defined(PNG_READ_tEXt_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600517 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600518 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500519 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
520 {
521 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500522 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500523 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500524
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600525 png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600526 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500527
Guy Schalnat6d764711995-12-19 03:22:19 -0600528#endif
529#if defined(PNG_READ_zTXt_SUPPORTED)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600530 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600531 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500532 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
533 {
534 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500535 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500536 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500537
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600538 png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600539 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500540
Guy Schalnat6d764711995-12-19 03:22:19 -0600541#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600542#if defined(PNG_READ_iTXt_SUPPORTED)
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600543 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600544 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500545 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
546 {
547 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500548 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500549 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500550
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600551 png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
552 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500553
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600554#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600555 else
556 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500557 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
558 {
559 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500560 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500561 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600562 png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600563 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600564
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600565 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
Guy Schalnat6d764711995-12-19 03:22:19 -0600566}
567
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500568void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500569png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
Guy Schalnat6d764711995-12-19 03:22:19 -0600570{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600571 png_ptr->process_mode = PNG_SKIP_MODE;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500572 png_ptr->skip_length = skip;
Guy Schalnat6d764711995-12-19 03:22:19 -0600573}
574
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500575void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500576png_push_crc_finish(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600577{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600578 if (png_ptr->skip_length && png_ptr->save_buffer_size)
579 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500580 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600581
Andreas Dilger47a0c421997-05-16 02:46:07 -0500582 if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
583 save_size = (png_size_t)png_ptr->skip_length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600584 else
585 save_size = png_ptr->save_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600586
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600587 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600588
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600589 png_ptr->skip_length -= save_size;
590 png_ptr->buffer_size -= save_size;
591 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500592 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600593 }
594 if (png_ptr->skip_length && png_ptr->current_buffer_size)
595 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500596 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600597
Andreas Dilger47a0c421997-05-16 02:46:07 -0500598 if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
599 save_size = (png_size_t)png_ptr->skip_length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600600 else
601 save_size = png_ptr->current_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600602
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600603 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600604
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600605 png_ptr->skip_length -= save_size;
606 png_ptr->buffer_size -= save_size;
607 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500608 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600609 }
610 if (!png_ptr->skip_length)
611 {
612 if (png_ptr->buffer_size < 4)
613 {
614 png_push_save_buffer(png_ptr);
615 return;
616 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600617
618 png_crc_finish(png_ptr, 0);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500619 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600620 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600621}
622
Glenn Randers-Pehrson25d82242002-05-01 11:51:26 -0500623void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500624png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600625{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600626 png_bytep ptr;
Guy Schalnat6d764711995-12-19 03:22:19 -0600627
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500628 if (png_ptr == NULL)
629 return;
630
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600631 ptr = buffer;
632 if (png_ptr->save_buffer_size)
633 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500634 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600635
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600636 if (length < png_ptr->save_buffer_size)
637 save_size = length;
638 else
639 save_size = png_ptr->save_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600640
Andreas Dilger47a0c421997-05-16 02:46:07 -0500641 png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600642 length -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500643 ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600644 png_ptr->buffer_size -= save_size;
645 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500646 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600647 }
648 if (length && png_ptr->current_buffer_size)
649 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500650 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600651
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600652 if (length < png_ptr->current_buffer_size)
653 save_size = length;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500654
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600655 else
656 save_size = png_ptr->current_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600657
Andreas Dilger47a0c421997-05-16 02:46:07 -0500658 png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600659 png_ptr->buffer_size -= save_size;
660 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500661 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600662 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600663}
664
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500665void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600666png_push_save_buffer(png_structp png_ptr)
667{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600668 if (png_ptr->save_buffer_size)
669 {
670 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
671 {
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500672 png_size_t i, istop;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600673 png_bytep sp;
674 png_bytep dp;
Guy Schalnat6d764711995-12-19 03:22:19 -0600675
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500676 istop = png_ptr->save_buffer_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600677 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500678 i < istop; i++, sp++, dp++)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600679 {
680 *dp = *sp;
681 }
682 }
683 }
684 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
685 png_ptr->save_buffer_max)
686 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500687 png_size_t new_max;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600688 png_bytep old_buffer;
Guy Schalnat6d764711995-12-19 03:22:19 -0600689
Glenn Randers-Pehrsone6474622006-03-04 16:50:47 -0600690 if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
Glenn Randers-Pehrson5fea36f2004-07-28 08:20:44 -0500691 (png_ptr->current_buffer_size + 256))
692 {
693 png_error(png_ptr, "Potential overflow of save_buffer");
694 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500695
Andreas Dilger47a0c421997-05-16 02:46:07 -0500696 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600697 old_buffer = png_ptr->save_buffer;
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500698 png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
699 (png_size_t)new_max);
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -0500700 png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
701 png_free(png_ptr, old_buffer);
702 png_ptr->save_buffer_max = new_max;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600703 }
704 if (png_ptr->current_buffer_size)
705 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500706 png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
707 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600708 png_ptr->save_buffer_size += png_ptr->current_buffer_size;
709 png_ptr->current_buffer_size = 0;
710 }
711 png_ptr->save_buffer_ptr = png_ptr->save_buffer;
712 png_ptr->buffer_size = 0;
Guy Schalnat6d764711995-12-19 03:22:19 -0600713}
714
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500715void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600716png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500717 png_size_t buffer_length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600718{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600719 png_ptr->current_buffer = buffer;
720 png_ptr->current_buffer_size = buffer_length;
721 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
722 png_ptr->current_buffer_ptr = png_ptr->current_buffer;
Guy Schalnat6d764711995-12-19 03:22:19 -0600723}
724
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500725void /* PRIVATE */
Guy Schalnate5a37791996-06-05 15:50:50 -0500726png_push_read_IDAT(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600727{
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600728#ifdef PNG_USE_LOCAL_ARRAYS
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500729 PNG_CONST PNG_IDAT;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600730#endif
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600731 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600732 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600733 png_byte chunk_length[4];
Guy Schalnat6d764711995-12-19 03:22:19 -0600734
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600735 if (png_ptr->buffer_size < 8)
736 {
737 png_push_save_buffer(png_ptr);
738 return;
739 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600740
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600741 png_push_fill_buffer(png_ptr, chunk_length, 4);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500742 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600743 png_reset_crc(png_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500744 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600745 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600746
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500747 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600748 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500749 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
Guy Schalnate5a37791996-06-05 15:50:50 -0500750 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600751 png_error(png_ptr, "Not enough compressed data");
752 return;
753 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600754
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600755 png_ptr->idat_size = png_ptr->push_length;
756 }
757 if (png_ptr->idat_size && png_ptr->save_buffer_size)
758 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500759 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600760
Andreas Dilger47a0c421997-05-16 02:46:07 -0500761 if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600762 {
763 save_size = (png_size_t)png_ptr->idat_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500764
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600765 /* check for overflow */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500766 if ((png_uint_32)save_size != png_ptr->idat_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600767 png_error(png_ptr, "save_size overflowed in pngpread");
768 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600769 else
770 save_size = png_ptr->save_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600771
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600772 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500773
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500774 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
775 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500776
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600777 png_ptr->idat_size -= save_size;
778 png_ptr->buffer_size -= save_size;
779 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500780 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600781 }
782 if (png_ptr->idat_size && png_ptr->current_buffer_size)
783 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500784 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600785
Andreas Dilger47a0c421997-05-16 02:46:07 -0500786 if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600787 {
788 save_size = (png_size_t)png_ptr->idat_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500789
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600790 /* check for overflow */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500791 if ((png_uint_32)save_size != png_ptr->idat_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600792 png_error(png_ptr, "save_size overflowed in pngpread");
793 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600794 else
795 save_size = png_ptr->current_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600796
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600797 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500798 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
799 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600800
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600801 png_ptr->idat_size -= save_size;
802 png_ptr->buffer_size -= save_size;
803 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500804 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600805 }
806 if (!png_ptr->idat_size)
807 {
808 if (png_ptr->buffer_size < 4)
809 {
810 png_push_save_buffer(png_ptr);
811 return;
812 }
813
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600814 png_crc_finish(png_ptr, 0);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600815 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500816 png_ptr->mode |= PNG_AFTER_IDAT;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600817 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600818}
819
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500820void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600821png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500822 png_size_t buffer_length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600823{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600824 int ret;
Guy Schalnat6d764711995-12-19 03:22:19 -0600825
Guy Schalnate5a37791996-06-05 15:50:50 -0500826 if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500827 png_benign_error(png_ptr, "Extra compression data");
Guy Schalnat6d764711995-12-19 03:22:19 -0600828
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600829 png_ptr->zstream.next_in = buffer;
830 png_ptr->zstream.avail_in = (uInt)buffer_length;
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500831 for (;;)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600832 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600833 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500834 if (ret != Z_OK)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600835 {
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500836 if (ret == Z_STREAM_END)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600837 {
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500838 if (png_ptr->zstream.avail_in)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500839 png_benign_error(png_ptr, "Extra compressed data");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500840
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500841 if (!(png_ptr->zstream.avail_out))
842 {
843 png_push_process_row(png_ptr);
844 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500845
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500846 png_ptr->mode |= PNG_AFTER_IDAT;
847 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
848 break;
849 }
850 else if (ret == Z_BUF_ERROR)
851 break;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500852
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500853 else
854 png_error(png_ptr, "Decompression Error");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600855 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600856 if (!(png_ptr->zstream.avail_out))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600857 {
Glenn Randers-Pehrsond020e9d2002-06-28 09:34:00 -0500858 if ((
859#if defined(PNG_READ_INTERLACING_SUPPORTED)
860 png_ptr->interlaced && png_ptr->pass > 6) ||
861 (!png_ptr->interlaced &&
862#endif
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500863 png_ptr->row_number == png_ptr->num_rows))
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500864 {
Glenn Randers-Pehrson8a7df002002-08-15 22:02:57 -0500865 if (png_ptr->zstream.avail_in)
866 png_warning(png_ptr, "Too much data in IDAT chunks");
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500867 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
868 break;
869 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600870 png_push_process_row(png_ptr);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600871 png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
872 png_ptr->zstream.next_out = png_ptr->row_buf;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600873 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500874
Andreas Dilger47a0c421997-05-16 02:46:07 -0500875 else
876 break;
877 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600878}
879
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500880void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600881png_push_process_row(png_structp png_ptr)
882{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600883 png_ptr->row_info.color_type = png_ptr->color_type;
Guy Schalnat6d764711995-12-19 03:22:19 -0600884 png_ptr->row_info.width = png_ptr->iwidth;
885 png_ptr->row_info.channels = png_ptr->channels;
886 png_ptr->row_info.bit_depth = png_ptr->bit_depth;
887 png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600888
Glenn Randers-Pehrson272489d2004-08-04 06:34:52 -0500889 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
890 png_ptr->row_info.width);
Guy Schalnat6d764711995-12-19 03:22:19 -0600891
Guy Schalnate5a37791996-06-05 15:50:50 -0500892 png_read_filter_row(png_ptr, &(png_ptr->row_info),
893 png_ptr->row_buf + 1, png_ptr->prev_row + 1,
894 (int)(png_ptr->row_buf[0]));
Guy Schalnat6d764711995-12-19 03:22:19 -0600895
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500896 png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
Guy Schalnat6d764711995-12-19 03:22:19 -0600897
Glenn Randers-Pehrson73b029f2004-11-26 17:28:09 -0600898 if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
Guy Schalnat6d764711995-12-19 03:22:19 -0600899 png_do_read_transformations(png_ptr);
900
901#if defined(PNG_READ_INTERLACING_SUPPORTED)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600902 /* blow up interlaced rows to full size */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500903 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600904 {
905 if (png_ptr->pass < 6)
Glenn Randers-Pehrson231e6872001-01-12 15:13:06 -0600906/* old interface (pre-1.0.9):
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600907 png_do_read_interlace(&(png_ptr->row_info),
Andreas Dilger47a0c421997-05-16 02:46:07 -0500908 png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
Glenn Randers-Pehrson231e6872001-01-12 15:13:06 -0600909 */
910 png_do_read_interlace(png_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -0600911
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600912 switch (png_ptr->pass)
913 {
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600914 case 0:
915 {
916 int i;
917 for (i = 0; i < 8 && png_ptr->pass == 0; i++)
918 {
919 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -0600920 png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600921 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500922
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -0600923 if (png_ptr->pass == 2) /* pass 1 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600924 {
925 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
926 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500927 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600928 png_read_push_finish_row(png_ptr);
929 }
930 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500931
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500932 if (png_ptr->pass == 4 && png_ptr->height <= 4)
933 {
934 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
935 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500936 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500937 png_read_push_finish_row(png_ptr);
938 }
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500939 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500940
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500941 if (png_ptr->pass == 6 && png_ptr->height <= 4)
942 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500943 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500944 png_read_push_finish_row(png_ptr);
945 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500946
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600947 break;
948 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500949
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600950 case 1:
951 {
952 int i;
953 for (i = 0; i < 8 && png_ptr->pass == 1; i++)
954 {
955 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
956 png_read_push_finish_row(png_ptr);
957 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500958
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -0600959 if (png_ptr->pass == 2) /* skip top 4 generated rows */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600960 {
961 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
962 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500963 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600964 png_read_push_finish_row(png_ptr);
965 }
966 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500967
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600968 break;
969 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500970
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600971 case 2:
972 {
973 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500974
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600975 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
976 {
977 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
978 png_read_push_finish_row(png_ptr);
979 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500980
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600981 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
982 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500983 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600984 png_read_push_finish_row(png_ptr);
985 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500986
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -0600987 if (png_ptr->pass == 4) /* pass 3 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600988 {
989 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
990 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500991 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600992 png_read_push_finish_row(png_ptr);
993 }
994 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500995
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600996 break;
997 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500998
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600999 case 3:
1000 {
1001 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001002
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001003 for (i = 0; i < 4 && png_ptr->pass == 3; i++)
1004 {
1005 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1006 png_read_push_finish_row(png_ptr);
1007 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001008
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -06001009 if (png_ptr->pass == 4) /* skip top two generated rows */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001010 {
1011 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1012 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001013 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001014 png_read_push_finish_row(png_ptr);
1015 }
1016 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001017
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001018 break;
1019 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001020
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001021 case 4:
1022 {
1023 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001024
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001025 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1026 {
1027 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1028 png_read_push_finish_row(png_ptr);
1029 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001030
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001031 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1032 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001033 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001034 png_read_push_finish_row(png_ptr);
1035 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001036
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -06001037 if (png_ptr->pass == 6) /* pass 5 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001038 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001039 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001040 png_read_push_finish_row(png_ptr);
1041 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001042
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001043 break;
1044 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001045
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001046 case 5:
1047 {
1048 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001049
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001050 for (i = 0; i < 2 && png_ptr->pass == 5; i++)
1051 {
1052 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1053 png_read_push_finish_row(png_ptr);
1054 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001055
Glenn Randers-Pehrsonbe9de0f2001-01-22 08:52:16 -06001056 if (png_ptr->pass == 6) /* skip top generated row */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001057 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001058 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001059 png_read_push_finish_row(png_ptr);
1060 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001061
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001062 break;
1063 }
1064 case 6:
1065 {
1066 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1067 png_read_push_finish_row(png_ptr);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001068
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001069 if (png_ptr->pass != 6)
1070 break;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001071
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001072 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001073 png_read_push_finish_row(png_ptr);
1074 }
1075 }
1076 }
1077 else
Guy Schalnat6d764711995-12-19 03:22:19 -06001078#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001079 {
1080 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1081 png_read_push_finish_row(png_ptr);
1082 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001083}
1084
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001085void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -06001086png_read_push_finish_row(png_structp png_ptr)
1087{
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -06001088#ifdef PNG_USE_LOCAL_ARRAYS
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001089 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001090
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001091 /* Start of interlace block */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001092 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001093
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001094 /* Offset to next interlace block */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001095 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001096
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001097 /* Start of interlace block in the y direction */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001098 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001099
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001100 /* Offset to next interlace block in the y direction */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001101 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001102
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001103 /* Height of interlace block. This is not currently used - if you need
1104 * it, uncomment it here and in png.h
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001105 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001106 */
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -06001107#endif
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001108
Guy Schalnat6d764711995-12-19 03:22:19 -06001109 png_ptr->row_number++;
1110 if (png_ptr->row_number < png_ptr->num_rows)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001111 return;
Guy Schalnat6d764711995-12-19 03:22:19 -06001112
1113 if (png_ptr->interlaced)
1114 {
1115 png_ptr->row_number = 0;
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001116 png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001117
Guy Schalnat6d764711995-12-19 03:22:19 -06001118 do
1119 {
1120 png_ptr->pass++;
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001121 if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1122 (png_ptr->pass == 3 && png_ptr->width < 3) ||
1123 (png_ptr->pass == 5 && png_ptr->width < 2))
1124 png_ptr->pass++;
1125
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -05001126 if (png_ptr->pass > 7)
1127 png_ptr->pass--;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001128
Guy Schalnat6d764711995-12-19 03:22:19 -06001129 if (png_ptr->pass >= 7)
1130 break;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001131
Guy Schalnat6d764711995-12-19 03:22:19 -06001132 png_ptr->iwidth = (png_ptr->width +
1133 png_pass_inc[png_ptr->pass] - 1 -
1134 png_pass_start[png_ptr->pass]) /
1135 png_pass_inc[png_ptr->pass];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001136
Glenn Randers-Pehrson272489d2004-08-04 06:34:52 -05001137 png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -05001138 png_ptr->iwidth) + 1;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001139
Guy Schalnat6d764711995-12-19 03:22:19 -06001140 if (png_ptr->transformations & PNG_INTERLACE)
1141 break;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001142
1143 png_ptr->num_rows = (png_ptr->height +
1144 png_pass_yinc[png_ptr->pass] - 1 -
1145 png_pass_ystart[png_ptr->pass]) /
1146 png_pass_yinc[png_ptr->pass];
1147
1148 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
Guy Schalnat6d764711995-12-19 03:22:19 -06001149 }
1150}
1151
Guy Schalnat6d764711995-12-19 03:22:19 -06001152#if defined(PNG_READ_tEXt_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001153void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001154png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1155 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001156{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001157 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001158 {
1159 png_error(png_ptr, "Out of place tEXt");
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001160 info_ptr = info_ptr; /* to quiet some compiler warnings */
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001161 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001162
Andreas Dilger47a0c421997-05-16 02:46:07 -05001163#ifdef PNG_MAX_MALLOC_64K
1164 png_ptr->skip_length = 0; /* This may not be necessary */
1165
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001166 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
Andreas Dilger47a0c421997-05-16 02:46:07 -05001167 {
1168 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001169 png_ptr->skip_length = length - (png_uint_32)65535L;
1170 length = (png_uint_32)65535L;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001171 }
1172#endif
1173
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001174 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001175 (png_size_t)(length + 1));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001176 png_ptr->current_text[length] = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001177 png_ptr->current_text_ptr = png_ptr->current_text;
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001178 png_ptr->current_text_size = (png_size_t)length;
1179 png_ptr->current_text_left = (png_size_t)length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001180 png_ptr->process_mode = PNG_READ_tEXt_MODE;
Guy Schalnat6d764711995-12-19 03:22:19 -06001181}
1182
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001183void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001184png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001185{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001186 if (png_ptr->buffer_size && png_ptr->current_text_left)
1187 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001188 png_size_t text_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001189
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001190 if (png_ptr->buffer_size < png_ptr->current_text_left)
1191 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001192
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001193 else
1194 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001195
Andreas Dilger47a0c421997-05-16 02:46:07 -05001196 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001197 png_ptr->current_text_left -= text_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001198 png_ptr->current_text_ptr += text_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001199 }
1200 if (!(png_ptr->current_text_left))
1201 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001202 png_textp text_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001203 png_charp text;
1204 png_charp key;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001205 int ret;
Guy Schalnat6d764711995-12-19 03:22:19 -06001206
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001207 if (png_ptr->buffer_size < 4)
1208 {
1209 png_push_save_buffer(png_ptr);
1210 return;
1211 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001212
Andreas Dilger47a0c421997-05-16 02:46:07 -05001213 png_push_crc_finish(png_ptr);
1214
1215#if defined(PNG_MAX_MALLOC_64K)
1216 if (png_ptr->skip_length)
1217 return;
1218#endif
Guy Schalnat6d764711995-12-19 03:22:19 -06001219
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001220 key = png_ptr->current_text;
Guy Schalnat6d764711995-12-19 03:22:19 -06001221
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001222 for (text = key; *text; text++)
1223 /* empty loop */ ;
Guy Schalnat6d764711995-12-19 03:22:19 -06001224
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001225 if (text < key + png_ptr->current_text_size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001226 text++;
1227
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001228 text_ptr = (png_textp)png_malloc(png_ptr,
1229 png_sizeof(png_text));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001230 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1231 text_ptr->key = key;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001232#ifdef PNG_iTXt_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001233 text_ptr->lang = NULL;
1234 text_ptr->lang_key = NULL;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001235#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -05001236 text_ptr->text = text;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001237
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001238 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001239
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -05001240 png_free(png_ptr, key);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001241 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001242 png_ptr->current_text = NULL;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001243
1244 if (ret)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001245 png_warning(png_ptr, "Insufficient memory to store text chunk");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001246 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001247}
1248#endif
1249
1250#if defined(PNG_READ_zTXt_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001251void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001252png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1253 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001254{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001255 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001256 {
1257 png_error(png_ptr, "Out of place zTXt");
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001258 info_ptr = info_ptr; /* to quiet some compiler warnings */
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001259 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001260
Andreas Dilger47a0c421997-05-16 02:46:07 -05001261#ifdef PNG_MAX_MALLOC_64K
1262 /* We can't handle zTXt chunks > 64K, since we don't have enough space
1263 * to be able to store the uncompressed data. Actually, the threshold
1264 * is probably around 32K, but it isn't as definite as 64K is.
1265 */
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001266 if (length > (png_uint_32)65535L)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001267 {
1268 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
1269 png_push_crc_skip(png_ptr, length);
1270 return;
1271 }
1272#endif
1273
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001274 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001275 (png_size_t)(length + 1));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001276 png_ptr->current_text[length] = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001277 png_ptr->current_text_ptr = png_ptr->current_text;
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001278 png_ptr->current_text_size = (png_size_t)length;
1279 png_ptr->current_text_left = (png_size_t)length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001280 png_ptr->process_mode = PNG_READ_zTXt_MODE;
Guy Schalnat6d764711995-12-19 03:22:19 -06001281}
1282
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001283void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001284png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001285{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001286 if (png_ptr->buffer_size && png_ptr->current_text_left)
1287 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001288 png_size_t text_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001289
Andreas Dilger47a0c421997-05-16 02:46:07 -05001290 if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001291 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001292
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001293 else
1294 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001295
Andreas Dilger47a0c421997-05-16 02:46:07 -05001296 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001297 png_ptr->current_text_left -= text_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001298 png_ptr->current_text_ptr += text_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001299 }
1300 if (!(png_ptr->current_text_left))
1301 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001302 png_textp text_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001303 png_charp text;
1304 png_charp key;
1305 int ret;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001306 png_size_t text_size, key_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001307
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001308 if (png_ptr->buffer_size < 4)
1309 {
1310 png_push_save_buffer(png_ptr);
1311 return;
1312 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001313
Andreas Dilger47a0c421997-05-16 02:46:07 -05001314 png_push_crc_finish(png_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -06001315
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001316 key = png_ptr->current_text;
Guy Schalnat6d764711995-12-19 03:22:19 -06001317
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001318 for (text = key; *text; text++)
1319 /* empty loop */ ;
Guy Schalnat6d764711995-12-19 03:22:19 -06001320
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001321 /* zTXt can't have zero text */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001322 if (text >= key + png_ptr->current_text_size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001323 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001324 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001325 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001326 return;
1327 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001328
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001329 text++;
Guy Schalnat6d764711995-12-19 03:22:19 -06001330
Andreas Dilger47a0c421997-05-16 02:46:07 -05001331 if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001332 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001333 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001334 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001335 return;
1336 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001337
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001338 text++;
Guy Schalnat6d764711995-12-19 03:22:19 -06001339
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001340 png_ptr->zstream.next_in = (png_bytep )text;
1341 png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001342 (text - key));
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001343 png_ptr->zstream.next_out = png_ptr->zbuf;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001344 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001345
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001346 key_size = text - key;
1347 text_size = 0;
1348 text = NULL;
1349 ret = Z_STREAM_END;
Guy Schalnat6d764711995-12-19 03:22:19 -06001350
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001351 while (png_ptr->zstream.avail_in)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001352 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001353 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001354 if (ret != Z_OK && ret != Z_STREAM_END)
1355 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001356 inflateReset(&png_ptr->zstream);
1357 png_ptr->zstream.avail_in = 0;
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001358 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001359 png_free(png_ptr, key);
1360 png_free(png_ptr, text);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001361 return;
1362 }
Andreas Dilger47a0c421997-05-16 02:46:07 -05001363 if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001364 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001365 if (text == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001366 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001367 text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001368 (png_ptr->zbuf_size
1369 - png_ptr->zstream.avail_out + key_size + 1));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001370
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001371 png_memcpy(text + key_size, png_ptr->zbuf,
1372 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001373
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001374 png_memcpy(text, key, key_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001375
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001376 text_size = key_size + png_ptr->zbuf_size -
1377 png_ptr->zstream.avail_out;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001378
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001379 *(text + text_size) = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001380 }
1381 else
1382 {
1383 png_charp tmp;
Guy Schalnat6d764711995-12-19 03:22:19 -06001384
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001385 tmp = text;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001386 text = (png_charp)png_malloc(png_ptr, text_size +
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001387 (png_ptr->zbuf_size
Glenn Randers-Pehrsona5fa5c92008-09-06 07:06:22 -05001388 - png_ptr->zstream.avail_out + 1));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001389
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001390 png_memcpy(text, tmp, text_size);
1391 png_free(png_ptr, tmp);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001392
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001393 png_memcpy(text + text_size, png_ptr->zbuf,
1394 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001395
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001396 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1397 *(text + text_size) = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001398 }
1399 if (ret != Z_STREAM_END)
1400 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001401 png_ptr->zstream.next_out = png_ptr->zbuf;
1402 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001403 }
1404 }
1405 else
1406 {
1407 break;
1408 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001409
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001410 if (ret == Z_STREAM_END)
1411 break;
1412 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001413
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001414 inflateReset(&png_ptr->zstream);
1415 png_ptr->zstream.avail_in = 0;
Guy Schalnat6d764711995-12-19 03:22:19 -06001416
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001417 if (ret != Z_STREAM_END)
1418 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001419 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001420 png_free(png_ptr, key);
1421 png_free(png_ptr, text);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001422 return;
1423 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001424
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001425 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001426 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001427 key = text;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001428 text += key_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001429
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001430 text_ptr = (png_textp)png_malloc(png_ptr,
1431 png_sizeof(png_text));
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001432 text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
1433 text_ptr->key = key;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001434#ifdef PNG_iTXt_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001435 text_ptr->lang = NULL;
1436 text_ptr->lang_key = NULL;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001437#endif
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001438 text_ptr->text = text;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001439
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001440 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001441
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -05001442 png_free(png_ptr, key);
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001443 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001444
1445 if (ret)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001446 png_warning(png_ptr, "Insufficient memory to store text chunk");
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001447 }
1448}
1449#endif
1450
1451#if defined(PNG_READ_iTXt_SUPPORTED)
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001452void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001453png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1454 length)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001455{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001456 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001457 {
1458 png_error(png_ptr, "Out of place iTXt");
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001459 info_ptr = info_ptr; /* to quiet some compiler warnings */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001460 }
1461
1462#ifdef PNG_MAX_MALLOC_64K
1463 png_ptr->skip_length = 0; /* This may not be necessary */
1464
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001465 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001466 {
1467 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
1468 png_ptr->skip_length = length - (png_uint_32)65535L;
1469 length = (png_uint_32)65535L;
1470 }
1471#endif
1472
1473 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001474 (png_size_t)(length + 1));
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001475 png_ptr->current_text[length] = '\0';
1476 png_ptr->current_text_ptr = png_ptr->current_text;
1477 png_ptr->current_text_size = (png_size_t)length;
1478 png_ptr->current_text_left = (png_size_t)length;
1479 png_ptr->process_mode = PNG_READ_iTXt_MODE;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001480}
1481
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001482void /* PRIVATE */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001483png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
1484{
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001485
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001486 if (png_ptr->buffer_size && png_ptr->current_text_left)
1487 {
1488 png_size_t text_size;
1489
1490 if (png_ptr->buffer_size < png_ptr->current_text_left)
1491 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001492
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001493 else
1494 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001495
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001496 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1497 png_ptr->current_text_left -= text_size;
1498 png_ptr->current_text_ptr += text_size;
1499 }
1500 if (!(png_ptr->current_text_left))
1501 {
1502 png_textp text_ptr;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001503 png_charp key;
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001504 int comp_flag;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001505 png_charp lang;
1506 png_charp lang_key;
1507 png_charp text;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001508 int ret;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001509
1510 if (png_ptr->buffer_size < 4)
1511 {
1512 png_push_save_buffer(png_ptr);
1513 return;
1514 }
1515
1516 png_push_crc_finish(png_ptr);
1517
1518#if defined(PNG_MAX_MALLOC_64K)
1519 if (png_ptr->skip_length)
1520 return;
1521#endif
1522
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001523 key = png_ptr->current_text;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001524
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001525 for (lang = key; *lang; lang++)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001526 /* empty loop */ ;
1527
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001528 if (lang < key + png_ptr->current_text_size - 3)
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001529 lang++;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001530
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001531 comp_flag = *lang++;
1532 lang++; /* skip comp_type, always zero */
1533
1534 for (lang_key = lang; *lang_key; lang_key++)
1535 /* empty loop */ ;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001536
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001537 lang_key++; /* skip NUL separator */
1538
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001539 text=lang_key;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001540
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001541 if (lang_key < key + png_ptr->current_text_size - 1)
1542 {
1543 for (; *text; text++)
1544 /* empty loop */ ;
1545 }
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001546
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001547 if (text < key + png_ptr->current_text_size)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001548 text++;
1549
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001550 text_ptr = (png_textp)png_malloc(png_ptr,
1551 png_sizeof(png_text));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001552
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001553 text_ptr->compression = comp_flag + 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001554 text_ptr->key = key;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001555 text_ptr->lang = lang;
1556 text_ptr->lang_key = lang_key;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001557 text_ptr->text = text;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001558 text_ptr->text_length = 0;
1559 text_ptr->itxt_length = png_strlen(text);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001560
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001561 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001562
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001563 png_ptr->current_text = NULL;
1564
Andreas Dilger47a0c421997-05-16 02:46:07 -05001565 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001566 if (ret)
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001567 png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001568 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001569}
1570#endif
1571
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001572/* This function is called when we haven't found a handler for this
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001573 * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
1574 * name or a critical chunk), the chunk is (currently) silently ignored.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001575 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001576void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001577png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
1578 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001579{
Glenn Randers-Pehrson895a9c92008-07-25 08:51:18 -05001580 png_uint_32 skip = 0;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001581
1582 if (!(png_ptr->chunk_name[0] & 0x20))
1583 {
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001584#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001585 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1586 PNG_HANDLE_CHUNK_ALWAYS
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001587#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001588 && png_ptr->read_user_chunk_fn == NULL
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001589#endif
1590 )
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001591#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001592 png_chunk_error(png_ptr, "unknown critical chunk");
1593
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001594 info_ptr = info_ptr; /* to quiet some compiler warnings */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001595 }
1596
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001597#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1598 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
1599 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001600#ifdef PNG_MAX_MALLOC_64K
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001601 if (length > (png_uint_32)65535L)
1602 {
1603 png_warning(png_ptr, "unknown chunk too large to fit in memory");
1604 skip = length - (png_uint_32)65535L;
1605 length = (png_uint_32)65535L;
1606 }
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001607#endif
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001608 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
1609 (png_charp)png_ptr->chunk_name,
1610 png_sizeof(png_ptr->unknown_chunk.name));
Glenn Randers-Pehrson895a9c92008-07-25 08:51:18 -05001611 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
1612 = '\0';
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001613
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001614 png_ptr->unknown_chunk.size = (png_size_t)length;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001615
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001616 if (length == 0)
1617 png_ptr->unknown_chunk.data = NULL;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001618
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001619 else
1620 {
1621 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
1622 (png_size_t)length);
1623 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
1624 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001625
Glenn Randers-Pehrsone1eff582001-04-14 20:15:41 -05001626#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001627 if (png_ptr->read_user_chunk_fn != NULL)
1628 {
1629 /* callback to user unknown chunk handler */
1630 int ret;
1631 ret = (*(png_ptr->read_user_chunk_fn))
1632 (png_ptr, &png_ptr->unknown_chunk);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001633
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001634 if (ret < 0)
1635 png_chunk_error(png_ptr, "error in user chunk");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001636
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001637 if (ret == 0)
1638 {
1639 if (!(png_ptr->chunk_name[0] & 0x20))
1640 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1641 PNG_HANDLE_CHUNK_ALWAYS)
1642 png_chunk_error(png_ptr, "unknown critical chunk");
1643 png_set_unknown_chunks(png_ptr, info_ptr,
1644 &png_ptr->unknown_chunk, 1);
1645 }
1646 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001647
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001648 else
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001649#endif
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001650 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
1651 png_free(png_ptr, png_ptr->unknown_chunk.data);
1652 png_ptr->unknown_chunk.data = NULL;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001653 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001654
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001655 else
1656#endif
1657 skip=length;
1658 png_push_crc_skip(png_ptr, skip);
Guy Schalnat6d764711995-12-19 03:22:19 -06001659}
1660
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001661void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001662png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1663{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001664 if (png_ptr->info_fn != NULL)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001665 (*(png_ptr->info_fn))(png_ptr, info_ptr);
1666}
1667
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001668void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001669png_push_have_end(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001670{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001671 if (png_ptr->end_fn != NULL)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001672 (*(png_ptr->end_fn))(png_ptr, info_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -06001673}
1674
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001675void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -06001676png_push_have_row(png_structp png_ptr, png_bytep row)
1677{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001678 if (png_ptr->row_fn != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001679 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1680 (int)png_ptr->pass);
Guy Schalnat6d764711995-12-19 03:22:19 -06001681}
1682
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001683void PNGAPI
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001684png_progressive_combine_row (png_structp png_ptr,
1685 png_bytep old_row, png_bytep new_row)
Guy Schalnat6d764711995-12-19 03:22:19 -06001686{
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -06001687#ifdef PNG_USE_LOCAL_ARRAYS
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001688 PNG_CONST int FARDATA png_pass_dsp_mask[7] =
Glenn Randers-Pehrson5e5c1e12000-11-10 12:26:19 -06001689 {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -06001690#endif
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001691 if (png_ptr == NULL)
1692 return;
1693
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -05001694 if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001695 png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
Guy Schalnat6d764711995-12-19 03:22:19 -06001696}
1697
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001698void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -06001699png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001700 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1701 png_progressive_end_ptr end_fn)
Guy Schalnat6d764711995-12-19 03:22:19 -06001702{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001703 if (png_ptr == NULL)
1704 return;
1705
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001706 png_ptr->info_fn = info_fn;
1707 png_ptr->row_fn = row_fn;
Guy Schalnat6d764711995-12-19 03:22:19 -06001708 png_ptr->end_fn = end_fn;
Guy Schalnate5a37791996-06-05 15:50:50 -05001709
Glenn Randers-Pehrson25d82242002-05-01 11:51:26 -05001710 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
Guy Schalnat6d764711995-12-19 03:22:19 -06001711}
1712
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001713png_voidp PNGAPI
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001714png_get_progressive_ptr(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001715{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001716 if (png_ptr == NULL)
1717 return (NULL);
1718
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001719 return png_ptr->io_ptr;
Guy Schalnat6d764711995-12-19 03:22:19 -06001720}
Guy Schalnat4ee97b01996-01-16 01:51:56 -06001721#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */