mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
Separate png_compress_IDAT into w/c
I.e. write/compress, also remove some trailing spaces and clean up pnglibconf stuff. Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
parent
8978eba436
commit
8fe2eac47f
28
pngstruct.h
28
pngstruct.h
@ -566,7 +566,7 @@ struct png_struct_def
|
||||
* wherein !(r==g==b).
|
||||
*/
|
||||
#endif /* RGB_TO_GRAY */
|
||||
#endif /* TRANFORM_MECH */
|
||||
#endif /* TRANSFORM_MECH */
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
/* These, and IDAT_size below, control how much input and output (at most) is
|
||||
@ -599,12 +599,7 @@ struct png_struct_def
|
||||
int zlib_set_window_bits;
|
||||
int zlib_set_mem_level;
|
||||
int zlib_set_strategy;
|
||||
|
||||
unsigned int zbuffer_start; /* Bytes written from start */
|
||||
png_uint_32 zbuffer_len; /* Length of data in list */
|
||||
png_compression_bufferp zbuffer_list; /* Created on demand during write */
|
||||
png_compression_bufferp *zbuffer_end; /* 'next' field of current buffer */
|
||||
#endif
|
||||
#endif /* WRITE */
|
||||
|
||||
/* ERROR HANDLING */
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
@ -748,14 +743,23 @@ struct png_struct_def
|
||||
* zlib expects a 'zstream' as the fundamental control structure, it allows
|
||||
* all the parameters to be passed as one pointer.
|
||||
*/
|
||||
png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
|
||||
z_stream zstream; /* decompression structure */
|
||||
unsigned int zstream_start:1; /* before first byte of stream */
|
||||
unsigned int zstream_ended:1; /* no more zlib output available */
|
||||
unsigned int zstream_error:1; /* zlib error message has been output */
|
||||
png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
|
||||
# ifdef PNG_WRITE_SUPPORTED
|
||||
png_compression_bufferp zbuffer_list; /* Created on demand during write */
|
||||
png_compression_bufferp *zbuffer_end; /* 'next' field of current buffer */
|
||||
png_uint_32 zbuffer_len; /* Length of data in list */
|
||||
unsigned int zbuffer_start; /* Bytes written from start */
|
||||
# endif /* WRITE */
|
||||
# ifdef PNG_READ_SUPPORTED
|
||||
unsigned int zstream_ended:1; /* no more zlib output available [read] */
|
||||
unsigned int zstream_error:1; /* zlib error message has been output [read] */
|
||||
# endif /* READ */
|
||||
# ifdef PNG_PROGRESSIVE_READ_SUPPORTED
|
||||
unsigned int zstream_eod :1; /* all the required uncompressed data has been
|
||||
* received; set by the zstream using code for
|
||||
* its own purposes. */
|
||||
* its own purposes. [progressive read] */
|
||||
# endif /* PROGRESSIVE_READ */
|
||||
|
||||
/* MNG SUPPORT */
|
||||
#ifdef PNG_MNG_FEATURES_SUPPORTED
|
||||
|
311
pngwutil.c
311
pngwutil.c
@ -1907,11 +1907,148 @@ png_start_IDAT(png_structrp png_ptr)
|
||||
}
|
||||
|
||||
static void
|
||||
png_compress_IDAT(png_structrp png_ptr, png_const_voidp input, uInt input_len,
|
||||
int flush)
|
||||
png_write_IDAT(png_structrp png_ptr, int end_of_image)
|
||||
{
|
||||
png_compression_bufferp *listp = &png_ptr->zbuffer_list;
|
||||
png_compression_bufferp list;
|
||||
png_uint_32 output_len = png_ptr->zbuffer_len;
|
||||
png_uint_32 start = png_ptr->zbuffer_start;
|
||||
png_uint_32 size = png_ptr->IDAT_size;
|
||||
const png_uint_32 min_size = (end_of_image ? 1U : size);
|
||||
|
||||
affirm(output_len >= min_size);
|
||||
|
||||
/* png_struct::zbuffer_end points to the pointer to the next (unused)
|
||||
* compression buffer. We don't need those blocks to produce output so
|
||||
* free them now to save space. This also ensures that *zbuffer_end is
|
||||
* NULL so can be used to store the list head when wrapping the list.
|
||||
*/
|
||||
png_free_buffer_list(png_ptr, png_ptr->zbuffer_end);
|
||||
|
||||
/* Write at least one chunk, of size 'size', write chunks until
|
||||
* 'output_len' is less than 'min_size'.
|
||||
*/
|
||||
list = *listp;
|
||||
|
||||
/* First, if this is the very first IDAT (PNG_HAVE_IDAT not set)
|
||||
* optimize the CINFO field:
|
||||
*/
|
||||
# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
|
||||
if ((png_ptr->mode & PNG_HAVE_IDAT) == 0U)
|
||||
{
|
||||
affirm(start == 0U);
|
||||
optimize_cmf(list->output, png_image_size(png_ptr));
|
||||
}
|
||||
# endif /* WRITE_OPTIMIZE_CMF */
|
||||
|
||||
do /* write chunks */
|
||||
{
|
||||
/* 'size' is the size of the chunk to write, limited to IDAT_size:
|
||||
*/
|
||||
if (size > output_len) /* Z_FINISH */
|
||||
size = output_len;
|
||||
|
||||
debug(size >= min_size);
|
||||
png_write_chunk_header(png_ptr, png_IDAT, size);
|
||||
|
||||
do /* write the data of one chunk */
|
||||
{
|
||||
/* The chunk data may be split across multiple compression
|
||||
* buffers. This loop moves 'list' down the available
|
||||
* compression buffers.
|
||||
*/
|
||||
png_uint_32 avail = PNG_ROW_BUFFER_SIZE - start; /* in *list */
|
||||
|
||||
if (avail > output_len) /* valid bytes */
|
||||
avail = output_len;
|
||||
|
||||
if (avail > size) /* bytes needed for chunk */
|
||||
avail = size;
|
||||
|
||||
affirm(list != NULL && avail > 0U &&
|
||||
start+avail <= PNG_ROW_BUFFER_SIZE);
|
||||
png_write_chunk_data(png_ptr, list->output+start, avail);
|
||||
output_len -= avail;
|
||||
size -= avail;
|
||||
start += avail;
|
||||
|
||||
if (start == PNG_ROW_BUFFER_SIZE)
|
||||
{
|
||||
/* End of the buffer. If all the compressed data has been
|
||||
* consumed (output_len == 0) this will set list to NULL
|
||||
* because of the png_free_buffer_list call above. At this
|
||||
* point 'size' should be 0 too and the loop will terminate.
|
||||
*/
|
||||
start = 0U;
|
||||
listp = &list->next;
|
||||
list = *listp; /* May be NULL at the end */
|
||||
}
|
||||
} while (size > 0);
|
||||
|
||||
png_write_chunk_end(png_ptr);
|
||||
size = png_ptr->IDAT_size; /* For the next chunk */
|
||||
} while (output_len >= min_size);
|
||||
|
||||
png_ptr->mode |= PNG_HAVE_IDAT;
|
||||
png_ptr->zbuffer_len = output_len;
|
||||
|
||||
if (output_len > 0U) /* Still got stuff to write */
|
||||
{
|
||||
affirm(!end_of_image && list != NULL);
|
||||
|
||||
/* If any compression buffers have been completely written move them
|
||||
* to the end of the list so that they can be re-used and move
|
||||
* 'list' to the head:
|
||||
*/
|
||||
if (listp != &png_ptr->zbuffer_list) /* list not at start */
|
||||
{
|
||||
debug(list != png_ptr->zbuffer_list /* obviously */ &&
|
||||
listp != png_ptr->zbuffer_end /* because *end == NULL */);
|
||||
*png_ptr->zbuffer_end = png_ptr->zbuffer_list;
|
||||
*listp = NULL;
|
||||
png_ptr->zbuffer_list = list;
|
||||
}
|
||||
|
||||
/* 'list' is now at the start, so 'start' can be stored. */
|
||||
png_ptr->zbuffer_start = start;
|
||||
png_ptr->zbuffer_len = output_len;
|
||||
}
|
||||
|
||||
else /* output_len == 0U; all compressed data has been written */
|
||||
{
|
||||
if (end_of_image)
|
||||
{
|
||||
png_ptr->zowner = 0U; /* release z_stream */
|
||||
png_ptr->mode |= PNG_AFTER_IDAT;
|
||||
}
|
||||
|
||||
/* Else: this is unlikely but possible; the compression code managed
|
||||
* to exactly fill an IDAT chunk with the data for this block of row
|
||||
* bytes so nothing is left in the buffer list. Simply reset the
|
||||
* output pointers to the start of the list. This code is executed
|
||||
* on Z_FINISH as well just to make the state safe.
|
||||
*/
|
||||
png_ptr->zstream.next_out = NULL;
|
||||
png_ptr->zstream.avail_out = 0U;
|
||||
png_ptr->zbuffer_start = 0U;
|
||||
png_ptr->zbuffer_len = 0U;
|
||||
png_ptr->zbuffer_end = &png_ptr->zbuffer_list;
|
||||
} /* output_len == 0 */
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
png_compression_bufferp *zbuffer_end; /* 'next' field of current buffer */
|
||||
png_uint_32 zbuffer_len; /* Length of data in list */
|
||||
} png_IDAT_compression_state;
|
||||
|
||||
static int
|
||||
png_compress_IDAT_test(png_structrp png_ptr, png_IDAT_compression_state *state,
|
||||
z_stream *zstream, png_const_voidp input, uInt input_len, int flush)
|
||||
{
|
||||
png_uint_32 output_len = 0U;
|
||||
int ret;
|
||||
|
||||
|
||||
/* The stream must have been claimed: */
|
||||
affirm(png_ptr->zowner == png_IDAT);
|
||||
|
||||
@ -1919,22 +2056,34 @@ png_compress_IDAT(png_structrp png_ptr, png_const_voidp input, uInt input_len,
|
||||
* buffer list. next_in must be set here, avail_in comes from the input_len
|
||||
* parameter:
|
||||
*/
|
||||
{
|
||||
png_uint_32 output_len = 0U;
|
||||
zstream->next_in = PNGZ_INPUT_CAST(png_voidcast(const Bytef*, input));
|
||||
ret = png_compress(png_ptr, zstream, &state->zbuffer_end, input_len,
|
||||
&output_len, flush);
|
||||
implies(ret == Z_OK || ret == Z_FINISH, zstream->avail_in == 0U);
|
||||
zstream->next_in = NULL;
|
||||
zstream->avail_in = 0U; /* safety */
|
||||
|
||||
png_ptr->zstream.next_in =
|
||||
PNGZ_INPUT_CAST(png_voidcast(const Bytef*,input));
|
||||
ret = png_compress(png_ptr, &png_ptr->zstream, &png_ptr->zbuffer_end,
|
||||
input_len, &output_len, flush);
|
||||
implies(ret == Z_OK || ret == Z_FINISH, png_ptr->zstream.avail_in == 0U);
|
||||
png_ptr->zstream.next_in = NULL;
|
||||
png_ptr->zstream.avail_in = 0U; /* safety */
|
||||
/* If IDAT_size is set to PNG_UINT_31_MAX the length will be larger, but
|
||||
* not enough to overflow a png_uint_32.
|
||||
*/
|
||||
state->zbuffer_len += output_len;
|
||||
return ret;
|
||||
|
||||
/* If IDAT_size is set to PNG_UINT_31_MAX the length will be larger, but
|
||||
* not enough to overflow a png_uint_32.
|
||||
*/
|
||||
png_ptr->zbuffer_len += output_len;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
png_compress_IDAT(png_structp png_ptr, png_const_voidp input, uInt input_len,
|
||||
int flush)
|
||||
{
|
||||
png_IDAT_compression_state state;
|
||||
int ret;
|
||||
|
||||
state.zbuffer_end = png_ptr->zbuffer_end;
|
||||
state.zbuffer_len = png_ptr->zbuffer_len;
|
||||
ret = png_compress_IDAT_test(png_ptr, &state, &png_ptr->zstream, input,
|
||||
input_len, flush);
|
||||
png_ptr->zbuffer_end = state.zbuffer_end;
|
||||
png_ptr->zbuffer_len = state.zbuffer_len;
|
||||
|
||||
/* Check the return code. */
|
||||
if (ret == Z_OK || ret == Z_STREAM_END)
|
||||
@ -1956,133 +2105,7 @@ png_compress_IDAT(png_structrp png_ptr, png_const_voidp input, uInt input_len,
|
||||
* written this function call is complete.
|
||||
*/
|
||||
if (flush == Z_FINISH || png_ptr->zbuffer_len >= png_ptr->IDAT_size)
|
||||
{
|
||||
png_compression_bufferp *listp = &png_ptr->zbuffer_list;
|
||||
png_compression_bufferp list;
|
||||
png_uint_32 output_len = png_ptr->zbuffer_len;
|
||||
png_uint_32 start = png_ptr->zbuffer_start;
|
||||
png_uint_32 size = png_ptr->IDAT_size;
|
||||
const png_uint_32 min_size = (flush == Z_FINISH ? 1U : size);
|
||||
|
||||
affirm(output_len >= min_size);
|
||||
|
||||
/* png_struct::zbuffer_end points to the pointer to the next (unused)
|
||||
* compression buffer. We don't need those blocks to produce output so
|
||||
* free them now to save space. This also ensures that *zbuffer_end is
|
||||
* NULL so can be used to store the list head when wrapping the list.
|
||||
*/
|
||||
png_free_buffer_list(png_ptr, png_ptr->zbuffer_end);
|
||||
|
||||
/* Write at least one chunk, of size 'size', write chunks until
|
||||
* 'output_len' is less than 'min_size'.
|
||||
*/
|
||||
list = *listp;
|
||||
|
||||
/* First, if this is the very first IDAT (PNG_HAVE_IDAT not set)
|
||||
* optimize the CINFO field:
|
||||
*/
|
||||
# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
|
||||
if ((png_ptr->mode & PNG_HAVE_IDAT) == 0U)
|
||||
{
|
||||
affirm(start == 0U);
|
||||
optimize_cmf(list->output, png_image_size(png_ptr));
|
||||
}
|
||||
# endif /* WRITE_OPTIMIZE_CMF */
|
||||
|
||||
do /* write chunks */
|
||||
{
|
||||
/* 'size' is the size of the chunk to write, limited to IDAT_size:
|
||||
*/
|
||||
if (size > output_len) /* Z_FINISH */
|
||||
size = output_len;
|
||||
|
||||
debug(size >= min_size);
|
||||
png_write_chunk_header(png_ptr, png_IDAT, size);
|
||||
|
||||
do /* write the data of one chunk */
|
||||
{
|
||||
/* The chunk data may be split across multiple compression
|
||||
* buffers. This loop moves 'list' down the available
|
||||
* compression buffers.
|
||||
*/
|
||||
png_uint_32 avail = PNG_ROW_BUFFER_SIZE - start; /* in *list */
|
||||
|
||||
if (avail > output_len) /* valid bytes */
|
||||
avail = output_len;
|
||||
|
||||
if (avail > size) /* bytes needed for chunk */
|
||||
avail = size;
|
||||
|
||||
affirm(list != NULL && avail > 0U &&
|
||||
start+avail <= PNG_ROW_BUFFER_SIZE);
|
||||
png_write_chunk_data(png_ptr, list->output+start, avail);
|
||||
output_len -= avail;
|
||||
size -= avail;
|
||||
start += avail;
|
||||
|
||||
if (start == PNG_ROW_BUFFER_SIZE)
|
||||
{
|
||||
/* End of the buffer. If all the compressed data has been
|
||||
* consumed (output_len == 0) this will set list to NULL
|
||||
* because of the png_free_buffer_list call above. At this
|
||||
* point 'size' should be 0 too and the loop will terminate.
|
||||
*/
|
||||
start = 0U;
|
||||
listp = &list->next;
|
||||
list = *listp; /* May be NULL at the end */
|
||||
}
|
||||
} while (size > 0);
|
||||
|
||||
png_write_chunk_end(png_ptr);
|
||||
size = png_ptr->IDAT_size; /* For the next chunk */
|
||||
} while (output_len >= min_size);
|
||||
|
||||
png_ptr->mode |= PNG_HAVE_IDAT;
|
||||
png_ptr->zbuffer_len = output_len;
|
||||
|
||||
if (output_len > 0U) /* Still got stuff to write */
|
||||
{
|
||||
affirm(flush != Z_FINISH && list != NULL);
|
||||
|
||||
/* If any compression buffers have been completely written move them
|
||||
* to the end of the list so that they can be re-used and move
|
||||
* 'list' to the head:
|
||||
*/
|
||||
if (listp != &png_ptr->zbuffer_list) /* list not at start */
|
||||
{
|
||||
debug(list != png_ptr->zbuffer_list /* obviously */ &&
|
||||
listp != png_ptr->zbuffer_end /* because *end == NULL */);
|
||||
*png_ptr->zbuffer_end = png_ptr->zbuffer_list;
|
||||
*listp = NULL;
|
||||
png_ptr->zbuffer_list = list;
|
||||
}
|
||||
|
||||
/* 'list' is now at the start, so 'start' can be stored. */
|
||||
png_ptr->zbuffer_start = start;
|
||||
png_ptr->zbuffer_len = output_len;
|
||||
}
|
||||
|
||||
else /* output_len == 0U; all compressed data has been written */
|
||||
{
|
||||
if (flush == Z_FINISH) /* end of data */
|
||||
{
|
||||
png_ptr->zowner = 0U; /* release z_stream */
|
||||
png_ptr->mode |= PNG_AFTER_IDAT;
|
||||
}
|
||||
|
||||
/* Else: this is unlikely but possible; the compression code managed
|
||||
* to exactly fill an IDAT chunk with the data for this block of row
|
||||
* bytes so nothing is left in the buffer list. Simply reset the
|
||||
* output pointers to the start of the list. This code is executed
|
||||
* on Z_FINISH as well just to make the state safe.
|
||||
*/
|
||||
png_ptr->zstream.next_out = NULL;
|
||||
png_ptr->zstream.avail_out = 0U;
|
||||
png_ptr->zbuffer_start = 0U;
|
||||
png_ptr->zbuffer_len = 0U;
|
||||
png_ptr->zbuffer_end = &png_ptr->zbuffer_list;
|
||||
} /* output_len == 0 */
|
||||
} /* flush == FINISH || png_ptr->zbuffer_len >= png_ptr->IDAT_size */
|
||||
png_write_IDAT(png_ptr, flush == Z_FINISH);
|
||||
}
|
||||
|
||||
else /* ret != Z_OK && ret != Z_STREAM_END */
|
||||
|
@ -243,7 +243,7 @@ $1 == "file" && NF >= 2{
|
||||
|
||||
# option NAME ( (requires|enables|if) NAME* | on | off | disabled |
|
||||
# sets SETTING VALUE+ )*
|
||||
#
|
||||
#
|
||||
# Declares an option 'NAME' and describes its default setting (disabled)
|
||||
# and its relationship to other options. The option is disabled
|
||||
# unless *all* the options listed after 'requires' are set and at
|
||||
|
@ -125,7 +125,7 @@ file pnglibconf.h scripts/pnglibconf.dfa PNGLCONF_H
|
||||
#
|
||||
# To avoid confusion use -DPNG_foo_SUPPORTED= on the command line, which does
|
||||
# the same thing as the #define.
|
||||
#
|
||||
#
|
||||
# SUMMARY:
|
||||
# These lines/macro settings are equivalent:
|
||||
#
|
||||
@ -460,7 +460,7 @@ option SET_USER_LIMITS requires USER_LIMITS
|
||||
# See the comments above about how to change options and settings.
|
||||
|
||||
# READ/WRITE tranform support
|
||||
#
|
||||
#
|
||||
# The internal TRANSFORM_MECH options are used to turn on (or off) the required
|
||||
# support code for the read and write transforms. They are off by default,
|
||||
# switching them on is not a good idea. Switching them off will cause the build
|
||||
@ -496,7 +496,7 @@ option READ_16BIT requires READ enables 16BIT
|
||||
option READ_TRANSFORMS requires READ
|
||||
= NO_READ_TRANSFORMS READ_TRANSFORMS_NOT_SUPPORTED
|
||||
|
||||
option READ_QUANTIZE requires READ_TRANSFORMS enables TRANFORM_MECH
|
||||
option READ_QUANTIZE requires READ_TRANSFORMS enables TRANSFORM_MECH
|
||||
|
||||
# Read gamma handling. Gamma processing is a core part of libpng and many of
|
||||
# the capabilities are dependent on libpng performing gamma correction.
|
||||
|
@ -116,7 +116,6 @@
|
||||
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_TEXT_SUPPORTED
|
||||
#define PNG_TIME_RFC1123_SUPPORTED
|
||||
#define PNG_TRANFORM_MECH_SUPPORTED
|
||||
#define PNG_TRANSFORM_MECH_SUPPORTED
|
||||
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_USER_CHUNKS_SUPPORTED
|
||||
@ -194,7 +193,7 @@
|
||||
#define PNG_DEFAULT_GAMMA_ACCURACY 665
|
||||
#define PNG_DEFAULT_READ_MACROS 1
|
||||
#define PNG_GAMMA_THRESHOLD_FIXED 153
|
||||
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
|
||||
#define PNG_IDAT_READ_SIZE 4096
|
||||
#define PNG_INFLATE_BUF_SIZE 1024
|
||||
#define PNG_MAX_GAMMA_8 11
|
||||
#define PNG_QUANTIZE_BLUE_BITS 5
|
||||
@ -206,7 +205,7 @@
|
||||
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
|
||||
#define PNG_USER_HEIGHT_MAX 1000000
|
||||
#define PNG_USER_WIDTH_MAX 1000000
|
||||
#define PNG_ZBUF_SIZE 8192
|
||||
#define PNG_ZBUF_SIZE 4096
|
||||
#define PNG_ZLIB_HEADER <zlib.h>
|
||||
#define PNG_ZLIB_VERNUM 0
|
||||
#define PNG_Z_DEFAULT_COMPRESSION (-1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user