Store uncompressed if compression was worse
If the data was uncompressible and this deflate implementation expanded by more than the overhead of simply storing it uncompressed, fall back to deflate's uncompressed storage mode. This bounds the maximum deflated size at the original size plus an overhead of 6 fixed bytes with another 5 bytes per 32767 byte block. Fixes issue #948.
This commit is contained in:
parent
14c224c84e
commit
db6e91b7d8
@ -140,6 +140,7 @@ CREDITS:
|
||||
Ivan Tikhonov
|
||||
github:ignotion
|
||||
Adam Schackart
|
||||
Andrew Kensler
|
||||
|
||||
LICENSE
|
||||
|
||||
@ -969,6 +970,23 @@ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, i
|
||||
(void) stbiw__sbfree(hash_table[i]);
|
||||
STBIW_FREE(hash_table);
|
||||
|
||||
// store uncompressed instead if compression was worse
|
||||
if (stbiw__sbn(out) > data_len + 2 + ((data_len+32766)/32767)*5) {
|
||||
stbiw__sbn(out) = 2; // truncate to DEFLATE 32K window and FLEVEL = 1
|
||||
for (j = 0; j < data_len;) {
|
||||
int blocklen = data_len - j;
|
||||
if (blocklen > 32767) blocklen = 32767;
|
||||
stbiw__sbpush(out, data_len - j == blocklen); // BFINAL = ?, BTYPE = 0 -- no compression
|
||||
stbiw__sbpush(out, STBIW_UCHAR(blocklen)); // LEN
|
||||
stbiw__sbpush(out, STBIW_UCHAR(blocklen >> 8));
|
||||
stbiw__sbpush(out, STBIW_UCHAR(~blocklen)); // NLEN
|
||||
stbiw__sbpush(out, STBIW_UCHAR(~blocklen >> 8));
|
||||
memcpy(out+stbiw__sbn(out), data+j, blocklen);
|
||||
stbiw__sbn(out) += blocklen;
|
||||
j += blocklen;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// compute adler32 on input
|
||||
unsigned int s1=1, s2=0;
|
||||
@ -1599,6 +1617,8 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
|
||||
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
/* Revision history
|
||||
1.15 ( )
|
||||
make Deflate code emit uncompressed blocks when it would otherwise expand
|
||||
1.14 (2020-02-02) updated JPEG writer to downsample chroma channels
|
||||
1.13
|
||||
1.12
|
||||
|
Loading…
Reference in New Issue
Block a user