# To install in $HOME instead of /usr/local, use:
# make install prefix=$HOME
-CC=cc
+CC=gcc
-CFLAGS=-O
+CFLAGS=-O3 -DHAVE_UNISTD_H -DUSE_MMAP
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DDEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
# -Wstrict-prototypes -Wmissing-prototypes
LDFLAGS=-L. -lz
-LDSHARED=$(CC)
-CPP=$(CC) -E
+LDSHARED=gcc
+CPP=gcc -E
VER=1.1.3
LIBS=libz.a
TAR=tar
SHELL=/bin/sh
-prefix = /usr/local
-exec_prefix = ${prefix}
-libdir = ${exec_prefix}/lib
-includedir = ${prefix}/include
+prefix =/usr/local
+exec_prefix =${prefix}
+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
rm -f _match.s
$(SHAREDLIB).$(VER): $(OBJS)
- $(LDSHARED) -o $@ $(OBJS)
+ $(LDSHARED) -o $@ $(OBJS) -lc
rm -f $(SHAREDLIB) $(SHAREDLIB).1
ln -s $@ $(SHAREDLIB)
ln -s $@ $(SHAREDLIB).1
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
--- /dev/null
+#define partial_crc32 __z_partial_crc32
+#define partial_crc32_copy __z_partial_crc32_copy
+
+#ifdef __i386__ /* { */
+struct __crc32_fool_gcc {
+ char x[32768];
+};
+
+#if 0
+#define PREFETCH(p) __asm__ __volatile__("prefetch %0": : "m" (*(struct __crc32_fool_gcc *)(p)))
+#else
+#define PREFETCH(p) (*(long *)(struct __crc32_fool_gcc *)(p))
+#endif
+
+#if 0
+#define PREFETCH(p) do ; while (0)
+#endif
+
+static inline void partial_crc32_prep(uLong *crcp)
+{
+ *crcp ^= 0xffffffffL;
+}
+
+static inline void partial_crc32_finish(uLong *crcp)
+{
+ *crcp ^= 0xffffffffL;
+}
+
+static inline uLong get_crc_from_partial(uLong *crcp)
+{
+ return *crcp ^ 0xffffffffL;
+}
+
+extern const uLongf crc_table[256];
+
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+
+static __inline__ uLong __partial_crc32(uLong crc, const Bytef *buf, uInt len, int copy, Bytef *dst)
+{
+ uInt n = len / 4;
+
+#if 1 /* { */
+
+#define DOlong(p, d) do { \
+ int i; \
+ crc ^= *(p); \
+ if (copy) \
+ *(d) = *(p); \
+ crc = crc_table[crc & 0xff] ^ (crc >> 8); \
+ crc = crc_table[crc & 0xff] ^ (crc >> 8); \
+ crc = crc_table[crc & 0xff] ^ (crc >> 8); \
+ crc = crc_table[crc & 0xff] ^ (crc >> 8); \
+} while(0)
+
+#if 0 /* { */
+#define UPDcrc(x) crc =
+#define DOlong(p) \
+ __asm__ __volatile__( \
+ "xorl %1,%0;" \
+ : "=a" (crc) \
+ : "0" (crc) \
+ : "ebx" \
+ )
+#endif /* } */
+
+ if (n) {
+ long *x = (long *)buf;
+ long *y;
+ int j = n / 8;
+
+ PREFETCH(x);
+ PREFETCH(x+8);
+ PREFETCH(x+16);
+
+ if (copy)
+ y = (long *)dst;
+
+ while (n >= 8) {
+ PREFETCH(x+24);
+ /* I hate gcc. If I turn on loop unrolling,
+ * everything else is slowed down. */
+ DOlong(x+0, y+0);
+ DOlong(x+1, y+1);
+ DOlong(x+2, y+2);
+ DOlong(x+3, y+3);
+ DOlong(x+4, y+4);
+ DOlong(x+5, y+5);
+ DOlong(x+6, y+6);
+ DOlong(x+7, y+7);
+ x += 8;
+ y += 8;
+ n -= 8;
+ }
+
+ while (n--) {
+ DOlong(x, y);
+ x++;
+ y++;
+ }
+
+ buf = (Bytef *)x;
+ if (copy)
+ dst = (Bytef *)y;
+ }
+ len &= 3;
+ while (len--) {
+ if (copy)
+ *dst++ = *buf;
+ DO1(buf);
+ }
+
+#else /* } { */
+
+ if (n) {
+ do {
+ DO4(buf);
+ } while (--n);
+ }
+
+ len &= 3;
+ switch(len) {
+ case 3:
+ if (copy)
+ *dst++ = *buf;
+ DO1(buf);
+ case 2:
+ if (copy)
+ *dst++ = *buf;
+ DO1(buf);
+ case 1:
+ if (copy)
+ *dst++ = *buf;
+ DO1(buf);
+ }
+
+#endif /* } */
+
+ return crc;
+}
+
+#undef DO1
+#undef DOlong
+
+#if 0
+#define partial_crc32(crc,buf,len) __partial_crc32(crc, buf, len, 0, 0)
+#define partial_crc32_copy(crc,buf,len,dst) __partial_crc32((crc), (buf), (len), 1, (dst))
+#endif
+
+extern uLong partial_crc32(uLong crc, const Bytef *buf, uInt len) __attribute__((regparm(3)));
+extern uLong partial_crc32_copy(uLong crcp, const Bytef *buf, uInt len, Bytef *dst) __attribute__((regparm(3)));
+
+#endif /* } */
+++ /dev/null
-/* 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
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-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 */
-
-};
-
-
-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;
- 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;
- 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)
- LEAVE
- c->mode = END;
- case END:
- r = Z_STREAM_END;
- LEAVE
- case BADCODE: /* x: got error */
- r = Z_DATA_ERROR;
- LEAVE
- default:
- r = Z_STREAM_ERROR;
- LEAVE
- }
-#ifdef NEED_DUMMY_RETURN
- return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-#endif
-}
-
-
-void inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_streamp z;
-{
- ZFREE(z, c);
- Tracev((stderr, "inflate: codes free\n"));
-}