From 4edb00de5aac7e4aa9110374bd1991c4d070eddb Mon Sep 17 00:00:00 2001 From: Mark Adler Date: Mon, 12 Jan 2026 09:29:40 -0800 Subject: Add _z versions of the compress and uncompress functions. Provide size_t arguments for Windows, on which a long is 32 bits. --- compress.c | 29 +++++++++++++++------ contrib/vstudio/vc10/zlibvc.def | 4 +++ contrib/vstudio/vc11/zlibvc.def | 4 +++ contrib/vstudio/vc12/zlibvc.def | 4 +++ contrib/vstudio/vc14/zlibvc.def | 4 +++ contrib/vstudio/vc17/zlibvc.def | 4 +++ contrib/vstudio/vc9/zlibvc.def | 4 +++ os400/bndsrc | 4 +++ os400/zlib.inc | 25 ++++++++++++++++++ uncompr.c | 56 +++++++++++++++++++++++++---------------- win32/zlib.def | 4 +++ zconf.h | 4 +++ zconf.h.in | 4 +++ zlib.h | 37 ++++++++++++++++----------- zlib.map | 4 +++ 15 files changed, 148 insertions(+), 43 deletions(-) diff --git a/compress.c b/compress.c index 0c709d06..a27223ca 100644 --- a/compress.c +++ b/compress.c @@ -18,13 +18,15 @@ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. + + The _z versions of the functions take size_t length arguments. */ -int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen, int level) { +int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t sourceLen, int level) { z_stream stream; int err; const uInt max = (uInt)-1; - uLong left; + z_size_t left; left = *destLen; *destLen = 0; @@ -43,23 +45,36 @@ int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, do { if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; + stream.avail_out = left > (z_size_t)max ? max : (uInt)left; left -= stream.avail_out; } if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; + stream.avail_in = sourceLen > (z_size_t)max ? max : + (uInt)sourceLen; sourceLen -= stream.avail_in; } err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); } while (err == Z_OK); - *destLen = stream.total_out; + *destLen = stream.next_out - dest; deflateEnd(&stream); return err == Z_STREAM_END ? Z_OK : err; } - +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { + int ret; + z_size_t got = *destLen; + ret = compress2_z(dest, &got, source, sourceLen, level); + *destLen = (uLong)got; + return ret; +} /* =========================================================================== */ +int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t sourceLen) { + return compress2_z(dest, destLen, source, sourceLen, + Z_DEFAULT_COMPRESSION); +} int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); diff --git a/contrib/vstudio/vc10/zlibvc.def b/contrib/vstudio/vc10/zlibvc.def index e7fdebf1..e7fe0a32 100644 --- a/contrib/vstudio/vc10/zlibvc.def +++ b/contrib/vstudio/vc10/zlibvc.def @@ -163,3 +163,7 @@ EXPORTS ; zlib1 v1.3.2 added: compressBound_z @180 deflateBound_z @181 + compress_z @182 + compress2_z @183 + uncompress_z @184 + uncompress2_z @185 diff --git a/contrib/vstudio/vc11/zlibvc.def b/contrib/vstudio/vc11/zlibvc.def index e7fdebf1..e7fe0a32 100644 --- a/contrib/vstudio/vc11/zlibvc.def +++ b/contrib/vstudio/vc11/zlibvc.def @@ -163,3 +163,7 @@ EXPORTS ; zlib1 v1.3.2 added: compressBound_z @180 deflateBound_z @181 + compress_z @182 + compress2_z @183 + uncompress_z @184 + uncompress2_z @185 diff --git a/contrib/vstudio/vc12/zlibvc.def b/contrib/vstudio/vc12/zlibvc.def index e7fdebf1..e7fe0a32 100644 --- a/contrib/vstudio/vc12/zlibvc.def +++ b/contrib/vstudio/vc12/zlibvc.def @@ -163,3 +163,7 @@ EXPORTS ; zlib1 v1.3.2 added: compressBound_z @180 deflateBound_z @181 + compress_z @182 + compress2_z @183 + uncompress_z @184 + uncompress2_z @185 diff --git a/contrib/vstudio/vc14/zlibvc.def b/contrib/vstudio/vc14/zlibvc.def index e7fdebf1..e7fe0a32 100644 --- a/contrib/vstudio/vc14/zlibvc.def +++ b/contrib/vstudio/vc14/zlibvc.def @@ -163,3 +163,7 @@ EXPORTS ; zlib1 v1.3.2 added: compressBound_z @180 deflateBound_z @181 + compress_z @182 + compress2_z @183 + uncompress_z @184 + uncompress2_z @185 diff --git a/contrib/vstudio/vc17/zlibvc.def b/contrib/vstudio/vc17/zlibvc.def index e7fdebf1..e7fe0a32 100644 --- a/contrib/vstudio/vc17/zlibvc.def +++ b/contrib/vstudio/vc17/zlibvc.def @@ -163,3 +163,7 @@ EXPORTS ; zlib1 v1.3.2 added: compressBound_z @180 deflateBound_z @181 + compress_z @182 + compress2_z @183 + uncompress_z @184 + uncompress2_z @185 diff --git a/contrib/vstudio/vc9/zlibvc.def b/contrib/vstudio/vc9/zlibvc.def index e7fdebf1..e7fe0a32 100644 --- a/contrib/vstudio/vc9/zlibvc.def +++ b/contrib/vstudio/vc9/zlibvc.def @@ -163,3 +163,7 @@ EXPORTS ; zlib1 v1.3.2 added: compressBound_z @180 deflateBound_z @181 + compress_z @182 + compress2_z @183 + uncompress_z @184 + uncompress2_z @185 diff --git a/os400/bndsrc b/os400/bndsrc index ce48ff4d..6b0d297a 100644 --- a/os400/bndsrc +++ b/os400/bndsrc @@ -136,5 +136,9 @@ STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB') EXPORT SYMBOL("compressBound_z") EXPORT SYMBOL("deflateBound_z") + EXPORT SYMBOL("compress_z") + EXPORT SYMBOL("compress2_z") + EXPORT SYMBOL("uncompress_z") + EXPORT SYMBOL("uncompress2_z") ENDPGMEXP diff --git a/os400/zlib.inc b/os400/zlib.inc index 031ff3ec..f884f8f0 100644 --- a/os400/zlib.inc +++ b/os400/zlib.inc @@ -122,6 +122,19 @@ D destLen 10U 0 Destination length D source 65535 const options(*varsize) Source buffer D sourceLen 10U 0 value Source length + D level 10I 0 value Compression level + * + D compress_z PR 10I 0 extproc('compress') + D dest 65535 options(*varsize) Destination buffer + D destLen 20U 0 Destination length + D source 65535 const options(*varsize) Source buffer + D sourceLen 20u 0 value Source length + * + D compress2_z PR 10I 0 extproc('compress2') + D dest 65535 options(*varsize) Destination buffer + D destLen 20U 0 Destination length + D source 65535 const options(*varsize) Source buffer + D sourceLen 20U 0 value Source length D level 10I 0 value Compression level * D compressBound PR 10U 0 extproc('compressBound') @@ -142,6 +155,18 @@ D source 65535 const options(*varsize) Source buffer D sourceLen 10U 0 Source length * + D uncompress_z PR 10I 0 extproc('uncompress') + D dest 65535 options(*varsize) Destination buffer + D destLen 20U 0 Destination length + D source 65535 const options(*varsize) Source buffer + D sourceLen 20U 0 value Source length + * + D uncompress2_z PR 10I 0 extproc('uncompress2') + D dest 65535 options(*varsize) Destination buffer + D destLen 20U 0 Destination length + D source 65535 const options(*varsize) Source buffer + D sourceLen 20U 0 Source length + * /if not defined(LARGE_FILES) D gzopen PR extproc('gzopen') D like(gzFile) diff --git a/uncompr.c b/uncompr.c index 5e256663..8f7438ee 100644 --- a/uncompr.c +++ b/uncompr.c @@ -23,24 +23,20 @@ memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted, including if the input data is an incomplete zlib stream. + + The _z versions of the functions take size_t length arguments. */ -int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong *sourceLen) { +int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t *sourceLen) { z_stream stream; int err; const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + z_size_t len, left; len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } + left = *destLen; + if (left == 0 && dest == Z_NULL) + dest = (Bytef *)&stream.reserved; /* next_out cannot be NULL */ stream.next_in = (z_const Bytef *)source; stream.avail_in = 0; @@ -56,30 +52,46 @@ int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, do { if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; + stream.avail_out = left > (z_size_t)max ? max : (uInt)left; left -= stream.avail_out; } if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; + stream.avail_in = len > (z_size_t)max ? max : (uInt)len; len -= stream.avail_in; } err = inflate(&stream, Z_NO_FLUSH); } while (err == Z_OK); - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; + /* Set len and left to the unused input data and unused output space. Set + *sourceLen to the amount of input consumed. Set *destLen to the amount + of data produced. */ + len += stream.avail_in; + left += stream.avail_out; + *sourceLen -= len; + *destLen -= left; inflateEnd(&stream); return err == Z_STREAM_END ? Z_OK : err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err == Z_BUF_ERROR && len == 0 ? Z_DATA_ERROR : err; } - +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { + int ret; + z_size_t got = *destLen, used = *sourceLen; + ret = uncompress2_z(dest, &got, source, &used); + *sourceLen = (uLong)used; + *destLen = (uLong)got; + return ret; +} +int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, const Bytef *source, + z_size_t sourceLen) { + z_size_t used = sourceLen; + return uncompress2_z(dest, destLen, source, &used); +} int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) { - return uncompress2(dest, destLen, source, &sourceLen); + uLong used = sourceLen; + return uncompress2(dest, destLen, source, &used); } diff --git a/win32/zlib.def b/win32/zlib.def index dc44e7c0..25da22d3 100644 --- a/win32/zlib.def +++ b/win32/zlib.def @@ -34,10 +34,14 @@ EXPORTS ; utility functions compress compress2 + compress_z + compress2_z compressBound compressBound_z uncompress uncompress2 + uncompress_z + uncompress2_z gzopen gzdopen gzbuffer diff --git a/zconf.h b/zconf.h index 524192ad..a7143810 100644 --- a/zconf.h +++ b/zconf.h @@ -33,6 +33,8 @@ # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 +# define compress_z z_compress_z +# define compress2_z z_compress2_z # define compressBound z_compressBound # define compressBound_z z_compressBound_z # endif @@ -135,6 +137,8 @@ # ifndef Z_SOLO # define uncompress z_uncompress # define uncompress2 z_uncompress2 +# define uncompress_z z_uncompress_z +# define uncompress2_z z_uncompress2_z # endif # define zError z_zError # ifndef Z_SOLO diff --git a/zconf.h.in b/zconf.h.in index 524192ad..a7143810 100644 --- a/zconf.h.in +++ b/zconf.h.in @@ -33,6 +33,8 @@ # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 +# define compress_z z_compress_z +# define compress2_z z_compress2_z # define compressBound z_compressBound # define compressBound_z z_compressBound_z # endif @@ -135,6 +137,8 @@ # ifndef Z_SOLO # define uncompress z_uncompress # define uncompress2 z_uncompress2 +# define uncompress_z z_uncompress_z +# define uncompress2_z z_uncompress2_z # endif # define zError z_zError # ifndef Z_SOLO diff --git a/zlib.h b/zlib.h index 5567bcc3..afa3d5a9 100644 --- a/zlib.h +++ b/zlib.h @@ -779,8 +779,8 @@ ZEXTERN z_size_t ZEXPORT deflateBound_z(z_streamp strm, z_size_t sourceLen); be larger than the value returned by deflateBound() if flush options other than Z_FINISH or Z_NO_FLUSH are used. - delfateBound_z() is the same, but takes and returns a size_t length for - those systems on which a long is 32 bits. + delfateBound_z() is the same, but takes and returns a size_t length. Note + that a long is 32 bits on Windows. */ ZEXTERN int ZEXPORT deflatePending(z_streamp strm, @@ -1261,11 +1261,14 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags(void); stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can be modified if - you need special options. + you need special options. The _z versions of the functions use the size_t + type for lengths. Note that a long is 32 bits on Windows. */ -ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +ZEXTERN int ZEXPORT compress_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t sourceLen); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size @@ -1279,9 +1282,12 @@ ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, buffer. */ -ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +ZEXTERN int ZEXPORT compress2_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t sourceLen, + int level); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte @@ -1301,20 +1307,19 @@ ZEXTERN z_size_t ZEXPORT compressBound_z(z_size_t sourceLen); compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. - - compressBound_z() is the same, but takes and returns a size_t length for - those systems on which a long is 32 bits. */ -ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +ZEXTERN int ZEXPORT uncompress_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t sourceLen); /* Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size + the byte length of the source buffer. On entry, *destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen + mechanism outside the scope of this compression library.) On exit, *destLen is the actual size of the uncompressed data. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not @@ -1324,8 +1329,10 @@ ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ -ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong *sourceLen); +ZEXTERN int ZEXPORT uncompress2_z(Bytef *dest, z_size_t *destLen, + const Bytef *source, z_size_t *sourceLen); /* Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of @@ -1819,7 +1826,8 @@ ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len); /* - Same as adler32(), but with a size_t length. + Same as adler32(), but with a size_t length. Note that a long is 32 bits + on Windows. */ /* @@ -1855,7 +1863,8 @@ ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, z_size_t len); /* - Same as crc32(), but with a size_t length. + Same as crc32(), but with a size_t length. Note that a long is 32 bits on + Windows. */ /* diff --git a/zlib.map b/zlib.map index aba65ab6..f505623c 100644 --- a/zlib.map +++ b/zlib.map @@ -108,4 +108,8 @@ ZLIB_1.3.1.2 { ZLIB_1.3.2 { compressBound_z; deflateBound_z; + compress_z; + compress2_z; + uncompress_z; + uncompress2_z; } ZLIB_1.3.1.2; \ No newline at end of file -- cgit v1.2.3-55-g6feb