diff --git a/ChangeLog b/ChangeLog index 57f99861..fc70594c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ ChangeLog file for zlib +Changes in 0.93 (25 June 95) +- temporarily disable inline functions +- make deflate deterministic +- give enough lookahead for PARTIAL_FLUSH +- Set binary mode for stdin/stdout in minigzip.c for OS/2 +- don't even use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures + Changes in 0.92 (3 May 95) - don't assume that char is signed (problem on SGI) - Clear bit buffer when starting a stored block diff --git a/README b/README index bc4a663d..e82b56fa 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -zlib 0.92 is a beta version of a general purpose compression library. +zlib 0.93 is a beta version of a general purpose compression library. The data format used by the zlib library is described in the files zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available @@ -14,9 +14,12 @@ To install the zlib library (libgz.a) in /usr/local/lib, type: make install To install in a different directory, use for example: make install prefix=$HOME This will install in $HOME/lib instead of /usr/local/lib. -The changes made in version 0.92 are documented in the file ChangeLog. +The changes made in version 0.93 are documented in the file ChangeLog. The main changes since 0.9 are: -- don't assume that char is signed (problem on SGI) +- temporarily disable inline functions +- make deflate deterministic +- don't use signed char in inflate (not portable enough) +- fix inflate memory leak for segmented architectures - Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h - Document the memory requirements in zconf.h - added "make install" @@ -50,7 +53,7 @@ medium model with far allocation of big objects. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@cco.caltech.edu + gzip@prep.ai.mit.edu madler@alumni.caltech.edu If you use the zlib library in a product, we would appreciate *not* receiving lengthy legal documents to sign. The sources are provided diff --git a/crc32.c b/crc32.c index d9485c26..92bc3f03 100644 --- a/crc32.c +++ b/crc32.c @@ -7,57 +7,35 @@ #include "zlib.h" -extern uLong crc_table[]; /* crc table, defined below */ - -#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); - -/* ========================================================================= */ -uLong crc32(crc, buf, len) - uLong crc; - Byte *buf; - uInt len; -{ - if (buf == Z_NULL) return 0L; - crc = crc ^ 0xffffffffL; - while (len >= 8) - { - DO8(buf); - len -= 8; - } - if (len) do { - DO1(buf); - } while (--len); - return crc ^ 0xffffffffL; -} +#define local static +#ifdef DYNAMIC_CRC_TABLE /* ========================================================================= * Make the crc table. This function is needed only if you want to compute * the table dynamically. */ -#ifdef DYNAMIC_CRC_TABLE +local int crc_table_empty = 1; +local uLong crc_table[256]; local void make_crc_table() { uLong c; int n, k; - for (n = 0; n < 256; n++) + for (n = 0; n < 256; n++) { c = (uLong)n; - for (k = 0; k < 8; k++) + for (k = 0; k < 8; k++) c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1; crc_table[n] = c; } + crc_table_empty = 0; } -#endif - +#else /* ======================================================================== * Table of CRC-32's of all single-byte values (made by make_crc_table) */ -uLong crc_table[] = { +local uLong crc_table[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, @@ -111,3 +89,32 @@ uLong crc_table[] = { 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; +#endif + +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong crc32(crc, buf, len) + uLong crc; + Byte *buf; + uInt len; +{ + if (buf == Z_NULL) return 0L; +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} diff --git a/deflate.c b/deflate.c index 6c0cd0aa..726da18a 100644 --- a/deflate.c +++ b/deflate.c @@ -117,7 +117,7 @@ local void fill_window __P((deflate_state *s)); local int deflate_fast __P((deflate_state *s, int flush)); local int deflate_slow __P((deflate_state *s, int flush)); local void lm_init __P((deflate_state *s)); -local int longest_match __P((deflate_state *s, IPos cur_match)); +local inline int longest_match __P((deflate_state *s, IPos cur_match)); local void putShortMSB __P((deflate_state *s, uInt b)); local void flush_pending __P((z_stream *strm)); local int read_buf __P((z_stream *strm, char *buf, unsigned size)); @@ -354,13 +354,17 @@ int deflate (strm, flush) } else { quit = deflate_slow(strm->state, flush); } - if (flush == Z_FULL_FLUSH) { + if (flush == Z_FULL_FLUSH || flush == Z_SYNC_FLUSH) { ct_stored_block(strm->state, (char*)0, 0L, 0); /* special marker */ flush_pending(strm); - CLEAR_HASH(strm->state); /* forget history */ - if (strm->avail_out == 0) return Z_OK; + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(strm->state); /* forget history */ + } + } else if (flush == Z_PARTIAL_FLUSH) { + ct_align(strm->state); + flush_pending(strm); } - if (quit) return Z_OK; + if (quit || strm->avail_out == 0) return Z_OK; } Assert(strm->avail_out > 0, "bug2"); @@ -447,8 +451,6 @@ local int read_buf(strm, buf, size) local void lm_init (s) deflate_state *s; { - register unsigned j; - s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); @@ -465,15 +467,10 @@ local void lm_init (s) s->lookahead = 0; s->match_length = MIN_MATCH-1; s->match_available = 0; + s->ins_h = 0; #ifdef ASMV match_init(); /* initialize the asm code */ #endif - - s->ins_h = 0; - for (j=0; jins_h, s->window[j]); - /* If lookahead < MIN_MATCH, ins_h is garbage, but this is - * not important since only literal bytes will be emitted. - */ } /* =========================================================================== @@ -488,7 +485,7 @@ local void lm_init (s) /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ -local INLINE int longest_match(s, cur_match) +local inline int longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { @@ -730,6 +727,16 @@ local void fill_window(s) more); s->lookahead += n; + /* Initialize the hash value now that we have some input: */ + if (s->strstart == 0 && s->lookahead >= MIN_MATCH-1) { + for (n=0; nins_h, s->window[n]); + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); } diff --git a/deflate.h b/deflate.h index c292fc79..fb6c2336 100644 --- a/deflate.h +++ b/deflate.h @@ -268,5 +268,6 @@ typedef struct internal_state { void ct_init __P((deflate_state *s)); int ct_tally __P((deflate_state *s, int dist, int lc)); ulg ct_flush_block __P((deflate_state *s, char *buf, ulg stored_len, int eof)); +void ct_align __P((deflate_state *s)); void ct_stored_block __P((deflate_state *s, char *buf, ulg stored_len, int eof)); diff --git a/infblock.c b/infblock.c index 3a9cf85c..04a56530 100644 --- a/infblock.c +++ b/infblock.c @@ -71,7 +71,11 @@ uLong *c; if (s->mode == BTREE || s->mode == DTREE) ZFREE(z, s->sub.trees.blens); if (s->mode == CODES) - inflate_codes_free(s->sub.codes, z); + { + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + } s->mode = TYPE; s->bitk = 0; s->bitb = 0; @@ -147,12 +151,14 @@ int r; inflate_huft *tl, *td; inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.codes == Z_NULL) + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) { r = Z_MEM_ERROR; LEAVE } + s->sub.decode.tl = Z_NULL; /* don't try to free these */ + s->sub.decode.td = Z_NULL; } DUMPBITS(3) s->mode = CODES; @@ -181,7 +187,7 @@ int r; LEAVE } s->sub.left = (uInt)b & 0xffff; - k = b = 0; /* dump bits */ + b = k = 0; /* dump bits */ Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); s->mode = s->sub.left ? STORED : TYPE; break; @@ -318,7 +324,9 @@ int r; LEAVE } ZFREE(z, s->sub.trees.blens); - s->sub.codes = c; + s->sub.decode.codes = c; + s->sub.decode.tl = tl; + s->sub.decode.td = td; } s->mode = CODES; case CODES: @@ -326,7 +334,9 @@ int r; if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) return inflate_flush(s, z, r); r = Z_OK; - inflate_codes_free(s->sub.codes, z); + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); LOAD Tracev((stderr, "inflate: codes end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : diff --git a/infcodes.c b/infcodes.c index 87e661bb..4305290d 100644 --- a/infcodes.c +++ b/infcodes.c @@ -83,7 +83,7 @@ int r; { uInt j; /* temporary storage */ inflate_huft *t; /* temporary pointer */ - int e; /* extra bits or operation */ + uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Byte *p; /* input data pointer */ @@ -91,7 +91,7 @@ int r; Byte *q; /* output window write pointer */ uInt m; /* bytes to end of window or read pointer */ Byte *f; /* pointer to copy strings from */ - struct inflate_codes_state *c = s->sub.codes; /* codes state */ + struct inflate_codes_state *c = s->sub.decode.codes; /* codes state */ /* copy input/output information to locals (UPDATE macro restores) */ LOAD @@ -121,27 +121,8 @@ int r; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) - if ((e = (int)(t->exop)) < 0) - { - if (e == -128) /* invalid code */ - { - c->mode = BADCODE; - z->msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - } - e = -e; - if (e & 64) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 16) /* literal */ + e = (uInt)(t->exop); + if (e == 0) /* literal */ { c->sub.lit = t->base; Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? @@ -150,9 +131,29 @@ int r; c->mode = LIT; break; } - c->sub.copy.get = e; - c->len = t->base; - c->mode = LENEXT; + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE case LENEXT: /* i: getting length extra (have base) */ j = c->sub.copy.get; NEEDBITS(j) @@ -167,22 +168,24 @@ int r; NEEDBITS(j) t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); DUMPBITS(t->bits) - if ((e = (int)(t->exop)) < 0) + e = (uInt)(t->exop); + if (e & 16) /* distance */ { - if (e == -128) - { - c->mode = BADCODE; - z->msg = "invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - } - c->sub.code.need = -e; + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; c->sub.code.tree = t->next; break; } - c->sub.copy.dist = t->base; - c->sub.copy.get = e; - c->mode = DISTEXT; + c->mode = BADCODE; /* invalid code */ + z->msg = "invalid distance code"; + r = Z_DATA_ERROR; + LEAVE case DISTEXT: /* i: getting distance extra */ j = c->sub.copy.get; NEEDBITS(j) @@ -231,8 +234,6 @@ void inflate_codes_free(c, z) struct inflate_codes_state *c; z_stream *z; { - inflate_trees_free(c->dtree, z); - inflate_trees_free(c->ltree, z); ZFREE(z, c); Tracev((stderr, "inflate: codes free\n")); } diff --git a/inffast.c b/inffast.c index 2fd707e2..49ed1df8 100644 --- a/inffast.c +++ b/inffast.c @@ -17,10 +17,6 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */ #define bits word.what.Bits /* macros for bit input with no checking and for returning unused bytes */ -#ifdef DEBUG -# undef NEXTBYTE -# define NEXTBYTE (n--?0:fprintf(stderr,"inffast underrun\n"),*p++) -#endif #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} @@ -36,7 +32,7 @@ struct inflate_blocks_state *s; z_stream *z; { inflate_huft *t; /* temporary pointer */ - int e; /* extra bits or operation */ + uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Byte *p; /* input data pointer */ @@ -52,7 +48,7 @@ z_stream *z; /* load input, output, bit values */ LOAD - /* initialize masks in registers */ + /* initialize masks */ ml = inflate_mask[bl]; md = inflate_mask[bd]; @@ -60,93 +56,106 @@ z_stream *z; do { /* assume called with m >= 258 && n >= 10 */ /* get literal/length code */ GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) < 0) - do { - if (e == -128) - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - DUMPBITS(t->bits) - e = -e; - if (e & 64) /* end of block */ - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); - DUMPBITS(t->bits) - - /* process literal or length (end of block already trapped) */ - if (e & 16) /* then it's a literal */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) { + DUMPBITS(t->bits) Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: * literal '%c'\n" : "inflate: * literal 0x%02x\n", t->base)); *q++ = (Byte)t->base; m--; + continue; } - else /* it's a length */ - { - /* get length of block to copy (already have extra bits) */ - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e); - Tracevv((stderr, "inflate: * length %u\n", c)); + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - if ((e = (t = td + ((uInt)b & md))->exop) < 0) + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; do { - if (e == -128) + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; + else { z->msg = "invalid distance code"; UNGRAB UPDATE return Z_DATA_ERROR; } - DUMPBITS(t->bits) - e = -e; - } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); - DUMPBITS(t->bits) - - /* get extra bits to add to distance base */ - GRABBITS((uInt)e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* if offset before destination, */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - do { - *q++ = *r++; - } while (--c); + } while (1); + break; } - else /* else offset after destination */ + if ((e & 64) == 0) { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > (uInt)e) /* if source crosses, */ + if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); } - } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = "invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); } while (m >= 258 && n >= 10); /* not enough input or output--restore pointers and return */ diff --git a/inftrees.c b/inftrees.c index 98589276..377e8dae 100644 --- a/inftrees.c +++ b/inftrees.c @@ -41,7 +41,7 @@ local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ /* actually lengths - 2; also see note #13 above about 258 */ local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 128, 128}; /* 128==invalid */ + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ 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, @@ -246,7 +246,7 @@ z_stream *zs; /* for zalloc function */ { x[h] = i; /* save pattern for backing up */ r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = -(Char)j; /* bits in this table */ + r.exop = j; /* bits in this table */ r.next = q; /* pointer to this table */ j = i >> (w - l); /* (get around Turbo C bug) */ u[h-1][j] = r; /* connect to last table */ @@ -256,15 +256,15 @@ z_stream *zs; /* for zalloc function */ /* set up table entry in r */ r.bits = (Byte)(k - w); if (p >= v + n) - r.exop = (Char)(-128); /* out of values--invalid code */ + r.exop = 128 + 64; /* out of values--invalid code */ else if (*p < s) { - r.exop = (Char)(*p < 256 ? 16 : -64); /* 256 is end-of-block code */ + r.exop = (*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ r.base = *p++; /* simple code is just the value */ } else { - r.exop = (Char)e[*p - s]; /* non-simple--look up in lists */ + r.exop = e[*p - s] + 16 + 64; /* non-simple--look up in lists */ r.base = d[*p++ - s]; } @@ -457,10 +457,6 @@ z_stream *z; /* for zfree function */ { register inflate_huft *p, *q; - /* Don't free fixed trees */ - if (t >= fixed_mem && t <= fixed_mem + FIXEDH) - return Z_OK; - /* Go through linked list, freeing from the malloced (t[-1]) address. */ p = t; while (p != Z_NULL) diff --git a/inftrees.h b/inftrees.h index 27e7222f..03b85c51 100644 --- a/inftrees.h +++ b/inftrees.h @@ -9,24 +9,13 @@ */ /* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). - Valid extra bits (exop) are 0..13. exop == -64 is EOB (end of block), - exop == 16 means that v is a literal, exop < 0 means that v is a pointer - to the next table, which codes -exop bits, and lastly exop == -128 - indicates an unused code. If a code with exop == -128 is looked up, - this implies an error in the data. */ - -#if defined(STDC) || defined(sgi) -typedef signed char Char; -#else -typedef char Char; /* just hope that char is signed */ -#endif + that have 16-bit pointers (e.g. PC's in the small or medium model). */ typedef struct inflate_huft_s inflate_huft; struct inflate_huft_s { union { struct { - Char Exop; /* number of extra bits or operation */ + Byte Exop; /* number of extra bits or operation */ Byte Bits; /* number of bits in this code or subcode */ } what; Byte *pad; /* pad structure to a power of 2 (4 bytes for */ diff --git a/infutil.h b/infutil.h index f234e9b1..b5639d64 100644 --- a/infutil.h +++ b/infutil.h @@ -35,8 +35,11 @@ struct inflate_blocks_state { uInt bb; /* bit length tree depth */ inflate_huft *tb; /* bit length decoding tree */ } trees; /* if DTREE, decoding info for trees */ - struct inflate_codes_state - *codes; /* if CODES, current state */ + struct { + inflate_huft *tl, *td; /* trees to free */ + struct inflate_codes_state + *codes; + } decode; /* if CODES, current state */ } sub; /* submode */ uInt last; /* true if this block is the last block */ diff --git a/minigzip.c b/minigzip.c index 017c3e4f..a542bfc0 100644 --- a/minigzip.c +++ b/minigzip.c @@ -27,7 +27,7 @@ extern int unlink __P((const char *)); # include #endif -#ifdef MSDOS +#if defined(MSDOS) || defined(OS2) || defined(WIN32) # include # include # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) diff --git a/trees.c b/trees.c index f85716ea..4c7c1365 100644 --- a/trees.c +++ b/trees.c @@ -738,6 +738,17 @@ void ct_stored_block(s, buf, stored_len, eof) copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate + */ +void ct_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +} + /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. This function diff --git a/zconf.h b/zconf.h index ce93061e..a819c8b6 100644 --- a/zconf.h +++ b/zconf.h @@ -28,8 +28,14 @@ #if defined(MSDOS) && !defined(__32BIT__) # define MAXSEG_64K #endif -#if !defined(STDC) && (defined(MSDOS) || defined(__STDC__)) -# define STDC +#ifndef STDC +# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) +# define STDC +# endif +#endif + +#if !defined(STDC) && !defined(const) +# define const #endif /* Maximum value for memLevel in deflateInit2 */ diff --git a/zlib.h b/zlib.h index 00a4394d..d27173d0 100644 --- a/zlib.h +++ b/zlib.h @@ -1,5 +1,5 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.92 May 3rd, 1995. + version 0.93 June 25th, 1995. Copyright (C) 1995 Jean-loup Gailly and Mark Adler @@ -20,7 +20,7 @@ 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@cco.caltech.edu + gzip@prep.ai.mit.edu madler@alumni.caltech.edu */ #ifndef _ZLIB_H @@ -28,7 +28,7 @@ #include "zconf.h" -#define ZLIB_VERSION "0.92" +#define ZLIB_VERSION "0.93" /* The 'zlib' compression library provides in-memory compression and @@ -108,6 +108,7 @@ typedef struct z_stream_s { #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 #define Z_FULL_FLUSH 2 +#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ #define Z_FINISH 4 /* See deflate() below for the usage of these constants */ diff --git a/zutil.h b/zutil.h index bc8af52d..fc54d57f 100644 --- a/zutil.h +++ b/zutil.h @@ -15,11 +15,9 @@ #include "zlib.h" -#ifdef __GNUC__ -# define INLINE inline -#else -# define INLINE -#endif +/* #ifndef __GNUC__ disable inline for now */ +# define inline +/* #endif */ #ifdef MSDOS # include