提交 0484693e 编写于 作者: M Mark Adler

zlib 1.2.2.2

上级 9811b53d
ChangeLog file for zlib
Changes in 1.2.2.2 (30 December 2004)
- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
avoid implicit memcpy calls (portability for no-library compilation)
- Increase sprintf() buffer size in gzdopen() to allow for large numbers
- Add INFLATE_STRICT to check distances against zlib header
- Improve WinCE errno handling and comments [Chang]
- Remove comment about no gzip header processing in FAQ
- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
- Add updated make_vms.com [Coghlan], update README
- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
- Add FAQ entry and comments in deflate.c on uninitialized memory access
- Add Solaris 9 make options in configure [Gilbert]
- Allow strerror() usage in gzio.c for STDC
- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
- Use z_off_t for adler32_combine() and crc32_combine() lengths
- Make adler32() much faster for small len
- Use OS_CODE in deflate() default gzip header
Changes in 1.2.2.1 (31 October 2004)
- Allow inflateSetDictionary() call for raw inflate
- Fix inflate header crc check bug for file names and comments
......@@ -20,6 +40,7 @@ Changes in 1.2.2.1 (31 October 2004)
- Do not define an exit() prototype in zutil.c unless DEBUG defined
- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
- Fix Darwin build version identification [Peterson]
Changes in 1.2.2 (3 October 2004)
- Update zlib.h comments on gzip in-memory processing
......
......@@ -148,13 +148,6 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
format using deflateInit2(). You can also request that inflate decode
the gzip format using inflateInit2(). Read zlib.h for more details.
Note that you cannot specify special gzip header contents (e.g. a file
name or modification date), nor will inflate tell you what was in the
gzip header. If you need to customize the header or see what's in it,
you can use the raw deflate and inflate operations and the crc32()
function and roll your own gzip encoding and decoding. Read the gzip
RFC 1952 for details of the header and trailer format.
21. Is zlib thread-safe?
Yes. However any library routines that zlib uses and any application-
......@@ -295,20 +288,29 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
were downright silly. So now, we simply make sure that the code always
works.
36. Will zlib read the (insert any ancient or arcane format here) compressed
36. Valgrind (or some similar memory access checker) says that deflate is
performing a conditional jump that depends on an uninitialized value.
Isn't that a bug?
No. That is intentional for performance reasons, and the output of
deflate is not affected. This only started showing up recently since
zlib 1.2.x uses malloc() by default for allocations, whereas earlier
versions used calloc(), which zeros out the allocated memory.
37. Will zlib read the (insert any ancient or arcane format here) compressed
data format?
Probably not. Look in the comp.compression FAQ for pointers to various
formats and associated software.
37. How can I encrypt/decrypt zip files with zlib?
38. How can I encrypt/decrypt zip files with zlib?
zlib doesn't support encryption. The original PKZIP encryption is very weak
and can be broken with freely available programs. To get strong encryption,
use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
For PKZIP compatible "encryption", look at http://www.info-zip.org/
38. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
"gzip" is the gzip format, and "deflate" is the zlib format. They should
probably have called the second one "zlib" instead to avoid confusion
......@@ -324,14 +326,14 @@ The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
Bottom line: use the gzip format for HTTP 1.1 encoding.
39. Does zlib support the new "Deflate64" format introduced by PKWare?
40. Does zlib support the new "Deflate64" format introduced by PKWare?
No. PKWare has apparently decided to keep that format proprietary, since
they have not documented it as they have previous compression formats.
In any case, the compression improvements are so modest compared to other
more modern approaches, that it's not worth the effort to implement.
40. Can you please sign these lengthy legal documents and fax them back to us
41. Can you please sign these lengthy legal documents and fax them back to us
so that we can use your software in our product?
No. Go away. Shoo.
......@@ -30,7 +30,7 @@ CPP=$(CC) -E
LIBS=libz.a
SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.2.1
SHAREDLIBV=libz.so.1.2.2.2
SHAREDLIBM=libz.so.1
AR=ar rc
......
......@@ -30,7 +30,7 @@ CPP=$(CC) -E
LIBS=libz.a
SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.2.1
SHAREDLIBV=libz.so.1.2.2.2
SHAREDLIBM=libz.so.1
AR=ar rc
......
ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.2.1 is a general purpose data compression library. All the code is
zlib 1.2.2.2 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
......@@ -16,9 +16,8 @@ minigzip.c.
To compile all files and run the test program, follow the instructions given at
the top of Makefile. In short "make test; make install" should work for most
machines. For Unix: "./configure; make test; make install" For MSDOS, use one
of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or
descrip.mms.
machines. For Unix: "./configure; make test; make install". For MSDOS, use one
of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is
......@@ -34,7 +33,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
The changes made in version 1.2.2.1 are documented in the file ChangeLog.
The changes made in version 1.2.2.2 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory "contrib".
......
......@@ -12,12 +12,13 @@
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* use NO_DIVIDE if your processor does not do division in hardware */
#ifdef NO_DIVIDE
# define MOD(a) \
do { \
......@@ -39,8 +40,17 @@
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
# define MOD4(a) \
do { \
if (a >= (BASE << 4)) a -= (BASE << 4); \
if (a >= (BASE << 3)) a -= (BASE << 3); \
if (a >= (BASE << 2)) a -= (BASE << 2); \
if (a >= (BASE << 1)) a -= (BASE << 1); \
if (a >= BASE) a -= BASE; \
} while (0)
#else
# define MOD(a) a %= BASE
# define MOD4(a) a %= BASE
#endif
/* ========================================================================= */
......@@ -49,48 +59,91 @@ uLong ZEXPORT adler32(adler, buf, len)
const Bytef *buf;
uInt len;
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int k;
unsigned long sum2;
unsigned n;
/* split Adler-32 into component sums */
sum2 = (adler >> 16) & 0xffff;
adler &= 0xffff;
/* in case user likes doing a byte at a time, keep it fast */
if (len == 1) {
adler += buf[0];
if (adler >= BASE)
adler -= BASE;
sum2 += adler;
if (sum2 >= BASE)
sum2 -= BASE;
return adler | (sum2 << 16);
}
if (buf == Z_NULL) return 1L;
/* initial Adler-32 value (deferred check for len == 1 speed) */
if (buf == Z_NULL)
return 1L;
while (len > 0) {
k = len < NMAX ? (int)len : NMAX;
len -= k;
while (k >= 16) {
/* in case short lengths are provided, keep it somewhat fast */
if (len < 16) {
while (len--) {
adler += *buf++;
sum2 += adler;
}
if (adler >= BASE)
adler -= BASE;
MOD4(sum2); /* only added so many BASE's */
return adler | (sum2 << 16);
}
/* do length NMAX blocks -- requires just one modulo operation */
while (len >= NMAX) {
len -= NMAX;
n = NMAX / 16; /* NMAX is divisible by 16 */
do {
DO16(buf); /* 16 sums unrolled */
buf += 16;
} while (--n);
MOD(adler);
MOD(sum2);
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if (len) { /* avoid modulos if none remaining */
while (len >= 16) {
len -= 16;
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
MOD(s1);
MOD(s2);
while (len--) {
adler += *buf++;
sum2 += adler;
}
MOD(adler);
MOD(sum2);
}
return (s2 << 16) | s1;
/* return recombined sums */
return adler | (sum2 << 16);
}
/* ========================================================================= */
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
uLong adler1;
uLong adler2;
uLong len2;
z_off_t len2;
{
unsigned long s1;
unsigned long s2;
unsigned long sum1;
unsigned long sum2;
unsigned rem;
len2 %= BASE;
s1 = adler1 & 0xffff;
s2 = len2 * s1;
MOD(s2);
s1 += (adler2 & 0xffff) + BASE - 1;
s2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - len2;
if (s1 > BASE) s1 -= BASE;
if (s1 > BASE) s1 -= BASE;
if (s2 > (BASE << 1)) s2 -= (BASE << 1);
if (s2 > BASE) s2 -= BASE;
return (s2 << 16) | s1;
/* the derivation of this formula is left as an exercise for the reader */
rem = (unsigned)(len2 % BASE);
sum1 = adler1 & 0xffff;
sum2 = rem * sum1;
MOD(sum2);
sum1 += (adler2 & 0xffff) + BASE - 1;
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
if (sum1 > BASE) sum1 -= BASE;
if (sum1 > BASE) sum1 -= BASE;
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
if (sum2 > BASE) sum2 -= BASE;
return sum1 | (sum2 << 16);
}
* ZLIB.INC - Interface to the general purpose compression library
*
* ILE RPG400 version by Patrick Monnerat, DATASPHERE.
* Version 1.2.2.1
* Version 1.2.2.2
*
*
* WARNING:
......@@ -20,8 +20,8 @@
* Constants
**************************************************************************
*
D ZLIB_VERSION C '1.2.2.1' Header's version
D ZLIB_VERNUM C X'1221'
D ZLIB_VERSION C '1.2.2.2' Header's version
D ZLIB_VERNUM C X'1222'
*
D Z_NO_FLUSH C 0
D Z_SYNC_FLUSH C 2
......
......@@ -89,7 +89,7 @@ if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
SHAREDLIB=libz$shared_ext
SHAREDLIBV=libz.$VER$shared_ext
SHAREDLIBM=libz.$VER1$shared_ext
LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBV -compatibility_version $VER2 -current_version $VER"};;
LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};;
*) LDSHARED=${LDSHARED-"$cc -shared"};;
esac
else
......@@ -125,6 +125,9 @@ else
SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
CFLAGS=${CFLAGS-"-O2"}
LDSHARED=${LDSHARED-"ld"};;
SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"}
LDSHARED=${LDSHARED-"cc -xarch=v9b"};;
UNIX_System_V\ 4.2.0)
SFLAGS=${CFLAGS-"-KPIC -O"}
CFLAGS=${CFLAGS-"-O"}
......
......@@ -22,9 +22,6 @@ delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro>
dotzlib/ by Henrik Ravn <henrik@ravn.com>
Support for Microsoft .Net and Visual C++ .Net
gzappend/ by Mark Adler <madler@alumni.caltech.edu>
append to a gzip file -- illustrates the use of Z_BLOCK
infback9/ by Mark Adler <madler@alumni.caltech.edu>
Unsupported diffs to infback to decode the deflate64 format
......
......@@ -344,7 +344,7 @@ begin
strm.avail_out := OutBytes;
DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
try
while DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do
while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
begin
P := OutBuf;
Inc(OutBytes, BufInc);
......
......@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate9_copyright[] =
" inflate9 1.2.2.1 Copyright 1995-2004 Mark Adler ";
" inflate9 1.2.2.2 Copyright 1995-2004 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
......@@ -64,7 +64,7 @@ unsigned short FAR *work;
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
133, 133, 133, 133, 144, 77, 207};
133, 133, 133, 133, 144, 72, 199};
static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
......
......@@ -47,21 +47,25 @@
; all the +4 offsets are due to the addition of pending_buf_size (in zlib
; all the +addstr offsets are due to the addition of pending_buf_size in zlib 1.04
; and adding gzhead and gzindex in zlib 1.2.2.1
; in the deflate_state structure since the asm code was first written
; (if you compile with zlib 1.0.4 or older, remove the +4).
; (if you compile with zlib 1.0.4 or older, set addstr to 0).
; (if you compiler with zlib between 1.04 and 1.2.1, set addstr to 4)
; Note : these value are good with a 8 bytes boundary pack structure
dep_chain_length equ 70h+4
dep_window equ 2ch+4
dep_strstart equ 60h+4
dep_prev_length equ 6ch+4
dep_nice_match equ 84h+4
dep_w_size equ 20h+4
dep_prev equ 34h+4
dep_w_mask equ 28h+4
dep_good_match equ 80h+4
dep_match_start equ 64h+4
dep_lookahead equ 68h+4
addstr equ 4+8
dep_chain_length equ 70h+addstr
dep_window equ 2ch+addstr
dep_strstart equ 60h+addstr
dep_prev_length equ 6ch+addstr
dep_nice_match equ 84h+addstr
dep_w_size equ 20h+addstr
dep_prev equ 34h+addstr
dep_w_mask equ 28h+addstr
dep_good_match equ 80h+addstr
dep_match_start equ 64h+addstr
dep_lookahead equ 68h+addstr
_TEXT segment
......@@ -597,19 +601,19 @@ curmatch equ esp + 60
;;; program to crash horribly, without so much as a warning at
;;; compile time. Sigh.)
dsWSize equ 36
dsWMask equ 44
dsWindow equ 48
dsPrev equ 56
dsMatchLen equ 88
dsPrevMatch equ 92
dsStrStart equ 100
dsMatchStart equ 104
dsLookahead equ 108
dsPrevLen equ 112
dsMaxChainLen equ 116
dsGoodMatch equ 132
dsNiceMatch equ 136
dsWSize equ 36+addstr-4
dsWMask equ 44+addstr-4
dsWindow equ 48+addstr-4
dsPrev equ 56+addstr-4
dsMatchLen equ 88+addstr-4
dsPrevMatch equ 92+addstr-4
dsStrStart equ 100+addstr-4
dsMatchStart equ 104+addstr-4
dsLookahead equ 108+addstr-4
dsPrevLen equ 112+addstr-4
dsMaxChainLen equ 116+addstr-4
dsGoodMatch equ 132+addstr-4
dsNiceMatch equ 136+addstr-4
;;; match.asm -- Pentium-Pro-optimized version of longest_match()
......
......@@ -84,17 +84,20 @@ dd 2147483647
dd 4294967295
; head was added in zlib 1.2.2.1, so we add addstr
; set addstr to 0 with zlib 1.2.1 of below
addstr equ 4
mode_state equ 0 ;/* state->mode */
wsize_state equ 32 ;/* state->wsize */
write_state equ (36+4) ;/* state->write */
window_state equ (40+4) ;/* state->window */
hold_state equ (44+4) ;/* state->hold */
bits_state equ (48+4) ;/* state->bits */
lencode_state equ (64+4) ;/* state->lencode */
distcode_state equ (68+4) ;/* state->distcode */
lenbits_state equ (72+4) ;/* state->lenbits */
distbits_state equ (76+4) ;/* state->distbits */
wsize_state equ 32+addstr ;/* state->wsize */
write_state equ (36+4+addstr) ;/* state->write */
window_state equ (40+4+addstr) ;/* state->window */
hold_state equ (44+4+addstr) ;/* state->hold */
bits_state equ (48+4+addstr) ;/* state->bits */
lencode_state equ (64+4+addstr) ;/* state->lencode */
distcode_state equ (68+4+addstr) ;/* state->distcode */
lenbits_state equ (72+4+addstr) ;/* state->lenbits */
distbits_state equ (76+4+addstr) ;/* state->distbits */
;;SECTION .text
......
Building instructions for the DLL versions of Zlib 1.21
Building instructions for the DLL versions of Zlib 1.2.x
=======================================================
This directory contains projects that build zlib and minizip using
......
......@@ -2,8 +2,8 @@
#define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1,2,2,1
PRODUCTVERSION 1,2,2,1
FILEVERSION 1,2,2,2
PRODUCTVERSION 1,2,2,2
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32
......@@ -17,7 +17,7 @@ BEGIN
BEGIN
VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", "1.2.2.1\0"
VALUE "FileVersion", "1.2.2.2\0"
VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlib.dll\0"
VALUE "ProductName", "ZLib.DLL\0"
......
......@@ -369,7 +369,7 @@ local void gf2_matrix_square(square, mat)
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
uLong crc1;
uLong crc2;
uLong len2;
z_off_t len2;
{
int n;
unsigned long row;
......
......@@ -52,7 +52,7 @@
#include "deflate.h"
const char deflate_copyright[] =
" deflate 1.2.2.1 Copyright 1995-2004 Jean-loup Gailly ";
" deflate 1.2.2.2 Copyright 1995-2004 Jean-loup Gailly ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
......@@ -264,7 +264,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
#endif
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
strategy < 0 || strategy > Z_RLE) {
strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
......@@ -432,7 +432,7 @@ int ZEXPORT deflateParams(strm, level, strategy)
#else
if (level == Z_DEFAULT_COMPRESSION) level = 6;
#endif
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) {
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
return Z_STREAM_ERROR;
}
func = configuration_table[s->level].func;
......@@ -573,7 +573,7 @@ int ZEXPORT deflate (strm, flush)
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
4 : 0));
put_byte(s, 255);
put_byte(s, OS_CODE);
s->status = BUSY_STATE;
}
else {
......@@ -892,12 +892,12 @@ int ZEXPORT deflateCopy (dest, source)
ss = source->state;
*dest = *source;
zmemcpy(dest, source, sizeof(z_stream));
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
if (ds == Z_NULL) return Z_MEM_ERROR;
dest->state = (struct internal_state FAR *) ds;
*ds = *ss;
zmemcpy(ds, ss, sizeof(deflate_state));
ds->strm = dest;
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
......@@ -1057,7 +1057,12 @@ local uInt longest_match(s, cur_match)
match = s->window + cur_match;
/* Skip to next match if the match length cannot increase
* or if the match length is less than 2:
* or if the match length is less than 2. Note that the checks below
* for insufficient lookahead only occur occasionally for performance
* reasons. Therefore uninitialized memory will be accessed, and
* conditional jumps will be made that depend on those values.
* However the length of the match is limited to the lookahead, so
* the output of deflate is not affected by the uninitialized values.
*/
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
......@@ -1457,12 +1462,12 @@ local block_state deflate_fast(s, flush)
* of the string with itself at the start of the input file).
*/
#ifdef FASTEST
if ((s->strategy < Z_HUFFMAN_ONLY) ||
if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
(s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
s->match_length = longest_match_fast (s, hash_head);
}
#else
if (s->strategy < Z_HUFFMAN_ONLY) {
if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
......@@ -1566,7 +1571,7 @@ local block_state deflate_slow(s, flush)
* of window index 0 (in particular we have to avoid a match
* of the string with itself at the start of the input file).
*/
if (s->strategy < Z_HUFFMAN_ONLY) {
if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
s->match_length = longest_match (s, hash_head);
} else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
s->match_length = longest_match_fast (s, hash_head);
......
This directory contains examples of the use of zlib.
fitblk.c
compress just enough input to nearly fill a requested output size
- zlib isn't designed to do this, but fitblk does it anyway
gzappend.c
append to a gzip file
- illustrates the use of the Z_BLOCK flush parameter for inflate()
- illustrates the use of deflatePrime() to start at any bit
gzjoin.c
join gzip files without recalculating the crc or recompressing
- illustrates the use of the Z_BLOCK flush parameter for inflate()
- illustrates the use of crc32_combine()
gzlog.c
gzlog.h
efficiently maintain a message log file in gzip format
- illustrates use of raw deflate and Z_SYNC_FLUSH
- illustrates use of gzip header extra field
zlib_how.html
painfully comprehensive description of zpipe.c (see below)
- describes in excruciating detail the use of deflate() and inflate()
zpipe.c
reads and writes zlib streams from stdin to stdout
- illustrates the proper use of deflate() and inflate()
/* fitblk.c: example of fitting compressed output to a specified size
Not copyrighted -- provided to the public domain
Version 1.1 25 November 2004 Mark Adler */
/* Version history:
1.0 24 Nov 2004 First version
1.1 25 Nov 2004 Change deflateInit2() to deflateInit()
Use fixed-size, stack-allocated raw buffers
Simplify code moving compression to subroutines
Use assert() for internal errors
Add detailed description of approach
*/
/* Approach to just fitting a requested compressed size:
fitblk performs three compression passes on a portion of the input
data in order to determine how much of that input will compress to
nearly the requested output block size. The first pass generates
enough deflate blocks to produce output to fill the requested
output size plus a specfied excess amount (see the EXCESS define
below). The last deflate block may go quite a bit past that, but
is discarded. The second pass decompresses and recompresses just
the compressed data that fit in the requested plus excess sized
buffer. The deflate process is terminated after that amount of
input, which is less than the amount consumed on the first pass.
The last deflate block of the result will be of a comparable size
to the final product, so that the header for that deflate block and
the compression ratio for that block will be about the same as in
the final product. The third compression pass decompresses the
result of the second step, but only the compressed data up to the
requested size minus an amount to allow the compressed stream to
complete (see the MARGIN define below). That will result in a
final compressed stream whose length is less than or equal to the
requested size. Assuming sufficient input and a requested size
greater than a few hundred bytes, the shortfall will typically be
less than ten bytes.
If the input is short enough that the first compression completes
before filling the requested output size, then that compressed
stream is return with no recompression.
EXCESS is chosen to be just greater than the shortfall seen in a
two pass approach similar to the above. That shortfall is due to
the last deflate block compressing more efficiently with a smaller
header on the second pass. EXCESS is set to be large enough so
that there is enough uncompressed data for the second pass to fill
out the requested size, and small enough so that the final deflate
block of the second pass will be close in size to the final deflate
block of the third and final pass. MARGIN is chosen to be just
large enough to assure that the final compression has enough room
to complete in all cases.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "zlib.h"
#define local static
/* print nastygram and leave */
local void quit(char *why)
{
fprintf(stderr, "fitblk abort: %s\n", why);
exit(1);
}
#define RAWLEN 4096 /* intermediate uncompressed buffer size */
/* compress from file to def until provided buffer is full or end of
input reached; return last deflate() return value, or Z_ERRNO if
there was read error on the file */
local int partcompress(FILE *in, z_streamp def)
{
int ret, flush;
char raw[RAWLEN];
flush = Z_NO_FLUSH;
do {
def->avail_in = fread(raw, 1, RAWLEN, in);
if (ferror(in))
return Z_ERRNO;
def->next_in = raw;
if (feof(in))
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (def->avail_out != 0 && flush == Z_NO_FLUSH);
return ret;
}
/* recompress from inf's input to def's output; the input for inf and
the output for def are set in those structures before calling;
return last deflate() return value, or Z_MEM_ERROR if inflate()
was not able to allocate enough memory when it needed to */
local int recompress(z_streamp inf, z_streamp def)
{
int ret, flush;
char raw[RAWLEN];
flush = Z_NO_FLUSH;
do {
/* decompress */
inf->avail_out = RAWLEN;
inf->next_out = raw;
ret = inflate(inf, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
ret != Z_NEED_DICT);
if (ret == Z_MEM_ERROR)
return ret;
/* compress what was decompresed until done or no room */
def->avail_in = RAWLEN - inf->avail_out;
def->next_in = raw;
if (inf->avail_out != 0)
flush = Z_FINISH;
ret = deflate(def, flush);
assert(ret != Z_STREAM_ERROR);
} while (ret != Z_STREAM_END && def->avail_out != 0);
return ret;
}
#define EXCESS 256 /* empirically determined stream overage */
#define MARGIN 8 /* amount to back off for completion */
/* compress from stdin to fixed-size block on stdout */
int main(int argc, char **argv)
{
int ret; /* return code */
unsigned size; /* requested fixed output block size */
unsigned have; /* bytes written by deflate() call */
char *blk; /* intermediate and final stream */
char *tmp; /* close to desired size stream */
z_stream def, inf; /* zlib deflate and inflate states */
/* get requested output size */
if (argc != 2)
quit("need one argument: size of output block");
ret = strtol(argv[1], argv + 1, 10);
if (argv[1][0] != 0)
quit("argument must be a number");
if (ret < 8) /* 8 is minimum zlib stream size */
quit("need positive size of 8 or greater");
size = (unsigned)ret;
/* allocate memory for buffers and compression engine */
blk = malloc(size + EXCESS);
def.zalloc = Z_NULL;
def.zfree = Z_NULL;
def.opaque = Z_NULL;
ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK || blk == NULL)
quit("out of memory");
/* compress from stdin until output full, or no more input */
def.avail_out = size + EXCESS;
def.next_out = blk;
ret = partcompress(stdin, &def);
if (ret == Z_ERRNO)
quit("error reading input");
/* if it all fit, then size was undersubscribed -- done! */
if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
/* write block to stdout */
have = size + EXCESS - def.avail_out;
ret = fwrite(blk, 1, have, stdout);
if (ret != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr,
"%u bytes unused out of %u requested (all input)\n",
size - have, size);
return 0;
}
/* it didn't all fit -- set up for recompression */
inf.zalloc = Z_NULL;
inf.zfree = Z_NULL;
inf.opaque = Z_NULL;
inf.avail_in = 0;
inf.next_in = Z_NULL;
ret = inflateInit(&inf);
tmp = malloc(size + EXCESS);
if (ret != Z_OK || tmp == NULL)
quit("out of memory");
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do first recompression close to the right amount */
inf.avail_in = size + EXCESS;
inf.next_in = blk;
def.avail_out = size + EXCESS;
def.next_out = tmp;
ret = recompress(&inf, &def);
if (ret == Z_MEM_ERROR)
quit("out of memory");
/* set up for next reocmpression */
ret = inflateReset(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateReset(&def);
assert(ret != Z_STREAM_ERROR);
/* do second and final recompression (third compression) */
inf.avail_in = size - MARGIN; /* assure stream will complete */
inf.next_in = tmp;
def.avail_out = size;
def.next_out = blk;
ret = recompress(&inf, &def);
if (ret == Z_MEM_ERROR)
quit("out of memory");
assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */
/* done -- write block to stdout */
have = size - def.avail_out;
ret = fwrite(blk, 1, have, stdout);
if (ret != have || ferror(stdout))
quit("error writing output");
/* clean up and print results to stderr */
free(tmp);
ret = inflateEnd(&inf);
assert(ret != Z_STREAM_ERROR);
ret = deflateEnd(&def);
assert(ret != Z_STREAM_ERROR);
free(blk);
fprintf(stderr,
"%u bytes unused out of %u requested (%lu input)\n",
size - have, size, def.total_in);
return 0;
}
/* gzjoin -- command to join gzip files into one gzip file
Copyright (C) 2004 Mark Adler, all rights reserved
version 1.0, 11 Dec 2004
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
/*
* Change history:
*
* 1.0 11 Dec 2004 - First version
*/
/*
gzjoin takes one or more gzip files on the command line and writes out a
single gzip file that will uncompress to the concatenation of the
uncompressed data from the individual gzip files. gzjoin does this without
having to recompress any of the data and without having to calculate a new
crc32 for the concatenated uncompressed data. gzjoin does however have to
decompress all of the input data in order to find the bits in the compressed
data that need to be modified to concatenate the streams.
gzjoin does not do an integrity check on the input gzip files other than
checking the gzip header and decompressing the compressed data. They are
otherwise assumed to be complete and correct.
Each joint between gzip files removes at least 18 bytes of previous trailer
and subsequent header, and inserts an average of about three bytes to the
compressed data in order to connect the streams. The output gzip file
has a minimal ten-byte gzip header with no file name or modification time.
This program was written to illustrate the use of the Z_BLOCK option of
inflate() and the crc32_combine() function. gzjoin will not compile with
versions of zlib earlier than 1.2.3.
*/
#include <stdio.h> /* fputs(), fprintf(), fwrite(), putc() */
#include <stdlib.h> /* exit(), malloc(), free() */
#include <fcntl.h> /* open() */
#include <unistd.h> /* close(), read(), lseek() */
#include "zlib.h"
/* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
#define local static
/* exit with an error (return a value to allow use in an expression) */
local int bail(char *why1, char *why2)
{
fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
exit(1);
return 0;
}
/* -- simple buffered file input with access to the buffer -- */
#define CHUNK 32768 /* must be a power of two and fit in unsigned */
/* bin buffered input file type */
typedef struct {
char *name; /* name of file for error messages */
int fd; /* file descriptor */
unsigned left; /* bytes remaining at next */
unsigned char *next; /* next byte to read */
unsigned char *buf; /* allocated buffer of length CHUNK */
} bin;
/* close a buffered file and free allocated memory */
local void bclose(bin *in)
{
if (in != NULL) {
if (in->fd != -1)
close(in->fd);
if (in->buf != NULL)
free(in->buf);
free(in);
}
}
/* open a buffered file for input, return a pointer to type bin, or NULL on
failure */
local bin *bopen(char *name)
{
bin *in;
in = malloc(sizeof(bin));
if (in == NULL)
return NULL;
in->buf = malloc(CHUNK);
in->fd = open(name, O_RDONLY, 0);
if (in->buf == NULL || in->fd == -1) {
bclose(in);
return NULL;
}
in->left = 0;
in->next = in->buf;
in->name = name;
return in;
}
/* load buffer from file, return -1 on read error, 0 or 1 on success, with
1 indicating that end-of-file was reached */
local int bload(bin *in)
{
ssize_t len;
if (in == NULL)
return -1;
if (in->left != 0)
return 0;
in->next = in->buf;
do {
len = read(in->fd, in->buf + in->left, CHUNK - in->left);
if (len < 0)
return -1;
in->left += (unsigned)len;
} while (len != 0 && in->left < CHUNK);
return len == 0 ? 1 : 0;
}
/* get a byte from the file, bail if end of file */
#define bget(in) (in->left ? 0 : bload(in), \
in->left ? (in->left--, *(in->next)++) : \
bail("unexpected end of file on ", in->name))
/* get a four-byte little-endian unsigned integer from file */
local unsigned long bget4(bin *in)
{
unsigned long val;
val = bget(in);
val += (unsigned long)(bget(in)) << 8;
val += (unsigned long)(bget(in)) << 16;
val += (unsigned long)(bget(in)) << 24;
return val;
}
/* skip bytes in file */
local void bskip(bin *in, unsigned skip)
{
/* check pointer */
if (in == NULL)
return;
/* easy case -- skip bytes in buffer */
if (skip <= in->left) {
in->left -= skip;
in->next += skip;
return;
}
/* skip what's in buffer, discard buffer contents */
skip -= in->left;
in->left = 0;
/* seek past multiples of CHUNK bytes */
if (skip > CHUNK) {
unsigned left;
left = skip & (CHUNK - 1);
if (left == 0) {
/* exact number of chunks: seek all the way minus one byte to check
for end-of-file with a read */
lseek(in->fd, skip - 1, SEEK_CUR);
if (read(in->fd, in->buf, 1) != 1)
bail("unexpected end of file on ", in->name);
return;
}
/* skip the integral chunks, update skip with remainder */
lseek(in->fd, skip - left, SEEK_CUR);
skip = left;
}
/* read more input and skip remainder */
bload(in);
if (skip > in->left)
bail("unexpected end of file on ", in->name);
in->left -= skip;
in->next += skip;
}
/* -- end of buffered input functions -- */
/* skip the gzip header from file in */
local void gzhead(bin *in)
{
int flags;
/* verify gzip magic header and compression method */
if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
bail(in->name, " is not a valid gzip file");
/* get and verify flags */
flags = bget(in);
if ((flags & 0xe0) != 0)
bail("unknown reserved bits set in ", in->name);
/* skip modification time, extra flags, and os */
bskip(in, 6);
/* skip extra field if present */
if (flags & 4) {
unsigned len;
len = bget(in);
len += (unsigned)(bget(in)) << 8;
bskip(in, len);
}
/* skip file name if present */
if (flags & 8)
while (bget(in) != 0)
;
/* skip comment if present */
if (flags & 16)
while (bget(in) != 0)
;
/* skip header crc if present */
if (flags & 2)
bskip(in, 2);
}
/* write a four-byte little-endian unsigned integer to out */
local void put4(unsigned long val, FILE *out)
{
putc(val & 0xff, out);
putc((val >> 8) & 0xff, out);
putc((val >> 16) & 0xff, out);
putc((val >> 24) & 0xff, out);
}
/* Load up zlib stream from buffered input, bail if end of file */
local void zpull(z_streamp strm, bin *in)
{
if (in->left == 0)
bload(in);
if (in->left == 0)
bail("unexpected end of file on ", in->name);
strm->avail_in = in->left;
strm->next_in = in->next;
}
/* Write header for gzip file to out and initialize trailer. */
local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
{
fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
*crc = crc32(0L, Z_NULL, 0);
*tot = 0;
}
/* Copy the compressed data from name, zeroing the last block bit of the last
block if clr is true, and adding empty blocks as needed to get to a byte
boundary. If clr is false, then the last block becomes the last block of
the output, and the gzip trailer is written. crc and tot maintains the
crc and length (modulo 2^32) of the output for the trailer. The resulting
gzip file is written to out. gzinit() must be called before the first call
of gzcopy() to write the gzip header and to initialize crc and tot. */
local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
FILE *out)
{
int ret; /* return value from zlib functions */
int pos; /* where the "last block" bit is in byte */
int last; /* true if processing the last block */
bin *in; /* buffered input file */
unsigned char *start; /* start of compressed data in buffer */
unsigned char *junk; /* buffer for uncompressed data -- discarded */
z_off_t len; /* length of uncompressed data (support > 4 GB) */
z_stream strm; /* zlib inflate stream */
/* open gzip file and skip header */
in = bopen(name);
if (in == NULL)
bail("could not open ", name);
gzhead(in);
/* allocate buffer for uncompressed data and initialize raw inflate
stream */
junk = malloc(CHUNK);
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -15);
if (junk == NULL || ret != Z_OK)
bail("out of memory", "");
/* inflate and copy compressed data, clear last-block bit if requested */
len = 0;
zpull(&strm, in);
start = strm.next_in;
last = start[0] & 1;
if (last && clr)
start[0] &= ~1;
strm.avail_out = 0;
for (;;) {
/* if input used and output done, write used input and get more */
if (strm.avail_in == 0 && strm.avail_out != 0) {
fwrite(start, 1, strm.next_in - start, out);
start = in->buf;
in->left = 0;
zpull(&strm, in);
}
/* decompress -- return early when end-of-block reached */
strm.avail_out = CHUNK;
strm.next_out = junk;
ret = inflate(&strm, Z_BLOCK);
switch (ret) {
case Z_MEM_ERROR:
bail("out of memory", "");
case Z_DATA_ERROR:
bail("invalid compressed data in ", in->name);
}
/* update length of uncompressed data */
len += CHUNK - strm.avail_out;
/* check for block boundary (only get this when block copied out) */
if (strm.data_type & 128) {
/* if that was the last block, then done */
if (last)
break;
/* number of unused bits in last byte */
pos = strm.data_type & 7;
/* find the next last-block bit */
if (pos != 0) {
/* next last-block bit is in last used byte */
pos = 0x100 >> pos;
last = strm.next_in[-1] & pos;
if (last && clr)
strm.next_in[-1] &= ~pos;
}
else {
/* next last-block bit is in next unused byte */
if (strm.avail_in == 0) {
/* don't have that byte yet -- get it */
fwrite(start, 1, strm.next_in - start, out);
start = in->buf;
in->left = 0;
zpull(&strm, in);
}
last = strm.next_in[0] & 1;
if (last && clr)
strm.next_in[0] &= ~1;
}
}
}
/* update buffer with unused input */
in->left = strm.avail_in;
in->next = strm.next_in;
/* copy used input, write empty blocks to get to byte boundary */
pos = strm.data_type & 7;
fwrite(start, 1, in->next - start - 1, out);
last = in->next[-1];
if (pos == 0 || !clr)
/* already at byte boundary, or last file: write last byte */
putc(last, out);
else {
/* append empty blocks to last byte */
last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */
if (pos & 1) {
/* odd -- append an empty stored block */
putc(last, out);
if (pos == 1)
putc(0, out); /* two more bits in block header */
fwrite("\0\0\xff\xff", 1, 4, out);
}
else {
/* even -- append 1, 2, or 3 empty fixed blocks */
switch (pos) {
case 6:
putc(last | 8, out);
last = 0;
case 4:
putc(last | 0x20, out);
last = 0;
case 2:
putc(last | 0x80, out);
putc(0, out);
}
}
}
/* update crc and tot */
*crc = crc32_combine(*crc, bget4(in), len);
*tot += (unsigned long)len;
/* clean up */
inflateEnd(&strm);
free(junk);
bclose(in);
/* write trailer if this is the last gzip file */
if (!clr) {
put4(*crc, out);
put4(*tot, out);
}
}
/* join the gzip files on the command line, write result to stdout */
int main(int argc, char **argv)
{
unsigned long crc, tot; /* running crc and total uncompressed length */
/* skip command name */
argc--;
argv++;
/* show usage if no arguments */
if (argc == 0) {
fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
stderr);
return 0;
}
/* join gzip files on command line and write to stdout */
gzinit(&crc, &tot, stdout);
while (argc--)
gzcopy(*argv++, argc, &crc, &tot, stdout);
/* done */
return 0;
}
/*
* gzlog.c
* Copyright (C) 2004 Mark Adler
* For conditions of distribution and use, see copyright notice in gzlog.h
* version 1.0, 26 Nov 2004
*
*/
#include <string.h> /* memcmp() */
#include <stdlib.h> /* malloc(), free(), NULL */
#include <sys/types.h> /* size_t, off_t */
#include <unistd.h> /* read(), close(), sleep(), ftruncate(), */
/* lseek() */
#include <fcntl.h> /* open() */
#include <sys/file.h> /* flock() */
#include "zlib.h" /* deflateInit2(), deflate(), deflateEnd() */
#include "gzlog.h" /* interface */
#define local static
/* log object structure */
typedef struct {
int id; /* object identifier */
int fd; /* log file descriptor */
off_t extra; /* offset of extra "ap" subfield */
off_t mark_off; /* offset of marked data */
off_t last_off; /* offset of last block */
unsigned long crc; /* uncompressed crc */
unsigned long len; /* uncompressed length (modulo 2^32) */
unsigned stored; /* length of current stored block */
} gz_log;
#define GZLOGID 19334 /* gz_log object identifier */
#define LOCK_RETRY 1 /* retry lock once a second */
#define LOCK_PATIENCE 1200 /* try about twenty minutes before forcing */
/* acquire a lock on a file */
local int lock(int fd)
{
int patience;
/* try to lock every LOCK_RETRY seconds for LOCK_PATIENCE seconds */
patience = LOCK_PATIENCE;
do {
if (flock(fd, LOCK_EX + LOCK_NB) == 0)
return 0;
(void)sleep(LOCK_RETRY);
patience -= LOCK_RETRY;
} while (patience > 0);
/* we've run out of patience -- give up */
return -1;
}
/* release lock */
local void unlock(int fd)
{
(void)flock(fd, LOCK_UN);
}
/* release a log object */
local void log_clean(gz_log *log)
{
unlock(log->fd);
(void)close(log->fd);
free(log);
}
/* read an unsigned long from a byte buffer little-endian */
local unsigned long make_ulg(unsigned char *buf)
{
int n;
unsigned long val;
val = (unsigned long)(*buf++);
for (n = 8; n < 32; n += 8)
val += (unsigned long)(*buf++) << n;
return val;
}
/* read an off_t from a byte buffer little-endian */
local off_t make_off(unsigned char *buf)
{
int n;
off_t val;
val = (off_t)(*buf++);
for (n = 8; n < 64; n += 8)
val += (off_t)(*buf++) << n;
return val;
}
/* write an unsigned long little-endian to byte buffer */
local void dice_ulg(unsigned long val, unsigned char *buf)
{
int n;
for (n = 0; n < 4; n++) {
*buf++ = val & 0xff;
val >>= 8;
}
}
/* write an off_t little-endian to byte buffer */
local void dice_off(off_t val, unsigned char *buf)
{
int n;
for (n = 0; n < 8; n++) {
*buf++ = val & 0xff;
val >>= 8;
}
}
/* initial, empty gzip file for appending */
local char empty_gz[] = {
0x1f, 0x8b, /* magic gzip id */
8, /* compression method is deflate */
4, /* there is an extra field */
0, 0, 0, 0, /* no modification time provided */
0, 0xff, /* no extra flags, no OS */
20, 0, 'a', 'p', 16, 0, /* extra field with "ap" subfield */
32, 0, 0, 0, 0, 0, 0, 0, /* offset of uncompressed data */
32, 0, 0, 0, 0, 0, 0, 0, /* offset of last block */
1, 0, 0, 0xff, 0xff, /* empty stored block (last) */
0, 0, 0, 0, /* crc */
0, 0, 0, 0 /* uncompressed length */
};
/* initialize a log object with locking */
void *gzlog_open(char *path)
{
unsigned xlen;
unsigned char temp[20];
unsigned sub_len;
int good;
gz_log *log;
/* allocate log structure */
log = malloc(sizeof(gz_log));
if (log == NULL)
return NULL;
log->id = GZLOGID;
/* open file, creating it if necessary, and locking it */
log->fd = open(path, O_RDWR | O_CREAT, 0600);
if (log->fd < 0) {
free(log);
return NULL;
}
if (lock(log->fd)) {
close(log->fd);
free(log);
return NULL;
}
/* if file is empty, write new gzip stream */
if (lseek(log->fd, 0, SEEK_END) == 0) {
if (write(log->fd, empty_gz, sizeof(empty_gz)) != sizeof(empty_gz)) {
log_clean(log);
return NULL;
}
}
/* check gzip header */
(void)lseek(log->fd, 0, SEEK_SET);
if (read(log->fd, temp, 12) != 12 || temp[0] != 0x1f ||
temp[1] != 0x8b || temp[2] != 8 || (temp[3] & 4) == 0) {
log_clean(log);
return NULL;
}
/* process extra field to find "ap" sub-field */
xlen = temp[10] + (temp[11] << 8);
good = 0;
while (xlen) {
if (xlen < 4 || read(log->fd, temp, 4) != 4)
break;
sub_len = temp[2];
sub_len += temp[3] << 8;
xlen -= 4;
if (memcmp(temp, "ap", 2) == 0 && sub_len == 16) {
good = 1;
break;
}
if (xlen < sub_len)
break;
(void)lseek(log->fd, sub_len, SEEK_CUR);
xlen -= sub_len;
}
if (!good) {
log_clean(log);
return NULL;
}
/* read in "ap" sub-field */
log->extra = lseek(log->fd, 0, SEEK_CUR);
if (read(log->fd, temp, 16) != 16) {
log_clean(log);
return NULL;
}
log->mark_off = make_off(temp);
log->last_off = make_off(temp + 8);
/* get crc, length of gzip file */
(void)lseek(log->fd, log->last_off, SEEK_SET);
if (read(log->fd, temp, 13) != 13 ||
memcmp(temp, "\001\000\000\377\377", 5) != 0) {
log_clean(log);
return NULL;
}
log->crc = make_ulg(temp + 5);
log->len = make_ulg(temp + 9);
/* set up to write over empty last block */
(void)lseek(log->fd, log->last_off + 5, SEEK_SET);
log->stored = 0;
return (void *)log;
}
/* maximum amount to put in a stored block before starting a new one */
#define MAX_BLOCK 16384
/* write a block to a log object */
int gzlog_write(void *obj, char *data, size_t len)
{
size_t some;
unsigned char temp[5];
gz_log *log;
/* check object */
log = (gz_log *)obj;
if (log == NULL || log->id != GZLOGID)
return 1;
/* write stored blocks until all of the input is written */
do {
some = MAX_BLOCK - log->stored;
if (some > len)
some = len;
if (write(log->fd, data, some) != some)
return 1;
log->crc = crc32(log->crc, data, some);
log->len += some;
len -= some;
data += some;
log->stored += some;
/* if the stored block is full, end it and start another */
if (log->stored == MAX_BLOCK) {
(void)lseek(log->fd, log->last_off, SEEK_SET);
temp[0] = 0;
dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
temp + 1);
if (write(log->fd, temp, 5) != 5)
return 1;
log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
(void)lseek(log->fd, 5, SEEK_CUR);
log->stored = 0;
}
} while (len);
return 0;
}
/* recompress the remaining stored deflate data in place */
local int recomp(gz_log *log)
{
z_stream strm;
size_t len, max;
unsigned char *in;
unsigned char *out;
unsigned char temp[16];
/* allocate space and read it all in (it's around 1 MB) */
len = log->last_off - log->mark_off;
max = len + (len >> 12) + (len >> 14) + 11;
out = malloc(max);
if (out == NULL)
return 1;
in = malloc(len);
if (in == NULL) {
free(out);
return 1;
}
(void)lseek(log->fd, log->mark_off, SEEK_SET);
if (read(log->fd, in, len) != len) {
free(in);
free(out);
return 1;
}
/* recompress in memory, decoding stored data as we go */
/* note: this assumes that unsigned is four bytes or more */
/* consider not making that assumption */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 8,
Z_DEFAULT_STRATEGY) != Z_OK) {
free(in);
free(out);
return 1;
}
strm.next_in = in;
strm.avail_out = max;
strm.next_out = out;
while (len >= 5) {
if (strm.next_in[0] != 0)
break;
strm.avail_in = strm.next_in[1] + (strm.next_in[2] << 8);
strm.next_in += 5;
len -= 5;
if (strm.avail_in != 0) {
if (len < strm.avail_in)
break;
len -= strm.avail_in;
(void)deflate(&strm, Z_NO_FLUSH);
if (strm.avail_in != 0 || strm.avail_out == 0)
break;
}
}
(void)deflate(&strm, Z_SYNC_FLUSH);
(void)deflateEnd(&strm);
free(in);
if (len != 0 || strm.avail_out == 0) {
free(out);
return 1;
}
/* overwrite stored data with compressed data */
(void)lseek(log->fd, log->mark_off, SEEK_SET);
len = max - strm.avail_out;
if (write(log->fd, out, len) != len) {
free(out);
return 1;
}
free(out);
/* write last empty block, crc, and length */
log->mark_off = log->last_off = lseek(log->fd, 0, SEEK_CUR);
temp[0] = 1;
dice_ulg(0xffffL << 16, temp + 1);
dice_ulg(log->crc, temp + 5);
dice_ulg(log->len, temp + 9);
if (write(log->fd, temp, 13) != 13)
return 1;
/* truncate file to discard remaining stored data and old trailer */
ftruncate(log->fd, lseek(log->fd, 0, SEEK_CUR));
/* update extra field to point to new last empty block */
(void)lseek(log->fd, log->extra, SEEK_SET);
dice_off(log->mark_off, temp);
dice_off(log->last_off, temp + 8);
if (write(log->fd, temp, 16) != 16)
return 1;
return 0;
}
/* maximum accumulation of stored blocks before compressing */
#define MAX_STORED 1048576
/* close log object */
int gzlog_close(void *obj)
{
unsigned char temp[8];
gz_log *log;
/* check object */
log = (gz_log *)obj;
if (log == NULL || log->id != GZLOGID)
return 1;
/* go to start of most recent block being written */
(void)lseek(log->fd, log->last_off, SEEK_SET);
/* if some stuff was put there, update block */
if (log->stored) {
temp[0] = 0;
dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
temp + 1);
if (write(log->fd, temp, 5) != 5)
return 1;
log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
}
/* write last block (empty) */
if (write(log->fd, "\001\000\000\377\377", 5) != 5)
return 1;
/* write updated crc and uncompressed length */
dice_ulg(log->crc, temp);
dice_ulg(log->len, temp + 4);
if (write(log->fd, temp, 8) != 8)
return 1;
/* put offset of that last block in gzip extra block */
(void)lseek(log->fd, log->extra + 8, SEEK_SET);
dice_off(log->last_off, temp);
if (write(log->fd, temp, 8) != 8)
return 1;
/* if more than 1 MB stored, then time to compress it */
if (log->last_off - log->mark_off > MAX_STORED) {
if (recomp(log))
return 1;
}
/* unlock and close file */
log_clean(log);
return 0;
}
/* gzlog.h
Copyright (C) 2004 Mark Adler, all rights reserved
version 1.0, 26 Nov 2004
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
/*
The gzlog object allows writing short messages to a gzipped log file,
opening the log file locked for small bursts, and then closing it. The log
object works by appending stored data to the gzip file until 1 MB has been
accumulated. At that time, the stored data is compressed, and replaces the
uncompressed data in the file. The log file is truncated to its new size at
that time. After closing, the log file is always valid gzip file that can
decompressed to recover what was written.
A gzip header "extra" field contains two file offsets for appending. The
first points to just after the last compressed data. The second points to
the last stored block in the deflate stream, which is empty. All of the
data between those pointers is uncompressed.
*/
/* Open a gzlog object, creating the log file if it does not exist. Return
NULL on error. Note that gzlog_open() could take a long time to return if
there is difficulty in locking the file. */
void *gzlog_open(char *path);
/* Write to a gzlog object. Return non-zero on error. This function will
simply write data to the file uncompressed. Compression of the data
will not occur until gzlog_close() is called. It is expected that
gzlog_write() is used for a short message, and then gzlog_close() is
called. If a large amount of data is to be written, then the application
should write no more than 1 MB at a time with gzlog_write() before
calling gzlog_close() and then gzlog_open() again. */
int gzlog_write(void *log, char *data, size_t len);
/* Close a gzlog object. Return non-zero on error. The log file is locked
until this function is called. This function will compress stored data
at the end of the gzip file if at least 1 MB has been accumulated. Note
that the file will not be a valid gzip file until this function completes.
*/
int gzlog_close(void *log);
此差异已折叠。
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
Not copyrighted -- provided to the public domain
Version 1.2 9 November 2004 Mark Adler */
/* Version history:
1.0 30 Oct 2004 First version
1.1 8 Nov 2004 Add void casting for unused return values
Use switch statement for inflate() return values
1.2 9 Nov 2004 Add assertions to document zlib guarantees
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
int ret, flush;
unsigned have;
z_stream strm;
char in[CHUNK];
char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
/* compress until end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
/* clean up and return */
(void)deflateEnd(&strm);
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
char in[CHUNK];
char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
}
}
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
int ret;
/* do compression if no arguments */
if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* do decompression if -d specified */
else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
ret = inf(stdin, stdout);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* otherwise, report usage */
else {
fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
return 1;
}
}
......@@ -220,7 +220,7 @@ gzFile ZEXPORT gzdopen (fd, mode)
int fd;
const char *mode;
{
char name[20];
char name[46]; /* allow for up to 128-bit integers */
if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */
......@@ -959,6 +959,12 @@ int ZEXPORT gzclose (file)
return destroy((gz_stream*)file);
}
#ifdef STDC
# define zstrerror(errnum) strerror(errnum)
#else
# define zstrerror(errnum) ""
#endif
/* ===========================================================================
Returns the error message for the last error which occured on the
given compressed file. errnum is set to zlib error number. If an
......
......@@ -51,6 +51,7 @@ int stream_size;
if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n"));
strm->state = (voidpf)state;
state->dmax = 32768U;
state->wbits = windowBits;
state->wsize = 1U << windowBits;
state->window = window;
......
......@@ -74,6 +74,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
#ifdef INFLATE_STRICT
unsigned dmax; /* maximum distance from zlib header */
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
......@@ -98,6 +101,9 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
dmax = state->dmax;
#endif
wsize = state->wsize;
whave = state->whave;
write = state->write;
......@@ -167,6 +173,13 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
}
}
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
......
......@@ -113,6 +113,7 @@ z_streamp strm;
state->mode = HEAD;
state->last = 0;
state->havedict = 0;
state->dmax = 32768U;
state->head = Z_NULL;
state->wsize = 0;
state->whave = 0;
......@@ -600,11 +601,13 @@ int flush;
break;
}
DROPBITS(4);
if (BITS(4) + 8 > state->wbits) {
len = BITS(4) + 8;
if (len > state->wbits) {
strm->msg = (char *)"invalid window size";
state->mode = BAD;
break;
}
state->dmax = 1U << len;
Tracev((stderr, "inflate: zlib header ok\n"));
strm->adler = state->check = adler32(0L, Z_NULL, 0);
state->mode = hold & 0x200 ? DICTID : TYPE;
......@@ -1009,6 +1012,13 @@ int flush;
state->offset += BITS(state->extra);
DROPBITS(state->extra);
}
#ifdef INFLATE_STRICT
if (state->offset > state->dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
#endif
if (state->offset > state->whave + out - left) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD;
......@@ -1322,8 +1332,8 @@ z_streamp source;
}
/* copy state */
*dest = *source;
*copy = *state;
zmemcpy(dest, source, sizeof(z_stream));
zmemcpy(copy, state, sizeof(struct inflate_state));
copy->lencode = copy->codes + (state->lencode - state->codes);
copy->distcode = copy->codes + (state->distcode - state->codes);
copy->next = copy->codes + (state->next - state->codes);
......
......@@ -80,6 +80,7 @@ struct inflate_state {
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags (0 if zlib) */
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
unsigned long check; /* protected copy of check value */
unsigned long total; /* protected copy of output count */
gz_headerp head; /* where to save gzip header information */
......
......@@ -9,7 +9,7 @@
#define MAXBITS 15
const char inflate_copyright[] =
" inflate 1.2.2.1 Copyright 1995-2004 Mark Adler ";
" inflate 1.2.2.2 Copyright 1995-2004 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
......@@ -62,7 +62,7 @@ unsigned short FAR *work;
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 207};
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 199};
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
......
......@@ -32,25 +32,24 @@ $ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
compress.c zlib.h zconf.h
$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
crc32.c zlib.h zconf.h
crc32.c crc32.h zlib.h zconf.h zutil.h
$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
deflate.c deflate.h zutil.h zlib.h zconf.h
$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" -
$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio /define=""NO_vsnprintf""" -
gzio.c zutil.h zlib.h zconf.h
$ CALL MAKE infblock.OBJ "CC ''CCOPT' infblock" -
infblock.c zutil.h zlib.h zconf.h infblock.h
$ CALL MAKE infcodes.OBJ "CC ''CCOPT' infcodes" -
infcodes.c zutil.h zlib.h zconf.h inftrees.h
$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
infback.c zutil.h zlib.h zconf.h -
"inftrees.h inflate.h inffast.h inffixed.h"
$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
inffast.c zutil.h zlib.h zconf.h inffast.h
inffast.c zutil.h zlib.h zconf.h -
"inftrees.h inflate.h inffast.h"
$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
inflate.c zutil.h zlib.h zconf.h infblock.h
inflate.c zutil.h zlib.h zconf.h -
"inftrees.h inflate.h inffast.h inffixed.h"
$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
inftrees.c zutil.h zlib.h zconf.h inftrees.h
$ CALL MAKE infutil.OBJ "CC ''CCOPT' infutil" -
infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
trees.c deflate.h zutil.h zlib.h zconf.h
trees.c trees.h deflate.h zutil.h zlib.h zconf.h
$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
uncompr.c zlib.h zconf.h
$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
......@@ -65,7 +64,7 @@ $ write sys$output "Building minigzip..."
$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" -
minigzip.c zlib.h zconf.h
$ call make minigzip.exe -
"LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" -
"LINK minigzip,libz.olb/lib" -
minigzip.obj libz.olb
$ else
$ mms/macro=('comp')
......
......@@ -25,10 +25,10 @@
<QPG:Files>
<QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../libz.so.1.2.2.1" install="/opt/lib/" user="root:bin" permission="644"/>
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.2.1"/>
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.1"/>
<QPG:Add file="../libz.so.1.2.2.1" install="/opt/lib/" component="slib"/>
<QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" user="root:bin" permission="644"/>
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.2.2"/>
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.2.2"/>
<QPG:Add file="../libz.so.1.2.2.2" install="/opt/lib/" component="slib"/>
</QPG:Files>
<QPG:PackageFilter>
......@@ -63,7 +63,7 @@
</QPM:ProductDescription>
<QPM:ReleaseDescription>
<QPM:ReleaseVersion>1.2.2.1</QPM:ReleaseVersion>
<QPM:ReleaseVersion>1.2.2.2</QPM:ReleaseVersion>
<QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
<QPM:ReleaseStability>Stable</QPM:ReleaseStability>
<QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
......
......@@ -934,22 +934,6 @@ void _tr_flush_block(s, buf, stored_len, eof)
if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
set_data_type(s);
#ifdef DEBUG
/* Write out literal/length frequencies for benchmarking */
if (z_verbose) {
FILE *freq;
freq = fopen("defreq.txt", "a");
if (freq != NULL) {
int n;
fputs("ltree:", freq);
for (n = 0; n < L_CODES; n++)
fprintf(freq, " %d", s->dyn_ltree[n].Freq);
putc('\n', freq);
fclose(freq);
}
}
#endif
/* Construct the literal and distance trees */
build_tree(s, (tree_desc *)(&(s->l_desc)));
Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
......@@ -999,7 +983,7 @@ void _tr_flush_block(s, buf, stored_len, eof)
#ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */
#else
} else if (static_lenb == opt_lenb) {
} else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
#endif
send_bits(s, (STATIC_TREES<<1)+eof, 3);
compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
......
......@@ -5,8 +5,8 @@ VS_VERSION_INFO VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
#endif
FILEVERSION 1,2,2,1
PRODUCTVERSION 1,2,2,1
FILEVERSION 1,2,2,2
PRODUCTVERSION 1,2,2,2
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS 1
......@@ -23,12 +23,12 @@ BEGIN
//language ID = U.S. English, char set = Windows, Multilingual
BEGIN
VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", "1.2.2.1\0"
VALUE "FileVersion", "1.2.2.2\0"
VALUE "InternalName", "zlib1.dll\0"
VALUE "LegalCopyright", "(C) 1995-2004 Jean-loup Gailly & Mark Adler\0"
VALUE "OriginalFilename", "zlib1.dll\0"
VALUE "ProductName", "zlib\0"
VALUE "ProductVersion", "1.2.2.1\0"
VALUE "ProductVersion", "1.2.2.2\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
END
END
......
.TH ZLIB 3 "31 October 2004"
.TH ZLIB 3 "30 December 2004"
.SH NAME
zlib \- compression/decompression library
.SH SYNOPSIS
......@@ -133,7 +133,7 @@ before asking for help.
Send questions and/or comments to zlib@gzip.org,
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
.SH AUTHORS
Version 1.2.2.1
Version 1.2.2.2
Copyright (C) 1995-2004 Jean-loup Gailly (jloup@gzip.org)
and Mark Adler (madler@alumni.caltech.edu).
.LP
......
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.2.1, October 31st, 2004
version 1.2.2.2, December 30th, 2004
Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
......@@ -37,8 +37,8 @@
extern "C" {
#endif
#define ZLIB_VERSION "1.2.2.1"
#define ZLIB_VERNUM 0x1221
#define ZLIB_VERSION "1.2.2.2"
#define ZLIB_VERNUM 0x1222
/*
The 'zlib' compression library provides in-memory compression and
......@@ -189,6 +189,7 @@ typedef gz_header FAR *gz_headerp;
#define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2
#define Z_RLE 3
#define Z_FIXED 4
#define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */
......@@ -391,11 +392,11 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
output as possible to the output buffer. Z_BLOCK requests that inflate() stop
if and when it get to the next deflate block boundary. When decoding the zlib
or gzip format, this will cause inflate() to return immediately after the
header and before the first block. When doing a raw inflate, inflate() will
go ahead and process the first block, and will return when it gets to the end
of that block, or when it runs out of data.
if and when it gets to the next deflate block boundary. When decoding the
zlib or gzip format, this will cause inflate() to return immediately after
the header and before the first block. When doing a raw inflate, inflate()
will go ahead and process the first block, and will return when it gets to
the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams.
Also to assist in this, on return inflate() will set strm->data_type to the
......@@ -524,7 +525,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
parameter only affects the compression ratio but not the correctness of the
compressed output even if it is not set appropriately.
compressed output even if it is not set appropriately. Z_FIXED prevents the
use of dynamic Huffman codes, allowing for a simpler decoder for special
applications.
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
......@@ -1230,7 +1233,7 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
*/
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
uLong len2));
z_off_t len2));
/*
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
......@@ -1254,7 +1257,7 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error();
*/
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, uLong len2));
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
/*
Combine two CRC-32 check values into one. For two sequences of bytes,
......
......@@ -137,7 +137,10 @@ const char * ZEXPORT zError(err)
}
#if defined(_WIN32_WCE)
/* does not exist on WCE */
/* The Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used.
*/
int errno = 0;
#endif
......
......@@ -22,6 +22,14 @@
# include <stdlib.h>
#endif
#ifdef NO_ERRNO_H
# ifdef _WIN32_WCE
/* The Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used. We rename it to
* avoid conflict with other libraries that use the same workaround.
*/
# define errno z_errno
# endif
extern int errno;
#else
# include <errno.h>
......@@ -193,15 +201,6 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
# define NO_vsnprintf
#endif
#ifdef HAVE_STRERROR
# ifndef VMS
extern char *strerror OF((int));
# endif
# define zstrerror(errnum) strerror(errnum)
#else
# define zstrerror(errnum) ""
#endif
#if defined(pyr)
# define NO_MEMCPY
#endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册