Skip to content

Commit 70f608c

Browse files
committed
Fix deflateBound and compressBound returning very small size estimates.
Remove workaround in switchlevels.c, so we do actual testing of this. Use named defines instead of magic numbers where we can.
1 parent 3b2d34a commit 70f608c

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed

compress.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,11 @@ z_size_t Z_EXPORT PREFIX(compressBound)(z_size_t sourceLen) {
9191
return complen + ZLIB_WRAPLEN;
9292

9393
#ifndef NO_QUICK_STRATEGY
94-
/* Quick deflate strategy worse case is 9 bits per literal, rounded to nearest byte,
95-
plus the size of block & gzip headers and footers */
96-
return sourceLen + ((sourceLen + 13 + 7) >> 3) + 18;
94+
return sourceLen /* The source size itself */
95+
+ DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */
96+
+ DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */
97+
+ ZLIB_WRAPLEN; /* zlib wrapper */
9798
#else
98-
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13;
99+
return sourceLen + (sourceLen >> 4) + 7 + ZLIB_WRAPLEN;
99100
#endif
100101
}

deflate.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -611,11 +611,11 @@ unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long
611611
wraplen = 0;
612612
break;
613613
case 1: /* zlib wrapper */
614-
wraplen = 6 + (s->strstart ? 4 : 0);
614+
wraplen = ZLIB_WRAPLEN + (s->strstart ? 4 : 0);
615615
break;
616616
#ifdef GZIP
617617
case 2: /* gzip wrapper */
618-
wraplen = 18;
618+
wraplen = GZIP_WRAPLEN;
619619
if (s->gzhead != NULL) { /* user-supplied gzip header */
620620
unsigned char *str;
621621
if (s->gzhead->extra != NULL) {
@@ -639,16 +639,22 @@ unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long
639639
break;
640640
#endif
641641
default: /* for compiler happiness */
642-
wraplen = 6;
642+
wraplen = ZLIB_WRAPLEN;
643643
}
644644

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

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

654660
/* =========================================================================

test/switchlevels.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last)
6868
goto done;
6969
}
7070

71-
compsize = 100 + 2 * PREFIX(deflateBound)(strm, size);
71+
compsize = PREFIX(deflateBound)(strm, size);
7272
buf = malloc(size + compsize);
7373
if (buf == NULL) {
7474
fprintf(stderr, "Out of memory\n");

zutil.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,19 @@ extern z_const char * const PREFIX(z_errmsg)[10]; /* indexed by 2-zlib_error */
7878
#define ADLER32_INITIAL_VALUE 1 /* initial adler-32 hash value */
7979
#define CRC32_INITIAL_VALUE 0 /* initial crc-32 hash value */
8080

81-
#define ZLIB_WRAPLEN 6 /* zlib format overhead */
81+
#define ZLIB_WRAPLEN 6 /* zlib format overhead */
82+
#define GZIP_WRAPLEN 18 /* gzip format overhead */
83+
84+
#define DEFLATE_HEADER_BITS 3
85+
#define DEFLATE_EOBS_BITS 15
86+
#define DEFLATE_PAD_BITS 6
87+
#define DEFLATE_BLOCK_OVERHEAD ((DEFLATE_HEADER_BITS + DEFLATE_EOBS_BITS + DEFLATE_PAD_BITS) >> 3)
88+
/* deflate block overhead: 3 bits for block start + 15 bits for block end + padding to nearest byte */
89+
90+
#define DEFLATE_QUICK_LIT_MAX_BITS 9
91+
#define DEFLATE_QUICK_OVERHEAD(x) ((x * (DEFLATE_QUICK_LIT_MAX_BITS - 8) + 7) >> 3)
92+
/* deflate_quick worst-case overhead: 9 bits per literal, round up to next byte (+7) */
93+
8294

8395
/* target dependencies */
8496

0 commit comments

Comments
 (0)