mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[master] Revised png_decompress_chunk() to improve speed and memory
usage when decoding large chunks.
This commit is contained in:
parent
610e7b5bd6
commit
1a86bd2a09
7
pngget.c
7
pngget.c
@ -895,14 +895,15 @@ png_get_user_height_max (png_structp png_ptr)
|
|||||||
png_uint_32 PNGAPI
|
png_uint_32 PNGAPI
|
||||||
png_get_chunk_cache_max (png_structp png_ptr)
|
png_get_chunk_cache_max (png_structp png_ptr)
|
||||||
{
|
{
|
||||||
return (png_ptr? (png_ptr->user_chunk_cache_max? 0x7fffffffL :
|
return (png_ptr? (png_ptr->user_chunk_cache_max?
|
||||||
png_ptr->user_chunk_cache_max - 1) : 0);
|
png_ptr->user_chunk_cache_max - 1 : 0x7fffffffL) : 0);
|
||||||
}
|
}
|
||||||
/* This function was added to libpng 1.4.1 */
|
/* This function was added to libpng 1.4.1 */
|
||||||
png_uint_32 PNGAPI
|
png_uint_32 PNGAPI
|
||||||
png_get_chunk_malloc_max (png_structp png_ptr)
|
png_get_chunk_malloc_max (png_structp png_ptr)
|
||||||
{
|
{
|
||||||
return (png_ptr? png_ptr->user_chunk_cache_max : 0);
|
return (png_ptr? (png_ptr->user_chunk_malloc_max?
|
||||||
|
png_ptr->user_chunk_malloc_max : 0x7fffffffL) : 0);
|
||||||
}
|
}
|
||||||
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
|
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
|
|||||||
png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
|
png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
|
||||||
/* Added at libpng-1.4.0 */
|
/* Added at libpng-1.4.0 */
|
||||||
png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
|
png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
|
||||||
|
png_ptr->user_chunk_malloc_max = png_get_chunk_malloc_max(png_ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
#ifdef PNG_SETJMP_SUPPORTED
|
||||||
|
|||||||
78
pngrutil.c
78
pngrutil.c
@ -210,8 +210,8 @@ png_crc_error(png_structp png_ptr)
|
|||||||
*/
|
*/
|
||||||
void /* PRIVATE */
|
void /* PRIVATE */
|
||||||
png_decompress_chunk(png_structp png_ptr, int comp_type,
|
png_decompress_chunk(png_structp png_ptr, int comp_type,
|
||||||
png_size_t chunklength,
|
png_size_t chunklength,
|
||||||
png_size_t prefix_size, png_size_t *newlength)
|
png_size_t prefix_size, png_size_t *newlength)
|
||||||
{
|
{
|
||||||
static PNG_CONST char msg[] = "Error decoding compressed chunk";
|
static PNG_CONST char msg[] = "Error decoding compressed chunk";
|
||||||
png_charp text;
|
png_charp text;
|
||||||
@ -248,12 +248,12 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
|
|||||||
text_size = prefix_size + png_sizeof(msg) + 1;
|
text_size = prefix_size + png_sizeof(msg) + 1;
|
||||||
text = (png_charp)png_malloc_warn(png_ptr, text_size);
|
text = (png_charp)png_malloc_warn(png_ptr, text_size);
|
||||||
if (text == NULL)
|
if (text == NULL)
|
||||||
{
|
{
|
||||||
png_error(png_ptr,
|
png_error(png_ptr,
|
||||||
"Not enough memory to decompress chunk");
|
"Not enough memory to decompress chunk");
|
||||||
text_size = 0;
|
text_size = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
png_memcpy(text, png_ptr->chunkdata, prefix_size);
|
png_memcpy(text, png_ptr->chunkdata, prefix_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,9 +261,11 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
|
|||||||
|
|
||||||
/* Copy what we can of the error message into the text chunk */
|
/* Copy what we can of the error message into the text chunk */
|
||||||
text_size = (png_size_t)(chunklength -
|
text_size = (png_size_t)(chunklength -
|
||||||
(text - png_ptr->chunkdata) - 1);
|
(text - png_ptr->chunkdata) - 1);
|
||||||
|
|
||||||
if (text_size > png_sizeof(msg))
|
if (text_size > png_sizeof(msg))
|
||||||
text_size = png_sizeof(msg);
|
text_size = png_sizeof(msg);
|
||||||
|
|
||||||
png_memcpy(text + prefix_size, msg, text_size);
|
png_memcpy(text + prefix_size, msg, text_size);
|
||||||
buffer_size = text_size;
|
buffer_size = text_size;
|
||||||
break;
|
break;
|
||||||
@ -283,9 +285,9 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
|
|||||||
text_size = 0;
|
text_size = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
png_memcpy(text, png_ptr->chunkdata, prefix_size);
|
|
||||||
png_memcpy(text + prefix_size, png_ptr->zbuf,
|
png_memcpy(text + prefix_size, png_ptr->zbuf,
|
||||||
text_size - prefix_size);
|
text_size - prefix_size);
|
||||||
|
png_memcpy(text, png_ptr->chunkdata, prefix_size);
|
||||||
*(text + text_size) = 0x00;
|
*(text + text_size) = 0x00;
|
||||||
buffer_size = text_size;
|
buffer_size = text_size;
|
||||||
}
|
}
|
||||||
@ -303,33 +305,49 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
|
|||||||
buffer_size = new_text_size;
|
buffer_size = new_text_size;
|
||||||
else
|
else
|
||||||
buffer_size += buffer_size;
|
buffer_size += buffer_size;
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_CHUNK_MALLOC_LIMIT_SUPPORTED
|
#ifdef PNG_CHUNK_MALLOC_LIMIT_SUPPORTED
|
||||||
if (png_ptr->user_chunk_malloc_max <= buffer_size)
|
if (buffer_size >= png_ptr->user_chunk_malloc_max - 1)
|
||||||
{
|
{
|
||||||
png_free(png_ptr, tmp);
|
if (new_text_size >=
|
||||||
png_warning(png_ptr, "No space for decompressed chunk");
|
png_ptr->user_chunk_malloc_max - 1)
|
||||||
text = NULL;
|
{
|
||||||
}
|
png_free(png_ptr, tmp);
|
||||||
|
png_warning(png_ptr,
|
||||||
|
"No space for decompressed chunk");
|
||||||
|
text = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer_size = png_ptr->user_chunk_malloc_max - 1;
|
||||||
|
text = (png_charp)png_malloc_warn(png_ptr,
|
||||||
|
buffer_size + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
text = (png_charp)png_malloc_warn(png_ptr,
|
text = (png_charp)png_malloc_warn(png_ptr,
|
||||||
buffer_size + 1);
|
buffer_size + 1);
|
||||||
#else
|
#else
|
||||||
text = (png_charp)png_malloc_warn(png_ptr,
|
text = (png_charp)png_malloc_warn(png_ptr,
|
||||||
buffer_size + 1);
|
buffer_size + 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (text == NULL)
|
if (text == NULL)
|
||||||
{
|
{
|
||||||
png_warning(png_ptr,
|
png_warning(png_ptr,
|
||||||
"Not enough memory to decompress chunk");
|
"Not enough memory to decompress chunk");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
png_memcpy(text, tmp, text_size);
|
png_memcpy(text, tmp, text_size);
|
||||||
png_free(png_ptr, tmp);
|
png_free(png_ptr, tmp);
|
||||||
|
}
|
||||||
|
/* FIX ME: zTXt chunk written by pngtest is 6 bytes too large */
|
||||||
|
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)
|
if (ret == Z_STREAM_END)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user