[devel] Optimize the zlib CMF byte in non-IDAT compressed chunks
This commit is contained in:
parent
e99107b1aa
commit
6785856858
1
ANNOUNCE
1
ANNOUNCE
@ -36,6 +36,7 @@ Version 1.5.3beta02 [April 2, 2011]
|
|||||||
Only compile the new zlib re-initializing code when text or iCCP is
|
Only compile the new zlib re-initializing code when text or iCCP is
|
||||||
supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro.
|
supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro.
|
||||||
Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03).
|
Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03).
|
||||||
|
Optimize the zlib CMF byte in non-IDAT compressed chunks
|
||||||
|
|
||||||
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
|
||||||
|
1
CHANGES
1
CHANGES
@ -3297,6 +3297,7 @@ Version 1.5.3beta02 [April 2, 2011]
|
|||||||
Only compile the new zlib re-initializing code when text or iCCP is
|
Only compile the new zlib re-initializing code when text or iCCP is
|
||||||
supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro.
|
supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro.
|
||||||
Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03).
|
Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03).
|
||||||
|
Optimize the zlib CMF byte in non-IDAT compressed chunks
|
||||||
|
|
||||||
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
|
||||||
|
74
pngwutil.c
74
pngwutil.c
@ -220,13 +220,12 @@ png_text_compress(png_structp png_ptr,
|
|||||||
comp->max_output_ptr = 0;
|
comp->max_output_ptr = 0;
|
||||||
comp->output_ptr = NULL;
|
comp->output_ptr = NULL;
|
||||||
comp->input = NULL;
|
comp->input = NULL;
|
||||||
comp->input_len = 0;
|
comp->input_len = text_len;
|
||||||
|
|
||||||
/* We may just want to pass the text right through */
|
/* We may just want to pass the text right through */
|
||||||
if (compression == PNG_TEXT_COMPRESSION_NONE)
|
if (compression == PNG_TEXT_COMPRESSION_NONE)
|
||||||
{
|
{
|
||||||
comp->input = (png_const_bytep)text;
|
comp->input = (png_const_bytep)text;
|
||||||
comp->input_len = text_len;
|
|
||||||
return((int)text_len);
|
return((int)text_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +287,6 @@ png_text_compress(png_structp png_ptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set up the compression buffers */
|
/* Set up the compression buffers */
|
||||||
|
|
||||||
/* TODO: the following cast hides a potential overflow problem. */
|
/* TODO: the following cast hides a potential overflow problem. */
|
||||||
png_ptr->zstream.avail_in = (uInt)text_len;
|
png_ptr->zstream.avail_in = (uInt)text_len;
|
||||||
|
|
||||||
@ -451,6 +449,69 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1 /* For testing */
|
||||||
|
|
||||||
|
if (comp->input_len >= 2 && comp->input_len < 16384)
|
||||||
|
{
|
||||||
|
unsigned int z_cmf; /* zlib compression method and flags */
|
||||||
|
|
||||||
|
/* Optimize the CMF field in the zlib stream. This hack of the zlib
|
||||||
|
* stream is compliant to the stream specification.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (comp->num_output_ptr)
|
||||||
|
z_cmf = comp->output_ptr[0][0];
|
||||||
|
else
|
||||||
|
z_cmf = png_ptr->zbuf[0];
|
||||||
|
|
||||||
|
if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
|
||||||
|
{
|
||||||
|
unsigned int z_cinfo;
|
||||||
|
unsigned int half_z_window_size;
|
||||||
|
png_uint_32 uncompressed_idat_size = comp->input_len;
|
||||||
|
|
||||||
|
z_cinfo = z_cmf >> 4;
|
||||||
|
half_z_window_size = 1 << (z_cinfo + 7);
|
||||||
|
|
||||||
|
while (uncompressed_idat_size <= half_z_window_size &&
|
||||||
|
half_z_window_size >= 256)
|
||||||
|
{
|
||||||
|
z_cinfo--;
|
||||||
|
half_z_window_size >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
|
||||||
|
|
||||||
|
if (comp->num_output_ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (comp->output_ptr[0][0] != z_cmf)
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
comp->output_ptr[0][0] = (png_byte)z_cmf;
|
||||||
|
tmp = comp->output_ptr[0][1] & 0xe0;
|
||||||
|
tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
|
||||||
|
comp->output_ptr[0][1] = (png_byte)tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
png_ptr->zbuf[0] = (png_byte)z_cmf;
|
||||||
|
tmp = png_ptr->zbuf[1] & 0xe0;
|
||||||
|
tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
|
||||||
|
png_ptr->zbuf[1] = (png_byte)tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
png_error(png_ptr,
|
||||||
|
"Invalid zlib compression method or flags in non-IDAT chunk");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Write saved output buffers, if any */
|
/* Write saved output buffers, if any */
|
||||||
for (i = 0; i < comp->num_output_ptr; i++)
|
for (i = 0; i < comp->num_output_ptr; i++)
|
||||||
{
|
{
|
||||||
@ -842,7 +903,8 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
|
|||||||
/* Compute the maximum possible length of the datastream */
|
/* Compute the maximum possible length of the datastream */
|
||||||
|
|
||||||
/* Number of pixels, plus for each row a filter byte and possible
|
/* Number of pixels, plus for each row a filter byte and possible
|
||||||
* padding byte
|
* and possibly a padding byte, so increase the maximum
|
||||||
|
* size to account for these.
|
||||||
*/
|
*/
|
||||||
unsigned int z_cinfo;
|
unsigned int z_cinfo;
|
||||||
unsigned int half_z_window_size;
|
unsigned int half_z_window_size;
|
||||||
@ -1013,7 +1075,10 @@ png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type,
|
|||||||
(png_size_t)(name_len + 2));
|
(png_size_t)(name_len + 2));
|
||||||
|
|
||||||
if (profile_len)
|
if (profile_len)
|
||||||
|
{
|
||||||
|
comp.input_len = profile_len;
|
||||||
png_write_compressed_data_out(png_ptr, &comp);
|
png_write_compressed_data_out(png_ptr, &comp);
|
||||||
|
}
|
||||||
|
|
||||||
png_write_chunk_end(png_ptr);
|
png_write_chunk_end(png_ptr);
|
||||||
png_free(png_ptr, new_name);
|
png_free(png_ptr, new_name);
|
||||||
@ -1594,6 +1659,7 @@ png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text,
|
|||||||
png_write_chunk_data(png_ptr, &buf, (png_size_t)1);
|
png_write_chunk_data(png_ptr, &buf, (png_size_t)1);
|
||||||
|
|
||||||
/* Write the compressed data */
|
/* Write the compressed data */
|
||||||
|
comp.input_len = text_len;
|
||||||
png_write_compressed_data_out(png_ptr, &comp);
|
png_write_compressed_data_out(png_ptr, &comp);
|
||||||
|
|
||||||
/* Close the chunk */
|
/* Close the chunk */
|
||||||
|
Loading…
Reference in New Issue
Block a user