From: Hans Kristian Rosbach Date: Mon, 13 Dec 2021 21:30:58 +0000 (+0100) Subject: Fix deflateBound and compressBound returning very small size estimates. X-Git-Tag: 2.0.6~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a378ba9b85e23a6e2e67b01a1b3d738e86faefe;p=thirdparty%2Fzlib-ng.git 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. --- diff --git a/compress.c b/compress.c index d5379591..46e8f8e3 100644 --- a/compress.c +++ b/compress.c @@ -3,8 +3,8 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -#define ZLIB_INTERNAL #include "zbuild.h" +#include "zutil.h" #if defined(ZLIB_COMPAT) # include "zlib.h" #else @@ -74,10 +74,11 @@ int Z_EXPORT PREFIX(compress)(unsigned char *dest, z_size_t *destLen, const unsi */ z_size_t Z_EXPORT PREFIX(compressBound)(z_size_t sourceLen) { #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 } diff --git a/deflate.c b/deflate.c index ca9dafa8..031a1bb0 100644 --- a/deflate.c +++ b/deflate.c @@ -685,11 +685,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) { @@ -713,7 +713,7 @@ 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 */ @@ -721,8 +721,14 @@ unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long 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 } /* ========================================================================= diff --git a/test/switchlevels.c b/test/switchlevels.c index a4ec4b7c..1e1fb00a 100644 --- a/test/switchlevels.c +++ b/test/switchlevels.c @@ -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"); diff --git a/zutil.h b/zutil.h index c9e769c6..015219ae 100644 --- a/zutil.h +++ b/zutil.h @@ -78,6 +78,20 @@ 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 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 */ #ifdef AMIGA