Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deflateBound and compressBound returning very small size estimates. #1071

Merged
merged 1 commit into from
Dec 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,11 @@ z_size_t Z_EXPORT PREFIX(compressBound)(z_size_t sourceLen) {
return complen + ZLIB_WRAPLEN;

#ifndef NO_QUICK_STRATEGY
/* Quick deflate strategy worse case is 9 bits per literal, rounded to nearest byte,
plus the size of block & gzip headers and footers */
return sourceLen + ((sourceLen + 13 + 7) >> 3) + 18;
return sourceLen /* The source size itself */
+ DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */
+ DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */
+ ZLIB_WRAPLEN; /* zlib wrapper */
#else
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13;
return sourceLen + (sourceLen >> 4) + 7 + ZLIB_WRAPLEN;
#endif
}
16 changes: 11 additions & 5 deletions deflate.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,11 +611,11 @@ unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long
wraplen = 0;
break;
case 1: /* zlib wrapper */
wraplen = 6 + (s->strstart ? 4 : 0);
wraplen = ZLIB_WRAPLEN + (s->strstart ? 4 : 0);
break;
#ifdef GZIP
case 2: /* gzip wrapper */
wraplen = 18;
wraplen = GZIP_WRAPLEN;
if (s->gzhead != NULL) { /* user-supplied gzip header */
unsigned char *str;
if (s->gzhead->extra != NULL) {
Expand All @@ -639,16 +639,22 @@ unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long
break;
#endif
default: /* for compiler happiness */
wraplen = 6;
wraplen = ZLIB_WRAPLEN;
}

/* if not default parameters, return conservative bound */
if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || /* hook for IBM Z DFLTCC */
s->w_bits != 15 || HASH_BITS < 15)
return complen + wraplen;

/* default settings: return tight bound for that case */
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13 - 6 + wraplen;
#ifndef NO_QUICK_STRATEGY
return sourceLen /* The source size itself */
+ DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */
+ DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */
+ wraplen; /* none, zlib or gzip wrapper */
#else
return sourceLen + (sourceLen >> 4) + 7 + wraplen;
#endif
}

/* =========================================================================
Expand Down
2 changes: 1 addition & 1 deletion test/switchlevels.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last)
goto done;
}

compsize = 100 + 2 * PREFIX(deflateBound)(strm, size);
compsize = PREFIX(deflateBound)(strm, size);
buf = malloc(size + compsize);
if (buf == NULL) {
fprintf(stderr, "Out of memory\n");
Expand Down
14 changes: 13 additions & 1 deletion zutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,19 @@ extern z_const char * const PREFIX(z_errmsg)[10]; /* indexed by 2-zlib_error */
#define ADLER32_INITIAL_VALUE 1 /* initial adler-32 hash value */
#define CRC32_INITIAL_VALUE 0 /* initial crc-32 hash value */

#define ZLIB_WRAPLEN 6 /* zlib format overhead */
#define ZLIB_WRAPLEN 6 /* zlib format overhead */
#define GZIP_WRAPLEN 18 /* gzip format overhead */

#define DEFLATE_HEADER_BITS 3
#define DEFLATE_EOBS_BITS 15
#define DEFLATE_PAD_BITS 6
#define DEFLATE_BLOCK_OVERHEAD ((DEFLATE_HEADER_BITS + DEFLATE_EOBS_BITS + DEFLATE_PAD_BITS) >> 3)
/* deflate block overhead: 3 bits for block start + 15 bits for block end + padding to nearest byte */

#define DEFLATE_QUICK_LIT_MAX_BITS 9
#define DEFLATE_QUICK_OVERHEAD(x) ((x * (DEFLATE_QUICK_LIT_MAX_BITS - 8) + 7) >> 3)
/* deflate_quick worst-case overhead: 9 bits per literal, round up to next byte (+7) */


/* target dependencies */

Expand Down