summaryrefslogtreecommitdiff
path: root/png/pngpread.c
diff options
context:
space:
mode:
Diffstat (limited to 'png/pngpread.c')
-rw-r--r--png/pngpread.c215
1 files changed, 28 insertions, 187 deletions
diff --git a/png/pngpread.c b/png/pngpread.c
index ffab19c08..37aa432ae 100644
--- a/png/pngpread.c
+++ b/png/pngpread.c
@@ -1,7 +1,6 @@
-
/* pngpread.c - read a png file in push mode
*
- * Copyright (c) 2018-2024 Cosmin Truta
+ * Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -32,6 +31,21 @@ if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
if (png_ptr->buffer_size < N) \
{ png_push_save_buffer(png_ptr); return; }
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Arrays to facilitate interlacing - use pass (0 - 6) as index. */
+
+/* Start of interlace block */
+static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+/* Offset to next interlace block */
+static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+/* Start of interlace block in the y direction */
+static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+/* Offset to next interlace block in the y direction */
+static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+
+/* TODO: Move these arrays to a common utility module to avoid duplication. */
+#endif
+
void PNGAPI
png_process_data(png_structrp png_ptr, png_inforp info_ptr,
png_bytep buffer, size_t buffer_size)
@@ -179,17 +193,8 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
*/
if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
{
- png_byte chunk_length[4];
- png_byte chunk_tag[4];
-
PNG_PUSH_SAVE_BUFFER_IF_LT(8)
- png_push_fill_buffer(png_ptr, chunk_length, 4);
- png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
- png_reset_crc(png_ptr);
- png_crc_read(png_ptr, chunk_tag, 4);
- png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
- png_check_chunk_name(png_ptr, png_ptr->chunk_name);
- png_check_chunk_length(png_ptr, png_ptr->push_length);
+ png_ptr->push_length = png_read_chunk_header(png_ptr);
png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
}
@@ -224,19 +229,27 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_benign_error(png_ptr, "Too many IDATs found");
}
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ /* These flags must be set consistently for all non-IDAT chunks,
+ * including the unknown chunks.
+ */
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT;
+ }
+
if (chunk_name == png_IHDR)
{
if (png_ptr->push_length != 13)
png_error(png_ptr, "Invalid IHDR length");
PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+ png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
}
else if (chunk_name == png_IEND)
{
PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+ png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
png_ptr->process_mode = PNG_READ_DONE_MODE;
png_push_have_end(png_ptr, info_ptr);
@@ -253,12 +266,6 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
}
#endif
- else if (chunk_name == png_PLTE)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
- }
-
else if (chunk_name == png_IDAT)
{
png_ptr->idat_size = png_ptr->push_length;
@@ -271,155 +278,10 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
return;
}
-#ifdef PNG_READ_gAMA_SUPPORTED
- else if (png_ptr->chunk_name == png_gAMA)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_sBIT_SUPPORTED
- else if (png_ptr->chunk_name == png_sBIT)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_cHRM_SUPPORTED
- else if (png_ptr->chunk_name == png_cHRM)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_eXIf_SUPPORTED
- else if (png_ptr->chunk_name == png_eXIf)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_sRGB_SUPPORTED
- else if (chunk_name == png_sRGB)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_iCCP_SUPPORTED
- else if (png_ptr->chunk_name == png_iCCP)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_sPLT_SUPPORTED
- else if (chunk_name == png_sPLT)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_tRNS_SUPPORTED
- else if (chunk_name == png_tRNS)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_bKGD_SUPPORTED
- else if (chunk_name == png_bKGD)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_hIST_SUPPORTED
- else if (chunk_name == png_hIST)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_pHYs_SUPPORTED
- else if (chunk_name == png_pHYs)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_oFFs_SUPPORTED
- else if (chunk_name == png_oFFs)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-
-#ifdef PNG_READ_pCAL_SUPPORTED
- else if (chunk_name == png_pCAL)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_sCAL_SUPPORTED
- else if (chunk_name == png_sCAL)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_tIME_SUPPORTED
- else if (chunk_name == png_tIME)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_tEXt_SUPPORTED
- else if (chunk_name == png_tEXt)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_zTXt_SUPPORTED
- else if (chunk_name == png_zTXt)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-
-#endif
-#ifdef PNG_READ_iTXt_SUPPORTED
- else if (chunk_name == png_iTXt)
- {
- PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
- }
-#endif
-
else
{
PNG_PUSH_SAVE_BUFFER_IF_FULL
- png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
- PNG_HANDLE_CHUNK_AS_DEFAULT);
+ png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length);
}
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
@@ -976,27 +838,6 @@ png_push_process_row(png_structrp png_ptr)
void /* PRIVATE */
png_read_push_finish_row(png_structrp png_ptr)
{
-#ifdef PNG_READ_INTERLACING_SUPPORTED
- /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
-
- /* Start of interlace block */
- static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
-
- /* Offset to next interlace block */
- static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
-
- /* Start of interlace block in the y direction */
- static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
-
- /* Offset to next interlace block in the y direction */
- static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
-
- /* Height of interlace block. This is not currently used - if you need
- * it, uncomment it here and in png.h
- static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
- */
-#endif
-
png_ptr->row_number++;
if (png_ptr->row_number < png_ptr->num_rows)
return;