summaryrefslogtreecommitdiff
path: root/zlib
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2001-11-21 20:47:36 +0000
committerjbj <devnull@localhost>2001-11-21 20:47:36 +0000
commitb20a562f23b0969b6c7e7679a6c82fc801fbbd22 (patch)
tree00cd5ba14739f5972c9508a4ed0d9cb9e8e25606 /zlib
parenta758bedad830501ddc8d7c277f6f92645c1a7e18 (diff)
downloadlibrpm-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.in12
-rw-r--r--zlib/crc32.c40
-rw-r--r--zlib/gzio.c149
-rw-r--r--zlib/infblock.c253
-rw-r--r--zlib/infcodes.h42
-rw-r--r--zlib/inffast.c125
-rw-r--r--zlib/inffast.h5
-rw-r--r--zlib/inflate.c10
-rw-r--r--zlib/infutil.c24
-rw-r--r--zlib/infutil.h9
-rw-r--r--zlib/minigzip.c4
-rw-r--r--zlib/zlib.h2
-rw-r--r--zlib/zutil.h36
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 */