zlib 0.93
This commit is contained in:
parent
bdde4e09d2
commit
6b834a58bd
@ -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
|
||||
|
11
README
11
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
|
||||
|
69
crc32.c
69
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;
|
||||
}
|
||||
|
35
deflate.c
35
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; j<MIN_MATCH-1; j++) UPDATE_HASH(s, s->ins_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; n<MIN_MATCH-1; n++) {
|
||||
UPDATE_HASH(s, s->ins_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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
22
infblock.c
22
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 :
|
||||
|
81
infcodes.c
81
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"));
|
||||
}
|
||||
|
155
inffast.c
155
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)<<k;k+=8;}}
|
||||
#define UNGRAB {n+=(c=k>>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 */
|
||||
|
14
inftrees.c
14
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)
|
||||
|
15
inftrees.h
15
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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -27,7 +27,7 @@ extern int unlink __P((const char *));
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef MSDOS
|
||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32)
|
||||
# include <fcntl.h>
|
||||
# include <io.h>
|
||||
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
|
||||
|
11
trees.c
11
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
|
||||
|
10
zconf.h
10
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 */
|
||||
|
7
zlib.h
7
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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user