mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[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.
This commit is contained in:
parent
025d415838
commit
4a6c6df6c7
8
ANNOUNCE
8
ANNOUNCE
@ -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
|
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
|
(not currently part of the test suite). Comments in the header files now
|
||||||
explain how the unknown handling works.
|
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
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
7
CHANGES
7
CHANGES
@ -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
|
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
|
(not currently part of the test suite). Comments in the header files now
|
||||||
explain how the unknown handling works.
|
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
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
@ -2814,7 +2814,9 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
|
|||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||||
|
# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
||||||
keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
|
keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* One of the following methods will read the chunk or skip it (at least one
|
/* One of the following methods will read the chunk or skip it (at least one
|
||||||
|
23
pngset.c
23
pngset.c
@ -1111,6 +1111,29 @@ png_set_unknown_chunks(png_const_structrp png_ptr,
|
|||||||
if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0)
|
if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0)
|
||||||
return;
|
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
|
/* 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
|
* unknown critical chunks could be lost with just a warning resulting in
|
||||||
* undefined behavior. Changing to png_malloc fixes this by producing a
|
* undefined behavior. Changing to png_malloc fixes this by producing a
|
||||||
|
16
pngtest.c
16
pngtest.c
@ -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 */
|
/* 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
|
/* (sTER is a public chunk not yet known by libpng. vpAg is a private
|
||||||
chunk used in ImageMagick to store "virtual page" size). */
|
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
|
/* 0: sTER mode + 1
|
||||||
* 1: vpAg width
|
* 1: vpAg width
|
||||||
@ -580,6 +582,7 @@ static png_uint_32 user_chunk_data[4];
|
|||||||
* 3: vpAg units
|
* 3: vpAg units
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
|
||||||
static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
|
static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr,
|
||||||
png_unknown_chunkp chunk)
|
png_unknown_chunkp chunk)
|
||||||
{
|
{
|
||||||
@ -726,7 +729,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
|
|||||||
pngtest_warning);
|
pngtest_warning);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
|
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
|
||||||
user_chunk_data[0] = 0;
|
user_chunk_data[0] = 0;
|
||||||
user_chunk_data[1] = 0;
|
user_chunk_data[1] = 0;
|
||||||
user_chunk_data[2] = 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);
|
png_set_write_user_transform_fn(write_ptr, count_zero_samples);
|
||||||
#endif
|
#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
|
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
||||||
# ifndef PNG_HANDLE_CHUNK_ALWAYS
|
# ifndef PNG_HANDLE_CHUNK_ALWAYS
|
||||||
# define PNG_HANDLE_CHUNK_ALWAYS 3
|
# define PNG_HANDLE_CHUNK_ALWAYS 3
|
||||||
@ -875,6 +881,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
|
|||||||
# endif
|
# endif
|
||||||
png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
|
png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_IF_SAFE,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pngtest_debug("Reading info struct");
|
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);
|
png_write_info(write_ptr, write_info_ptr);
|
||||||
|
|
||||||
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
if (user_chunk_data[0] != 0)
|
if (user_chunk_data[0] != 0)
|
||||||
{
|
{
|
||||||
png_byte png_sTER[5] = {115, 84, 69, 82, '\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
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SINGLE_ROWBUF_ALLOC
|
#ifdef SINGLE_ROWBUF_ALLOC
|
||||||
pngtest_debug("Allocating row buffer...");
|
pngtest_debug("Allocating row buffer...");
|
||||||
|
@ -35,6 +35,10 @@ write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
|
|||||||
++up)
|
++up)
|
||||||
if (up->location & where)
|
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);
|
int keep = png_handle_as_unknown(png_ptr, up->name);
|
||||||
|
|
||||||
/* NOTE: this code is radically different from the read side in the
|
/* 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_ALWAYS ||
|
||||||
(keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
|
(keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
|
||||||
png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
|
png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/* TODO: review, what is wrong with a zero length unknown chunk? */
|
/* TODO: review, what is wrong with a zero length unknown chunk? */
|
||||||
if (up->size == 0)
|
if (up->size == 0)
|
||||||
@ -872,7 +877,7 @@ png_write_destroy(png_structrp png_ptr)
|
|||||||
png_free(png_ptr, png_ptr->inv_filter_costs);
|
png_free(png_ptr, png_ptr->inv_filter_costs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
|
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
||||||
png_free(png_ptr, png_ptr->chunk_list);
|
png_free(png_ptr, png_ptr->chunk_list);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -647,13 +647,13 @@ option UNKNOWN_CHUNKS
|
|||||||
# set by png_set_unknown_chunks will be written otherwise it is an error to call
|
# set by png_set_unknown_chunks will be written otherwise it is an error to call
|
||||||
# that API on a write struct.
|
# that API on a write struct.
|
||||||
option WRITE_UNKNOWN_CHUNKS requires WRITE requires UNKNOWN_CHUNKS
|
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
|
# 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
|
# to png_get_unknown_chunks, the application must call
|
||||||
# png_set_keep_unknown_chunks to cause this to actually happen (see png.h)
|
# 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 requires READ requires SET_UNKNOWN_CHUNKS
|
||||||
option SAVE_UNKNOWN_CHUNKS enables READ_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
|
# 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
|
# 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 requires READ requires UNKNOWN_CHUNKS
|
||||||
option READ_USER_CHUNKS enables READ_UNKNOWN_CHUNKS USER_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
|
# Two further options are provided to allow detailed control of the handling.
|
||||||
# providing the relevant chunks to png_set_keep_unknown_chunks. This is turned
|
# The first enables png_set_keep_unknown_chunks; this allows the default to be
|
||||||
# on by the following option. In 1.6.0 turning this option *off* no longer
|
# changed from discarding unknown chunks and allows per-chunk control. This is
|
||||||
# disables png_set_keep_unknown_chunks, a behavior which effectively prevented
|
# required to use the SAVE_UNKNOWN_CHUNKS option. If enabled this option also
|
||||||
# unknown chunk saving by the first mechanism on read.
|
# 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
|
# The second option extends the unknown handling to allow known chunks to be
|
||||||
# safely disabled and will prevent applications stopping libpng reading known
|
# handled as though they were unknown. This option doesn't change any APIs, it
|
||||||
# chunks.
|
# 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
|
option HANDLE_AS_UNKNOWN requires SET_UNKNOWN_CHUNKS
|
||||||
|
|
||||||
# The following options are derived from the above and should not be turned on
|
# The following options are derived from the above and should not be turned on
|
||||||
# explicitly.
|
# explicitly.
|
||||||
option READ_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
|
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 STORE_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
|
||||||
option SET_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
|
|
||||||
|
|
||||||
option CONVERT_tIME requires WRITE_ANCILLARY_CHUNKS
|
option CONVERT_tIME requires WRITE_ANCILLARY_CHUNKS
|
||||||
# The "tm" structure is not supported on WindowsCE
|
# The "tm" structure is not supported on WindowsCE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user