提交 4a6c6df6 编写于 作者: J John Bowler 提交者: Glenn Randers-Pehrson

[libpng16] Allow fine grain control of unknown chunk APIs. This change allows

png_set_keep_unknown_chunks() to be turned off if not required and causes
both read and write to behave appropriately (on read this is only possible
if the user callback is used to handle unknown chunks).  The change
also removes the support for storing unknown chunks in the info_struct
if the only unknown handling enabled is via the callback, allowing libpng
to be configured with callback reading and none of the unnecessary code.
上级 025d4158
......@@ -450,6 +450,14 @@ Version 1.6.0beta28 [August 16, 2012]
There is a new test program, test-unknown.c, which is a work in progress
(not currently part of the test suite). Comments in the header files now
explain how the unknown handling works.
Allow fine grain control of unknown chunk APIs. This change allows
png_set_keep_unknown_chunks() to be turned off if not required and causes
both read and write to behave appropriately (on read this is only possible
if the user callback is used to handle unknown chunks). The change
also removes the support for storing unknown chunks in the info_struct
if the only unknown handling enabled is via the callback, allowing libpng
to be configured with callback reading and none of the unnecessary code.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
......
......@@ -4201,6 +4201,13 @@ Version 1.6.0beta28 [August 16, 2012]
There is a new test program, test-unknown.c, which is a work in progress
(not currently part of the test suite). Comments in the header files now
explain how the unknown handling works.
Allow fine grain control of unknown chunk APIs. This change allows
png_set_keep_unknown_chunks() to be turned off if not required and causes
both read and write to behave appropriately (on read this is only possible
if the user callback is used to handle unknown chunks). The change
also removes the support for storing unknown chunks in the info_struct
if the only unknown handling enabled is via the callback, allowing libpng
to be configured with callback reading and none of the unnecessary code.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit
......
......@@ -2814,7 +2814,9 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
* function.
*/
# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
# endif
# endif
/* One of the following methods will read the chunk or skip it (at least one
......
......@@ -1111,6 +1111,29 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0)
return;
/* Check for the failure cases where support has been disabled at compile
* time. This code is hardly ever compiled - it's here because
* STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
* code) but may be meaningless if the read or write handling of unknown
* chunks is not compiled in.
*/
# if !(defined PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
(defined PNG_READ_SUPPORTED)
if (png_ptr->mode & PNG_IS_READ_STRUCT)
{
png_app_error(png_ptr, "no unknown chunk support on read");
return;
}
# endif
# if !(defined PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
(defined PNG_WRITE_SUPPORTED)
if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
{
png_app_error(png_ptr, "no unknown chunk support on write");
return;
}
# endif
/* Prior to 1.6.0 this code used png_malloc_warn, however this meant that
* unknown critical chunks could be lost with just a warning resulting in
* undefined behavior. Changing to png_malloc fixes this by producing a
......
......@@ -567,12 +567,14 @@ png_debug_free(png_structp png_ptr, png_voidp ptr)
/* Demonstration of user chunk support of the sTER and vpAg chunks */
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
/* (sTER is a public chunk not yet known by libpng. vpAg is a private
chunk used in ImageMagick to store "virtual page" size). */
static png_uint_32 user_chunk_data[4];
/* The initializer must match the values actually stored in pngtest.png so that
* pngtest will pass if we don't have read callback support.
*/
static png_uint_32 user_chunk_data[4] = {2, 'd', 'd', 0};
/* 0: sTER mode + 1
* 1: vpAg width
......@@ -580,6 +582,7 @@ static png_uint_32 user_chunk_data[4];
* 3: vpAg units
*/
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
png_unknown_chunkp chunk)
{
......@@ -726,7 +729,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
pngtest_warning);
#endif
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
user_chunk_data[0] = 0;
user_chunk_data[1] = 0;
user_chunk_data[2] = 0;
......@@ -862,6 +865,9 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
png_set_write_user_transform_fn(write_ptr, count_zero_samples);
#endif
#if 0 /* the following code is pointless, it doesn't work unless
PNG_READ_USER_CHUNKS_SUPPORTED, in which case it does nothing. */
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
# ifndef PNG_HANDLE_CHUNK_ALWAYS
# define PNG_HANDLE_CHUNK_ALWAYS 3
......@@ -875,6 +881,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
# endif
png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
NULL, 0);
#endif
#endif
#endif
pngtest_debug("Reading info struct");
......@@ -1163,7 +1171,6 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
*/
png_write_info(write_ptr, write_info_ptr);
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
if (user_chunk_data[0] != 0)
{
png_byte png_sTER[5] = {115, 84, 69, 82, '\0'};
......@@ -1199,7 +1206,6 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
}
#endif
#endif
#ifdef SINGLE_ROWBUF_ALLOC
pngtest_debug("Allocating row buffer...");
......
......@@ -35,6 +35,10 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
++up)
if (up->location & where)
{
/* If per-chunk unknown chunk handling is enabled use it, otherwise
* just write the chunks the application has set.
*/
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
int keep = png_handle_as_unknown(png_ptr, up->name);
/* NOTE: this code is radically different from the read side in the
......@@ -54,6 +58,7 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
keep == PNG_HANDLE_CHUNK_ALWAYS ||
(keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
#endif
{
/* TODO: review, what is wrong with a zero length unknown chunk? */
if (up->size == 0)
......@@ -872,7 +877,7 @@ png_write_destroy(png_structrp png_ptr)
png_free(png_ptr, png_ptr->inv_filter_costs);
#endif
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
png_free(png_ptr, png_ptr->chunk_list);
#endif
......
......@@ -647,13 +647,13 @@ option UNKNOWN_CHUNKS
# set by png_set_unknown_chunks will be written otherwise it is an error to call
# that API on a write struct.
option WRITE_UNKNOWN_CHUNKS requires WRITE requires UNKNOWN_CHUNKS
option WRITE_UNKNOWN_CHUNKS enables STORE_UNKNOWN_CHUNKS SET_UNKNOWN_CHUNKS
option WRITE_UNKNOWN_CHUNKS enables STORE_UNKNOWN_CHUNKS
# The first way to read user chunks is to have libpng save them for a later call
# to png_get_unknown_chunks, the application must call
# png_set_keep_unknown_chunks to cause this to actually happen (see png.h)
option SAVE_UNKNOWN_CHUNKS requires READ requires UNKNOWN_CHUNKS
option SAVE_UNKNOWN_CHUNKS enables READ_UNKNOWN_CHUNKS
option SAVE_UNKNOWN_CHUNKS requires READ requires SET_UNKNOWN_CHUNKS
option SAVE_UNKNOWN_CHUNKS enables READ_UNKNOWN_CHUNKS STORE_UNKNOWN_CHUNKS
# The second approach is to use an application provided callback to process the
# chunks, the callback can either handle the chunk entirely itself or request
......@@ -664,23 +664,26 @@ option SAVE_UNKNOWN_CHUNKS enables READ_UNKNOWN_CHUNKS
option READ_USER_CHUNKS requires READ requires UNKNOWN_CHUNKS
option READ_USER_CHUNKS enables READ_UNKNOWN_CHUNKS USER_CHUNKS
# A further option allows known chunks to be handled using the unknown code by
# providing the relevant chunks to png_set_keep_unknown_chunks. This is turned
# on by the following option. In 1.6.0 turning this option *off* no longer
# disables png_set_keep_unknown_chunks, a behavior which effectively prevented
# unknown chunk saving by the first mechanism on read.
# Two further options are provided to allow detailed control of the handling.
# The first enables png_set_keep_unknown_chunks; this allows the default to be
# changed from discarding unknown chunks and allows per-chunk control. This is
# required to use the SAVE_UNKNOWN_CHUNKS option. If enabled this option also
# applies to write (see png.h), otherwise the write API simply writes all the
# chunks it is given.
#
# Notice that this option no longer affects the write code either. It can be
# safely disabled and will prevent applications stopping libpng reading known
# chunks.
# The second option extends the unknown handling to allow known chunks to be
# handled as though they were unknown. This option doesn't change any APIs, it
# merely turns on the code to check known as well as unknown chunks.
#
# This option no longer affects the write code. It can be safely disabled and
# will prevent applications stopping libpng reading known chunks.
option SET_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS
option HANDLE_AS_UNKNOWN requires SET_UNKNOWN_CHUNKS
# The following options are derived from the above and should not be turned on
# explicitly.
option READ_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
option READ_UNKNOWN_CHUNKS enables STORE_UNKNOWN_CHUNKS SET_UNKNOWN_CHUNKS
option STORE_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
option SET_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
option CONVERT_tIME requires WRITE_ANCILLARY_CHUNKS
# The "tm" structure is not supported on WindowsCE
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册