blob: 11055e75d7a551363a42a9d953976ced84acccb7 [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-Pehrson65a22372010-03-03 05:38:29 -06004 * Last changed in libpng 1.5.0 [March 3, 2010]
Glenn Randers-Pehrsone69b55d2010-01-01 10:29:06 -06005 * Copyright (c) 1998-2010 Glenn Randers-Pehrson
Glenn Randers-Pehrsond4366722000-06-04 14:29:29 -05006 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
Glenn Randers-Pehrson3e61d792009-06-24 09:31:28 -05008 *
Glenn Randers-Pehrsonbfbf8652009-06-26 21:46:52 -05009 * This code is released under the libpng license.
Glenn Randers-Pehrsonc332bbc2009-06-25 13:43:50 -050010 * For conditions of distribution and use, see the disclaimer
Glenn Randers-Pehrson037023b2009-06-24 10:27:36 -050011 * and license in png.h
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -060012 */
Guy Schalnat6d764711995-12-19 03:22:19 -060013
Glenn Randers-Pehrsonf9795312010-02-09 01:16:48 -060014#define PNG_EXPOSE_INTERNAL_STRUCTURES
Glenn Randers-Pehrson03f9b022009-12-04 08:40:41 -060015#define PNG_NO_PEDANTIC_WARNINGS
Guy Schalnat6d764711995-12-19 03:22:19 -060016#include "png.h"
Guy Schalnat4ee97b01996-01-16 01:51:56 -060017#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -050018#include "pngpriv.h"
Guy Schalnat4ee97b01996-01-16 01:51:56 -060019
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -050020/* Push model modes */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060021#define PNG_READ_SIG_MODE 0
22#define PNG_READ_CHUNK_MODE 1
23#define PNG_READ_IDAT_MODE 2
24#define PNG_SKIP_MODE 3
25#define PNG_READ_tEXt_MODE 4
26#define PNG_READ_zTXt_MODE 5
27#define PNG_READ_DONE_MODE 6
28#define PNG_READ_iTXt_MODE 7
29#define PNG_ERROR_MODE 8
30
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050031void PNGAPI
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060032png_process_data(png_structp png_ptr, png_infop info_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -060033 png_bytep buffer, png_size_t buffer_size)
Guy Schalnat6d764711995-12-19 03:22:19 -060034{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050035 if (png_ptr == NULL || info_ptr == NULL)
36 return;
37
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060038 png_push_restore_buffer(png_ptr, buffer, buffer_size);
Guy Schalnat6d764711995-12-19 03:22:19 -060039
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060040 while (png_ptr->buffer_size)
41 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060042 png_process_some_data(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060043 }
Guy Schalnat6d764711995-12-19 03:22:19 -060044}
45
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060046/* What we do with the incoming data depends on what we were previously
47 * doing before we ran out of data...
48 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -050049void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060050png_process_some_data(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -060051{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050052 if (png_ptr == NULL)
53 return;
54
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060055 switch (png_ptr->process_mode)
56 {
57 case PNG_READ_SIG_MODE:
58 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060059 png_push_read_sig(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060060 break;
61 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050062
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060063 case PNG_READ_CHUNK_MODE:
64 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060065 png_push_read_chunk(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060066 break;
67 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050068
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060069 case PNG_READ_IDAT_MODE:
70 {
Guy Schalnate5a37791996-06-05 15:50:50 -050071 png_push_read_IDAT(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060072 break;
73 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050074
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -050075#ifdef PNG_READ_tEXt_SUPPORTED
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060076 case PNG_READ_tEXt_MODE:
77 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060078 png_push_read_tEXt(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060079 break;
80 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050081
Guy Schalnat6d764711995-12-19 03:22:19 -060082#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -050083#ifdef PNG_READ_zTXt_SUPPORTED
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060084 case PNG_READ_zTXt_MODE:
85 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -060086 png_push_read_zTXt(png_ptr, info_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060087 break;
88 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050089
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060090#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -050091#ifdef PNG_READ_iTXt_SUPPORTED
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060092 case PNG_READ_iTXt_MODE:
93 {
94 png_push_read_iTXt(png_ptr, info_ptr);
95 break;
96 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -050097
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -060098#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -060099 case PNG_SKIP_MODE:
100 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500101 png_push_crc_finish(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600102 break;
103 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500104
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600105 default:
106 {
107 png_ptr->buffer_size = 0;
108 break;
109 }
110 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600111}
112
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600113/* Read any remaining signature bytes from the stream and compare them with
114 * the correct PNG signature. It is possible that this routine is called
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -0500115 * with bytes already read from the signature, either because they have been
116 * checked by the calling application, or because of multiple calls to this
117 * routine.
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600118 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500119void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600120png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600121{
Andreas Dilger47a0c421997-05-16 02:46:07 -0500122 png_size_t num_checked = png_ptr->sig_bytes,
123 num_to_check = 8 - num_checked;
Guy Schalnat6d764711995-12-19 03:22:19 -0600124
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600125 if (png_ptr->buffer_size < num_to_check)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600126 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600127 num_to_check = png_ptr->buffer_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600128 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600129
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600130 png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600131 num_to_check);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500132 png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
Guy Schalnat6d764711995-12-19 03:22:19 -0600133
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600134 if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600135 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600136 if (num_checked < 4 &&
137 png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
138 png_error(png_ptr, "Not a PNG file");
139 else
140 png_error(png_ptr, "PNG file corrupted by ASCII conversion");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600141 }
142 else
143 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600144 if (png_ptr->sig_bytes >= 8)
145 {
146 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
147 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600148 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600149}
150
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500151void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600152png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600153{
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500154 PNG_IHDR;
155 PNG_IDAT;
156 PNG_IEND;
157 PNG_PLTE;
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500158#ifdef PNG_READ_bKGD_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500159 PNG_bKGD;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600160#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500161#ifdef PNG_READ_cHRM_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500162 PNG_cHRM;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600163#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500164#ifdef PNG_READ_gAMA_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500165 PNG_gAMA;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600166#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500167#ifdef PNG_READ_hIST_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500168 PNG_hIST;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600169#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500170#ifdef PNG_READ_iCCP_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500171 PNG_iCCP;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600172#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500173#ifdef PNG_READ_iTXt_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500174 PNG_iTXt;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600175#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500176#ifdef PNG_READ_oFFs_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500177 PNG_oFFs;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600178#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500179#ifdef PNG_READ_pCAL_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500180 PNG_pCAL;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600181#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500182#ifdef PNG_READ_pHYs_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500183 PNG_pHYs;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600184#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500185#ifdef PNG_READ_sBIT_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500186 PNG_sBIT;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600187#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500188#ifdef PNG_READ_sCAL_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500189 PNG_sCAL;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600190#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500191#ifdef PNG_READ_sRGB_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500192 PNG_sRGB;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600193#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500194#ifdef PNG_READ_sPLT_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500195 PNG_sPLT;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600196#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500197#ifdef PNG_READ_tEXt_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500198 PNG_tEXt;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600199#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500200#ifdef PNG_READ_tIME_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500201 PNG_tIME;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600202#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500203#ifdef PNG_READ_tRNS_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500204 PNG_tRNS;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600205#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500206#ifdef PNG_READ_zTXt_SUPPORTED
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500207 PNG_zTXt;
Glenn Randers-Pehrson074af5e1999-11-28 23:32:18 -0600208#endif
Glenn Randers-Pehrsona2567be2009-10-19 20:31:31 -0500209
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600210 /* First we make sure we have enough data for the 4 byte chunk name
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600211 * and the 4 byte chunk length before proceeding with decoding the
212 * chunk data. To fully decode each of these chunks, we also make
213 * sure we have enough data in the buffer for the 4 byte CRC at the
214 * end of every chunk (except IDAT, which is handled separately).
215 */
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600216 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600217 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600218 png_byte chunk_length[4];
Guy Schalnat6d764711995-12-19 03:22:19 -0600219
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600220 if (png_ptr->buffer_size < 8)
221 {
222 png_push_save_buffer(png_ptr);
223 return;
224 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600225
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600226 png_push_fill_buffer(png_ptr, chunk_length, 4);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500227 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600228 png_reset_crc(png_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500229 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
Glenn Randers-Pehrsoneb580912008-07-30 14:47:09 -0500230 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600231 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600232 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600233
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500234 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600235 if (png_ptr->mode & PNG_AFTER_IDAT)
236 png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500237
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600238 if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600239 {
Glenn Randers-Pehrsoneb580912008-07-30 14:47:09 -0500240 if (png_ptr->push_length != 13)
241 png_error(png_ptr, "Invalid IHDR length");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500242
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500243 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
244 {
245 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600246 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500247 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500248
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600249 png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600250 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500251
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500252 else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
253 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500254 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
255 {
256 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500257 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500258 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500259
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500260 png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
261
262 png_ptr->process_mode = PNG_READ_DONE_MODE;
263 png_push_have_end(png_ptr, info_ptr);
264 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500265
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500266#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
267 else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
268 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500269 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
270 {
271 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500272 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500273 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500274
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500275 if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
276 png_ptr->mode |= PNG_HAVE_IDAT;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500277
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500278 png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500279
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500280 if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
281 png_ptr->mode |= PNG_HAVE_PLTE;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500282
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500283 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
284 {
285 if (!(png_ptr->mode & PNG_HAVE_IHDR))
286 png_error(png_ptr, "Missing IHDR before IDAT");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500287
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500288 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600289 !(png_ptr->mode & PNG_HAVE_PLTE))
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500290 png_error(png_ptr, "Missing PLTE before IDAT");
291 }
292 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500293
Glenn Randers-Pehrsond029a752004-08-09 21:50:32 -0500294#endif
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600295 else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600296 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500297 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
298 {
299 png_push_save_buffer(png_ptr);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600300 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500301 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600302 png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600303 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500304
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500305 else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600306 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600307 /* If we reach an IDAT chunk, this means we have read all of the
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600308 * header chunks, and we can start reading the image (or if this
309 * is called after the image has been read - we have an error).
310 */
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500311
312 if (!(png_ptr->mode & PNG_HAVE_IHDR))
313 png_error(png_ptr, "Missing IHDR before IDAT");
314
315 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
316 !(png_ptr->mode & PNG_HAVE_PLTE))
317 png_error(png_ptr, "Missing PLTE before IDAT");
Glenn Randers-Pehrson73d57cb2002-03-25 18:49:08 -0600318
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600319 if (png_ptr->mode & PNG_HAVE_IDAT)
320 {
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500321 if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500322 if (png_ptr->push_length == 0)
323 return;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600324
325 if (png_ptr->mode & PNG_AFTER_IDAT)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500326 png_benign_error(png_ptr, "Too many IDATs found");
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600327 }
328
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600329 png_ptr->idat_size = png_ptr->push_length;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600330 png_ptr->mode |= PNG_HAVE_IDAT;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600331 png_ptr->process_mode = PNG_READ_IDAT_MODE;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600332 png_push_have_info(png_ptr, info_ptr);
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600333 png_ptr->zstream.avail_out =
334 (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
335 png_ptr->iwidth) + 1;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600336 png_ptr->zstream.next_out = png_ptr->row_buf;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600337 return;
338 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500339
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500340#ifdef PNG_READ_gAMA_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600341 else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
342 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500343 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
344 {
345 png_push_save_buffer(png_ptr);
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600346 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500347 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500348
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600349 png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600350 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500351
Guy Schalnat6d764711995-12-19 03:22:19 -0600352#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500353#ifdef PNG_READ_sBIT_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600354 else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600355 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500356 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
357 {
358 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600359 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500360 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500361
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600362 png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600363 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500364
Guy Schalnat6d764711995-12-19 03:22:19 -0600365#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500366#ifdef PNG_READ_cHRM_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600367 else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600368 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500369 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
370 {
371 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600372 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500373 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500374
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600375 png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600376 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500377
Guy Schalnat6d764711995-12-19 03:22:19 -0600378#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500379#ifdef PNG_READ_sRGB_SUPPORTED
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600380 else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
381 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500382 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
383 {
384 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600385 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500386 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500387
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600388 png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
389 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500390
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -0600391#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500392#ifdef PNG_READ_iCCP_SUPPORTED
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600393 else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
394 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500395 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
396 {
397 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600398 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500399 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500400
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600401 png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
402 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500403
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600404#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500405#ifdef PNG_READ_sPLT_SUPPORTED
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600406 else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
407 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500408 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
409 {
410 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600411 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500412 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500413
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600414 png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
415 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500416
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600417#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500418#ifdef PNG_READ_tRNS_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600419 else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600420 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500421 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
422 {
423 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600424 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500425 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500426
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600427 png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600428 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500429
Guy Schalnat6d764711995-12-19 03:22:19 -0600430#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500431#ifdef PNG_READ_bKGD_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600432 else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600433 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500434 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
435 {
436 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600437 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500438 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500439
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600440 png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600441 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500442
Guy Schalnat6d764711995-12-19 03:22:19 -0600443#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500444#ifdef PNG_READ_hIST_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600445 else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600446 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500447 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
448 {
449 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600450 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500451 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500452
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600453 png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600454 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500455
Guy Schalnat6d764711995-12-19 03:22:19 -0600456#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500457#ifdef PNG_READ_pHYs_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600458 else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600459 {
460 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
461 {
462 png_push_save_buffer(png_ptr);
463 return;
464 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500465
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600466 png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600467 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500468
Guy Schalnat6d764711995-12-19 03:22:19 -0600469#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500470#ifdef PNG_READ_oFFs_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600471 else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600472 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500473 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
474 {
475 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600476 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500477 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500478
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600479 png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600480 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600481#endif
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500482
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500483#ifdef PNG_READ_pCAL_SUPPORTED
Andreas Dilger47a0c421997-05-16 02:46:07 -0500484 else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
485 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500486 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
487 {
488 png_push_save_buffer(png_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500489 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500490 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500491
Andreas Dilger47a0c421997-05-16 02:46:07 -0500492 png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
493 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500494
Andreas Dilger47a0c421997-05-16 02:46:07 -0500495#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500496#ifdef PNG_READ_sCAL_SUPPORTED
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600497 else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
498 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500499 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
500 {
501 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600502 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500503 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500504
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600505 png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
506 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500507
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600508#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500509#ifdef PNG_READ_tIME_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600510 else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600511 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500512 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
513 {
514 png_push_save_buffer(png_ptr);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600515 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500516 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500517
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600518 png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600519 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500520
Guy Schalnat6d764711995-12-19 03:22:19 -0600521#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500522#ifdef PNG_READ_tEXt_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600523 else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600524 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500525 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
526 {
527 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500528 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500529 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500530
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600531 png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600532 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500533
Guy Schalnat6d764711995-12-19 03:22:19 -0600534#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500535#ifdef PNG_READ_zTXt_SUPPORTED
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600536 else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600537 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500538 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
539 {
540 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500541 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500542 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500543
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600544 png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600545 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500546
Guy Schalnat6d764711995-12-19 03:22:19 -0600547#endif
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500548#ifdef PNG_READ_iTXt_SUPPORTED
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -0600549 else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600550 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500551 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
552 {
553 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500554 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500555 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500556
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600557 png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
558 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500559
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -0600560#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600561 else
562 {
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500563 if (png_ptr->push_length + 4 > png_ptr->buffer_size)
564 {
565 png_push_save_buffer(png_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500566 return;
Glenn Randers-Pehrson79084212008-08-04 13:31:41 -0500567 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600568 png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600569 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600570
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600571 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
Guy Schalnat6d764711995-12-19 03:22:19 -0600572}
573
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500574void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500575png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
Guy Schalnat6d764711995-12-19 03:22:19 -0600576{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600577 png_ptr->process_mode = PNG_SKIP_MODE;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500578 png_ptr->skip_length = skip;
Guy Schalnat6d764711995-12-19 03:22:19 -0600579}
580
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500581void /* PRIVATE */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500582png_push_crc_finish(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600583{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600584 if (png_ptr->skip_length && png_ptr->save_buffer_size)
585 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500586 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600587
Andreas Dilger47a0c421997-05-16 02:46:07 -0500588 if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
589 save_size = (png_size_t)png_ptr->skip_length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600590 else
591 save_size = png_ptr->save_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600592
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600593 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600594
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600595 png_ptr->skip_length -= save_size;
596 png_ptr->buffer_size -= save_size;
597 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500598 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600599 }
600 if (png_ptr->skip_length && png_ptr->current_buffer_size)
601 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500602 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600603
Andreas Dilger47a0c421997-05-16 02:46:07 -0500604 if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
605 save_size = (png_size_t)png_ptr->skip_length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600606 else
607 save_size = png_ptr->current_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600608
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600609 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600610
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600611 png_ptr->skip_length -= save_size;
612 png_ptr->buffer_size -= save_size;
613 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500614 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600615 }
616 if (!png_ptr->skip_length)
617 {
618 if (png_ptr->buffer_size < 4)
619 {
620 png_push_save_buffer(png_ptr);
621 return;
622 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600623
624 png_crc_finish(png_ptr, 0);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500625 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600626 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600627}
628
Glenn Randers-Pehrson25d82242002-05-01 11:51:26 -0500629void PNGAPI
Andreas Dilger47a0c421997-05-16 02:46:07 -0500630png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600631{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600632 png_bytep ptr;
Guy Schalnat6d764711995-12-19 03:22:19 -0600633
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500634 if (png_ptr == NULL)
635 return;
636
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600637 ptr = buffer;
638 if (png_ptr->save_buffer_size)
639 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500640 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600641
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600642 if (length < png_ptr->save_buffer_size)
643 save_size = length;
644 else
645 save_size = png_ptr->save_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600646
Andreas Dilger47a0c421997-05-16 02:46:07 -0500647 png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600648 length -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500649 ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600650 png_ptr->buffer_size -= save_size;
651 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500652 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600653 }
654 if (length && png_ptr->current_buffer_size)
655 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500656 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600657
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600658 if (length < png_ptr->current_buffer_size)
659 save_size = length;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500660
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600661 else
662 save_size = png_ptr->current_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600663
Andreas Dilger47a0c421997-05-16 02:46:07 -0500664 png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600665 png_ptr->buffer_size -= save_size;
666 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500667 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600668 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600669}
670
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500671void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600672png_push_save_buffer(png_structp png_ptr)
673{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600674 if (png_ptr->save_buffer_size)
675 {
676 if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
677 {
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500678 png_size_t i, istop;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600679 png_bytep sp;
680 png_bytep dp;
Guy Schalnat6d764711995-12-19 03:22:19 -0600681
Glenn Randers-Pehrson896239b1998-04-21 15:03:57 -0500682 istop = png_ptr->save_buffer_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600683 for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600684 i < istop; i++, sp++, dp++)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600685 {
686 *dp = *sp;
687 }
688 }
689 }
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600690 if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600691 png_ptr->save_buffer_max)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600692 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500693 png_size_t new_max;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600694 png_bytep old_buffer;
Guy Schalnat6d764711995-12-19 03:22:19 -0600695
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600696 if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600697 (png_ptr->current_buffer_size + 256))
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600698 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600699 png_error(png_ptr, "Potential overflow of save_buffer");
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600700 }
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600701
Glenn Randers-Pehrsone00ed362010-02-07 22:42:58 -0600702 new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600703 old_buffer = png_ptr->save_buffer;
Glenn Randers-Pehrsonf1eb9182010-02-08 15:36:41 -0600704 png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600705 (png_size_t)new_max);
Glenn Randers-Pehrsonf1eb9182010-02-08 15:36:41 -0600706 if (png_ptr->save_buffer == NULL)
707 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600708 png_free(png_ptr, old_buffer);
709 png_error(png_ptr, "Insufficient memory for save_buffer");
Glenn Randers-Pehrsonf1eb9182010-02-08 15:36:41 -0600710 }
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -0500711 png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
712 png_free(png_ptr, old_buffer);
713 png_ptr->save_buffer_max = new_max;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600714 }
715 if (png_ptr->current_buffer_size)
716 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500717 png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
718 png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600719 png_ptr->save_buffer_size += png_ptr->current_buffer_size;
720 png_ptr->current_buffer_size = 0;
721 }
722 png_ptr->save_buffer_ptr = png_ptr->save_buffer;
723 png_ptr->buffer_size = 0;
Guy Schalnat6d764711995-12-19 03:22:19 -0600724}
725
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500726void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600727png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500728 png_size_t buffer_length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600729{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600730 png_ptr->current_buffer = buffer;
731 png_ptr->current_buffer_size = buffer_length;
732 png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
733 png_ptr->current_buffer_ptr = png_ptr->current_buffer;
Guy Schalnat6d764711995-12-19 03:22:19 -0600734}
735
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500736void /* PRIVATE */
Guy Schalnate5a37791996-06-05 15:50:50 -0500737png_push_read_IDAT(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -0600738{
Glenn Randers-Pehrson9bf60832009-09-20 13:37:50 -0500739 PNG_IDAT;
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600740 if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600741 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600742 png_byte chunk_length[4];
Guy Schalnat6d764711995-12-19 03:22:19 -0600743
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600744 if (png_ptr->buffer_size < 8)
745 {
746 png_push_save_buffer(png_ptr);
747 return;
748 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600749
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600750 png_push_fill_buffer(png_ptr, chunk_length, 4);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500751 png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600752 png_reset_crc(png_ptr);
Andreas Dilger47a0c421997-05-16 02:46:07 -0500753 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600754 png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600755
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500756 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600757 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500758 png_ptr->process_mode = PNG_READ_CHUNK_MODE;
Guy Schalnate5a37791996-06-05 15:50:50 -0500759 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600760 png_error(png_ptr, "Not enough compressed data");
761 return;
762 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600763
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600764 png_ptr->idat_size = png_ptr->push_length;
765 }
766 if (png_ptr->idat_size && png_ptr->save_buffer_size)
767 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500768 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600769
Andreas Dilger47a0c421997-05-16 02:46:07 -0500770 if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600771 {
772 save_size = (png_size_t)png_ptr->idat_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500773
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500774 /* Check for overflow */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500775 if ((png_uint_32)save_size != png_ptr->idat_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600776 png_error(png_ptr, "save_size overflowed in pngpread");
777 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600778 else
779 save_size = png_ptr->save_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600780
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600781 png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500782
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500783 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
784 png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500785
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600786 png_ptr->idat_size -= save_size;
787 png_ptr->buffer_size -= save_size;
788 png_ptr->save_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500789 png_ptr->save_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600790 }
791 if (png_ptr->idat_size && png_ptr->current_buffer_size)
792 {
Andreas Dilger47a0c421997-05-16 02:46:07 -0500793 png_size_t save_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600794
Andreas Dilger47a0c421997-05-16 02:46:07 -0500795 if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600796 {
797 save_size = (png_size_t)png_ptr->idat_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500798
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500799 /* Check for overflow */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500800 if ((png_uint_32)save_size != png_ptr->idat_size)
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -0600801 png_error(png_ptr, "save_size overflowed in pngpread");
802 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600803 else
804 save_size = png_ptr->current_buffer_size;
Guy Schalnat6d764711995-12-19 03:22:19 -0600805
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600806 png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500807 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600808 png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
Guy Schalnat6d764711995-12-19 03:22:19 -0600809
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600810 png_ptr->idat_size -= save_size;
811 png_ptr->buffer_size -= save_size;
812 png_ptr->current_buffer_size -= save_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -0500813 png_ptr->current_buffer_ptr += save_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600814 }
815 if (!png_ptr->idat_size)
816 {
817 if (png_ptr->buffer_size < 4)
818 {
819 png_push_save_buffer(png_ptr);
820 return;
821 }
822
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600823 png_crc_finish(png_ptr, 0);
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -0600824 png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500825 png_ptr->mode |= PNG_AFTER_IDAT;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600826 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600827}
828
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500829void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600830png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
Andreas Dilger47a0c421997-05-16 02:46:07 -0500831 png_size_t buffer_length)
Guy Schalnat6d764711995-12-19 03:22:19 -0600832{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600833 int ret;
Guy Schalnat6d764711995-12-19 03:22:19 -0600834
Guy Schalnate5a37791996-06-05 15:50:50 -0500835 if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500836 png_benign_error(png_ptr, "Extra compression data");
Guy Schalnat6d764711995-12-19 03:22:19 -0600837
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600838 png_ptr->zstream.next_in = buffer;
839 png_ptr->zstream.avail_in = (uInt)buffer_length;
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -0500840 for (;;)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600841 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600842 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500843 if (ret != Z_OK)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600844 {
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500845 if (ret == Z_STREAM_END)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600846 {
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500847 if (png_ptr->zstream.avail_in)
Glenn Randers-Pehrson6bc53be2006-06-16 07:52:03 -0500848 png_benign_error(png_ptr, "Extra compressed data");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500849
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500850 if (!(png_ptr->zstream.avail_out))
851 {
852 png_push_process_row(png_ptr);
853 }
Andreas Dilger47a0c421997-05-16 02:46:07 -0500854
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500855 png_ptr->mode |= PNG_AFTER_IDAT;
856 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
857 break;
858 }
859 else if (ret == Z_BUF_ERROR)
860 break;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500861
Glenn Randers-Pehrson104622b2000-05-29 08:58:03 -0500862 else
863 png_error(png_ptr, "Decompression Error");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600864 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600865 if (!(png_ptr->zstream.avail_out))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600866 {
Glenn Randers-Pehrsond020e9d2002-06-28 09:34:00 -0500867 if ((
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500868#ifdef PNG_READ_INTERLACING_SUPPORTED
Glenn Randers-Pehrsond020e9d2002-06-28 09:34:00 -0500869 png_ptr->interlaced && png_ptr->pass > 6) ||
870 (!png_ptr->interlaced &&
871#endif
Glenn Randers-Pehrsondff799e2004-08-07 21:42:49 -0500872 png_ptr->row_number == png_ptr->num_rows))
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500873 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600874 if (png_ptr->zstream.avail_in)
875 png_warning(png_ptr, "Too much data in IDAT chunks");
876 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
877 break;
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -0500878 }
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600879 png_push_process_row(png_ptr);
Glenn Randers-Pehrsone3f3c4e2010-02-07 18:08:50 -0600880 png_ptr->zstream.avail_out =
881 (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
882 png_ptr->iwidth) + 1;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -0600883 png_ptr->zstream.next_out = png_ptr->row_buf;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600884 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500885
Andreas Dilger47a0c421997-05-16 02:46:07 -0500886 else
887 break;
888 }
Guy Schalnat6d764711995-12-19 03:22:19 -0600889}
890
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -0500891void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -0600892png_push_process_row(png_structp png_ptr)
893{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600894 png_ptr->row_info.color_type = png_ptr->color_type;
Guy Schalnat6d764711995-12-19 03:22:19 -0600895 png_ptr->row_info.width = png_ptr->iwidth;
896 png_ptr->row_info.channels = png_ptr->channels;
897 png_ptr->row_info.bit_depth = png_ptr->bit_depth;
898 png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -0600899
Glenn Randers-Pehrson272489d2004-08-04 06:34:52 -0500900 png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
901 png_ptr->row_info.width);
Guy Schalnat6d764711995-12-19 03:22:19 -0600902
Guy Schalnate5a37791996-06-05 15:50:50 -0500903 png_read_filter_row(png_ptr, &(png_ptr->row_info),
904 png_ptr->row_buf + 1, png_ptr->prev_row + 1,
905 (int)(png_ptr->row_buf[0]));
Guy Schalnat6d764711995-12-19 03:22:19 -0600906
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500907 png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
Guy Schalnat6d764711995-12-19 03:22:19 -0600908
Glenn Randers-Pehrson73b029f2004-11-26 17:28:09 -0600909 if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
Guy Schalnat6d764711995-12-19 03:22:19 -0600910 png_do_read_transformations(png_ptr);
911
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -0500912#ifdef PNG_READ_INTERLACING_SUPPORTED
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500913 /* Blow up interlaced rows to full size */
Andreas Dilger47a0c421997-05-16 02:46:07 -0500914 if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600915 {
916 if (png_ptr->pass < 6)
Glenn Randers-Pehrson231e6872001-01-12 15:13:06 -0600917/* old interface (pre-1.0.9):
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600918 png_do_read_interlace(&(png_ptr->row_info),
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -0600919 png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
Glenn Randers-Pehrson231e6872001-01-12 15:13:06 -0600920 */
921 png_do_read_interlace(png_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -0600922
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600923 switch (png_ptr->pass)
924 {
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600925 case 0:
926 {
927 int i;
928 for (i = 0; i < 8 && png_ptr->pass == 0; i++)
929 {
930 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500931 png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600932 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500933
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500934 if (png_ptr->pass == 2) /* Pass 1 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600935 {
936 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
937 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500938 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600939 png_read_push_finish_row(png_ptr);
940 }
941 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500942
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500943 if (png_ptr->pass == 4 && png_ptr->height <= 4)
944 {
945 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
946 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500947 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -0500948 png_read_push_finish_row(png_ptr);
949 }
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500950 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500951
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500952 if (png_ptr->pass == 6 && png_ptr->height <= 4)
953 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500954 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -0500955 png_read_push_finish_row(png_ptr);
956 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500957
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600958 break;
959 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500960
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600961 case 1:
962 {
963 int i;
964 for (i = 0; i < 8 && png_ptr->pass == 1; i++)
965 {
966 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
967 png_read_push_finish_row(png_ptr);
968 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500969
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500970 if (png_ptr->pass == 2) /* Skip top 4 generated rows */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600971 {
972 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
973 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500974 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600975 png_read_push_finish_row(png_ptr);
976 }
977 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500978
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600979 break;
980 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500981
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600982 case 2:
983 {
984 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500985
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600986 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
987 {
988 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
989 png_read_push_finish_row(png_ptr);
990 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500991
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600992 for (i = 0; i < 4 && png_ptr->pass == 2; i++)
993 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -0500994 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -0600995 png_read_push_finish_row(png_ptr);
996 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -0500997
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -0500998 if (png_ptr->pass == 4) /* Pass 3 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -0600999 {
1000 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1001 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001002 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001003 png_read_push_finish_row(png_ptr);
1004 }
1005 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001006
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001007 break;
1008 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001009
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001010 case 3:
1011 {
1012 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001013
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001014 for (i = 0; i < 4 && png_ptr->pass == 3; i++)
1015 {
1016 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1017 png_read_push_finish_row(png_ptr);
1018 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001019
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001020 if (png_ptr->pass == 4) /* Skip top two generated rows */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001021 {
1022 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1023 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001024 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001025 png_read_push_finish_row(png_ptr);
1026 }
1027 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001028
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001029 break;
1030 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001031
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001032 case 4:
1033 {
1034 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001035
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001036 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1037 {
1038 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1039 png_read_push_finish_row(png_ptr);
1040 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001041
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001042 for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1043 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001044 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001045 png_read_push_finish_row(png_ptr);
1046 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001047
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001048 if (png_ptr->pass == 6) /* Pass 5 might be empty */
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001049 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001050 png_push_have_row(png_ptr, NULL);
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001051 png_read_push_finish_row(png_ptr);
1052 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001053
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001054 break;
1055 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001056
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001057 case 5:
1058 {
1059 int i;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001060
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001061 for (i = 0; i < 2 && png_ptr->pass == 5; i++)
1062 {
1063 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1064 png_read_push_finish_row(png_ptr);
1065 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001066
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001067 if (png_ptr->pass == 6) /* Skip top generated row */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001068 {
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001069 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001070 png_read_push_finish_row(png_ptr);
1071 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001072
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001073 break;
1074 }
1075 case 6:
1076 {
1077 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1078 png_read_push_finish_row(png_ptr);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001079
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001080 if (png_ptr->pass != 6)
1081 break;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001082
Glenn Randers-Pehrsonbeb572e2006-08-19 13:59:24 -05001083 png_push_have_row(png_ptr, NULL);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001084 png_read_push_finish_row(png_ptr);
1085 }
1086 }
1087 }
1088 else
Guy Schalnat6d764711995-12-19 03:22:19 -06001089#endif
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001090 {
1091 png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1092 png_read_push_finish_row(png_ptr);
1093 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001094}
1095
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001096void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -06001097png_read_push_finish_row(png_structp png_ptr)
1098{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001099 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001100
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001101 /* Start of interlace block */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001102 PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001103
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001104 /* Offset to next interlace block */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001105 PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001106
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001107 /* Start of interlace block in the y direction */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001108 PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001109
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001110 /* Offset to next interlace block in the y direction */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001111 PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001112
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001113 /* Height of interlace block. This is not currently used - if you need
1114 * it, uncomment it here and in png.h
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001115 PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
Glenn Randers-Pehrson5379b241999-11-27 10:22:33 -06001116 */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001117
Guy Schalnat6d764711995-12-19 03:22:19 -06001118 png_ptr->row_number++;
1119 if (png_ptr->row_number < png_ptr->num_rows)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001120 return;
Guy Schalnat6d764711995-12-19 03:22:19 -06001121
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001122#ifdef PNG_READ_INTERLACING_SUPPORTED
Guy Schalnat6d764711995-12-19 03:22:19 -06001123 if (png_ptr->interlaced)
1124 {
1125 png_ptr->row_number = 0;
Glenn Randers-Pehrsona31c74f2009-05-18 15:52:01 -05001126 png_memset(png_ptr->prev_row, 0,
1127 png_ptr->rowbytes + 1);
Guy Schalnat6d764711995-12-19 03:22:19 -06001128 do
1129 {
1130 png_ptr->pass++;
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001131 if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1132 (png_ptr->pass == 3 && png_ptr->width < 3) ||
1133 (png_ptr->pass == 5 && png_ptr->width < 2))
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001134 png_ptr->pass++;
Glenn Randers-Pehrsoncdf140b2001-01-15 12:22:32 -06001135
Glenn Randers-Pehrson859665d2002-08-06 18:06:11 -05001136 if (png_ptr->pass > 7)
1137 png_ptr->pass--;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001138
Guy Schalnat6d764711995-12-19 03:22:19 -06001139 if (png_ptr->pass >= 7)
1140 break;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001141
Guy Schalnat6d764711995-12-19 03:22:19 -06001142 png_ptr->iwidth = (png_ptr->width +
1143 png_pass_inc[png_ptr->pass] - 1 -
1144 png_pass_start[png_ptr->pass]) /
1145 png_pass_inc[png_ptr->pass];
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001146
Guy Schalnat6d764711995-12-19 03:22:19 -06001147 if (png_ptr->transformations & PNG_INTERLACE)
1148 break;
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001149
1150 png_ptr->num_rows = (png_ptr->height +
1151 png_pass_yinc[png_ptr->pass] - 1 -
1152 png_pass_ystart[png_ptr->pass]) /
1153 png_pass_yinc[png_ptr->pass];
1154
1155 } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
Guy Schalnat6d764711995-12-19 03:22:19 -06001156 }
Glenn Randers-Pehrsona31c74f2009-05-18 15:52:01 -05001157#endif /* PNG_READ_INTERLACING_SUPPORTED */
Guy Schalnat6d764711995-12-19 03:22:19 -06001158}
1159
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001160#ifdef PNG_READ_tEXt_SUPPORTED
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001161void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001162png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001163 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001164{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001165 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001166 {
1167 png_error(png_ptr, "Out of place tEXt");
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001168 info_ptr = info_ptr; /* To quiet some compiler warnings */
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001169 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001170
Andreas Dilger47a0c421997-05-16 02:46:07 -05001171#ifdef PNG_MAX_MALLOC_64K
1172 png_ptr->skip_length = 0; /* This may not be necessary */
1173
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001174 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
Andreas Dilger47a0c421997-05-16 02:46:07 -05001175 {
1176 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001177 png_ptr->skip_length = length - (png_uint_32)65535L;
1178 length = (png_uint_32)65535L;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001179 }
1180#endif
1181
Glenn Randers-Pehrson5c6aeb21998-12-29 11:47:59 -06001182 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001183 (png_size_t)(length + 1));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001184 png_ptr->current_text[length] = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001185 png_ptr->current_text_ptr = png_ptr->current_text;
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001186 png_ptr->current_text_size = (png_size_t)length;
1187 png_ptr->current_text_left = (png_size_t)length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001188 png_ptr->process_mode = PNG_READ_tEXt_MODE;
Guy Schalnat6d764711995-12-19 03:22:19 -06001189}
1190
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001191void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001192png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001193{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001194 if (png_ptr->buffer_size && png_ptr->current_text_left)
1195 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001196 png_size_t text_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001197
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001198 if (png_ptr->buffer_size < png_ptr->current_text_left)
1199 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001200
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001201 else
1202 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001203
Andreas Dilger47a0c421997-05-16 02:46:07 -05001204 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001205 png_ptr->current_text_left -= text_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001206 png_ptr->current_text_ptr += text_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001207 }
1208 if (!(png_ptr->current_text_left))
1209 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001210 png_textp text_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001211 png_charp text;
1212 png_charp key;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001213 int ret;
Guy Schalnat6d764711995-12-19 03:22:19 -06001214
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001215 if (png_ptr->buffer_size < 4)
1216 {
1217 png_push_save_buffer(png_ptr);
1218 return;
1219 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001220
Andreas Dilger47a0c421997-05-16 02:46:07 -05001221 png_push_crc_finish(png_ptr);
1222
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001223#ifdef PNG_MAX_MALLOC_64K
Andreas Dilger47a0c421997-05-16 02:46:07 -05001224 if (png_ptr->skip_length)
1225 return;
1226#endif
Guy Schalnat6d764711995-12-19 03:22:19 -06001227
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001228 key = png_ptr->current_text;
Guy Schalnat6d764711995-12-19 03:22:19 -06001229
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001230 for (text = key; *text; text++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001231 /* Empty loop */ ;
Guy Schalnat6d764711995-12-19 03:22:19 -06001232
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001233 if (text < key + png_ptr->current_text_size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001234 text++;
1235
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001236 text_ptr = (png_textp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001237 png_sizeof(png_text));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001238 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1239 text_ptr->key = key;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001240#ifdef PNG_iTXt_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001241 text_ptr->lang = NULL;
1242 text_ptr->lang_key = NULL;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001243#endif
Andreas Dilger47a0c421997-05-16 02:46:07 -05001244 text_ptr->text = text;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001245
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001246 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001247
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -05001248 png_free(png_ptr, key);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001249 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001250 png_ptr->current_text = NULL;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001251
1252 if (ret)
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001253 png_warning(png_ptr, "Insufficient memory to store text chunk");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001254 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001255}
1256#endif
1257
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001258#ifdef PNG_READ_zTXt_SUPPORTED
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001259void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001260png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1261 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001262{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001263 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001264 {
1265 png_error(png_ptr, "Out of place zTXt");
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001266 info_ptr = info_ptr; /* To quiet some compiler warnings */
Glenn Randers-Pehrsona357b991998-02-08 20:56:40 -06001267 }
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001268
Andreas Dilger47a0c421997-05-16 02:46:07 -05001269#ifdef PNG_MAX_MALLOC_64K
1270 /* We can't handle zTXt chunks > 64K, since we don't have enough space
1271 * to be able to store the uncompressed data. Actually, the threshold
1272 * is probably around 32K, but it isn't as definite as 64K is.
1273 */
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001274 if (length > (png_uint_32)65535L)
Andreas Dilger47a0c421997-05-16 02:46:07 -05001275 {
1276 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
1277 png_push_crc_skip(png_ptr, length);
1278 return;
1279 }
1280#endif
1281
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001282 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001283 (png_size_t)(length + 1));
Andreas Dilger47a0c421997-05-16 02:46:07 -05001284 png_ptr->current_text[length] = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001285 png_ptr->current_text_ptr = png_ptr->current_text;
Glenn Randers-Pehrson0f881d61998-02-07 10:20:57 -06001286 png_ptr->current_text_size = (png_size_t)length;
1287 png_ptr->current_text_left = (png_size_t)length;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001288 png_ptr->process_mode = PNG_READ_zTXt_MODE;
Guy Schalnat6d764711995-12-19 03:22:19 -06001289}
1290
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001291void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001292png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001293{
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001294 if (png_ptr->buffer_size && png_ptr->current_text_left)
1295 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001296 png_size_t text_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001297
Andreas Dilger47a0c421997-05-16 02:46:07 -05001298 if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001299 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001300
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001301 else
1302 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001303
Andreas Dilger47a0c421997-05-16 02:46:07 -05001304 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001305 png_ptr->current_text_left -= text_size;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001306 png_ptr->current_text_ptr += text_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001307 }
1308 if (!(png_ptr->current_text_left))
1309 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001310 png_textp text_ptr;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001311 png_charp text;
1312 png_charp key;
1313 int ret;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001314 png_size_t text_size, key_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001315
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001316 if (png_ptr->buffer_size < 4)
1317 {
1318 png_push_save_buffer(png_ptr);
1319 return;
1320 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001321
Andreas Dilger47a0c421997-05-16 02:46:07 -05001322 png_push_crc_finish(png_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -06001323
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001324 key = png_ptr->current_text;
Guy Schalnat6d764711995-12-19 03:22:19 -06001325
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001326 for (text = key; *text; text++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001327 /* Empty loop */ ;
Guy Schalnat6d764711995-12-19 03:22:19 -06001328
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001329 /* zTXt can't have zero text */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001330 if (text >= key + png_ptr->current_text_size)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001331 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001332 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001333 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001334 return;
1335 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001336
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001337 text++;
Guy Schalnat6d764711995-12-19 03:22:19 -06001338
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001339 if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001340 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001341 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001342 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001343 return;
1344 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001345
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001346 text++;
Guy Schalnat6d764711995-12-19 03:22:19 -06001347
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001348 png_ptr->zstream.next_in = (png_bytep )text;
1349 png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001350 (text - key));
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001351 png_ptr->zstream.next_out = png_ptr->zbuf;
Glenn Randers-Pehrson08a33431998-03-07 06:06:55 -06001352 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
Guy Schalnat6d764711995-12-19 03:22:19 -06001353
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001354 key_size = text - key;
1355 text_size = 0;
1356 text = NULL;
1357 ret = Z_STREAM_END;
Guy Schalnat6d764711995-12-19 03:22:19 -06001358
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001359 while (png_ptr->zstream.avail_in)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001360 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001361 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001362 if (ret != Z_OK && ret != Z_STREAM_END)
1363 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001364 inflateReset(&png_ptr->zstream);
1365 png_ptr->zstream.avail_in = 0;
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001366 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001367 png_free(png_ptr, key);
1368 png_free(png_ptr, text);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001369 return;
1370 }
Andreas Dilger47a0c421997-05-16 02:46:07 -05001371 if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001372 {
Andreas Dilger47a0c421997-05-16 02:46:07 -05001373 if (text == NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001374 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001375 text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001376 (png_ptr->zbuf_size
1377 - png_ptr->zstream.avail_out + key_size + 1));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001378
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001379 png_memcpy(text + key_size, png_ptr->zbuf,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001380 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001381
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001382 png_memcpy(text, key, key_size);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001383
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001384 text_size = key_size + png_ptr->zbuf_size -
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001385 png_ptr->zstream.avail_out;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001386
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001387 *(text + text_size) = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001388 }
1389 else
1390 {
1391 png_charp tmp;
Guy Schalnat6d764711995-12-19 03:22:19 -06001392
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001393 tmp = text;
Glenn Randers-Pehrson46f61e21998-01-30 21:45:12 -06001394 text = (png_charp)png_malloc(png_ptr, text_size +
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001395 (png_ptr->zbuf_size
1396 - png_ptr->zstream.avail_out + 1));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001397
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001398 png_memcpy(text, tmp, text_size);
1399 png_free(png_ptr, tmp);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001400
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001401 png_memcpy(text + text_size, png_ptr->zbuf,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001402 png_ptr->zbuf_size - png_ptr->zstream.avail_out);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001403
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001404 text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1405 *(text + text_size) = '\0';
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001406 }
1407 if (ret != Z_STREAM_END)
1408 {
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001409 png_ptr->zstream.next_out = png_ptr->zbuf;
1410 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001411 }
1412 }
1413 else
1414 {
1415 break;
1416 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001417
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001418 if (ret == Z_STREAM_END)
1419 break;
1420 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001421
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001422 inflateReset(&png_ptr->zstream);
1423 png_ptr->zstream.avail_in = 0;
Guy Schalnat6d764711995-12-19 03:22:19 -06001424
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001425 if (ret != Z_STREAM_END)
1426 {
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001427 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001428 png_free(png_ptr, key);
1429 png_free(png_ptr, text);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001430 return;
1431 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001432
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001433 png_ptr->current_text = NULL;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001434 png_free(png_ptr, key);
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001435 key = text;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001436 text += key_size;
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001437
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001438 text_ptr = (png_textp)png_malloc(png_ptr,
1439 png_sizeof(png_text));
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001440 text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
1441 text_ptr->key = key;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001442#ifdef PNG_iTXt_SUPPORTED
Glenn Randers-Pehrson3f549252001-10-27 07:35:13 -05001443 text_ptr->lang = NULL;
1444 text_ptr->lang_key = NULL;
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001445#endif
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001446 text_ptr->text = text;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001447
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001448 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001449
Glenn Randers-Pehrson316f97a2000-07-08 13:19:41 -05001450 png_free(png_ptr, key);
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001451 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001452
1453 if (ret)
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001454 png_warning(png_ptr, "Insufficient memory to store text chunk");
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001455 }
1456}
1457#endif
1458
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001459#ifdef PNG_READ_iTXt_SUPPORTED
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001460void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001461png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001462 length)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001463{
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001464 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001465 {
1466 png_error(png_ptr, "Out of place iTXt");
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001467 info_ptr = info_ptr; /* To quiet some compiler warnings */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001468 }
1469
1470#ifdef PNG_MAX_MALLOC_64K
1471 png_ptr->skip_length = 0; /* This may not be necessary */
1472
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001473 if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001474 {
1475 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
1476 png_ptr->skip_length = length - (png_uint_32)65535L;
1477 length = (png_uint_32)65535L;
1478 }
1479#endif
1480
1481 png_ptr->current_text = (png_charp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001482 (png_size_t)(length + 1));
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001483 png_ptr->current_text[length] = '\0';
1484 png_ptr->current_text_ptr = png_ptr->current_text;
1485 png_ptr->current_text_size = (png_size_t)length;
1486 png_ptr->current_text_left = (png_size_t)length;
1487 png_ptr->process_mode = PNG_READ_iTXt_MODE;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001488}
1489
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001490void /* PRIVATE */
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001491png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
1492{
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001493
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001494 if (png_ptr->buffer_size && png_ptr->current_text_left)
1495 {
1496 png_size_t text_size;
1497
1498 if (png_ptr->buffer_size < png_ptr->current_text_left)
1499 text_size = png_ptr->buffer_size;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001500
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001501 else
1502 text_size = png_ptr->current_text_left;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001503
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001504 png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1505 png_ptr->current_text_left -= text_size;
1506 png_ptr->current_text_ptr += text_size;
1507 }
1508 if (!(png_ptr->current_text_left))
1509 {
1510 png_textp text_ptr;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001511 png_charp key;
Glenn Randers-Pehrson520a7642000-03-21 05:13:06 -06001512 int comp_flag;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001513 png_charp lang;
1514 png_charp lang_key;
1515 png_charp text;
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001516 int ret;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001517
1518 if (png_ptr->buffer_size < 4)
1519 {
1520 png_push_save_buffer(png_ptr);
1521 return;
1522 }
1523
1524 png_push_crc_finish(png_ptr);
1525
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001526#ifdef PNG_MAX_MALLOC_64K
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001527 if (png_ptr->skip_length)
1528 return;
1529#endif
1530
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001531 key = png_ptr->current_text;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001532
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001533 for (lang = key; *lang; lang++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001534 /* Empty loop */ ;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001535
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001536 if (lang < key + png_ptr->current_text_size - 3)
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001537 lang++;
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001538
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001539 comp_flag = *lang++;
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001540 lang++; /* Skip comp_type, always zero */
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001541
1542 for (lang_key = lang; *lang_key; lang_key++)
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001543 /* Empty loop */ ;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001544
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001545 lang_key++; /* Skip NUL separator */
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001546
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001547 text=lang_key;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001548
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001549 if (lang_key < key + png_ptr->current_text_size - 1)
1550 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001551 for (; *text; text++)
1552 /* Empty loop */ ;
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001553 }
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001554
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001555 if (text < key + png_ptr->current_text_size)
Glenn Randers-Pehrson166c5a31999-12-10 09:43:02 -06001556 text++;
1557
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001558 text_ptr = (png_textp)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001559 png_sizeof(png_text));
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001560
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001561 text_ptr->compression = comp_flag + 2;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001562 text_ptr->key = key;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001563 text_ptr->lang = lang;
1564 text_ptr->lang_key = lang_key;
Andreas Dilger47a0c421997-05-16 02:46:07 -05001565 text_ptr->text = text;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001566 text_ptr->text_length = 0;
1567 text_ptr->itxt_length = png_strlen(text);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001568
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001569 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
Andreas Dilger47a0c421997-05-16 02:46:07 -05001570
Glenn Randers-Pehrsond1e8c862002-06-20 06:54:34 -05001571 png_ptr->current_text = NULL;
1572
Andreas Dilger47a0c421997-05-16 02:46:07 -05001573 png_free(png_ptr, text_ptr);
Glenn Randers-Pehrson07748d12002-05-25 11:12:10 -05001574 if (ret)
Glenn Randers-Pehrsonf81b50b2009-12-29 16:50:15 -06001575 png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001576 }
Guy Schalnat6d764711995-12-19 03:22:19 -06001577}
1578#endif
1579
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001580/* This function is called when we haven't found a handler for this
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001581 * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
1582 * name or a critical chunk), the chunk is (currently) silently ignored.
Glenn Randers-Pehrsonb6ce43d1998-01-01 07:13:13 -06001583 */
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001584void /* PRIVATE */
Glenn Randers-Pehrson3097f612001-05-07 14:52:45 -05001585png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001586 length)
Guy Schalnat6d764711995-12-19 03:22:19 -06001587{
Glenn Randers-Pehrson895a9c92008-07-25 08:51:18 -05001588 png_uint_32 skip = 0;
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001589
1590 if (!(png_ptr->chunk_name[0] & 0x20))
1591 {
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001592#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001593 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001594 PNG_HANDLE_CHUNK_ALWAYS
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001595#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001596 && png_ptr->read_user_chunk_fn == NULL
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001597#endif
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001598 )
Glenn Randers-Pehrson6942d532000-05-01 09:31:54 -05001599#endif
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001600 png_chunk_error(png_ptr, "unknown critical chunk");
1601
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001602 info_ptr = info_ptr; /* To quiet some compiler warnings */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001603 }
1604
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001605#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001606 if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
1607 {
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001608#ifdef PNG_MAX_MALLOC_64K
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001609 if (length > (png_uint_32)65535L)
1610 {
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001611 png_warning(png_ptr, "unknown chunk too large to fit in memory");
1612 skip = length - (png_uint_32)65535L;
1613 length = (png_uint_32)65535L;
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001614 }
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001615#endif
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001616 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001617 (png_charp)png_ptr->chunk_name,
1618 png_sizeof(png_ptr->unknown_chunk.name));
Glenn Randers-Pehrson895a9c92008-07-25 08:51:18 -05001619 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001620 = '\0';
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001621
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001622 png_ptr->unknown_chunk.size = (png_size_t)length;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001623
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001624 if (length == 0)
1625 png_ptr->unknown_chunk.data = NULL;
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001626
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001627 else
1628 {
1629 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001630 (png_size_t)length);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001631 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
1632 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001633
Glenn Randers-Pehrsone26c0952009-09-23 11:22:08 -05001634#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001635 if (png_ptr->read_user_chunk_fn != NULL)
1636 {
Glenn Randers-Pehrson4bb4d012009-05-20 12:45:29 -05001637 /* Callback to user unknown chunk handler */
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001638 int ret;
1639 ret = (*(png_ptr->read_user_chunk_fn))
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001640 (png_ptr, &png_ptr->unknown_chunk);
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001641
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001642 if (ret < 0)
1643 png_chunk_error(png_ptr, "error in user chunk");
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001644
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001645 if (ret == 0)
1646 {
1647 if (!(png_ptr->chunk_name[0] & 0x20))
1648 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001649 PNG_HANDLE_CHUNK_ALWAYS)
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001650 png_chunk_error(png_ptr, "unknown critical chunk");
1651 png_set_unknown_chunks(png_ptr, info_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001652 &png_ptr->unknown_chunk, 1);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001653 }
1654 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001655
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001656 else
Glenn Randers-Pehrson82ae3832001-04-20 10:32:10 -05001657#endif
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001658 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001659 png_free(png_ptr, png_ptr->unknown_chunk.data);
1660 png_ptr->unknown_chunk.data = NULL;
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001661 }
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001662
Glenn Randers-Pehrson61c32d92000-02-04 23:40:16 -06001663 else
1664#endif
1665 skip=length;
1666 png_push_crc_skip(png_ptr, skip);
Guy Schalnat6d764711995-12-19 03:22:19 -06001667}
1668
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001669void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001670png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1671{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001672 if (png_ptr->info_fn != NULL)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001673 (*(png_ptr->info_fn))(png_ptr, info_ptr);
1674}
1675
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001676void /* PRIVATE */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001677png_push_have_end(png_structp png_ptr, png_infop info_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001678{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001679 if (png_ptr->end_fn != NULL)
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001680 (*(png_ptr->end_fn))(png_ptr, info_ptr);
Guy Schalnat6d764711995-12-19 03:22:19 -06001681}
1682
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001683void /* PRIVATE */
Guy Schalnat6d764711995-12-19 03:22:19 -06001684png_push_have_row(png_structp png_ptr, png_bytep row)
1685{
Andreas Dilger47a0c421997-05-16 02:46:07 -05001686 if (png_ptr->row_fn != NULL)
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001687 (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1688 (int)png_ptr->pass);
Guy Schalnat6d764711995-12-19 03:22:19 -06001689}
1690
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001691void PNGAPI
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001692png_progressive_combine_row (png_structp png_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001693 png_bytep old_row, png_bytep new_row)
Guy Schalnat6d764711995-12-19 03:22:19 -06001694{
Glenn Randers-Pehrson145f5c82008-07-10 09:13:13 -05001695 PNG_CONST int FARDATA png_pass_dsp_mask[7] =
Glenn Randers-Pehrson5e5c1e12000-11-10 12:26:19 -06001696 {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
Glenn Randers-Pehrson86312502009-08-31 14:17:23 -05001697
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001698 if (png_ptr == NULL)
1699 return;
1700
Glenn Randers-Pehrson345bc271998-06-14 14:43:31 -05001701 if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001702 png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
Guy Schalnat6d764711995-12-19 03:22:19 -06001703}
1704
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001705void PNGAPI
Guy Schalnat6d764711995-12-19 03:22:19 -06001706png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
Glenn Randers-Pehrson262d0ff2010-03-03 07:06:54 -06001707 png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1708 png_progressive_end_ptr end_fn)
Guy Schalnat6d764711995-12-19 03:22:19 -06001709{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001710 if (png_ptr == NULL)
1711 return;
1712
Guy Schalnatb2e01bd1996-01-26 01:38:47 -06001713 png_ptr->info_fn = info_fn;
1714 png_ptr->row_fn = row_fn;
Guy Schalnat6d764711995-12-19 03:22:19 -06001715 png_ptr->end_fn = end_fn;
Guy Schalnate5a37791996-06-05 15:50:50 -05001716
Glenn Randers-Pehrson25d82242002-05-01 11:51:26 -05001717 png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
Guy Schalnat6d764711995-12-19 03:22:19 -06001718}
1719
Glenn Randers-Pehrson75294572000-05-06 14:09:57 -05001720png_voidp PNGAPI
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001721png_get_progressive_ptr(png_structp png_ptr)
Guy Schalnat6d764711995-12-19 03:22:19 -06001722{
Glenn Randers-Pehrson glennrp@comcast.netb1c0d332009-05-15 20:39:34 -05001723 if (png_ptr == NULL)
1724 return (NULL);
1725
Andreas Dilger02ad0ef1997-01-17 01:34:35 -06001726 return png_ptr->io_ptr;
Guy Schalnat6d764711995-12-19 03:22:19 -06001727}
Guy Schalnat4ee97b01996-01-16 01:51:56 -06001728#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */