From: Ilya Leoshkevich Date: Mon, 11 Oct 2021 10:24:20 +0000 (+0200) Subject: IBM Z: Adjust compressBound() for DFLTCC X-Git-Tag: 2.1.0-beta1~501 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63e0002cba437eda71f263d306bcd6dbb5fe90a6;p=thirdparty%2Fzlib-ng.git IBM Z: Adjust compressBound() for DFLTCC When DFLTCC was introduced, deflateBound() was adjusted, but compressBound() was not, leading to compression failures when using compressBound() + compress() with poorly compressible data. --- diff --git a/arch/s390/dfltcc_common.h b/arch/s390/dfltcc_common.h index f46f9cafb..6de8bb18f 100644 --- a/arch/s390/dfltcc_common.h +++ b/arch/s390/dfltcc_common.h @@ -26,4 +26,28 @@ void Z_INTERNAL dfltcc_free_window(PREFIX3(streamp) strm, void *w); #define TRY_FREE_WINDOW dfltcc_free_window +#define DFLTCC_BLOCK_HEADER_BITS 3 +#define DFLTCC_HLITS_COUNT_BITS 5 +#define DFLTCC_HDISTS_COUNT_BITS 5 +#define DFLTCC_HCLENS_COUNT_BITS 4 +#define DFLTCC_MAX_HCLENS 19 +#define DFLTCC_HCLEN_BITS 3 +#define DFLTCC_MAX_HLITS 286 +#define DFLTCC_MAX_HDISTS 30 +#define DFLTCC_MAX_HLIT_HDIST_BITS 7 +#define DFLTCC_MAX_SYMBOL_BITS 16 +#define DFLTCC_MAX_EOBS_BITS 15 +#define DFLTCC_MAX_PADDING_BITS 7 + +#define DEFLATE_BOUND_COMPLEN(source_len) \ + ((DFLTCC_BLOCK_HEADER_BITS + \ + DFLTCC_HLITS_COUNT_BITS + \ + DFLTCC_HDISTS_COUNT_BITS + \ + DFLTCC_HCLENS_COUNT_BITS + \ + DFLTCC_MAX_HCLENS * DFLTCC_HCLEN_BITS + \ + (DFLTCC_MAX_HLITS + DFLTCC_MAX_HDISTS) * DFLTCC_MAX_HLIT_HDIST_BITS + \ + (source_len) * DFLTCC_MAX_SYMBOL_BITS + \ + DFLTCC_MAX_EOBS_BITS + \ + DFLTCC_MAX_PADDING_BITS) >> 3) + #endif diff --git a/arch/s390/dfltcc_deflate.h b/arch/s390/dfltcc_deflate.h index 7e32380bd..218e59469 100644 --- a/arch/s390/dfltcc_deflate.h +++ b/arch/s390/dfltcc_deflate.h @@ -41,8 +41,7 @@ int Z_INTERNAL dfltcc_deflate_get_dictionary(PREFIX3(streamp) strm, unsigned cha #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \ do { \ if (dfltcc_can_deflate((strm))) \ - (complen) = (3 + 5 + 5 + 4 + 19 * 3 + (286 + 30) * 7 + \ - (source_len) * 16 + 15 + 7) >> 3; \ + (complen) = DEFLATE_BOUND_COMPLEN(source_len); \ } while (0) #define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) (dfltcc_can_deflate((strm))) diff --git a/compress.c b/compress.c index d5379591d..de45e29e6 100644 --- a/compress.c +++ b/compress.c @@ -3,14 +3,25 @@ * 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 # include "zlib-ng.h" #endif +/* =========================================================================== + * Architecture-specific hooks. + */ +#ifdef S390_DFLTCC_DEFLATE +# include "arch/s390/dfltcc_common.h" +#else +/* Returns the upper bound on compressed data length based on uncompressed data length, assuming default settings. + * Zero means that arch-specific deflation code behaves identically to the regular zlib-ng algorithms. */ +# define DEFLATE_BOUND_COMPLEN(source_len) 0 +#endif + /* =========================================================================== Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -73,6 +84,12 @@ int Z_EXPORT PREFIX(compress)(unsigned char *dest, z_size_t *destLen, const unsi this function needs to be updated. */ z_size_t Z_EXPORT PREFIX(compressBound)(z_size_t sourceLen) { + z_size_t complen = DEFLATE_BOUND_COMPLEN(sourceLen); + + if (complen > 0) + /* Architecture-specific code provided an upper bound. */ + 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 */ diff --git a/zutil.h b/zutil.h index 0a44f775c..e7cb9ad3e 100644 --- a/zutil.h +++ b/zutil.h @@ -78,6 +78,8 @@ 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 */ + /* target dependencies */ #ifdef AMIGA