Skip to content

Commit

Permalink
Fix deflateBound and compressBound returning very small size estimates.
Browse files Browse the repository at this point in the history
Remove workaround in switchlevels.c, so we do actual testing of this.
Use named defines instead of magic numbers where we can.
  • Loading branch information
Dead2 committed Dec 20, 2021
1 parent 3b2d34a commit 70f608c
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 11 deletions.
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

0 comments on commit 70f608c

Please sign in to comment.