diff options
author | jbj <devnull@localhost> | 2001-11-21 20:47:36 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2001-11-21 20:47:36 +0000 |
commit | b20a562f23b0969b6c7e7679a6c82fc801fbbd22 (patch) | |
tree | 00cd5ba14739f5972c9508a4ed0d9cb9e8e25606 /zlib | |
parent | a758bedad830501ddc8d7c277f6f92645c1a7e18 (diff) | |
download | librpm-tizen-b20a562f23b0969b6c7e7679a6c82fc801fbbd22.tar.gz librpm-tizen-b20a562f23b0969b6c7e7679a6c82fc801fbbd22.tar.bz2 librpm-tizen-b20a562f23b0969b6c7e7679a6c82fc801fbbd22.zip |
Apply speedup patch from Ben LaHaise <bcrl@redhat.com> from
http://touchme.toronto.redhat.com/~bcrl/zlib-x86-opt-20010103C.diff
CVS patchset: 5202
CVS date: 2001/11/21 20:47:36
Diffstat (limited to 'zlib')
-rw-r--r-- | zlib/Makefile.in | 12 | ||||
-rw-r--r-- | zlib/crc32.c | 40 | ||||
-rw-r--r-- | zlib/gzio.c | 149 | ||||
-rw-r--r-- | zlib/infblock.c | 253 | ||||
-rw-r--r-- | zlib/infcodes.h | 42 | ||||
-rw-r--r-- | zlib/inffast.c | 125 | ||||
-rw-r--r-- | zlib/inffast.h | 5 | ||||
-rw-r--r-- | zlib/inflate.c | 10 | ||||
-rw-r--r-- | zlib/infutil.c | 24 | ||||
-rw-r--r-- | zlib/infutil.h | 9 | ||||
-rw-r--r-- | zlib/minigzip.c | 4 | ||||
-rw-r--r-- | zlib/zlib.h | 2 | ||||
-rw-r--r-- | zlib/zutil.h | 36 |
13 files changed, 572 insertions, 139 deletions
diff --git a/zlib/Makefile.in b/zlib/Makefile.in index e887f833b..9c64be78a 100644 --- a/zlib/Makefile.in +++ b/zlib/Makefile.in @@ -39,7 +39,7 @@ libdir = ${exec_prefix}/lib includedir = ${prefix}/include OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + zutil.o inflate.o infblock.o inftrees.o infutil.o inffast.o OBJA = # to use the asm code: make OBJA=match.o @@ -161,18 +161,16 @@ lclint: adler32.o: zlib.h zconf.h compress.o: zlib.h zconf.h -crc32.o: zlib.h zconf.h +crc32.o: zlib.h zconf.h crc32.h deflate.o: deflate.h zutil.h zlib.h zconf.h example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h crc32.h infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h -infcodes.o: zutil.h zlib.h zconf.h -infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h crc32.h inffast.o: infblock.h infcodes.h infutil.h inffast.h inflate.o: zutil.h zlib.h zconf.h infblock.h inftrees.o: zutil.h zlib.h zconf.h inftrees.h -infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h crc32.h minigzip.o: zlib.h zconf.h trees.o: deflate.h zutil.h zlib.h zconf.h trees.h uncompr.o: zlib.h zconf.h diff --git a/zlib/crc32.c b/zlib/crc32.c index a91101a81..a6db63781 100644 --- a/zlib/crc32.c +++ b/zlib/crc32.c @@ -3,10 +3,12 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id$ */ +/* @(#) $Id: crc32.c,v 1.1.1.1 2001/11/21 19:43:12 jbj Exp $ */ #include "zlib.h" +#include "crc32.h" + #define local static #ifdef DYNAMIC_CRC_TABLE @@ -65,7 +67,7 @@ local void make_crc_table() /* ======================================================================== * Table of CRC-32's of all single-byte values (made by make_crc_table) */ -local const uLongf crc_table[256] = { +/*local*/ const uLongf crc_table[256] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, @@ -132,31 +134,23 @@ const uLongf * ZEXPORT get_crc_table() return (const uLongf *)crc_table; } -/* ========================================================================= */ -#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 partial_crc32_copy(uLong crc, const Bytef *buf, uInt len, Bytef *dst) +{ + return __partial_crc32(crc, buf, len, 1, dst); +} + +extern uLong partial_crc32(uLong crc, const Bytef *buf, uInt len) +{ + return __partial_crc32(crc, buf, len, 0, 0); +} -/* ========================================================================= */ uLong ZEXPORT crc32(crc, buf, len) uLong crc; const Bytef *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; + if (buf != Z_NULL) + return __partial_crc32(crc ^ 0xffffffffL, buf, len, 0, 0) ^ 0xffffffffL; + return 0L; } + diff --git a/zlib/gzio.c b/zlib/gzio.c index f7c336a55..9cff6f20e 100644 --- a/zlib/gzio.c +++ b/zlib/gzio.c @@ -5,19 +5,25 @@ * Compile this file with -DNO_DEFLATE to avoid the compression code. */ -/* @(#) $Id$ */ +/* @(#) $Id: gzio.c,v 1.1.1.1 2001/11/21 19:43:12 jbj Exp $ */ + +#include <sys/stat.h> +#include <unistd.h> +#include <sys/mman.h> #include <stdio.h> #include "zutil.h" +#include "crc32.h" + struct internal_state {int dummy;}; /* for buggy compilers */ #ifndef Z_BUFSIZE # ifdef MAXSEG_64K # define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ # else -# define Z_BUFSIZE 16384 +# define Z_BUFSIZE (256 * 1024) /*262144 16384*/ # endif #endif #ifndef Z_PRINTF_BUFSIZE @@ -44,12 +50,15 @@ typedef struct gz_stream { FILE *file; /* .gz file */ Byte *inbuf; /* input buffer */ Byte *outbuf; /* output buffer */ - uLong crc; /* crc32 of uncompressed data */ char *msg; /* error message */ char *path; /* path name for debugging only */ int transparent; /* 1 if input file is not a .gz file */ char mode; /* 'w' or 'r' */ + char mmap_mode; long startpos; /* start of compressed data in file (header skipped) */ + off_t mmap_pos; + off_t mmap_end; + int fd; } gz_stream; @@ -97,9 +106,11 @@ local gzFile gz_open (path, mode, fd) s->file = NULL; s->z_err = Z_OK; s->z_eof = 0; - s->crc = crc32(0L, Z_NULL, 0); + s->stream.crc = /*crc32(0L, Z_NULL, 0)*/0; + partial_crc32_prep(&s->stream.crc); s->msg = NULL; s->transparent = 0; + s->mmap_mode = 0; s->path = (char*)ALLOC(strlen(path)+1); if (s->path == NULL) { @@ -153,10 +164,40 @@ local gzFile gz_open (path, mode, fd) s->stream.avail_out = Z_BUFSIZE; errno = 0; - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + if ((fd >= 0) && (s->mode == 'r')) { + struct stat stat; + if (!fstat(fd, &stat) && S_ISREG(stat.st_mode) && (lseek(fd, 0, SEEK_CUR) != -1)) { + char *test = mmap(0, Z_BUFSIZE, PROT_READ, MAP_SHARED, fd, 0); + if (test != (char *)-1) { + long n; + off_t pos; + s->mmap_mode = 1; + s->fd = fd; + TRYFREE(s->inbuf); + munmap(test, Z_BUFSIZE); + pos = lseek(fd, 0, SEEK_CUR); + s->mmap_end = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + + s->mmap_pos = pos & ~(off_t)(Z_BUFSIZE - 1); + s->inbuf = mmap(0, Z_BUFSIZE, PROT_READ, MAP_SHARED, fd, s->mmap_pos); + s->mmap_pos += Z_BUFSIZE; + s->stream.next_in = s->inbuf + (pos & (Z_BUFSIZE - 1)); + s->stream.avail_in = s->mmap_end - pos; + if (s->stream.avail_in > (s->mmap_pos - pos)) + s->stream.avail_in = s->mmap_pos - pos; + for (n=0; n<s->stream.avail_in; n+=4096) + ((volatile char *)s->inbuf)[n]; + } + } + } - if (s->file == NULL) { - return destroy(s), (gzFile)Z_NULL; + if (!s->mmap_mode) { + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } } if (s->mode == 'w') { /* Write a very simple .gz header: @@ -171,7 +212,10 @@ local gzFile gz_open (path, mode, fd) */ } else { check_header(s); /* skip the .gz header */ - s->startpos = (ftell(s->file) - s->stream.avail_in); + if (s->mmap_mode) + s->startpos = s->mmap_pos - s->stream.avail_in; + else + s->startpos = (ftell(s->file) - s->stream.avail_in); } return (gzFile)s; @@ -228,24 +272,58 @@ int ZEXPORT gzsetparams (file, level, strategy) return deflateParams (&(s->stream), level, strategy); } +static inline int gz_refill_inbuf(gz_stream *s) +{ + if (s->mmap_mode) { + long n; + s->stream.avail_in = 0; + if (s->mmap_pos >= s->mmap_end) { + s->z_eof = 1; + return 0; + } + if (s->inbuf) + munmap(s->inbuf, Z_BUFSIZE); + s->inbuf = mmap(s->inbuf, Z_BUFSIZE, PROT_READ, MAP_SHARED|MAP_FIXED, s->fd, s->mmap_pos); + if (s->inbuf == (Byte *)-1) { + s->inbuf = NULL; + s->z_err = errno; + return 1; + } + s->stream.next_in = s->inbuf; + s->stream.avail_in = Z_BUFSIZE; + s->mmap_pos += Z_BUFSIZE; + if (s->mmap_pos > s->mmap_end) + s->stream.avail_in = s->mmap_end - s->mmap_pos + Z_BUFSIZE; + for (n=0; n<s->stream.avail_in; n+=4096) + ((volatile char *)s->inbuf)[n]; + return 0; + } + + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + return 1; + } + } + s->stream.next_in = s->inbuf; + return 0; +} + /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been sucessfully opened for reading. */ -local int get_byte(s) +local inline int get_byte(s) gz_stream *s; { if (s->z_eof) return EOF; if (s->stream.avail_in == 0) { errno = 0; - s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) s->z_err = Z_ERRNO; + if(gz_refill_inbuf(s)) return EOF; - } - s->stream.next_in = s->inbuf; } s->stream.avail_in--; return *(s->stream.next_in)++; @@ -322,6 +400,14 @@ local int destroy (s) TRYFREE(s->msg); + if (s->mmap_mode) { + if (s->inbuf) + munmap(s->inbuf, Z_BUFSIZE); + s->inbuf = NULL; + close(s->fd); + s->mmap_mode = 0; + } + if (s->stream.state != NULL) { if (s->mode == 'w') { #ifdef NO_DEFLATE @@ -374,7 +460,9 @@ int ZEXPORT gzread (file, buf, len) if (s->transparent) { /* Copy first the lookahead bytes: */ - uInt n = s->stream.avail_in; + uInt n; +again: + n = s->stream.avail_in; if (n > s->stream.avail_out) n = s->stream.avail_out; if (n > 0) { zmemcpy(s->stream.next_out, s->stream.next_in, n); @@ -385,8 +473,8 @@ int ZEXPORT gzread (file, buf, len) s->stream.avail_in -= n; } if (s->stream.avail_out > 0) { - s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, - s->file); + if (!s->stream.avail_in && !gz_refill_inbuf(s)) + goto again; } len -= s->stream.avail_out; s->stream.total_in += (uLong)len; @@ -397,24 +485,16 @@ int ZEXPORT gzread (file, buf, len) if (s->stream.avail_in == 0 && !s->z_eof) { errno = 0; - s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) { - s->z_err = Z_ERRNO; - break; - } - } - s->stream.next_in = s->inbuf; + if (gz_refill_inbuf(s)) + break; } s->z_err = inflate(&(s->stream), Z_NO_FLUSH); if (s->z_err == Z_STREAM_END) { /* Check CRC and original size */ - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); start = s->stream.next_out; - if (getLong(s) != s->crc) { + if (getLong(s) != get_crc_from_partial(&s->stream.crc)) { s->z_err = Z_DATA_ERROR; } else { (void)getLong(s); @@ -430,13 +510,13 @@ int ZEXPORT gzread (file, buf, len) inflateReset(&(s->stream)); s->stream.total_in = total_in; s->stream.total_out = total_out; - s->crc = crc32(0L, Z_NULL, 0); + s->stream.crc = /*crc32(0L, Z_NULL, 0)*/0; + partial_crc32_prep(&s->stream.crc); } } } if (s->z_err != Z_OK || s->z_eof) break; } - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); return (int)(len - s->stream.avail_out); } @@ -509,7 +589,7 @@ int ZEXPORT gzwrite (file, buf, len) s->z_err = deflate(&(s->stream), Z_NO_FLUSH); if (s->z_err != Z_OK) break; } - s->crc = crc32(s->crc, (const Bytef *)buf, len); + s->stream.crc = partial_crc32(s->stream.crc, (const Bytef *)buf, len); return (int)(len - s->stream.avail_in); } @@ -749,7 +829,8 @@ int ZEXPORT gzrewind (file) s->z_eof = 0; s->stream.avail_in = 0; s->stream.next_in = s->inbuf; - s->crc = crc32(0L, Z_NULL, 0); + s->stream.crc = 0; + partial_crc32_prep(&s->stream.crc); if (s->startpos == 0) { /* not a compressed file */ rewind(s->file); @@ -834,7 +915,7 @@ int ZEXPORT gzclose (file) err = do_flush (file, Z_FINISH); if (err != Z_OK) return destroy((gz_stream*)file); - putLong (s->file, s->crc); + putLong (s->file, get_crc_from_partial(&s->stream.crc)); putLong (s->file, s->stream.total_in); #endif } diff --git a/zlib/infblock.c b/zlib/infblock.c index f4920faa5..9ab4297b6 100644 --- a/zlib/infblock.c +++ b/zlib/infblock.c @@ -2,14 +2,18 @@ * Copyright (C) 1995-1998 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ - #include "zutil.h" #include "infblock.h" #include "inftrees.h" #include "infcodes.h" #include "infutil.h" +//#include "infutil.c" +#include "inffast.h" + +#if 0 struct inflate_codes_state {int dummy;}; /* for buggy compilers */ +#endif /* simplify the use of the inflate_huft type with some defines */ #define exop word.what.Exop @@ -162,7 +166,7 @@ int r; if (s->sub.decode.codes == Z_NULL) { r = Z_MEM_ERROR; - LEAVE + goto leave; } } DUMPBITS(3) @@ -179,7 +183,7 @@ int r; s->mode = BAD; z->msg = (char*)"invalid block type"; r = Z_DATA_ERROR; - LEAVE + goto leave; } break; case LENS: @@ -189,7 +193,7 @@ int r; s->mode = BAD; z->msg = (char*)"invalid stored block lengths"; r = Z_DATA_ERROR; - LEAVE + goto leave; } s->sub.left = (uInt)b & 0xffff; b = k = 0; /* dump bits */ @@ -198,7 +202,7 @@ int r; break; case STORED: if (n == 0) - LEAVE + goto leave; NEEDOUT t = s->sub.left; if (t > n) t = n; @@ -222,14 +226,14 @@ int r; s->mode = BAD; z->msg = (char*)"too many length or distance symbols"; r = Z_DATA_ERROR; - LEAVE + goto leave; } #endif t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) { r = Z_MEM_ERROR; - LEAVE + goto leave; } DUMPBITS(14) s->sub.trees.index = 0; @@ -253,7 +257,7 @@ int r; r = t; if (r == Z_DATA_ERROR) s->mode = BAD; - LEAVE + goto leave; } s->sub.trees.index = 0; Tracev((stderr, "inflate: bits tree ok\n")); @@ -292,7 +296,7 @@ int r; s->mode = BAD; z->msg = (char*)"invalid bit length repeat"; r = Z_DATA_ERROR; - LEAVE + goto leave; } c = c == 16 ? s->sub.trees.blens[i - 1] : 0; do { @@ -319,13 +323,13 @@ int r; if (t == (uInt)Z_DATA_ERROR) s->mode = BAD; r = t; - LEAVE + goto leave; } Tracev((stderr, "inflate: trees ok\n")); if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) { r = Z_MEM_ERROR; - LEAVE + goto leave; } s->sub.decode.codes = c; } @@ -349,18 +353,21 @@ int r; case DRY: FLUSH if (s->read != s->write) - LEAVE + goto leave; s->mode = DONE; case DONE: r = Z_STREAM_END; - LEAVE + goto leave; case BAD: r = Z_DATA_ERROR; - LEAVE + goto leave; default: r = Z_STREAM_ERROR; - LEAVE + goto leave; } + +leave: + LEAVE } @@ -396,3 +403,219 @@ inflate_blocks_statef *s; { return s->mode == LENS; } + +/*********************************infcodes.c*********************/ + +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-1998 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(/*c->lbits, c->dbits, c->ltree, c->dtree,*/ s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + 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 + t->base; + 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 = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + goto leave; + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + 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 + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + goto leave; + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; +#else + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); +#endif + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + goto leave; + c->mode = END; + case END: + r = Z_STREAM_END; + goto leave; + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + goto leave; + default: + r = Z_STREAM_ERROR; + goto leave; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif + +leave: + LEAVE +} + + +void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff --git a/zlib/infcodes.h b/zlib/infcodes.h index 6c750d896..83f841cc9 100644 --- a/zlib/infcodes.h +++ b/zlib/infcodes.h @@ -8,7 +8,47 @@ subject to change. Applications should only use zlib.h. */ -struct inflate_codes_state; +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + typedef struct inflate_codes_state FAR inflate_codes_statef; extern inflate_codes_statef *inflate_codes_new OF(( diff --git a/zlib/inffast.c b/zlib/inffast.c index 61a78ee93..06d9a09a5 100644 --- a/zlib/inffast.c +++ b/zlib/inffast.c @@ -9,15 +9,16 @@ #include "infcodes.h" #include "infutil.h" #include "inffast.h" - -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ +#include "crc32.h" /* simplify the use of the inflate_huft type with some defines */ #define exop word.what.Exop #define bits word.what.Bits /* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define GRABBITS(j) {\ + if (k+8 < (j)) { b |= NEXTSHORT << k; k += 16; } \ + if (k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} #define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} /* Called with number of bytes left to write in window at least 258 @@ -25,13 +26,19 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */ at least ten. The ten bytes are six bytes for the longest length/ distance pair plus four bytes for overloading the bit buffer. */ -int inflate_fast(bl, bd, tl, td, s, z) +int inflate_fast(/*bl, bd, tl, td,*/ s, z) +#if 0 uInt bl, bd; inflate_huft *tl; inflate_huft *td; /* need separate declaration for Borland C++ */ +#endif inflate_blocks_statef *s; z_streamp z; { +inflate_codes_statef *sc = s->sub.decode.codes; +uInt bl = sc->lbits, bd = sc->dbits; +inflate_huft *tl = sc->ltree; +inflate_huft *td = sc->dtree; /* need separate declaration for Borland C++ */ inflate_huft *t; /* temporary pointer */ uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ @@ -45,10 +52,13 @@ z_streamp z; uInt c; /* bytes to copy */ uInt d; /* distance back to copy from */ Bytef *r; /* copy source pointer */ +int ret; /* load input, output, bit values */ LOAD + PREFETCH(p); + PREFETCH(p+32); /* initialize masks */ ml = inflate_mask[bl]; md = inflate_mask[bd]; @@ -56,6 +66,7 @@ z_streamp z; /* do until not enough input or output space for fast loop */ do { /* assume called with m >= 258 && n >= 10 */ /* get literal/length code */ + PREFETCH(p+64); GRABBITS(20) /* max bits for literal/length code */ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) { @@ -63,8 +74,7 @@ z_streamp z; Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: * literal '%c'\n" : "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; + OUTBYTE((Byte)t->base); continue; } do { @@ -93,6 +103,7 @@ z_streamp z; /* do the copy */ m -= c; +#if 1 if ((uInt)(q - s->window) >= d) /* offset before dest */ { /* just copy */ r = q - d; @@ -106,65 +117,99 @@ z_streamp z; if (c > e) /* if source crosses, */ { c -= e; /* copy to end of window */ +#ifdef __i386__ + {int delta = (int)q - (int)r; + if (delta <= 0 || delta > 3) { + quickmemcpy(q, r, e); + q += e; + e = 0; + goto rest; + } + } +#endif do { *q++ = *r++; } while (--e); +rest: r = s->window; /* copy rest from start of window */ } } +#ifdef __i386__ + {int delta = (int)q - (int)r; + if (delta <= 0 || delta > 3) { + quickmemcpy(q, r, c); + q += c; + r += c; + c = 0; + break; + } + } +#endif do { /* copy all or what's left */ *q++ = *r++; } while (--c); +#endif break; } else if ((e & 64) == 0) { t += t->base; e = (t += ((uInt)b & inflate_mask[e]))->exop; + continue; } else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } + goto inv_dist_code; } while (1); break; } - if ((e & 64) == 0) - { +if (!(e & 64)) { + t += t->base; - if ((e = (t += ((uInt)b & inflate_mask[e]))->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--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) != 0) + continue; + 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; +} else +{ uInt temp = e & 96; + if (temp == 96) + goto stream_end; + if (temp == 64) + goto data_error; +} + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + ret = Z_OK; + +ungrab: UNGRAB UPDATE - return Z_STREAM_END; - } - else + return ret; + +data_error: { z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; + ret = Z_DATA_ERROR; + goto ungrab; } - } while (1); - } while (m >= 258 && n >= 10); - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; +stream_end: + { + Tracevv((stderr, "inflate: * end of block\n")); + ret = Z_STREAM_END; + goto ungrab; + } + +inv_dist_code: + { + z->msg = (char*)"invalid distance code"; + ret = Z_DATA_ERROR; + goto ungrab; + } } diff --git a/zlib/inffast.h b/zlib/inffast.h index 8facec553..c9a64e07b 100644 --- a/zlib/inffast.h +++ b/zlib/inffast.h @@ -9,9 +9,10 @@ */ extern int inflate_fast OF(( - uInt, + /* uInt, uInt, inflate_huft *, inflate_huft *, + */ inflate_blocks_statef *, - z_streamp )); + z_streamp )); // __attribute__((regparm(3))); diff --git a/zlib/inflate.c b/zlib/inflate.c index 32e9b8de6..f177186dd 100644 --- a/zlib/inflate.c +++ b/zlib/inflate.c @@ -144,8 +144,8 @@ int stream_size; } -#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) +#define NEEDBYTE {if(z->avail_in==0)goto out_NEEDBYTE;r=f;} +#define NEXTBYTE (z->avail_in--,/*z->total_in++,*/ *z->next_in++) int ZEXPORT inflate(z, f) z_streamp z; @@ -153,9 +153,10 @@ int f; { int r; uInt b; - +#if 0 if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) return Z_STREAM_ERROR; +#endif f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; r = Z_BUF_ERROR; while (1) switch (z->state->mode) @@ -272,6 +273,9 @@ int f; #ifdef NEED_DUMMY_RETURN return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ #endif + +out_NEEDBYTE: + return r; } diff --git a/zlib/infutil.c b/zlib/infutil.c index 824dab571..ce4dcb686 100644 --- a/zlib/infutil.c +++ b/zlib/infutil.c @@ -2,14 +2,15 @@ * Copyright (C) 1995-1998 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ - +#if 1 #include "zutil.h" #include "infblock.h" #include "inftrees.h" #include "infcodes.h" #include "infutil.h" +#endif -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ +#include "crc32.h" /* And'ing with mask[n] masks the lower n bits */ uInt inflate_mask[17] = { @@ -43,11 +44,15 @@ int r; z->total_out += n; /* update check information */ - if (s->checkfn != Z_NULL) + if (s->checkfn == Z_NULL) + z->crc = partial_crc32_copy(z->crc, q, n, p); + else if (s->checkfn != Z_NULL) { z->adler = s->check = (*s->checkfn)(s->check, q, n); - /* copy as far as end of window */ - zmemcpy(p, q, n); + /* copy as far as end of window */ + zmemcpy(p, q, n); + } + p += n; q += n; @@ -69,11 +74,14 @@ int r; z->total_out += n; /* update check information */ - if (s->checkfn != Z_NULL) + if (!s->checkfn) + z->crc = partial_crc32_copy(z->crc, q, n, p); + else if (s->checkfn != Z_NULL) { z->adler = s->check = (*s->checkfn)(s->check, q, n); - /* copy */ - zmemcpy(p, q, n); + /* copy */ + zmemcpy(p, q, n); + } p += n; q += n; } diff --git a/zlib/infutil.h b/zlib/infutil.h index 99d1135d0..6af34df3d 100644 --- a/zlib/infutil.h +++ b/zlib/infutil.h @@ -72,6 +72,11 @@ struct inflate_blocks_state { #define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} #define NEEDBYTE {if(n)r=Z_OK;else LEAVE} #define NEXTBYTE (n--,*p++) +#ifdef __i386__ +#define NEXTSHORT (n-=2, p+=2, (uLong)((unsigned short *)p)[-1]) +#else +#define NEXTSHORT (n-=2, p+=2, (uLong)p[-2] | ((uLong)p[-1] << 8)) +#endif #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} #define DUMPBITS(j) {b>>=(j);k-=(j);} /* output bytes */ @@ -88,10 +93,10 @@ struct inflate_blocks_state { extern uInt inflate_mask[17]; /* copy as much as possible from the sliding window to the output area */ -extern int inflate_flush OF(( +int inflate_flush OF(( inflate_blocks_statef *, z_streamp , - int)); + int)) __attribute__((regparm(3))); struct internal_state {int dummy;}; /* for buggy compilers */ diff --git a/zlib/minigzip.c b/zlib/minigzip.c index 7215eaeb0..2ba0d2ebb 100644 --- a/zlib/minigzip.c +++ b/zlib/minigzip.c @@ -13,7 +13,7 @@ * or in pipe mode. */ -/* @(#) $Id$ */ +/* @(#) $Id: minigzip.c,v 1.1.1.1 2001/11/21 19:43:12 jbj Exp $ */ #include <stdio.h> #include "zlib.h" @@ -61,7 +61,7 @@ #endif #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) -#define BUFLEN 16384 +#define BUFLEN (16384 * 2) #define MAX_NAME_LEN 1024 #ifdef MAXSEG_64K diff --git a/zlib/zlib.h b/zlib/zlib.h index 49f56b43b..24df5df04 100644 --- a/zlib/zlib.h +++ b/zlib/zlib.h @@ -83,7 +83,7 @@ typedef struct z_stream_s { int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ + uLong crc; /* crc32 as updated during decompression */ } z_stream; typedef z_stream FAR *z_streamp; diff --git a/zlib/zutil.h b/zlib/zutil.h index 6f2cb97ca..e2118dfe4 100644 --- a/zlib/zutil.h +++ b/zlib/zutil.h @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id$ */ +/* @(#) $Id: zutil.h,v 1.1.1.1 2001/11/21 19:43:12 jbj Exp $ */ #ifndef _Z_UTIL_H #define _Z_UTIL_H @@ -176,7 +176,11 @@ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else +#ifdef __i386__ +#define zmemcpy(to,from,n) quickmemcpy(to, from, n) +#else # define zmemcpy memcpy +#endif # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif @@ -217,4 +221,34 @@ void zcfree OF((voidpf opaque, voidpf ptr)); #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} +#ifdef __i386__ +/* This function comes from Linus Torvalds' memcpy: + * NO Copyright (C) 1991, 1992 Linus Torvalds, + * consider these trivial functions to be PD. + */ +#define quickmemcpy(to, from, n) \ +do { \ +int d0, d1, d2; \ +__asm__ __volatile__( \ + "cld\n" \ + "rep ; movsl\n\t" \ + "testb $2,%b4\n\t" \ + "je 1f\n\t" \ + "movsw\n" \ + "1:\ttestb $1,%b4\n\t" \ + "je 2f\n\t" \ + "movsb\n" \ + "2:" \ + : "=&c" (d0), "=&D" (d1), "=&S" (d2) \ + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) \ + : "memory"); \ +} while(0) +#else +static __inline__ void quickmemcpy(void *_to, const void *_from, long n) +{ + char *to = _to, *from = _from; + while (n-- > 0) + *to++ = *from++; +} +#endif #endif /* _Z_UTIL_H */ |