summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2010-01-22 19:30:23 -0600
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2010-01-22 19:34:44 -0600
commit86f6c04d8480fc029ef20a61152786fb7a592ce1 (patch)
tree3431d860403394b391266de98587024d7e012d17
parentfb3a1da4bbb475ec2d2bdfe478e45204fce77adf (diff)
downloadlibpng-86f6c04d8480fc029ef20a61152786fb7a592ce1.tar.gz
[master] Imported from libpng-1.4.1beta04.tarv1.4.1beta04
-rw-r--r--ANNOUNCE6
-rw-r--r--CHANGES6
-rw-r--r--libpng-1.4.1beta04.txt12
-rw-r--r--libpng.320
-rw-r--r--png.h15
-rw-r--r--pngconf.h4
-rw-r--r--pngget.c10
-rw-r--r--pngrutil.c95
-rw-r--r--pngset.c11
-rw-r--r--scripts/png32ce.def3
-rw-r--r--scripts/pngos2.def3
-rw-r--r--scripts/pngwin.def3
12 files changed, 151 insertions, 37 deletions
diff --git a/ANNOUNCE b/ANNOUNCE
index d713b3526..cbb331d86 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -44,7 +44,13 @@ version 1.4.1beta02 [January 9, 2010]
version 1.4.1beta03 [January 10, 2010]
Removed png_set_premultiply_alpha() from scripts/*.def
+version 1.4.1rc01 [January 16, 2010]
+ No changes.
+
version 1.4.1beta04 [January 23, 2010]
+ Revised png_decompress_chunk() to improve speed and memory usage when
+ decoding large chunks.
+ Added png_set|get_chunk_malloc_max() function and PNG_CHUNK_MALLOC_MAX macro.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
diff --git a/CHANGES b/CHANGES
index 40d1f2bd5..1e5772656 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2476,7 +2476,13 @@ version 1.4.1beta02 [January 9, 2010]
version 1.4.1beta03 [January 10, 2010]
Removed png_set_premultiply_alpha() from scripts/*.def
+version 1.4.1rc01 [January 16, 2010]
+ No changes.
+
version 1.4.1beta04 [January 23, 2010]
+ Revised png_decompress_chunk() to improve speed and memory usage when
+ decoding large chunks.
+ Added png_set|get_chunk_malloc_max() function and PNG_CHUNK_MALLOC_MAX macro.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
diff --git a/libpng-1.4.1beta04.txt b/libpng-1.4.1beta04.txt
index c928df6b1..ad7cb7492 100644
--- a/libpng-1.4.1beta04.txt
+++ b/libpng-1.4.1beta04.txt
@@ -432,6 +432,18 @@ where 0x7fffffffL means unlimited. You can retrieve this limit with
This limit also applies to the number of buffers that can be allocated
by png_decompress_chunk() while decompressing iTXt, zTXt, and iCCP chunks.
+You can also set a limit on the amount of memory that a compressed chunk
+other than IDAT can occupy, with
+
+ png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);
+
+and you can retrieve the limit with
+
+ chunk_malloc_max = png_get_chunk_malloc_max(png_ptr);
+
+Any chunks that would cause either of these limits to be exceeded will
+be ignored.
+
The high-level read interface
At this point there are two ways to proceed; through the high-level
diff --git a/libpng.3 b/libpng.3
index 7b9cfcaf7..2790363fc 100644
--- a/libpng.3
+++ b/libpng.3
@@ -192,6 +192,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.4.1beta04
\fI\fB
+\fBpng_uint_32 png_get_chunk_malloc_max (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP
\fI\fB
@@ -538,6 +542,10 @@ libpng \- Portable Network Graphics (PNG) Reference Library 1.4.1beta04
\fI\fB
+\fBvoid png_set_chunk_malloc_max (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIuser_chunk_cache_max\fP\fB);\fP
+
+\fI\fB
+
\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
\fI\fB
@@ -1209,6 +1217,18 @@ where 0x7fffffffL means unlimited. You can retrieve this limit with
This limit also applies to the number of buffers that can be allocated
by png_decompress_chunk() while decompressing iTXt, zTXt, and iCCP chunks.
+You can also set a limit on the amount of memory that a compressed chunk
+other than IDAT can occupy, with
+
+ png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max);
+
+and you can retrieve the limit with
+
+ chunk_malloc_max = png_get_chunk_malloc_max(png_ptr);
+
+Any chunks that would cause either of these limits to be exceeded will
+be ignored.
+
.SS The high-level read interface
At this point there are two ways to proceed; through the high-level
diff --git a/png.h b/png.h
index c30fcedb3..2da190da6 100644
--- a/png.h
+++ b/png.h
@@ -1336,10 +1336,18 @@ struct png_struct_def
/* New member added in libpng-1.2.30 */
png_charp chunkdata PNG_DEPSTRUCT; /* buffer for reading chunk data */
-/* New member added in libpng-1.4.0 */
#ifdef PNG_IO_STATE_SUPPORTED
+/* New member added in libpng-1.4.0 */
png_uint_32 io_state PNG_DEPSTRUCT;
#endif
+
+/* Added in libpng-1.4.1 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
+ * can occupy when decompressed.
+ */
+ png_uint_32 user_chunk_malloc_max PNG_DEPSTRUCT;
+#endif
};
@@ -2396,6 +2404,11 @@ extern PNG_EXPORT(void,png_set_chunk_cache_max) PNGARG((png_structp
png_ptr, png_uint_32 user_chunk_cache_max));
extern PNG_EXPORT(png_uint_32,png_get_chunk_cache_max)
PNGARG((png_structp png_ptr));
+/* Added in libpng-1.4.1 */
+extern PNG_EXPORT(void,png_set_chunk_malloc_max) PNGARG((png_structp
+ png_ptr, png_uint_32 user_chunk_cache_max));
+extern PNG_EXPORT(png_uint_32,png_get_chunk_malloc_max)
+ PNGARG((png_structp png_ptr));
#endif
#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
diff --git a/pngconf.h b/pngconf.h
index 2a7ba163f..a295037a8 100644
--- a/pngconf.h
+++ b/pngconf.h
@@ -675,6 +675,10 @@
#ifndef PNG_SET_USER_LIMITS_SUPPORTED
# ifndef PNG_NO_SET_USER_LIMITS
# define PNG_SET_USER_LIMITS_SUPPORTED
+ /* Feature added at libpng-1.4.0, this flag added at 1.4.1 */
+# define PNG_CHUNK_CACHE_LIMIT_SUPPORTED
+ /* Feature added at libpng-1.4.1, this flag added at 1.4.1 */
+# define PNG_CHUNK_MALLOC_LIMIT_SUPPORTED
# endif
#endif
diff --git a/pngget.c b/pngget.c
index 0674bf59d..9fa2ac079 100644
--- a/pngget.c
+++ b/pngget.c
@@ -895,8 +895,14 @@ png_get_user_height_max (png_structp png_ptr)
png_uint_32 PNGAPI
png_get_chunk_cache_max (png_structp png_ptr)
{
- return (png_ptr? png_ptr->user_chunk_cache_max? 0x7fffffffL :
- png_ptr->user_chunk_cache_max - 1 : 0);
+ return (png_ptr? (png_ptr->user_chunk_cache_max? 0x7fffffffL :
+ png_ptr->user_chunk_cache_max - 1) : 0);
+}
+/* This function was added to libpng 1.4.1 */
+png_uint_32 PNGAPI
+png_get_chunk_malloc_max (png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_chunk_cache_max : 0);
}
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
diff --git a/pngrutil.c b/pngrutil.c
index 0bee16e31..e0222d6e5 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -278,63 +278,90 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
if (text == NULL)
{
- png_free(png_ptr, png_ptr->chunkdata);
- png_ptr->chunkdata = NULL;
png_error(png_ptr,
"Not enough memory to decompress chunk");
+ text_size = 0;
+ break;
}
+ png_memcpy(text, png_ptr->chunkdata, prefix_size);
png_memcpy(text + prefix_size, png_ptr->zbuf,
text_size - prefix_size);
- png_memcpy(text, png_ptr->chunkdata, prefix_size);
*(text + text_size) = 0x00;
buffer_size = text_size;
}
else /* Enlarge the decompression buffer */
{
- png_charp tmp;
+ png_charp tmp = text;
+ png_size_t new_text_size;
+
+ new_text_size = text_size + png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out;
+
+ if (new_text_size > buffer_size)
+ {
+ if (png_ptr->zstream.avail_out)
+ buffer_size = new_text_size;
+ else
+ buffer_size += buffer_size;
+ }
- tmp = text;
#ifdef PNG_CHUNK_MALLOC_LIMIT_SUPPORTED
- if ((png_ptr->user_chunk_cache_max != 0) &&
- (--png_ptr->user_chunk_cache_max == 0))
+ if (png_ptr->user_chunk_malloc_max <= buffer_size)
{
- png_warning(png_ptr, "No space in chunk cache");
+ png_free(png_ptr, tmp);
+ png_warning(png_ptr, "No space for decompressed chunk");
text = NULL;
}
else
- {
-#endif
text = (png_charp)png_malloc_warn(png_ptr,
- (png_size_t)(text_size +
- png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
-#ifdef PNG_CHUNK_MALLOC_LIMIT_SUPPORTED
- }
+ buffer_size + 1);
+#else
+ text = (png_charp)png_malloc_warn(png_ptr,
+ buffer_size + 1);
#endif
+
if (text == NULL)
{
- png_free(png_ptr, tmp);
- png_free(png_ptr, png_ptr->chunkdata);
- png_ptr->chunkdata = NULL;
- png_error(png_ptr,
+ png_warning(png_ptr,
"Not enough memory to decompress chunk");
+ break;
}
+
png_memcpy(text, tmp, text_size);
png_free(png_ptr, tmp);
- png_memcpy(text + text_size, png_ptr->zbuf,
- (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
- text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
- *(text + text_size) = 0x00;
- }
- if (ret == Z_STREAM_END)
- break;
- else
- {
- png_ptr->zstream.next_out = png_ptr->zbuf;
- png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
}
}
+ if (ret == Z_STREAM_END)
+ break;
+
+ else
+ {
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+
+ if (text != NULL && buffer_size > text_size)
+ {
+ /* Reduce text allocation to actual size */
+ png_charp tmp;
+
+ tmp = text;
+ text = (png_charp)png_malloc_warn(png_ptr,
+ text_size);
+
+ if (text == NULL)
+ text = tmp;
+
+ else
+ {
+ png_memcpy(text, tmp, text_size + 1);
+ png_free(png_ptr, tmp);
+ }
+
}
+
if (ret != Z_STREAM_END)
{
#ifdef PNG_STDIO_SUPPORTED
@@ -365,11 +392,11 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
{
text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
if (text == NULL)
- {
- png_free(png_ptr, png_ptr->chunkdata);
- png_ptr->chunkdata = NULL;
- png_error(png_ptr, "Not enough memory for text");
- }
+ {
+ png_free(png_ptr, png_ptr->chunkdata);
+ png_ptr->chunkdata = NULL;
+ png_error(png_ptr, "Not enough memory for text");
+ }
png_memcpy(text, png_ptr->chunkdata, prefix_size);
}
*(text + text_size) = 0x00;
diff --git a/pngset.c b/pngset.c
index cb3953ed8..1afae2376 100644
--- a/pngset.c
+++ b/pngset.c
@@ -1130,6 +1130,7 @@ png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max,
png_ptr->user_width_max = user_width_max;
png_ptr->user_height_max = user_height_max;
}
+
/* This function was added to libpng 1.4.0 */
void PNGAPI
png_set_chunk_cache_max (png_structp png_ptr,
@@ -1143,6 +1144,16 @@ png_set_chunk_cache_max (png_structp png_ptr,
else
png_ptr->user_chunk_cache_max = user_chunk_cache_max + 1;
}
+
+/* This function was added to libpng 1.4.1 */
+void PNGAPI
+png_set_chunk_malloc_max (png_structp png_ptr,
+ png_uint_32 user_chunk_malloc_max)
+{
+ if (png_ptr == NULL)
+ return;
+ png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
+}
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
diff --git a/scripts/png32ce.def b/scripts/png32ce.def
index 97ff838e9..b270cda70 100644
--- a/scripts/png32ce.def
+++ b/scripts/png32ce.def
@@ -254,3 +254,6 @@ EXPORTS
png_check_cHRM_fixed @217
png_calloc @218
png_set_longjmp_fn @219
+; Added at version 1.4.1
+ png_get_chunk_malloc_max @220
+ png_set_chunk_malloc_max @221
diff --git a/scripts/pngos2.def b/scripts/pngos2.def
index 11d4c9ba4..ffe957272 100644
--- a/scripts/pngos2.def
+++ b/scripts/pngos2.def
@@ -214,6 +214,9 @@ EXPORTS
png_check_cHRM_fixed
png_calloc
png_set_longjmp_fn
+; Added at version 1.4.1
+ png_get_chunk_malloc_max
+ png_set_chunk_malloc_max
; These are not present when libpng is compiled with PNG_NO_GLOBAL_ARRAYS
png_libpng_ver
diff --git a/scripts/pngwin.def b/scripts/pngwin.def
index f10bd8564..bf1d2b00b 100644
--- a/scripts/pngwin.def
+++ b/scripts/pngwin.def
@@ -209,3 +209,6 @@ EXPORTS
png_check_cHRM_fixed
png_calloc
png_set_longjmp_fn
+; Added at version 1.4.1
+ png_get_chunk_malloc_max
+ png_set_chunk_malloc_max