zlib 1.0.1
diff --git a/ChangeLog b/ChangeLog
index 6a7ff7a..36e05dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,20 +1,54 @@
 
 		ChangeLog file for zlib
 
-Changes in 1.0 (15 Jan 96)
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+  and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
 - fixed deflate for 64-bit systems (detected on Cray)
 - fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
 - make falloc completely reentrant (inftrees.c)
 - fixed very unlikely race condition in ct_static_init
-- always return Z_BUF_ERROR when deflate() has nothing to do
-- add deflateParams in zlib.h.
-- test large buffers and deflateParams in example.c
-- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
-- Document Z_SYNC_FLUSH
-- added deflateGetAdler32 and deflateSetAdler32
 - free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
 - Check for __cpluplus in zlib.h
-- Finer test in ct_align for partial flush
+- Better test in ct_align for partial flush
 - avoid harmless warnings for Borland C++
 - initialize hash_head in deflate.c
 - avoid warning on fdopen (gzio.c) for HP cc -Aa
@@ -23,7 +57,7 @@
 - ignore error if ranlib doesn't exist
 - call ranlib twice for NeXTSTEP
 - use exec_prefix instead of prefix for libz.a
-- renamed ct_* as tr_* to avoid conflict with another application.
+- renamed ct_* as _tr_* to avoid conflict with applications
 - clear z->msg in inflateInit2 before any error return
 - initialize opaque in example.c, gzio.c, deflate.c and inflate.c
 - fixed typo in zconf.h (_GNUC__ => __GNUC__)
@@ -32,6 +66,22 @@
 - in fcalloc, normalize pointer if size > 65520 bytes
 - don't use special fcalloc for 32 bit Borland C++
 - use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
+     (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
 
 Changes in 0.95 (16 Aug 95)
 - fix MSDOS small and medium model (now easier to adapt to any compiler)
diff --git a/INDEX b/INDEX
new file mode 100644
index 0000000..c4a3ede
--- /dev/null
+++ b/INDEX
@@ -0,0 +1,46 @@
+ChangeLog	history of changes
+INDEX		this file
+Make_vms.com	script for Vax/VMS
+Makefile	makefile for Unix (generated by configure)
+Makefile.b32	makefile for Borland C++   32-bit
+Makefile.bor	makefile for Borland C/C++ 16-bit
+Makefile.dj2	makefile for DJGPP 2.x
+Makefile.in	makefile for Unix (template for configure)
+Makefile.msc	makefile for Microsoft C 16-bit
+Makefile.sas	makefile for Amiga SAS/C
+Makefile.tc	makefile for Turbo C
+Makefile.wat	makefile for Watcom C
+README		guess what
+configure	configure script for Unix
+descrip.mms	makefile for Vax/VMS
+
+		zlib public header files (must be kept):
+zconf.h
+zlib.h
+
+		private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+deflate.c
+deflate.h
+gzio.c
+infblock.c
+infblock.h
+infcodes.c
+infcodes.h
+inffast.c
+inffast.h
+inflate.c
+inftrees.c
+inftrees.h
+infutil.c
+infutil.h
+trees.c
+uncompr.c
+zutil.c
+zutil.h
+
+		source files for sample programs:
+example.c
+minigzip.c
diff --git a/Makefile b/Makefile
index 45c96e4..3b41059 100644
--- a/Makefile
+++ b/Makefile
@@ -2,78 +2,128 @@
 # Copyright (C) 1995-1996 Jean-loup Gailly.
 # For conditions of distribution and use, see copyright notice in zlib.h 
 
-CC=cc
-CFLAGS=-O
-#use -O3 for gcc
-#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-#CFLAGS=-g -DDEBUG
-LDFLAGS=-L. -lz
+# To compile and test, type:
+#   ./configure; make test
+# The call of configure is optional if you don't have special requirements
 
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+#    make install
+# To install in $HOME instead of /usr/local, use:
+#    make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#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)
+
+VER=1.0.1
+LIBS=libz.a
+
+AR=ar rc
 RANLIB=ranlib
+TAR=tar
 
 prefix=/usr/local
-exec_prefix = ${prefix}
+exec_prefix = $(prefix)
 
 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
 
 TEST_OBJS = example.o minigzip.o
 
+DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] descrip.mms *.[ch]
+
 all: example minigzip
 
 test: all
 	./example
 	echo hello world | ./minigzip | ./minigzip -d 
 
-install: libz.a
-	-@mkdir $(prefix)/include
-	-@mkdir $(exec_prefix)/lib
-	cp zlib.h zconf.h $(prefix)/include
-	chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
-	cp libz.a $(exec_prefix)/lib
-	chmod 644 $(exec_prefix)/lib/libz.a
-	-@$(RANLIB) $(prefix)/lib/libz.a
-# This second ranlib is needed on NeXTSTEP which checks file times
-
 libz.a: $(OBJS)
-	ar rc $@ $(OBJS)
-	-@$(RANLIB) $@
+	$(AR) $@ $(OBJS)
+	-@ ($(RANLIB) $@ || true) 2>/dev/null
 
-example: example.o libz.a
+libz.so.$(VER): $(OBJS)
+	$(LDSHARED) -o $@ $(OBJS)
+	rm -f libz.so; ln -s $@ libz.so
+
+example: example.o $(LIBS)
 	$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
 
-minigzip: minigzip.o libz.a
+minigzip: minigzip.o $(LIBS)
 	$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
 
+install: $(LIBS)
+	-@if [ ! $(prefix)/include  ]; then mkdir $(prefix)/include; fi
+	-@if [ ! $(exec_prefix)/lib ]; then mkdir $(exec_prefix)/lib; fi
+	cp zlib.h zconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
+	cp $(LIBS) $(exec_prefix)/lib
+	cd $(exec_prefix)/lib; chmod 644 $(LIBS)
+	-@(cd $(exec_prefix)/lib; $(RANLIB) libz.a || true) >/dev/null 2>&1
+	cd $(exec_prefix)/lib; if test -f libz.so.$(VER); then \
+	  ln -s libz.so.$(VER) libz.so; \
+	fi
+# The ranlib in install is needed on NeXTSTEP which checks file times
+
+uninstall:
+	cd $(exec_prefix)/lib; rm -f $(LIBS); \
+	if test -f libz.so; then \
+	 v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p'<$(prefix)/include/zlib.h`;\
+	 rm -f libz.so.$$v libz.so; \
+	fi
+	cd $(prefix)/include; rm -f zlib.h zconf.h
+
 clean:
-	rm -f *.o example minigzip libz.a foo.gz
+	rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
 
 zip:
-	zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
-	  descrip.mms *.[ch]
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	v=`sed -n -e 's/\./-/g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	zip -ul9 zlib-$$v $(DISTFILES)
+	mv Makefile~ Makefile
 
-tgz:
-	cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
-	  zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
+dist:
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	rm -f $$d.tar.gz; \
+	if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
+	files=""; \
+	for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
+	cd ..; \
+	GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
+	if test ! -d $$d; then rm -f $$d; fi
+	mv Makefile~ Makefile
 
-TAGS:
+tags:	
 	etags *.[ch]
 
+depend:
+	makedepend -- $(CFLAGS) -- *.[ch]
+
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
-adler32.o: zutil.h zlib.h zconf.h
+adler32.o: zlib.h zconf.h
 compress.o: zlib.h zconf.h
-crc32.o: zutil.h zlib.h zconf.h
+crc32.o: zlib.h zconf.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
-infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.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: 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 inftrees.h infutil.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h
+infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+minigzip.o:  zlib.h zconf.h 
+trees.o: deflate.h zutil.h zlib.h zconf.h 
 uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h  
diff --git a/Makefile.b32 b/Makefile.b32
new file mode 100644
index 0000000..fc3ac68
--- /dev/null
+++ b/Makefile.b32
@@ -0,0 +1,104 @@
+# Makefile for zlib
+# Borland C++   
+
+# This version of the zlib makefile was adapted by Chris Young for use
+# with Borland C 4.5x with the Dos Power Pack for a 32-bit protected mode
+# flat memory model.  It was created for use with POV-Ray ray tracer and
+# you may choose to edit the CFLAGS to suit your needs but the
+# switches -WX and -DMSDOS are required.
+# -- Chris Young 76702.1655@compuserve.com
+
+# To use, do "make -fmakefile.b32"
+
+# See zconf.h for details about the memory requirements.
+
+# ------------- Borland C++ -------------
+MODEL=-WX 
+CFLAGS= $(MODEL) -P-C -K -N- -k- -d -3 -r- -v- -f -DMSDOS
+CC=bcc32
+LD=bcc32
+LIB=tlib
+LDFLAGS= $(MODEL)
+O=.obj
+
+# variables
+OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
+  trees$(O)
+OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
+  trees$(O)
+OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
+  infutil$(O) inffast$(O)
+OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
+  infutil$(O)+inffast$(O)
+
+all: test
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
+   infcodes.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
+   infcodes.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+example.obj: example.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zlib.lib: $(OBJ1) $(OBJ2)
+	del zlib.lib
+	$(LIB) zlib +$(OBJP1)
+	$(LIB) zlib +$(OBJP2)
+
+example.exe: example.obj zlib.lib
+	$(LD) $(LDFLAGS) example.obj zlib.lib
+
+minigzip.exe: minigzip.obj zlib.lib
+	$(LD) $(LDFLAGS) minigzip.obj zlib.lib
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d 
+
+#clean:
+#	del *.obj
+#	del *.exe
diff --git a/Makefile.bor b/Makefile.bor
index 536b76d..2116563 100644
--- a/Makefile.bor
+++ b/Makefile.bor
@@ -18,7 +18,7 @@
 CC=bcc
 LD=bcc
 LIB=tlib
-#   replace bcc with tcc for Turbo C++ 1.0
+#   replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
 LDFLAGS=$(MODEL)
 O=.obj
 
diff --git a/Makefile.dj2 b/Makefile.dj2
new file mode 100644
index 0000000..82f55ea
--- /dev/null
+++ b/Makefile.dj2
@@ -0,0 +1,79 @@
+# Makefile for zlib.  Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
+# Copyright (C) 1995-1996 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h 
+
+# To compile and test, type:
+#   make -fmakefile.dj2;  make test -fmakefile.dj2
+
+# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
+#    make install -fmakefile.dj2
+# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env for [make].
+# Alternately these variables may be defined below.
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+           -Wstrict-prototypes -Wmissing-prototypes
+INSTALL=install
+LDLIBS=-L. -lz
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+VER=1.0
+LIBS=libz.a
+
+AR=ar rcs
+# The default value of RM is "rm -f."  If "rm.exe" is not found, uncomment:
+# RM=del
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+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
+
+TEST_OBJS = example.o minigzip.o
+
+DISTFILES = README Change.Log configur Makefile.in Makefile Makefile.msc \
+	    Makefile.bor Makefile.tc Make_vms.com descrip.mms zlib099.pat \
+	    *.bak *.old *.[ch]
+
+all: example.exe minigzip.exe
+
+test: all
+	./example
+	echo hello world | .\minigzip | .\minigzip -d 
+
+%.o : %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+libz.a: $(OBJS)
+	$(AR) $@ $(OBJS)
+
+libz.so.$(VER): $(OBJS)
+	$(LDSHARED) -o $@ $(OBJS)
+	rm -f libz.so; ln -s $@ libz.so
+
+%.exe : %.o $(LIBS)
+	$(LD) $@ $< $(LDLIBS)
+
+# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env
+
+install: $(LIBS)
+	$(INSTALL) zlib.h zconf.h $(INCLUDE_PATH)
+	$(INSTALL) $(LIBS) $(LIBRARY_PATH)
+
+uninstall:
+	$(RM) $(LIBRARY_PATH)/$(LIBS)
+	$(RM) $(INCLUDE_PATH)/zlib.h $(INCLUDE_PATH)/zconf.h
+
+clean:
+	$(RM) *.d *.o *.~ *.exe libz.a libz.so* foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..3b41059
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,129 @@
+# Makefile for zlib
+# Copyright (C) 1995-1996 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h 
+
+# To compile and test, type:
+#   ./configure; make test
+# The call of configure is optional if you don't have special requirements
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+#    make install
+# To install in $HOME instead of /usr/local, use:
+#    make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#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)
+
+VER=1.0.1
+LIBS=libz.a
+
+AR=ar rc
+RANLIB=ranlib
+TAR=tar
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+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
+
+TEST_OBJS = example.o minigzip.o
+
+DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] descrip.mms *.[ch]
+
+all: example minigzip
+
+test: all
+	./example
+	echo hello world | ./minigzip | ./minigzip -d 
+
+libz.a: $(OBJS)
+	$(AR) $@ $(OBJS)
+	-@ ($(RANLIB) $@ || true) 2>/dev/null
+
+libz.so.$(VER): $(OBJS)
+	$(LDSHARED) -o $@ $(OBJS)
+	rm -f libz.so; ln -s $@ libz.so
+
+example: example.o $(LIBS)
+	$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o $(LIBS)
+	$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+install: $(LIBS)
+	-@if [ ! $(prefix)/include  ]; then mkdir $(prefix)/include; fi
+	-@if [ ! $(exec_prefix)/lib ]; then mkdir $(exec_prefix)/lib; fi
+	cp zlib.h zconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
+	cp $(LIBS) $(exec_prefix)/lib
+	cd $(exec_prefix)/lib; chmod 644 $(LIBS)
+	-@(cd $(exec_prefix)/lib; $(RANLIB) libz.a || true) >/dev/null 2>&1
+	cd $(exec_prefix)/lib; if test -f libz.so.$(VER); then \
+	  ln -s libz.so.$(VER) libz.so; \
+	fi
+# The ranlib in install is needed on NeXTSTEP which checks file times
+
+uninstall:
+	cd $(exec_prefix)/lib; rm -f $(LIBS); \
+	if test -f libz.so; then \
+	 v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p'<$(prefix)/include/zlib.h`;\
+	 rm -f libz.so.$$v libz.so; \
+	fi
+	cd $(prefix)/include; rm -f zlib.h zconf.h
+
+clean:
+	rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
+
+zip:
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	v=`sed -n -e 's/\./-/g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	zip -ul9 zlib-$$v $(DISTFILES)
+	mv Makefile~ Makefile
+
+dist:
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	rm -f $$d.tar.gz; \
+	if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
+	files=""; \
+	for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
+	cd ..; \
+	GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
+	if test ! -d $$d; then rm -f $$d; fi
+	mv Makefile~ Makefile
+
+tags:	
+	etags *.[ch]
+
+depend:
+	makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zlib.h zconf.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
+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: 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
+minigzip.o:  zlib.h zconf.h 
+trees.o: deflate.h zutil.h zlib.h zconf.h 
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h  
diff --git a/Makefile.qnx b/Makefile.qnx
deleted file mode 100644
index 22b1a23..0000000
--- a/Makefile.qnx
+++ /dev/null
@@ -1,75 +0,0 @@
-# Makefile for zlib
-# Copyright (C) 1995 Jean-loup Gailly.
-# For conditions of distribution and use, see copyright notice in zlib.h 
-
-# Modified slightly for QNX by Chris Herborth (chrish@qnx.com)
-
-CC=cc
-CFLAGS=-4 -O -Q
-#use -O3 for gcc to take advantage of inlining
-#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-#CFLAGS=-g -DDEBUG
-LDFLAGS=-L. -lz
-
-#RANLIB=ranlib
-
-prefix=/usr/local
-
-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
-
-TEST_OBJS = example.o minigzip.o
-
-all: example minigzip
-
-test: all
-	./example
-	echo hello world | ./minigzip | ./minigzip -d 
-
-install: zlib.lib
-	-@mkdir $(prefix)/include
-	-@mkdir $(prefix)/lib
-	cp zlib.h zconf.h $(prefix)/include
-	chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
-	cp zlib.lib $(prefix)/lib
-	chmod 644 $(prefix)/lib/zlib.lib
-
-zlib.lib: $(OBJS)
-	cc -A $@ $(OBJS)
-#	ar rc $@ $(OBJS)
-#	$(RANLIB) $@
-
-example: example.o zlib.lib
-	$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
-
-minigzip: minigzip.o zlib.lib
-	$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
-
-clean:
-	rm -f *.o example minigzip zlib.lib foo.gz
-
-zip:
-	zip -ul9 zlib README ChangeLog Makefile Makefile.??? Makefile.?? *.[ch]
-
-tgz:
-	cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
-		zlib/Makefile.??? zlib/Makefile.?? zlib/*.[ch]
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-adler32.o: zutil.h zlib.h zconf.h
-compress.o: zlib.h zconf.h
-crc32.o: zutil.h zlib.h zconf.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
-infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
-infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
-inffast.o: zutil.h zlib.h zconf.h inftrees.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 inftrees.h infutil.h
-minigzip.o: zlib.h zconf.h
-trees.o: deflate.h zutil.h zlib.h zconf.h
-uncompr.o: zlib.h zconf.h
-zutil.o: zutil.h zlib.h zconf.h
diff --git a/Makefile.sas b/Makefile.sas
new file mode 100644
index 0000000..5323e82
--- /dev/null
+++ b/Makefile.sas
@@ -0,0 +1,64 @@
+# SMakefile for zlib
+# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
+# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
+# Amiga, SAS/C 6.56 & Smake
+
+CC=sc
+CFLAGS=OPT
+#CFLAGS=OPT CPU=68030
+#CFLAGS=DEBUG=LINE
+LDFLAGS=LIB z.lib
+
+SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
+       NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX 
+
+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
+
+TEST_OBJS = example.o minigzip.o
+
+all: SCOPTIONS example minigzip
+
+test: all
+	`cd`/example
+	echo hello world | minigzip | minigzip -d 
+
+install: z.lib
+	copy zlib.h zconf.h INCLUDE: clone
+	copy z.lib LIB: clone
+
+z.lib: $(OBJS)
+	oml z.lib r $(OBJS)
+
+example: example.o z.lib
+	$(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o z.lib
+	$(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
+
+clean:
+	-delete force quiet *.o example minigzip z.lib foo.gz *.lnk SCOPTIONS
+
+SCOPTIONS: Smakefile
+        copy to $@ <from <
+$(SCOPTIONS)
+<
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zutil.h zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zutil.h zlib.h zconf.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
+infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.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 inftrees.h infutil.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/Makefile.wat b/Makefile.wat
new file mode 100644
index 0000000..2a3b629
--- /dev/null
+++ b/Makefile.wat
@@ -0,0 +1,103 @@
+# Makefile for zlib
+# Watcom 10a
+
+# This version of the zlib makefile was adapted by Chris Young for use
+# with Watcom 10a 32-bit protected mode flat memory model.  It was created 
+# for use with POV-Ray ray tracer and you may choose to edit the CFLAGS to 
+# suit your needs but the -DMSDOS is required.
+# -- Chris Young 76702.1655@compuserve.com
+
+# To use, do "wmake -f makefile.wat"
+
+# See zconf.h for details about the memory requirements.
+
+# ------------- Watcom 10a -------------
+MODEL=-mf 
+CFLAGS= $(MODEL) -fpi87 -fp5 -zp4 -5r -w5 -oneatx -DMSDOS
+CC=wcc386
+LD=wcl386
+LIB=wlib -b -c 
+LDFLAGS= 
+O=.obj
+
+# variables
+OBJ1=adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) 
+OBJ2=trees$(O) zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) 
+OBJ3=infutil$(O) inffast$(O)
+OBJP1=adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)
+OBJP2=trees$(O)+zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)
+OBJP3=infutil$(O)+inffast$(O)
+
+all: test
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h &
+  infcodes.h infutil.h
+	$(CC) $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h &
+  infcodes.h inffast.h
+	$(CC) $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+example.obj: example.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+	$(CC) $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zlib.lib: $(OBJ1) $(OBJ2) $(OBJ3) 
+	del zlib.lib
+	$(LIB) zlib.lib +$(OBJP1)
+	$(LIB) zlib.lib +$(OBJP2)
+	$(LIB) zlib.lib +$(OBJP3)
+
+example.exe: example.obj zlib.lib
+	$(LD) $(LDFLAGS) example.obj zlib.lib
+
+minigzip.exe: minigzip.obj zlib.lib
+	$(LD) $(LDFLAGS) minigzip.obj zlib.lib
+
+test: minigzip.exe example.exe
+	example
+	echo hello world | minigzip | minigzip -d >test
+	type test
+
+#clean:
+#	del *.obj
+#	del *.exe
diff --git a/README b/README
index b4ad14e..dd72d94 100644
--- a/README
+++ b/README
@@ -1,55 +1,62 @@
-zlib 1.0 is a general purpose data compression library.
-All the code is reentrant (thread safe).
-
-The data format used by the zlib library is described in the
-files zlib-3.2.doc, deflate-1.2.doc and gzip-4.2.doc, available
-in ftp://ftp.uu.net/pub/archiving/zip/doc
+zlib 1.0.1 is a general purpose data compression library.  All the code
+is reentrant (thread safe).  The data format used by the zlib library
+is described in the files zlib-3.3.doc, deflate-1.3.doc and
+gzip-4.3.doc, available in various formats from
+ftp://swrinde.nde.swri.edu/pub/png/documents/zlib/
 
 All functions of the compression library are documented in the file
 zlib.h. A usage example of the library is given in the file example.c
 which also tests that the library is working correctly. Another
-example is given in the file minigzip.c.
+example is given in the file minigzip.c. The compression library itself
+is composed of all source files except example.c and minigzip.c.
 
-To compile all files and run the test program, just type: make test
-(For MSDOS, use one of the special makefiles such as Makefile.msc;
-for VMS, use Make_vms.com or descrip.mms.)
-To install the zlib library (libz.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.
+To compile all files and run the test program, follow the instructions
+given at the top of Makefile. In short "make test; make install"
+should work for most machines.  For MSDOS, use one of the special
+makefiles such as Makefile.msc; for VMS, use Make_vms.com or descrip.mms.
 
-Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov>.
+Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov> or,
+if this fails, to the addresses given below in the Copyright section.
 
-The changes made in version 1.0 are documented in the file ChangeLog.
-The main changes since 0.95 are:
-- allow compression level 0 (no compression)
-- add deflateParams in zlib.h: allow dynamic change of compression level
-  and compression strategy.
-- test large buffers and deflateParams in example.c
-- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
-- fixes for 64-bit systems (needed for Alpha and Cray)
-- always return Z_BUF_ERROR when deflate() has nothing to do
-- fix some very unlikely race conditions.
-- several minor fixes for better portability
-- free in reverse order of allocation to help memory manager
+The changes made in version 1.0.1 are documented in the file ChangeLog.
+Version number 1.0 was skipped to avoid confusion with version 0.99
+which had some references to 1.0 already. The main changes since 0.99 are:
+
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- several portability improvements
 
 Notes for some targets:
 
-- For MSDOS, the small and medium models have been tested only with
-  Microsoft C.  (This should work for Borland C also, but I don't have
-  a Borland compiler to test with.) The small model was tested with
-  Turbo C but only with reduced performance to avoid any far
-  allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-
-  MS Visual C++1.5 in far model gives:
-     warning C4746: 'z_errmsg' : unsized array treated as '__far'
-     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
-  Ignore those warnings.
+- For Turbo C the small model is supported only with reduced performance to
+  avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
 
 - For 64-bit Iris, deflate.c must be compiled without any optimization.
-  With -O, one libpng test fails. The test works in 32 bit mode (with the
-  -32 compiler flag).
+  With -O, one libpng test fails. The test works in 32 bit mode (with
+  the -32 compiler flag).
 
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1   
+  it works when compiled with cc.
+
+- zlib doesn't work on HP-UX 9.05 with one cc compiler (the one not
+  accepting the -O option). It works with the other cc compiler.
+
+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
+is in the CPAN (Comprehensive Perl Archive Network) sites, such as:
+ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz. The deflate
+  and zlib specifications were written by Peter Deutsch. Thanks to all the
+  people who reported problems and suggested various improvements in zlib;
+  they are too numerous to cite here.
 
 Copyright notice:
 
diff --git a/adler32.c b/adler32.c
index 7e2e3f5..b6b5519 100644
--- a/adler32.c
+++ b/adler32.c
@@ -1,9 +1,9 @@
 /* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
-/* $Id: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp $ */
+/* $Id: adler32.c,v 1.9 1996/01/30 21:59:09 me Exp $ */
 
 #include "zlib.h"
 
@@ -11,16 +11,16 @@
 #define NMAX 5552
 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
 
-#define DO1(buf)  {s1 += *buf++; s2 += s1;}
-#define DO2(buf)  DO1(buf); DO1(buf);
-#define DO4(buf)  DO2(buf); DO2(buf);
-#define DO8(buf)  DO4(buf); DO4(buf);
-#define DO16(buf) DO8(buf); DO8(buf);
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
 
 /* ========================================================================= */
 uLong adler32(adler, buf, len)
     uLong adler;
-    Bytef *buf;
+    const Bytef *buf;
     uInt len;
 {
     unsigned long s1 = adler & 0xffff;
@@ -34,10 +34,12 @@
         len -= k;
         while (k >= 16) {
             DO16(buf);
+	    buf += 16;
             k -= 16;
         }
         if (k != 0) do {
-            DO1(buf);
+            s1 += *buf++;
+	    s2 += s1;
         } while (--k);
         s1 %= BASE;
         s2 %= BASE;
diff --git a/compress.c b/compress.c
index 5addd8d..1c58400 100644
--- a/compress.c
+++ b/compress.c
@@ -1,9 +1,9 @@
 /* compress.c -- compress a memory buffer
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
-/* $Id: compress.c,v 1.6 1995/05/03 17:27:08 jloup Exp $ */
+/* $Id: compress.c,v 1.9 1996/01/30 21:59:09 me Exp $ */
 
 #include "zlib.h"
 
@@ -22,13 +22,13 @@
 int compress (dest, destLen, source, sourceLen)
     Bytef *dest;
     uLongf *destLen;
-    Bytef *source;
+    const Bytef *source;
     uLong sourceLen;
 {
     z_stream stream;
     int err;
 
-    stream.next_in = source;
+    stream.next_in = (Bytef*)source;
     stream.avail_in = (uInt)sourceLen;
     /* Check for source > 64K on 16-bit machine: */
     if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
diff --git a/configure b/configure
new file mode 100755
index 0000000..a354e4c
--- /dev/null
+++ b/configure
@@ -0,0 +1,86 @@
+#!/bin/sh
+# configure script for zlib. This script is needed only if
+# you wish to build a shared library and your system supports them,
+# of if you need special compiler, flags or install directory.
+# Otherwise, you can just use directly "make test; make install"
+#
+# To impose specific compiler or flags or install directory, use for example:
+#    prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+#    (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+# LDSHARED is the command to be used to create a shared library
+
+LIBS=libz.a
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
+AR=${AR-"ar rc"}
+RANLIB=${RANLIB-"ranlib"}
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-$prefix}
+
+test -z "$CC" && echo Checking for gcc...
+test=ztest$$
+cat > $test.c <<EOF
+int hello() { printf("hello\n"); }
+EOF
+if test -z "$CC" && (gcc -c -O3 $test.c) 2>/dev/null; then
+  CC=gcc
+  SFLAGS=${CFLAGS-"-fPIC -O3"}
+  CFLAGS=${CFLAGS-"-O3"}
+  LDSHARED=${LDSHARED-"gcc -shared"}
+else
+  # find system name and corresponding cc options
+  CC=${CC-cc}
+  case `(uname -sr || echo unknown) 2>/dev/null` in
+  SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
+             CFLAGS=${CFLAGS-"-fast -xcg89"}
+	     LDSHARED=${LDSHARED-"cc -G"};;
+  SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+	     CFLAGS=${CFLAGS-"-O2"}
+	     LDSHARED=${LDSHARED-"ld"};;
+  IRIX*)     SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+	     CFLAGS=${CFLAGS-"-ansi -O2"}
+	     LDSHARED=${LDSHARED-"cc -shared"};;
+  QNX*)      SFLAGS=${CFLAGS-"-4 -O"}
+             CFLAGS=${CFLAGS-"-4 -O"}
+	     LDSHARED=${LDSHARED-"cc"}
+             RANLIB=${RANLIB-"true"}
+             AR="cc -A";;
+  SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+	     CFLAGS=${CFLAGS-"-O3"}
+	     LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
+  HP-UX*)    SFLAGS=${CFLAGS-"-O +z"}
+	     CFLAGS=${CFLAGS-"-O"}
+	     LDSHARED=${LDSHARED-"ld -b"}
+	     SHAREDLIBS='libz.sl';;
+  # send working options for other systems to gzip@prep.ai.mit.edu
+  *)         SFLAGS=${CFLAGS-"-O"}
+	     CFLAGS=${CFLAGS-"-O"}
+	     LDSHARED=${LDSHARED-"cc -shared"};;
+  esac
+fi
+
+echo Checking for shared library support...
+# we must test in two steps (cc then ld), required at least on SunOS 4.x
+if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
+   test "`($LDSHARED -o $test.so $test.o) 2>&1`" = ""; then
+  CFLAGS="$SFLAGS"
+  LIBS='libz.so.$(VER)'
+  echo Building shared library libz.so.$VER with $CC.
+else
+  LDSHARED="$CC"
+  echo Building static library $LIBS version $VER with $CC.
+fi
+rm -f $test.[co] $test.so
+
+# udpate Makefile
+sed < Makefile.in "
+/^CC *=/s/=.*/=$CC/
+/^CFLAGS *=/s/=.*/=$CFLAGS/
+/^LDSHARED *=/s/=.*/=$LDSHARED/
+/^LIBS *=/s,=.*,=$LIBS,
+/^AR *=/s/=.*/=$AR/
+/^RANLIB *=/s,=.*,=$RANLIB,
+/^VER *=/s/=.*/=$VER/
+/^prefix *=/s,=.*,=$prefix,
+/^exec_prefix *=/s,=.*,=$exec_prefix,
+" > Makefile
diff --git a/crc32.c b/crc32.c
index 4089255..58fc60e 100644
--- a/crc32.c
+++ b/crc32.c
@@ -1,32 +1,62 @@
 /* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
-/* $Id: crc32.c,v 1.4 1995/04/14 14:55:12 jloup Exp $ */
+/* $Id: crc32.c,v 1.8 1996/01/30 21:59:10 me Exp $ */
 
 #include "zlib.h"
 
 #define local static
 
 #ifdef DYNAMIC_CRC_TABLE
-/* =========================================================================
- * Make the crc table. This function is needed only if you want to compute
- * the table dynamically.
- */
-local int crc_table_empty = 1;
-local uLong crc_table[256];
 
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The table is simply the CRC of all possible eight bit values.  This is all
+  the information needed to generate CRC's on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.
+*/
 local void make_crc_table()
 {
   uLong c;
   int n, k;
+  uLong poly;            /* polynomial exclusive-or pattern */
+  /* terms of polynomial defining this crc (except x^32): */
+  static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* make exclusive-or pattern from polynomial (0xedb88320L) */
+  poly = 0L;
+  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+    poly |= 1L << (31 - p[n]);
  
   for (n = 0; n < 256; n++)
   {
     c = (uLong)n;
     for (k = 0; k < 8; k++)
-      c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1;
+      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
     crc_table[n] = c;
   }
   crc_table_empty = 0;
@@ -35,7 +65,7 @@
 /* ========================================================================
  * Table of CRC-32's of all single-byte values (made by make_crc_table)
  */
-local uLong crc_table[] = {
+local uLongf crc_table[256] = {
   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
   0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
   0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
@@ -91,6 +121,18 @@
 };
 #endif
 
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+uLongf *get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+  if (crc_table_empty) make_crc_table();
+#endif
+  return (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);
@@ -99,7 +141,7 @@
 /* ========================================================================= */
 uLong crc32(crc, buf, len)
     uLong crc;
-    Bytef *buf;
+    const Bytef *buf;
     uInt len;
 {
     if (buf == Z_NULL) return 0L;
diff --git a/deflate.c b/deflate.c
index 46ddc55..64710e6 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1,5 +1,5 @@
 /* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -47,11 +47,11 @@
  *
  */
 
-/* $Id: deflate.c,v 1.8 1995/05/03 17:27:08 jloup Exp $ */
+/* $Id: deflate.c,v 1.12 1996/01/30 21:59:11 me Exp $ */
 
 #include "deflate.h"
 
-char deflate_copyright[] = " deflate 1.0 Copyright 1995 Jean-loup Gailly ";
+char deflate_copyright[] = " deflate 1.0.1 Copyright 1995-1996 Jean-loup Gailly ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -60,15 +60,14 @@
  */
 
 /* ===========================================================================
- *  Prototypes for local functions.
+ *  Function prototypes.
  */
-
 local void fill_window    OF((deflate_state *s));
 local int  deflate_stored OF((deflate_state *s, int flush));
 local int  deflate_fast   OF((deflate_state *s, int flush));
 local int  deflate_slow   OF((deflate_state *s, int flush));
 local void lm_init        OF((deflate_state *s));
-local int longest_match   OF((deflate_state *s, IPos cur_match));
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
 local void putShortMSB    OF((deflate_state *s, uInt b));
 local void flush_pending  OF((z_stream *strm));
 local int read_buf        OF((z_stream *strm, charf *buf, unsigned size));
@@ -158,7 +157,7 @@
 #define INSERT_STRING(s, str, match_head) \
    (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
     s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
-    s->head[s->ins_h] = (str))
+    s->head[s->ins_h] = (Pos)(str))
 
 /* ===========================================================================
  * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
@@ -169,26 +168,41 @@
     zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
 
 /* ========================================================================= */
-int deflateInit (strm, level)
+int deflateInit_(strm, level, version, stream_size)
     z_stream *strm;
     int level;
+    const char *version;
+    int stream_size;
 {
-    return deflateInit2 (strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, 0);
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+			 Z_DEFAULT_STRATEGY, version, stream_size);
     /* To do: ignore strm->next_in if we use it as window */
 }
 
 /* ========================================================================= */
-int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
+int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+		  version, stream_size)
     z_stream *strm;
     int  level;
     int  method;
     int  windowBits;
     int  memLevel;
     int  strategy;
+    const char *version;
+    int stream_size;
 {
     deflate_state *s;
     int noheader = 0;
 
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != sizeof(z_stream)) {
+	return Z_VERSION_ERROR;
+    }
     if (strm == Z_NULL) return Z_STREAM_ERROR;
 
     strm->msg = Z_NULL;
@@ -230,20 +244,17 @@
 
     s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
 
-    s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush));
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
 
     if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
         s->pending_buf == Z_NULL) {
-        strm->msg = z_errmsg[1-Z_MEM_ERROR];
+        strm->msg = ERR_MSG(Z_MEM_ERROR);
         deflateEnd (strm);
         return Z_MEM_ERROR;
     }
-    s->l_buf = (uchf *) &(s->pending_buf[s->lit_bufsize]);
-    s->d_buf = (ushf *) &(s->pending_buf[2*s->lit_bufsize]);
-    /* We overlay pending_buf and d_buf+l_buf. This works since the average
-     * output size for (length,distance) codes is <= 32 bits (worst case
-     * is 15+15+13=33). d_buf is put last in case sizeof(short)>2.
-     */
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
 
     s->level = level;
     s->strategy = strategy;
@@ -252,32 +263,42 @@
     return deflateReset(strm);
 }
 
-/* =========================================================================
- * Undocumented function to return the Adler32 of a stream. It can be
- * called immediately after a flush with Z_SYNC_FLUSH, to allow later
- * resumption of the compressor with deflateSetAdler32.
- */
-uLong deflateGetAdler32 (strm)
+/* ========================================================================= */
+int deflateSetDictionary (strm, dictionary, dictLength)
     z_stream *strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
 {
-    if (strm == Z_NULL || strm->state == Z_NULL) return (uLong)Z_STREAM_ERROR;
-    /* Z_STREAM_ERROR happens to be an invalid Adler32 value. */
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
 
-    return strm->state->adler;
-}
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
 
-/* =========================================================================
- * Undocumented function to set the Adler32 of a stream. It can be called
- * immediately after deflateInit to reset the Adler32 of a compression
- * stream which had been interrupted.
- */
-int deflateSetAdler32 (strm, adler)
-    z_stream *strm;
-    uLong adler;
-{
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    strm->adler = adler32(strm->adler, dictionary, dictLength);
 
-    strm->state->adler = adler;
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+	length = MAX_DIST(s);
+	dictionary += dictLength - length;
+    }
+    zmemcpy((charf *)s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+	INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
     return Z_OK;
 }
 
@@ -302,10 +323,10 @@
         s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
     }
     s->status = s->noheader ? BUSY_STATE : INIT_STATE;
-    s->adler = 1;
+    strm->adler = 1;
     s->last_flush = Z_NO_FLUSH;
 
-    tr_init(s);
+    _tr_init(s);
     lm_init(s);
 
     return Z_OK;
@@ -319,6 +340,7 @@
 {
     deflate_state *s;
     compress_func func;
+    int err = Z_OK;
 
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     s = strm->state;
@@ -331,11 +353,9 @@
     }
     func = configuration_table[s->level].func;
 
-    if (func != configuration_table[level].func
-	&& strm->state->lookahead != 0) {
-
+    if (func != configuration_table[level].func && strm->total_in != 0) {
 	/* Flush the last buffer: */
-	(void)(*func)(strm->state, Z_PARTIAL_FLUSH);
+	err = deflate(strm, Z_PARTIAL_FLUSH);
     }
     if (s->level != level) {
 	s->level = level;
@@ -345,7 +365,7 @@
 	s->max_chain_length = configuration_table[level].max_chain;
     }
     s->strategy = strategy;
-    return Z_OK;
+    return err;
 }
 
 /* =========================================================================
@@ -392,36 +412,47 @@
     int flush;
 {
     int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
 
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     
+    s = strm->state;
+
     if (strm->next_out == Z_NULL ||
         (strm->next_in == Z_NULL && strm->avail_in != 0) ||
-	(strm->state->status == FINISH_STATE && flush != Z_FINISH)) {
+	(s->status == FINISH_STATE && flush != Z_FINISH)) {
         ERR_RETURN(strm, Z_STREAM_ERROR);
     }
     if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
 
-    strm->state->strm = strm; /* just in case */
-    old_flush = strm->state->last_flush;
-    strm->state->last_flush = flush;
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
 
     /* Write the zlib header */
-    if (strm->state->status == INIT_STATE) {
+    if (s->status == INIT_STATE) {
 
-        uInt header = (Z_DEFLATED + ((strm->state->w_bits-8)<<4)) << 8;
-        uInt level_flags = (strm->state->level-1) >> 1;
+        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+        uInt level_flags = (s->level-1) >> 1;
 
         if (level_flags > 3) level_flags = 3;
         header |= (level_flags << 6);
+	if (s->strstart != 0) header |= PRESET_DICT;
         header += 31 - (header % 31);
 
-        strm->state->status = BUSY_STATE;
-        putShortMSB(strm->state, header);
+        s->status = BUSY_STATE;
+        putShortMSB(s, header);
+
+	/* Save the adler32 of the preset dictionary: */
+	if (s->strstart != 0) {
+	    putShortMSB(s, (uInt)(strm->adler >> 16));
+	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+	    strm->adler = 1L;
+	}
     }
 
     /* Flush as much pending output as possible */
-    if (strm->state->pending != 0) {
+    if (s->pending != 0) {
         flush_pending(strm);
         if (strm->avail_out == 0) return Z_OK;
 
@@ -435,21 +466,20 @@
     }
 
     /* User must not provide more input after the first FINISH: */
-    if (strm->state->status == FINISH_STATE && strm->avail_in != 0) {
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
         ERR_RETURN(strm, Z_BUF_ERROR);
     }
 
     /* Start a new block or continue the current one.
      */
-    if (strm->avail_in != 0 || strm->state->lookahead != 0 ||
-        (flush != Z_NO_FLUSH && strm->state->status != FINISH_STATE)) {
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
         int quit;
 
         if (flush == Z_FINISH) {
-            strm->state->status = FINISH_STATE;
+            s->status = FINISH_STATE;
         }
-	quit = (*(configuration_table[strm->state->level].func))
-	    (strm->state, flush);
+	quit = (*(configuration_table[s->level].func))(s, flush);
 
         if (quit || strm->avail_out == 0) return Z_OK;
         /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
@@ -461,14 +491,14 @@
          */
         if (flush != Z_NO_FLUSH && flush != Z_FINISH) {
             if (flush == Z_PARTIAL_FLUSH) {
-                tr_align(strm->state);
+                _tr_align(s);
             } else { /* FULL_FLUSH or SYNC_FLUSH */
-                tr_stored_block(strm->state, (char*)0, 0L, 0);
+                _tr_stored_block(s, (char*)0, 0L, 0);
                 /* For a full flush, this empty block will be recognized
                  * as a special marker by inflate_sync().
                  */
                 if (flush == Z_FULL_FLUSH) {
-                    CLEAR_HASH(strm->state);             /* forget history */
+                    CLEAR_HASH(s);             /* forget history */
                 }
             }
             flush_pending(strm);
@@ -478,23 +508,25 @@
     Assert(strm->avail_out > 0, "bug2");
 
     if (flush != Z_FINISH) return Z_OK;
-    if (strm->state->noheader) return Z_STREAM_END;
+    if (s->noheader) return Z_STREAM_END;
 
     /* Write the zlib trailer (adler32) */
-    putShortMSB(strm->state, (uInt)(strm->state->adler >> 16));
-    putShortMSB(strm->state, (uInt)(strm->state->adler & 0xffff));
+    putShortMSB(s, (uInt)(strm->adler >> 16));
+    putShortMSB(s, (uInt)(strm->adler & 0xffff));
     flush_pending(strm);
     /* If avail_out is zero, the application will call deflate again
      * to flush the rest.
      */
-    strm->state->noheader = -1; /* write the trailer only once! */
-    return strm->state->pending != 0 ? Z_OK : Z_STREAM_END;
+    s->noheader = -1; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
 }
 
 /* ========================================================================= */
 int deflateEnd (strm)
     z_stream *strm;
 {
+    int status;
+
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
 
     /* Deallocate in reverse order of allocations: */
@@ -503,10 +535,11 @@
     TRY_FREE(strm, strm->state->prev);
     TRY_FREE(strm, strm->state->window);
 
+    status = strm->state->status;
     ZFREE(strm, strm->state);
     strm->state = Z_NULL;
 
-    return Z_OK;
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
 }
 
 /* ========================================================================= */
@@ -549,7 +582,7 @@
     strm->avail_in  -= len;
 
     if (!strm->state->noheader) {
-        strm->state->adler = adler32(strm->state->adler, strm->next_in, len);
+        strm->adler = adler32(strm->adler, strm->next_in, len);
     }
     zmemcpy(buf, strm->next_in, len);
     strm->next_in  += len;
@@ -593,12 +626,13 @@
  * garbage.
  * IN assertions: cur_match is the head of the hash chain for the current
  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
  */
 #ifndef ASMV
 /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
  * match.S. The code will be functionally equivalent.
  */
-local int longest_match(s, cur_match)
+local uInt longest_match(s, cur_match)
     deflate_state *s;
     IPos cur_match;                             /* current match */
 {
@@ -607,6 +641,7 @@
     register Bytef *match;                       /* matched string */
     register int len;                           /* length of current match */
     int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
     IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
         s->strstart - (IPos)MAX_DIST(s) : NIL;
     /* Stop when cur_match becomes <= limit. To simplify the code,
@@ -637,6 +672,11 @@
     if (s->prev_length >= s->good_match) {
         chain_length >>= 2;
     }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
     Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
 
     do {
@@ -715,7 +755,7 @@
         if (len > best_len) {
             s->match_start = cur_match;
             best_len = len;
-            if (len >= s->nice_match) break;
+            if (len >= nice_match) break;
 #ifdef UNALIGNED_OK
             scan_end = *(ushf*)(scan+best_len-1);
 #else
@@ -726,7 +766,8 @@
     } while ((cur_match = prev[cur_match & wmask]) > limit
              && --chain_length != 0);
 
-    return best_len;
+    if ((uInt)best_len <= s->lookahead) return best_len;
+    return s->lookahead;
 }
 #endif /* ASMV */
 
@@ -740,13 +781,13 @@
     int length;
 {
     /* check that the match is indeed a match */
-    if (memcmp((charf *)s->window + match,
+    if (zmemcmp((charf *)s->window + match,
                 (charf *)s->window + start, length) != EQUAL) {
-        fprintf(stderr,
-            " start %u, match %u, length %d\n",
-            start, match, length);
-        do { fprintf(stderr, "%c%c", s->window[match++],
-                     s->window[start++]); } while (--length != 0);
+        fprintf(stderr, " start %u, match %u, length %d\n",
+		start, match, length);
+        do {
+	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+	} while (--length != 0);
         z_error("invalid match");
     }
     if (verbose > 1) {
@@ -862,9 +903,11 @@
  * IN assertion: strstart is set to the end of the current match.
  */
 #define FLUSH_BLOCK_ONLY(s, eof) { \
-   tr_flush_block(s, (s->block_start >= 0L ? \
-               (charf *)&s->window[(unsigned)s->block_start] : \
-               (charf *)Z_NULL), (long)s->strstart - s->block_start, (eof)); \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+		(ulg)((long)s->strstart - s->block_start), \
+		(eof)); \
    s->block_start = s->strstart; \
    flush_pending(s->strm); \
    Tracev((stderr,"[FLUSH]")); \
@@ -906,7 +949,7 @@
 	s->lookahead = 0;
 
         /* Stored blocks are limited to 0xffff bytes: */
-        if (s->strstart == 0 || s->strstart > 0xffff) {
+        if (s->strstart == 0 || s->strstart > 0xfffe) {
 	    /* strstart == 0 is possible when wraparound on 16-bit machine */
 	    s->lookahead = s->strstart - 0xffff;
 	    s->strstart = 0xffff;
@@ -967,14 +1010,12 @@
                 s->match_length = longest_match (s, hash_head);
             }
             /* longest_match() sets match_start */
-
-            if (s->match_length > s->lookahead) s->match_length = s->lookahead;
         }
         if (s->match_length >= MIN_MATCH) {
             check_match(s, s->strstart, s->match_start, s->match_length);
 
-            bflush = tr_tally(s, s->strstart - s->match_start,
-                              s->match_length - MIN_MATCH);
+            bflush = _tr_tally(s, s->strstart - s->match_start,
+                               s->match_length - MIN_MATCH);
 
             s->lookahead -= s->match_length;
 
@@ -1007,7 +1048,7 @@
         } else {
             /* No match, output a literal byte */
             Tracevv((stderr,"%c", s->window[s->strstart]));
-            bflush = tr_tally (s, 0, s->window[s->strstart]);
+            bflush = _tr_tally (s, 0, s->window[s->strstart]);
             s->lookahead--;
             s->strstart++; 
         }
@@ -1065,7 +1106,6 @@
                 s->match_length = longest_match (s, hash_head);
             }
             /* longest_match() sets match_start */
-            if (s->match_length > s->lookahead) s->match_length = s->lookahead;
 
             if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
                  (s->match_length == MIN_MATCH &&
@@ -1086,8 +1126,8 @@
 
             check_match(s, s->strstart-1, s->prev_match, s->prev_length);
 
-            bflush = tr_tally(s, s->strstart -1 - s->prev_match,
-                              s->prev_length - MIN_MATCH);
+            bflush = _tr_tally(s, s->strstart -1 - s->prev_match,
+                               s->prev_length - MIN_MATCH);
 
             /* Insert in hash table all strings up to the end of the match.
              * strstart-1 and strstart are already inserted. If there is not
@@ -1113,7 +1153,7 @@
              * is longer, truncate the previous match to a single literal.
              */
             Tracevv((stderr,"%c", s->window[s->strstart-1]));
-            if (tr_tally (s, 0, s->window[s->strstart-1])) {
+            if (_tr_tally (s, 0, s->window[s->strstart-1])) {
                 FLUSH_BLOCK_ONLY(s, 0);
             }
             s->strstart++;
@@ -1131,7 +1171,7 @@
     Assert (flush != Z_NO_FLUSH, "no flush?");
     if (s->match_available) {
         Tracevv((stderr,"%c", s->window[s->strstart-1]));
-        tr_tally (s, 0, s->window[s->strstart-1]);
+        _tr_tally (s, 0, s->window[s->strstart-1]);
         s->match_available = 0;
     }
     FLUSH_BLOCK(s, flush == Z_FINISH);
diff --git a/deflate.h b/deflate.h
index 834563b..95ca0c2 100644
--- a/deflate.h
+++ b/deflate.h
@@ -1,5 +1,5 @@
 /* deflate.h -- internal compression state
- * Copyright (C) 1995 Jean-loup Gailly
+ * Copyright (C) 1995-1996 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -8,7 +8,10 @@
    subject to change. Applications should only use zlib.h.
  */
 
-/* $Id: deflate.h,v 1.5 1995/05/03 17:27:09 jloup Exp $ */
+/* $Id: deflate.h,v 1.9 1996/01/30 21:59:13 me Exp $ */
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
 
 #include "zutil.h"
 
@@ -16,11 +19,6 @@
  * Internal compression state.
  */
 
-/* Data type */
-#define BINARY  0
-#define ASCII   1
-#define UNKNOWN 2
-
 #define LENGTH_CODES 29
 /* number of length codes, not counting the special END_BLOCK code */
 
@@ -87,7 +85,6 @@
     Bytef *pending_buf;  /* output still pending */
     Bytef *pending_out;  /* next pending byte to output to the stream */
     int   pending;       /* nb of bytes in the pending buffer */
-    uLong adler;         /* adler32 of uncompressed data */
     int   noheader;      /* suppress zlib header and adler32 */
     Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
     Byte  method;        /* STORED (for zip only) or DEFLATED */
@@ -268,9 +265,11 @@
  */
 
         /* in trees.c */
-void tr_init      OF((deflate_state *s));
-int  tr_tally      OF((deflate_state *s, int dist, int lc));
-ulg tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof));
-void tr_align      OF((deflate_state *s));
-void tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
-                         int eof));
+void _tr_init         OF((deflate_state *s));
+int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+ulg  _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+			  int eof));
+void _tr_align        OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+#endif
diff --git a/example.c b/example.c
index fddb8f8..175fa81 100644
--- a/example.c
+++ b/example.c
@@ -1,9 +1,9 @@
 /* example.c -- usage example of the zlib compression library
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
-/* $Id: example.c,v 1.9 1995/05/03 17:27:09 jloup Exp $ */
+/* $Id: example.c,v 1.13 1996/01/30 21:59:13 me Exp $ */
 
 #include <stdio.h>
 #include "zlib.h"
@@ -22,38 +22,44 @@
     } \
 }
 
-char *hello = "hello, hello!";
+const char hello[] = "hello, hello!";
 /* "hello world" would be more standard, but the repeated "hello"
  * stresses the compression code better, sorry...
  */
 
-void test_compress      OF((Bytef *compr, uLong comprLen,
-		            Bytef *uncompr, uLong uncomprLen));
-void test_gzio          OF((char *out, char *in, 
-		            Bytef *uncompr, int uncomprLen));
-void test_deflate       OF((Bytef *compr, uLong comprLen));
-void test_inflate       OF((Bytef *compr, uLong comprLen,
-		            Bytef *uncompr, uLong uncomprLen));
-void test_large_deflate OF((Bytef *compr, uLong comprLen,
-		            Bytef *uncompr, uLong uncomprLen));
-void test_large_inflate OF((Bytef *compr, uLong comprLen,
-		            Bytef *uncompr, uLong uncomprLen));
-void test_flush         OF((Bytef *compr, uLong comprLen));
-void test_sync          OF((Bytef *compr, uLong comprLen,
-		            Bytef *uncompr, uLong uncomprLen));
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress      OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_gzio          OF((const char *out, const char *in, 
+		            Byte *uncompr, int uncomprLen));
+void test_deflate       OF((Byte *compr, uLong comprLen));
+void test_inflate       OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_flush         OF((Byte *compr, uLong comprLen));
+void test_sync          OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate  OF((Byte *compr, uLong comprLen));
+void test_dict_inflate  OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
 int  main               OF((int argc, char *argv[]));
 
 /* ===========================================================================
  * Test compress() and uncompress()
  */
 void test_compress(compr, comprLen, uncompr, uncomprLen)
-    Bytef *compr, *uncompr;
+    Byte *compr, *uncompr;
     uLong comprLen, uncomprLen;
 {
     int err;
     uLong len = strlen(hello)+1;
 
-    err = compress(compr, &comprLen, (Byte*)hello, len);
+    err = compress(compr, &comprLen, (const Bytef*)hello, len);
     CHECK_ERR(err, "compress");
 
     strcpy((char*)uncompr, "garbage");
@@ -72,9 +78,9 @@
  * Test read/write of .gz files
  */
 void test_gzio(out, in, uncompr, uncomprLen)
-    char *out; /* output file */
-    char *in;  /* input file */
-    Bytef *uncompr;
+    const char *out; /* output file */
+    const char *in;  /* input file */
+    Byte *uncompr;
     int  uncomprLen;
 {
     int err;
@@ -87,7 +93,7 @@
         exit(1);
     }
 
-    if (gzwrite(file, hello, len) != len) {
+    if (gzwrite(file, (const voidp)hello, (unsigned)len) != len) {
         fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
     }
     gzclose(file);
@@ -98,7 +104,7 @@
     }
     strcpy((char*)uncompr, "garbage");
 
-    uncomprLen = gzread(file, uncompr, uncomprLen);
+    uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
     if (uncomprLen != len) {
         fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
     }
@@ -115,7 +121,7 @@
  * Test deflate() with small buffers
  */
 void test_deflate(compr, comprLen)
-    Bytef *compr;
+    Byte *compr;
     uLong comprLen;
 {
     z_stream c_stream; /* compression stream */
@@ -153,7 +159,7 @@
  * Test inflate() with small buffers
  */
 void test_inflate(compr, comprLen, uncompr, uncomprLen)
-    Bytef *compr, *uncompr;
+    Byte *compr, *uncompr;
     uLong comprLen, uncomprLen;
 {
     int err;
@@ -171,7 +177,7 @@
     d_stream.next_in  = compr;
     d_stream.next_out = uncompr;
 
-    while (d_stream.total_out < uncomprLen) {
+    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
         d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
         err = inflate(&d_stream, Z_NO_FLUSH);
         if (err == Z_STREAM_END) break;
@@ -192,7 +198,7 @@
  * Test deflate() with large buffers and dynamic change of compression level
  */
 void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
-    Bytef *compr, *uncompr;
+    Byte *compr, *uncompr;
     uLong comprLen, uncomprLen;
 {
     z_stream c_stream; /* compression stream */
@@ -206,7 +212,7 @@
     CHECK_ERR(err, "deflateInit");
 
     c_stream.next_out = compr;
-    c_stream.avail_out = comprLen;
+    c_stream.avail_out = (uInt)comprLen;
 
     /* At this point, uncompr is still mostly zeroes, so it should compress
      * very well:
@@ -245,7 +251,7 @@
  * Test inflate() with large buffers
  */
 void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
-    Bytef *compr, *uncompr;
+    Byte *compr, *uncompr;
     uLong comprLen, uncomprLen;
 {
     int err;
@@ -265,7 +271,7 @@
 
     for (;;) {
         d_stream.next_out = uncompr;            /* discard the output */
-	d_stream.avail_out = uncomprLen;
+	d_stream.avail_out = (uInt)uncomprLen;
         err = inflate(&d_stream, Z_NO_FLUSH);
         if (err == Z_STREAM_END) break;
         CHECK_ERR(err, "large inflate");
@@ -285,7 +291,7 @@
  * Test deflate() with full flush
  */
 void test_flush(compr, comprLen)
-    Bytef *compr;
+    Byte *compr;
     uLong comprLen;
 {
     z_stream c_stream; /* compression stream */
@@ -321,7 +327,7 @@
  * Test inflateSync()
  */
 void test_sync(compr, comprLen, uncompr, uncomprLen)
-    Bytef *compr, *uncompr;
+    Byte *compr, *uncompr;
     uLong comprLen, uncomprLen;
 {
     int err;
@@ -344,7 +350,7 @@
     inflate(&d_stream, Z_NO_FLUSH);
     CHECK_ERR(err, "inflate");
 
-    d_stream.avail_in = (uInt)uncomprLen-2; /* read all compressed data */
+    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
     err = inflateSync(&d_stream);           /* but skip the damaged part */
     CHECK_ERR(err, "inflateSync");
 
@@ -360,6 +366,91 @@
 }
 
 /* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    err = deflateSetDictionary(&c_stream,
+			       (const Bytef*)dictionary, sizeof(dictionary));
+    CHECK_ERR(err, "deflateSetDictionary");
+
+    dictId = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    c_stream.next_in = (Bytef*)hello;
+    c_stream.avail_in = (uInt)strlen(hello)+1;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    for (;;) {
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+	if (err == Z_NEED_DICT) {
+	    if (d_stream.adler != dictId) {
+		fprintf(stderr, "unexpected dictionary");
+		exit(1);
+	    }
+	    err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+				       sizeof(dictionary));
+	}
+        CHECK_ERR(err, "inflate with dict");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate with dict\n");
+    } else {
+        printf("inflate with dictionary: %s\n", uncompr);
+    }
+}
+
+/* ===========================================================================
  * Usage:  example [output.gz  [input.gz]]
  */
 
@@ -367,8 +458,8 @@
     int argc;
     char *argv[];
 {
-    Bytef *compr, *uncompr;
-    uLong comprLen = 32750*sizeof(int); /* don't overflow on MSDOS */
+    Byte *compr, *uncompr;
+    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
     uLong uncomprLen = comprLen;
 
     if (zlib_version[0] != ZLIB_VERSION[0]) {
@@ -379,8 +470,8 @@
         fprintf(stderr, "warning: different zlib version\n");
     }
 
-    compr    = (Bytef*)malloc(comprLen);
-    uncompr  = (Bytef*)calloc(uncomprLen, 1); /* must be cleared initially */
+    compr    = (Byte*)malloc((uInt)comprLen);
+    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1); /* must be cleared */
     if (compr == Z_NULL || uncompr == Z_NULL) {
         printf("out of memory\n");
 	exit(1);
@@ -401,6 +492,9 @@
     test_flush(compr, comprLen);
     test_sync(compr, comprLen, uncompr, uncomprLen);
 
+    test_dict_deflate(compr, comprLen);
+    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
     exit(0);
     return 0; /* to avoid warning */
 }
diff --git a/gzio.c b/gzio.c
index 03a4674..6f6832b 100644
--- a/gzio.c
+++ b/gzio.c
@@ -1,9 +1,9 @@
 /* gzio.c -- IO on .gz files
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
-/* $Id: gzio.c,v 1.8 1995/05/03 17:27:09 jloup Exp $ */
+/* $Id: gzio.c,v 1.12 1996/01/30 21:59:14 me Exp $ */
 
 #include <stdio.h>
 
@@ -16,8 +16,7 @@
 #define ALLOC(size) malloc(size)
 #define TRYFREE(p) {if (p) free(p);}
 
-#define GZ_MAGIC_1 0x1f
-#define GZ_MAGIC_2 0x8b
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
 
 /* gzip flag byte */
 #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
@@ -27,10 +26,6 @@
 #define COMMENT      0x10 /* bit 4 set: file comment present */
 #define RESERVED     0xE0 /* bits 5..7: reserved */
 
-#ifndef SEEK_CUR
-#  define SEEK_CUR 1
-#endif
-
 typedef struct gz_stream {
     z_stream stream;
     int      z_err;   /* error code for last stream operation */
@@ -46,40 +41,12 @@
 } gz_stream;
 
 
-local int    destroy OF((gz_stream *s));
-local gzFile gz_open OF((char *path, char *mode, int  fd));
-local void   putLong OF((FILE *file, uLong x));
-local uLong  getLong OF((Bytef *buf));
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- */
-local int destroy (s)
-    gz_stream *s;
-{
-    int err = Z_OK;
-
-    if (!s) return Z_STREAM_ERROR;
-
-    TRYFREE(s->inbuf);
-    TRYFREE(s->outbuf);
-    TRYFREE(s->path);
-    TRYFREE(s->msg);
-
-    if (s->stream.state != NULL) {
-       if (s->mode == 'w') {
-           err = deflateEnd(&(s->stream));
-       } else if (s->mode == 'r') {
-           err = inflateEnd(&(s->stream));
-       }
-    }
-    if (s->file != NULL && fclose(s->file)) {
-        err = Z_ERRNO;
-    }
-    if (s->z_err < 0) err = s->z_err;
-    TRYFREE(s);
-    return err;
-}
+local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
+local int    get_byte     OF((gz_stream *s));
+local void   check_header OF((gz_stream *s));
+local int    destroy      OF((gz_stream *s));
+local void   putLong      OF((FILE *file, uLong x));
+local uLong  getLong      OF((gz_stream *s));
 
 /* ===========================================================================
      Opens a gzip (.gz) file for reading or writing. The mode parameter
@@ -91,15 +58,20 @@
    zlib error is Z_MEM_ERROR).
 */
 local gzFile gz_open (path, mode, fd)
-    char *path;
-    char *mode;
+    const char *path;
+    const char *mode;
     int  fd;
 {
     int err;
     int level = Z_DEFAULT_COMPRESSION; /* compression level */
-    char *p = mode;
-    gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream));
+    char *p = (char*)mode;
+    gz_stream *s;
+    char fmode[80]; /* copy of mode, without the compression level */
+    char *m = fmode;
 
+    if (!path || !mode) return Z_NULL;
+
+    s = (gz_stream *)ALLOC(sizeof(gz_stream));
     if (!s) return Z_NULL;
 
     s->stream.zalloc = (alloc_func)0;
@@ -124,9 +96,13 @@
     s->mode = '\0';
     do {
         if (*p == 'r') s->mode = 'r';
-        if (*p == 'w') s->mode = 'w';
-        if (*p >= '1' && *p <= '9') level = *p - '0';
-    } while (*p++);
+        if (*p == 'w' || *p == 'a') s->mode = 'w';
+        if (*p >= '0' && *p <= '9') {
+	    level = *p - '0';
+	} else {
+	    *m++ = *p; /* copy the mode */
+	}
+    } while (*p++ && m != fmode + sizeof(fmode));
     if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
     
     if (s->mode == 'w') {
@@ -150,7 +126,7 @@
     s->stream.avail_out = Z_BUFSIZE;
 
     errno = 0;
-    s->file = fd < 0 ? FOPEN(path, mode) : (FILE*)fdopen(fd, mode);
+    s->file = fd < 0 ? FOPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
 
     if (s->file == NULL) {
         return destroy(s), (gzFile)Z_NULL;
@@ -158,50 +134,10 @@
     if (s->mode == 'w') {
         /* Write a very simple .gz header:
          */
-        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2,
+        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
              Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
     } else {
-        /* Check and skip the header:
-         */
-        Byte c1 = 0, c2 = 0;
-        Byte method = 0;
-        Byte flags = 0;
-        Byte xflags = 0;
-        Byte time[4];
-        Byte osCode;
-        int c;
-
-        s->stream.avail_in = fread(s->inbuf, 1, 2, s->file);
-        if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1
-            || s->inbuf[1] != GZ_MAGIC_2) {
-            s->transparent = 1;
-            return (gzFile)s;
-        }
-        s->stream.avail_in = 0;
-        fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode);
-
-        if (method != Z_DEFLATED || feof(s->file) || (flags & RESERVED) != 0) {
-            s->z_err = Z_DATA_ERROR;
-            return (gzFile)s;
-        }
-        if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
-            long len;
-            fscanf(s->file, "%c%c", &c1, &c2);
-            len = c1 + ((long)c2<<8);
-            fseek(s->file, len, SEEK_CUR);
-        }
-        if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
-            while ((c = getc(s->file)) != 0 && c != EOF) ;
-        }
-        if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
-            while ((c = getc(s->file)) != 0 && c != EOF) ;
-        }
-        if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
-            fscanf(s->file, "%c%c", &c1, &c2);
-        }
-        if (feof(s->file)) {
-            s->z_err = Z_DATA_ERROR;
-        }
+	check_header(s); /* skip the .gz header */
     }
     return (gzFile)s;
 }
@@ -210,26 +146,139 @@
      Opens a gzip (.gz) file for reading or writing.
 */
 gzFile gzopen (path, mode)
-    char *path;
-    char *mode;
+    const char *path;
+    const char *mode;
 {
     return gz_open (path, mode, -1);
 }
 
 /* ===========================================================================
-     Associate a gzFile with the file descriptor fd.
+     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+   to mimic the behavio(u)r of fdopen.
 */
 gzFile gzdopen (fd, mode)
     int fd;
-    char *mode;
+    const char *mode;
 {
     char name[20];
+
+    if (fd < 0) return (gzFile)Z_NULL;
     sprintf(name, "<fd:%d>", fd); /* for debugging */
 
     return gz_open (name, mode, fd);
 }
 
 /* ===========================================================================
+     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)
+    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;
+	    return EOF;
+	}
+	s->stream.next_in = s->inbuf;
+    }
+    s->stream.avail_in--;
+    return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+      Check the gzip header of a gz_stream opened for reading. Set the stream
+    mode to transparent if the gzip magic header is not present; set s->err
+    to Z_DATA_ERROR if the magic header is present but the rest of the header
+    is incorrect.
+    IN assertion: the stream s has already been created sucessfully;
+       s->stream.avail_in is zero for the first time, but may be non-zero
+       for concatenated .gz files.
+*/
+local void check_header(s)
+    gz_stream *s;
+{
+    int method; /* method byte */
+    int flags;  /* flags byte */
+    uInt len;
+    int c;
+
+    /* Check the gzip magic header */
+    for (len = 0; len < 2; len++) {
+	c = get_byte(s);
+	if (c != gz_magic[len]) {
+	    s->transparent = 1;
+	    if (c != EOF) s->stream.avail_in++, s->stream.next_in--;
+	    s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
+	    return;
+	}
+    }
+    method = get_byte(s);
+    flags = get_byte(s);
+    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+	s->z_err = Z_DATA_ERROR;
+	return;
+    }
+
+    /* Discard time, xflags and OS code: */
+    for (len = 0; len < 6; len++) (void)get_byte(s);
+
+    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+	len  =  (uInt)get_byte(s);
+	len += ((uInt)get_byte(s))<<8;
+	/* len is garbage if EOF but the loop below will quit anyway */
+	while (len-- != 0 && get_byte(s) != EOF) ;
+    }
+    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+	while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
+	while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
+	for (len = 0; len < 2; len++) (void)get_byte(s);
+    }
+    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+   Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+    gz_stream *s;
+{
+    int err = Z_OK;
+
+    if (!s) return Z_STREAM_ERROR;
+
+    TRYFREE(s->msg);
+
+    if (s->stream.state != NULL) {
+       if (s->mode == 'w') {
+           err = deflateEnd(&(s->stream));
+       } else if (s->mode == 'r') {
+           err = inflateEnd(&(s->stream));
+       }
+    }
+    if (s->file != NULL && fclose(s->file)) {
+        err = Z_ERRNO;
+    }
+    if (s->z_err < 0) err = s->z_err;
+
+    TRYFREE(s->inbuf);
+    TRYFREE(s->outbuf);
+    TRYFREE(s->path);
+    TRYFREE(s);
+    return err;
+}
+
+/* ===========================================================================
      Reads the given number of uncompressed bytes from the compressed file.
    gzread returns the number of bytes actually read (0 for end of file).
 */
@@ -239,52 +288,73 @@
     unsigned len;
 {
     gz_stream *s = (gz_stream*)file;
+    Bytef *start = buf; /* starting point for crc computation */
+    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
 
     if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
 
-    if (s->transparent) {
-        int n = 0;
-        Byte *b = (Byte*)buf;
-        /* Copy the first two (non-magic) bytes if not done already */
-        while (s->stream.avail_in > 0 && len > 0) {
-            *b++ = *s->stream.next_in++;
-            s->stream.avail_in--;
-            len--; n++;
-        }
-        if (len == 0) return n;
-        return n + fread(b, 1, len, s->file);
-    }
-    if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
-    if (s->z_err == Z_STREAM_END) return 0;  /* don't read crc as data */
+    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
 
-    s->stream.next_out = buf;
+    s->stream.next_out = next_out = buf;
     s->stream.avail_out = len;
 
     while (s->stream.avail_out != 0) {
 
+	if (s->transparent) {
+	    /* Copy first the lookahead bytes: */
+	    uInt 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);
+		next_out += n;
+		s->stream.next_out = next_out;
+		s->stream.next_in   += n;
+		s->stream.avail_out -= n;
+		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);
+	    }
+	    return (int)(len - s->stream.avail_out);
+	}
         if (s->stream.avail_in == 0 && !s->z_eof) {
 
             errno = 0;
-            s->stream.avail_in =
-                fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
             if (s->stream.avail_in == 0) {
                 s->z_eof = 1;
-            } else if (s->stream.avail_in == (uInt)EOF) {
-                s->stream.avail_in = 0;
-                s->z_eof = 1;
-                s->z_err = Z_ERRNO;
-                break;
+		if (ferror(s->file)) {
+		    s->z_err = Z_ERRNO;
+		    break;
+		}
             }
             s->stream.next_in = s->inbuf;
         }
         s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
 
-        if (s->z_err == Z_STREAM_END ||
-            s->z_err != Z_OK  || s->z_eof) break;
+	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 || getLong(s) != s->stream.total_out) {
+		s->z_err = Z_DATA_ERROR;
+	    } else {
+		/* Check for concatenated .gz files: */
+		check_header(s);
+		if (s->z_err == Z_OK) {
+		    inflateReset(&(s->stream));
+		    s->crc = crc32(0L, Z_NULL, 0);
+		}
+	    }
+	}
+	if (s->z_err != Z_OK || s->z_eof) break;
     }
-    len -= s->stream.avail_out;
-    s->crc = crc32(s->crc, buf, len);
-    return (int)len;
+    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+    return (int)(len - s->stream.avail_out);
 }
 
 /* ===========================================================================
@@ -293,7 +363,7 @@
 */
 int gzwrite (file, buf, len)
     gzFile file;
-    voidp buf;
+    const voidp buf;
     unsigned len;
 {
     gz_stream *s = (gz_stream*)file;
@@ -344,7 +414,7 @@
         len = Z_BUFSIZE - s->stream.avail_out;
 
         if (len != 0) {
-            if (fwrite(s->outbuf, 1, len, s->file) != len) {
+            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
                 s->z_err = Z_ERRNO;
                 return Z_ERRNO;
             }
@@ -380,18 +450,19 @@
 }
 
 /* ===========================================================================
-   Reads a long in LSB order from the given buffer
+   Reads a long in LSB order from the given gz_stream. Sets 
 */
-local uLong getLong (buf)
-    Bytef *buf;
+local uLong getLong (s)
+    gz_stream *s;
 {
-    uLong x = 0;
-    Bytef *p = buf+4;
+    uLong x = (uLong)get_byte(s);
+    int c;
 
-    do {
-        x <<= 8;
-        x |= *--p; 
-    } while (p != buf);
+    x += ((uLong)get_byte(s))<<8;
+    x += ((uLong)get_byte(s))<<16;
+    c = get_byte(s);
+    if (c == EOF) s->z_err = Z_DATA_ERROR;
+    x += ((uLong)c)<<24;
     return x;
 }
 
@@ -402,7 +473,6 @@
 int gzclose (file)
     gzFile file;
 {
-    uInt n;
     int err;
     gz_stream *s = (gz_stream*)file;
 
@@ -415,25 +485,6 @@
         putLong (s->file, s->crc);
         putLong (s->file, s->stream.total_in);
 
-    } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) {
-
-        /* slide CRC and original size if they are at the end of inbuf */
-        if ((n = s->stream.avail_in) < 8  && !s->z_eof) {
-            Byte *p = s->inbuf;
-	    Bytef *q = s->stream.next_in;
-            while (n--) { *p++ = *q++; };
-
-            n = s->stream.avail_in;
-            n += fread(p, 1, 8, s->file);
-            s->stream.next_in = s->inbuf;
-        }
-        /* check CRC and original size */
-        if (n < 8 ||
-            getLong(s->stream.next_in) != s->crc ||
-            getLong(s->stream.next_in + 4) != s->stream.total_out) {
-
-            s->z_err = Z_DATA_ERROR;
-        }
     }
     return destroy(file);
 }
@@ -454,14 +505,14 @@
 
     if (s == NULL) {
         *errnum = Z_STREAM_ERROR;
-        return z_errmsg[1-Z_STREAM_ERROR];
+        return ERR_MSG(Z_STREAM_ERROR);
     }
     *errnum = s->z_err;
-    if (*errnum == Z_OK) return "";
+    if (*errnum == Z_OK) return (char*)"";
 
-    m =  *errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg;
+    m =  (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
 
-    if (m == NULL || *m == '\0') m = z_errmsg[1-s->z_err];
+    if (m == NULL || *m == '\0') m = ERR_MSG(s->z_err);
 
     TRYFREE(s->msg);
     s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
diff --git a/infblock.c b/infblock.c
index 9c6e6a8..733e983 100644
--- a/infblock.c
+++ b/infblock.c
@@ -1,5 +1,5 @@
 /* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -81,7 +81,7 @@
   s->bitb = 0;
   s->read = s->write = s->window;
   if (s->checkfn != Z_NULL)
-    s->check = (*s->checkfn)(0L, Z_NULL, 0);
+    z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
   Trace((stderr, "inflate:   blocks reset\n"));
 }
 
@@ -110,6 +110,9 @@
 }
 
 
+#ifdef DEBUG
+  extern uInt inflate_hufts;
+#endif
 int inflate_blocks(s, z, r)
 inflate_blocks_statef *s;
 z_stream *z;
@@ -172,7 +175,7 @@
         case 3:                         /* illegal */
           DUMPBITS(3)
           s->mode = BAD;
-          z->msg = "invalid block type";
+          z->msg = (char*)"invalid block type";
           r = Z_DATA_ERROR;
           LEAVE
       }
@@ -182,14 +185,14 @@
       if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
       {
         s->mode = BAD;
-        z->msg = "invalid stored block lengths";
+        z->msg = (char*)"invalid stored block lengths";
         r = Z_DATA_ERROR;
         LEAVE
       }
       s->sub.left = (uInt)b & 0xffff;
       b = k = 0;                      /* dump bits */
       Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
-      s->mode = s->sub.left ? STORED : TYPE;
+      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
       break;
     case STORED:
       if (n == 0)
@@ -215,7 +218,7 @@
       if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
       {
         s->mode = BAD;
-        z->msg = "too many length or distance symbols";
+        z->msg = (char*)"too many length or distance symbols";
         r = Z_DATA_ERROR;
         LEAVE
       }
@@ -285,7 +288,7 @@
               (c == 16 && i < 1))
           {
             s->mode = BAD;
-            z->msg = "invalid bit length repeat";
+            z->msg = (char*)"invalid bit length repeat";
             r = Z_DATA_ERROR;
             LEAVE
           }
@@ -306,6 +309,9 @@
         bl = 9;         /* must be <= 9 for lookahead assumptions */
         bd = 6;         /* must be <= 9 for lookahead assumptions */
         t = s->sub.trees.table;
+#ifdef DEBUG
+      inflate_hufts = 0;
+#endif
         t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
                                   s->sub.trees.blens, &bl, &bd, &tl, &td, z);
         if (t != Z_OK)
@@ -315,7 +321,8 @@
           r = t;
           LEAVE
         }
-        Tracev((stderr, "inflate:       trees ok\n"));
+        Tracev((stderr, "inflate:       trees ok, %d * %d bytes used\n",
+              inflate_hufts, sizeof(inflate_huft)));
         if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
         {
           inflate_trees_free(td, z);
@@ -383,3 +390,13 @@
   Trace((stderr, "inflate:   blocks freed\n"));
   return Z_OK;
 }
+
+
+void inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt  n;
+{
+  zmemcpy((charf *)s->window, d, n);
+  s->read = s->write = s->window + n;
+}
diff --git a/infblock.h b/infblock.h
index aba6e24..ee2c063 100644
--- a/infblock.h
+++ b/infblock.h
@@ -1,5 +1,5 @@
 /* infblock.h -- header to use infblock.c
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -30,3 +30,8 @@
     inflate_blocks_statef *,
     z_stream *,
     uLongf *));                  /* check value on output */
+
+extern void inflate_set_dictionary OF((
+    inflate_blocks_statef *s,
+    const Bytef *d,  /* dictionary */
+    uInt  n));       /* dictionary length */
diff --git a/infcodes.c b/infcodes.c
index a5fa8cc..6314e80 100644
--- a/infcodes.c
+++ b/infcodes.c
@@ -1,5 +1,5 @@
 /* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -58,7 +58,8 @@
 
 inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
 uInt bl, bd;
-inflate_huft *tl, *td;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
 z_stream *z;
 {
   inflate_codes_statef *c;
@@ -152,7 +153,7 @@
         break;
       }
       c->mode = BADCODE;        /* invalid code */
-      z->msg = "invalid literal/length code";
+      z->msg = (char*)"invalid literal/length code";
       r = Z_DATA_ERROR;
       LEAVE
     case LENEXT:        /* i: getting length extra (have base) */
@@ -184,7 +185,7 @@
         break;
       }
       c->mode = BADCODE;        /* invalid code */
-      z->msg = "invalid distance code";
+      z->msg = (char*)"invalid distance code";
       r = Z_DATA_ERROR;
       LEAVE
     case DISTEXT:       /* i: getting distance extra */
diff --git a/infcodes.h b/infcodes.h
index a772e42..8671efa 100644
--- a/infcodes.h
+++ b/infcodes.h
@@ -1,5 +1,5 @@
 /* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
diff --git a/inffast.c b/inffast.c
index 64c6289..209c0ee 100644
--- a/inffast.c
+++ b/inffast.c
@@ -1,5 +1,5 @@
 /* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -29,7 +29,8 @@
 
 int inflate_fast(bl, bd, tl, td, s, z)
 uInt bl, bd;
-inflate_huft *tl, *td;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
 inflate_blocks_statef *s;
 z_stream *z;
 {
@@ -122,7 +123,7 @@
             e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
           else
           {
-            z->msg = "invalid distance code";
+            z->msg = (char*)"invalid distance code";
             UNGRAB
             UPDATE
             return Z_DATA_ERROR;
@@ -152,7 +153,7 @@
       }
       else
       {
-        z->msg = "invalid literal/length code";
+        z->msg = (char*)"invalid literal/length code";
         UNGRAB
         UPDATE
         return Z_DATA_ERROR;
diff --git a/inffast.h b/inffast.h
index ad3cf97..843051f 100644
--- a/inffast.h
+++ b/inffast.h
@@ -1,5 +1,5 @@
 /* inffast.h -- header to use inffast.c
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
diff --git a/inflate.c b/inflate.c
index b71f74f..4eed100 100644
--- a/inflate.c
+++ b/inflate.c
@@ -1,5 +1,5 @@
 /* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -15,6 +15,11 @@
   enum {
       METHOD,   /* waiting for method byte */
       FLAG,     /* waiting for flag byte */
+      DICT4,    /* four dictionary check bytes to go */
+      DICT3,    /* three dictionary check bytes to go */
+      DICT2,    /* two dictionary check bytes to go */
+      DICT1,    /* one dictionary check byte to go */
+      DICT0,    /* waiting for inflateSetDictionary */
       BLOCKS,   /* decompressing blocks */
       CHECK4,   /* four check bytes to go */
       CHECK3,   /* three check bytes to go */
@@ -75,10 +80,16 @@
 }
 
 
-int inflateInit2(z, w)
+int inflateInit2_(z, w, version, stream_size)
 z_stream *z;
 int w;
+const char *version;
+int stream_size;
 {
+  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+      stream_size != sizeof(z_stream))
+      return Z_VERSION_ERROR;
+
   /* initialize state */
   if (z == Z_NULL)
     return Z_STREAM_ERROR;
@@ -112,7 +123,7 @@
 
   /* create inflate_blocks state */
   if ((z->state->blocks =
-       inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
+      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
       == Z_NULL)
   {
     inflateEnd(z);
@@ -126,10 +137,12 @@
 }
 
 
-int inflateInit(z)
+int inflateInit_(z, version, stream_size)
 z_stream *z;
+const char *version;
+int stream_size;
 {
-  return inflateInit2(z, DEF_WBITS);
+  return inflateInit2_(z, DEF_WBITS, version, stream_size);
 }
 
 
@@ -140,10 +153,10 @@
 z_stream *z;
 int f;
 {
-  int r = f;    /* to avoid warning about unused f */
+  int r;
   uInt b;
 
-  if (z == Z_NULL || z->next_in == Z_NULL)
+  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0)
     return Z_STREAM_ERROR;
   r = Z_BUF_ERROR;
   while (1) switch (z->state->mode)
@@ -153,36 +166,58 @@
       if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
       {
         z->state->mode = BAD;
-        z->msg = "unknown compression method";
+        z->msg = (char*)"unknown compression method";
         z->state->sub.marker = 5;       /* can't try inflateSync */
         break;
       }
       if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
       {
         z->state->mode = BAD;
-        z->msg = "invalid window size";
+        z->msg = (char*)"invalid window size";
         z->state->sub.marker = 5;       /* can't try inflateSync */
         break;
       }
       z->state->mode = FLAG;
     case FLAG:
       NEEDBYTE
-      if ((b = NEXTBYTE) & 0x20)
-      {
-        z->state->mode = BAD;
-        z->msg = "invalid reserved bit";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
+      b = NEXTBYTE;
       if (((z->state->sub.method << 8) + b) % 31)
       {
         z->state->mode = BAD;
-        z->msg = "incorrect header check";
+        z->msg = (char*)"incorrect header check";
         z->state->sub.marker = 5;       /* can't try inflateSync */
         break;
       }
       Trace((stderr, "inflate: zlib header ok\n"));
-      z->state->mode = BLOCKS;
+      if (!(b & PRESET_DICT))
+      {
+        z->state->mode = BLOCKS;
+	break;
+      }
+      z->state->mode = DICT4;
+    case DICT4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = DICT3;
+    case DICT3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = DICT2;
+    case DICT2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = DICT1;
+    case DICT1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+      z->adler = z->state->sub.check.need;
+      z->state->mode = DICT0;
+      return Z_NEED_DICT;
+    case DICT0:
+      z->state->mode = BAD;
+      z->msg = (char*)"need dictionary";
+      z->state->sub.marker = 0;       /* can try inflateSync */
+      return Z_STREAM_ERROR;
     case BLOCKS:
       r = inflate_blocks(z->state->blocks, z, r);
       if (r == Z_DATA_ERROR)
@@ -220,7 +255,7 @@
       if (z->state->sub.check.was != z->state->sub.check.need)
       {
         z->state->mode = BAD;
-        z->msg = "incorrect data check";
+        z->msg = (char*)"incorrect data check";
         z->state->sub.marker = 5;       /* can't try inflateSync */
         break;
       }
@@ -236,6 +271,29 @@
 }
 
 
+int inflateSetDictionary(z, dictionary, dictLength)
+z_stream *z;
+const Bytef *dictionary;
+uInt  dictLength;
+{
+  uInt length = dictLength;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
+    return Z_STREAM_ERROR;
+  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
+  z->adler = 1L;
+
+  if (length >= ((uInt)1<<z->state->wbits))
+  {
+    length = (1<<z->state->wbits)-1;
+    dictionary += dictLength - length;
+  }
+  inflate_set_dictionary(z->state->blocks, dictionary, length);
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
 int inflateSync(z)
 z_stream *z;
 {
diff --git a/inftrees.c b/inftrees.c
index e4d7bdf..3bf39a6 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -1,12 +1,12 @@
 /* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
 #include "zutil.h"
 #include "inftrees.h"
 
-char inflate_copyright[] = " inflate 1.0 Copyright 1995 Mark Adler ";
+char inflate_copyright[] = " inflate 1.0.1 Copyright 1995-1996 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -38,18 +38,18 @@
     uInt));             /* size of item */
 
 /* Tables for deflate from PKZIP's appnote.txt. */
-local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
+local uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
         3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
         /* actually lengths - 2; also see note #13 above about 258 */
-local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
+local uInt cplext[31] = { /* 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, 192, 192}; /* 192==invalid */
-local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
+local uInt cpdist[30] = { /* 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,
         8193, 12289, 16385, 24577};
-local uInt cpdext[] = { /* Extra bits for distance codes */
+local uInt cpdext[30] = { /* Extra bits for distance codes */
         0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
         7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
         12, 12, 13, 13};
@@ -215,7 +215,8 @@
         w += l;                 /* previous table always l bits */
 
         /* compute minimum size table less than or equal to l bits */
-        z = (z = g - w) > (uInt)l ? l : z;      /* table size upper limit */
+        z = g - w;
+        z = z > (uInt)l ? l : z;        /* table size upper limit */
         if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
         {                       /* too few codes for k-w bit table */
           f -= a + 1;           /* deduct codes from patterns left */
@@ -268,7 +269,7 @@
       }
       else
       {
-        r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
+        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
         r.base = d[*p++ - s];
       }
 
@@ -307,11 +308,11 @@
 
   r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
   if (r == Z_DATA_ERROR)
-    z->msg = "oversubscribed dynamic bit lengths tree";
+    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
   else if (r == Z_BUF_ERROR)
   {
     inflate_trees_free(*tb, z);
-    z->msg = "incomplete dynamic bit lengths tree";
+    z->msg = (char*)"incomplete dynamic bit lengths tree";
     r = Z_DATA_ERROR;
   }
   return r;
@@ -334,11 +335,11 @@
   if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
   {
     if (r == Z_DATA_ERROR)
-      z->msg = "oversubscribed literal/length tree";
+      z->msg = (char*)"oversubscribed literal/length tree";
     else if (r == Z_BUF_ERROR)
     {
       inflate_trees_free(*tl, z);
-      z->msg = "incomplete literal/length tree";
+      z->msg = (char*)"incomplete literal/length tree";
       r = Z_DATA_ERROR;
     }
     return r;
@@ -348,14 +349,14 @@
   if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
   {
     if (r == Z_DATA_ERROR)
-      z->msg = "oversubscribed literal/length tree";
+      z->msg = (char*)"oversubscribed literal/length tree";
     else if (r == Z_BUF_ERROR) {
 #ifdef PKZIP_BUG_WORKAROUND
       r = Z_OK;
     }
 #else
       inflate_trees_free(*td, z);
-      z->msg = "incomplete literal/length tree";
+      z->msg = (char*)"incomplete literal/length tree";
       r = Z_DATA_ERROR;
     }
     inflate_trees_free(*tl, z);
@@ -385,7 +386,7 @@
 {
   Assert(s == sizeof(inflate_huft) && n <= *(intf *)q,
          "inflate_trees falloc overflow");
-  *(intf *)q -= n;
+  *(intf *)q -= n+s-s; /* s-s to avoid warning */
   return (voidpf)(fixed_mem + *(intf *)q);
 }
 
diff --git a/inftrees.h b/inftrees.h
index 9eaaa66..0f0ca2b 100644
--- a/inftrees.h
+++ b/inftrees.h
@@ -1,5 +1,5 @@
 /* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
diff --git a/infutil.c b/infutil.c
index 96db3a4..7099b6d 100644
--- a/infutil.c
+++ b/infutil.c
@@ -1,5 +1,5 @@
 /* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -12,7 +12,7 @@
 struct inflate_codes_state {int dummy;}; /* for buggy compilers */
 
 /* And'ing with mask[n] masks the lower n bits */
-uInt inflate_mask[] = {
+uInt inflate_mask[17] = {
     0x0000,
     0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
     0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
@@ -43,7 +43,7 @@
 
   /* update check information */
   if (s->checkfn != Z_NULL)
-    s->check = (*s->checkfn)(s->check, q, n);
+    z->adler = s->check = (*s->checkfn)(s->check, q, n);
 
   /* copy as far as end of window */
   zmemcpy(p, q, n);
@@ -69,7 +69,7 @@
 
     /* update check information */
     if (s->checkfn != Z_NULL)
-      s->check = (*s->checkfn)(s->check, q, n);
+      z->adler = s->check = (*s->checkfn)(s->check, q, n);
 
     /* copy */
     zmemcpy(p, q, n);
diff --git a/infutil.h b/infutil.h
index c523155..ff7ac15 100644
--- a/infutil.h
+++ b/infutil.h
@@ -1,5 +1,5 @@
 /* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995 Mark Adler
+ * Copyright (C) 1995-1996 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -8,11 +8,10 @@
    subject to change. Applications should only use zlib.h.
  */
 
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
 
-  /* mode */
-  enum {
+typedef enum {
       TYPE,     /* get type bits (3, including end bit) */
       LENS,     /* get lengths for stored */
       STORED,   /* processing stored block */
@@ -23,7 +22,13 @@
       DRY,      /* output remaining window bytes */
       DONE,     /* finished last block, done */
       BAD}      /* got a data error--stuck here */
-    mode;               /* current inflate_block mode */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  inflate_block_mode  mode;     /* current inflate_block mode */
 
   /* mode dependent information */
   union {
@@ -36,7 +41,8 @@
       inflate_huft *tb;         /* bit length decoding tree */
     } trees;            /* if DTREE, decoding info for trees */
     struct {
-      inflate_huft *tl, *td;    /* trees to free */
+      inflate_huft *tl;
+      inflate_huft *td;         /* trees to free */
       inflate_codes_statef 
          *codes;
     } decode;           /* if CODES, current state */
@@ -71,16 +77,16 @@
 #define DUMPBITS(j) {b>>=(j);k-=(j);}
 /*   output bytes */
 #define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
 #define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
 #define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
 #define OUTBYTE(a) {*q++=(Byte)(a);m--;}
 /*   load local pointers */
 #define LOAD {LOADIN LOADOUT}
 
-/* masks for lower bits */
-extern uInt inflate_mask[];
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt inflate_mask[17];
 
 /* copy as much as possible from the sliding window to the output area */
 extern int inflate_flush OF((
@@ -89,3 +95,5 @@
     int));
 
 struct internal_state      {int dummy;}; /* for buggy compilers */
+
+#endif
diff --git a/minigzip.c b/minigzip.c
index fa0a188..eee52a5 100644
--- a/minigzip.c
+++ b/minigzip.c
@@ -1,5 +1,5 @@
 /* minigzip.c -- simulate gzip using the zlib compression library
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -13,7 +13,7 @@
  * or in pipe mode.
  */
 
-/* $Id: minigzip.c,v 1.5 1995/05/03 17:27:11 jloup Exp $ */
+/* $Id: minigzip.c,v 1.8 1996/01/30 21:59:23 me Exp $ */
 
 #include <stdio.h>
 #include "zlib.h"
@@ -24,7 +24,7 @@
 #else
    extern void exit  OF((int));
 #endif
-extern int unlink OF((const char *));
+
 
 #if defined(MSDOS) || defined(OS2) || defined(WIN32)
 #  include <fcntl.h>
@@ -35,12 +35,15 @@
 #endif
 
 #ifdef VMS
+#  define unlink delete
 #  define GZ_SUFFIX "-gz"
 #else
 #  define GZ_SUFFIX ".gz"
 #endif
 #define SUFFIX_LEN sizeof(GZ_SUFFIX)
 
+extern int unlink OF((const char *));
+
 #define BUFLEN 4096
 #define MAX_NAME_LEN 1024
 
@@ -52,7 +55,7 @@
 
 char *prog;
 
-void error           OF((char *msg));
+void error           OF((const char *msg));
 void gz_compress     OF((FILE   *in, gzFile out));
 void gz_uncompress   OF((gzFile in, FILE   *out));
 void file_compress   OF((char  *file));
@@ -63,7 +66,7 @@
  * Display error message and exit
  */
 void error(msg)
-    char *msg;
+    const char *msg;
 {
     fprintf(stderr, "%s: %s\n", prog, msg);
     exit(1);
@@ -88,7 +91,7 @@
         }
         if (len == 0) break;
 
-        if (gzwrite(out, buf, len) != len) error(gzerror(out, &err));
+        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
     }
     fclose(in);
     if (gzclose(out) != Z_OK) error("failed gzclose");
@@ -110,7 +113,9 @@
         if (len < 0) error (gzerror(in, &err));
         if (len == 0) break;
 
-        if (fwrite(buf, 1, len, out) != (uInt)len) error("failed fwrite");
+        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+	    error("failed fwrite");
+	}
     }
     if (fclose(out)) error("failed fclose");
 
diff --git a/trees.c b/trees.c
index 0ba0bad..fcfe68b 100644
--- a/trees.c
+++ b/trees.c
@@ -1,5 +1,5 @@
 /* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995 Jean-loup Gailly
+ * Copyright (C) 1995-1996 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -83,7 +83,7 @@
 local ct_data static_ltree[L_CODES+2];
 /* The static literal tree. Since the bit lengths are imposed, there is no
  * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see tr_init
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
  * below).
  */
 
@@ -232,7 +232,7 @@
  */
 local void tr_static_init()
 {
-    static static_init_done = 0;
+    static int static_init_done = 0;
     int n;        /* iterates over tree elements */
     int bits;     /* bit counter */
     int length;   /* length value */
@@ -292,7 +292,7 @@
     /* The static distance tree is trivial: */
     for (n = 0; n < D_CODES; n++) {
         static_dtree[n].Len = 5;
-        static_dtree[n].Code = bi_reverse(n, 5);
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
     }
     static_init_done = 1;
 }
@@ -300,7 +300,7 @@
 /* ===========================================================================
  * Initialize the tree data structures for a new zlib stream.
  */
-void tr_init(s)
+void _tr_init(s)
     deflate_state *s;
 {
     tr_static_init();
@@ -785,14 +785,14 @@
 /* ===========================================================================
  * Send a stored block
  */
-void tr_stored_block(s, buf, stored_len, eof)
+void _tr_stored_block(s, buf, stored_len, eof)
     deflate_state *s;
     charf *buf;       /* input block */
     ulg stored_len;   /* length of input block */
     int eof;          /* true if this is the last block for a file */
 {
     send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
-    s->compressed_len = (s->compressed_len + 3 + 7) & ~7L;
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
     s->compressed_len += (stored_len + 4) << 3;
 
     copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
@@ -809,7 +809,7 @@
  * To simplify the code, we assume the worst case of last real code encoded
  * on one bit only.
  */
-void tr_align(s)
+void _tr_align(s)
     deflate_state *s;
 {
     send_bits(s, STATIC_TREES<<1, 3);
@@ -835,20 +835,20 @@
  * trees or store, and output the encoded block to the zip file. This function
  * returns the total compressed length for the file so far.
  */
-ulg tr_flush_block(s, buf, stored_len, eof)
+ulg _tr_flush_block(s, buf, stored_len, eof)
     deflate_state *s;
     charf *buf;       /* input block, or NULL if too old */
     ulg stored_len;   /* length of input block */
     int eof;          /* true if this is the last block for a file */
 {
     ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
-    int max_blindex;  /* index of last bit length code of non zero freq */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
 
     /* Build the Huffman trees unless a stored block is forced */
     if (s->level > 0) {
 
 	 /* Check if the file is ascii or binary */
-	if (s->data_type == UNKNOWN) set_data_type(s);
+	if (s->data_type == Z_UNKNOWN) set_data_type(s);
 
 	/* Construct the literal and distance trees */
 	build_tree(s, (tree_desc *)(&(s->l_desc)));
@@ -879,7 +879,7 @@
 
     } else {
         Assert(buf != (char*)0, "lost buf");
-	opt_lenb = stored_len + 5; /* force a stored block */
+	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
     }
 
     /* If compression failed and this is the first and last block,
@@ -913,7 +913,7 @@
          * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
          * transform a block into a stored block.
          */
-        tr_stored_block(s, buf, stored_len, eof);
+        _tr_stored_block(s, buf, stored_len, eof);
 
 #ifdef FORCE_STATIC
     } else if (static_lenb >= 0) { /* force static trees */
@@ -947,10 +947,10 @@
  * Save the match info and tally the frequency counts. Return true if
  * the current block must be flushed.
  */
-int tr_tally (s, dist, lc)
+int _tr_tally (s, dist, lc)
     deflate_state *s;
-    int dist;  /* distance of matched string */
-    int lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
 {
     s->d_buf[s->last_lit] = (ush)dist;
     s->l_buf[s->last_lit++] = (uch)lc;
@@ -963,7 +963,7 @@
         dist--;             /* dist = match distance - 1 */
         Assert((ush)dist < (ush)MAX_DIST(s) &&
                (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
-               (ush)d_code(dist) < (ush)D_CODES,  "tr_tally: bad match");
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
 
         s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
         s->dyn_dtree[d_code(dist)].Freq++;
@@ -1057,7 +1057,7 @@
     while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
     while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
     while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
-    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII);
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
 }
 
 /* ===========================================================================
diff --git a/uncompr.c b/uncompr.c
index b423696..c3de969 100644
--- a/uncompr.c
+++ b/uncompr.c
@@ -1,9 +1,9 @@
 /* uncompr.c -- decompress a memory buffer
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
-/* $Id: uncompr.c,v 1.5 1995/05/03 17:27:12 jloup Exp $ */
+/* $Id: uncompr.c,v 1.8 1996/01/30 21:59:26 me Exp $ */
 
 #include "zlib.h"
 
@@ -25,13 +25,13 @@
 int uncompress (dest, destLen, source, sourceLen)
     Bytef *dest;
     uLongf *destLen;
-    Bytef *source;
+    const Bytef *source;
     uLong sourceLen;
 {
     z_stream stream;
     int err;
 
-    stream.next_in = source;
+    stream.next_in = (Bytef*)source;
     stream.avail_in = (uInt)sourceLen;
     /* Check for source > 64K on 16-bit machine: */
     if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
diff --git a/zconf.h b/zconf.h
index 3d78742..6ab1e4f 100644
--- a/zconf.h
+++ b/zconf.h
@@ -1,5 +1,5 @@
 /* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
@@ -9,11 +9,42 @@
 #define _ZCONF_H
 
 /*
-     The library does not install any signal handler. It is recommended to
-  add at least a handler for SIGSEGV when decompressing; the library checks
-  the consistency of the input data whenever possible but may go nuts
-  for some forms of corrupted input.
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
  */
+#ifdef Z_PREFIX
+#  define deflateInit_	z_deflateInit_
+#  define deflate	z_deflate
+#  define deflateEnd	z_deflateEnd
+#  define inflateInit_ 	z_inflateInit_
+#  define inflate	z_inflate
+#  define inflateEnd	z_inflateEnd
+#  define deflateInit2_	z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy	z_deflateCopy
+#  define deflateReset	z_deflateReset
+#  define deflateParams	z_deflateParams
+#  define inflateInit2_	z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync	z_inflateSync
+#  define inflateReset	z_inflateReset
+#  define compress	z_compress
+#  define uncompress	z_uncompress
+#  define adler32	z_adler32
+#  define crc32		z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte		z_Byte
+#  define uInt		z_uInt
+#  define uLong		z_uLong
+/* #  define Bytef	z_Bytef */
+#  define charf		z_charf
+#  define intf		z_intf
+#  define uIntf		z_uIntf
+#  define uLongf	z_uLongf
+#  define voidpf	z_voidpf
+#  define voidp		z_voidp
+#endif
 
 #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
 #  define WIN32
@@ -43,12 +74,15 @@
 #  define STDC
 #endif
 
-#if !defined(STDC) && !defined(const)
-#  define const
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const
+#  endif
 #endif
 
 #ifdef	__MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
 #  include <unix.h>
+#  define NO_DUMMY_DECL /* buggy compiler merges all .h files incorrectly */
 #endif
 
 /* Maximum value for memLevel in deflateInit2 */
@@ -95,6 +129,7 @@
  * just define FAR to be empty.
  */
 #if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */
+#  define SMALL_MEDIUM
 #  ifdef _MSC_VER
 #    define FAR __far
 #  else
@@ -102,20 +137,28 @@
 #  endif
 #endif
 #if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-#    define FAR _far /* completely untested, just a best guess */
+#    define SMALL_MEDIUM
+#    define FAR __far
 #endif
 #ifndef FAR
 #   define FAR
 #endif
+/* The Watcom compiler defines M_I86SM and __SMALL__ even in 32 bit mode */
+#if defined(__WATCOMC__) && defined(__386__)
+#  undef FAR
+#  define FAR
+#  undef SMALL_MEDIUM
+#endif
 
 typedef unsigned char  Byte;  /* 8 bits */
 typedef unsigned int   uInt;  /* 16 bits or more */
 typedef unsigned long  uLong; /* 32 bits or more */
 
-typedef Byte FAR Bytef;
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
+/* "typedef Byte  FAR Bytef;" doesn't work with Borland C/C++ */
+#define Bytef Byte  FAR 
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
 typedef uLong FAR uLongf;
 
 #ifdef STDC
diff --git a/zlib.h b/zlib.h
index a1c48ac..47960c2 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1,5 +1,5 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.0, Jan 14th, 1996.
+  version 1.0.1, May 20th, 1996.
 
   Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler
 
@@ -32,7 +32,7 @@
 
 #include "zconf.h"
 
-#define ZLIB_VERSION "1.0"
+#define ZLIB_VERSION "1.0.1"
 
 /* 
      The 'zlib' compression library provides in-memory compression and
@@ -51,6 +51,11 @@
   repeated calls of the compression function.  In the latter case, the
   application must provide more input and/or consume the output
   (providing more output space) before each call.
+
+     The library does not install any signal handler. It is recommended to
+  add at least a handler for SIGSEGV when decompressing; the library checks
+  the consistency of the input data whenever possible but may go nuts
+  for some forms of corrupted input.
 */
 
 typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
@@ -74,8 +79,9 @@
     free_func  zfree;   /* used to free the internal state */
     voidpf     opaque;  /* private data object passed to zalloc and zfree */
 
-    Byte     data_type; /* best guess about the data type: ascii or binary */
-
+    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 */
 } z_stream;
 
 /*
@@ -118,12 +124,16 @@
 
 #define Z_OK            0
 #define Z_STREAM_END    1
+#define Z_NEED_DICT     2
 #define Z_ERRNO        (-1)
 #define Z_STREAM_ERROR (-2)
 #define Z_DATA_ERROR   (-3)
 #define Z_MEM_ERROR    (-4)
 #define Z_BUF_ERROR    (-5)
-/* error codes for the compression/decompression functions */
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
 
 #define Z_NO_COMPRESSION         0
 #define Z_BEST_SPEED             1
@@ -134,18 +144,19 @@
 #define Z_FILTERED            1
 #define Z_HUFFMAN_ONLY        2
 #define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
 
 #define Z_BINARY   0
 #define Z_ASCII    1
 #define Z_UNKNOWN  2
-/* Used to set the data_type field */
+/* Possible values of the data_type field */
 
 #define Z_DEFLATED   8
 /* The deflate compression method (the only one supported in this version) */
 
 #define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
 
-extern char *zlib_version;
+extern const char *zlib_version;
 /* The application can compare zlib_version and ZLIB_VERSION for consistency.
    If the first character differs, the library code actually used is
    not compatible with the zlib.h header file used by the application.
@@ -153,8 +164,9 @@
 
                         /* basic functions */
 
-extern int deflateInit OF((z_stream *strm, int level));
 /* 
+extern int deflateInit OF((z_stream *strm, int level));
+
      Initializes the internal stream state for compression. The fields
    zalloc, zfree and opaque must be initialized before by the caller.
    If zalloc and zfree are set to Z_NULL, deflateInit updates them to
@@ -167,7 +179,9 @@
    compression (currently equivalent to level 6).
 
      deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if level is not a valid compression level.
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
    msg is set to null if there is no error message.  deflateInit does not
    perform any compression: this will be done by deflate().
 */
@@ -193,7 +207,9 @@
   more output, and updating avail_in or avail_out accordingly; avail_out
   should never be zero before the call. The application can consume the
   compressed output when it wants, for example when the output buffer is full
-  (avail_out == 0), or after each call of deflate().
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
 
     If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
   block is terminated and flushed to the output buffer so that the
@@ -247,22 +263,26 @@
    pending output.
 
      deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-   stream state was inconsistent. In the error case, msg may be set
-   but then points to a static string (which must not be deallocated).
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
 */
 
 
-extern int inflateInit OF((z_stream *strm));
 /* 
+extern int inflateInit OF((z_stream *strm));
+
      Initializes the internal stream state for decompression. The fields
    zalloc, zfree and opaque must be initialized before by the caller.  If
    zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
    allocation functions.
 
      inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory.  msg is set to null if there is no error message.
-   inflateInit does not perform any decompression: this will be done by
-   inflate().
+   enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
+   with the version assumed by the caller.  msg is set to null if there is no
+   error message. inflateInit does not perform any decompression: this will be
+   done by inflate().
 */
 
 
@@ -276,15 +296,18 @@
     will resume at this point for the next call of inflate().
 
   - Provide more output starting at next_out and update next_out and avail_out
-    accordingly.  inflate() always provides as much output as possible
-    (until there is no more input data or no more space in the output buffer).
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
 
   Before the call of inflate(), the application should ensure that at least
   one of the actions is possible, by providing more input and/or consuming
   more output, and updating the next_* and avail_* values accordingly.
   The application can consume the uncompressed output when it wants, for
   example when the output buffer is full (avail_out == 0), or after each
-  call of inflate().
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
 
     If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much
   output as possible to the output buffer. The flushing behavior of inflate is
@@ -306,12 +329,15 @@
     inflate() returns Z_OK if some progress has been made (more input
   processed or more output produced), Z_STREAM_END if the end of the
   compressed data has been reached and all uncompressed output has been
-  produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
-  the stream structure was inconsistent (for example if next_in or next_out
-  was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
-  progress is possible or if there was not enough room in the output buffer
-  when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
-  call inflateSync to look for a good compression block.
+  produced, Z_NEED_DICT if a preset dictionary is needed at this point (see
+  inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted,
+  Z_STREAM_ERROR if the stream structure was inconsistent (for example if
+  next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in
+  the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the
+  application may then call inflateSync to look for a good compression block.
+  In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the
+  dictionary chosen by the compressor.
 */
 
 
@@ -326,19 +352,20 @@
    static string (which must not be deallocated).
 */
 
-                        /* advanced functions */
+                        /* Advanced functions */
 
 /*
     The following functions are needed only in some special applications.
 */
 
+/*   
 extern int deflateInit2 OF((z_stream *strm,
                             int  level,
                             int  method,
                             int  windowBits,
                             int  memLevel,
                             int  strategy));
-/*   
+
      This is another version of deflateInit with more compression options. The
    fields next_in, zalloc, zfree and opaque must be initialized before by
    the caller.
@@ -353,20 +380,22 @@
    values of this parameter result in better compression at the expense of
    memory usage. The default value is 15 if deflateInit is used instead.
 
-    The memLevel parameter specifies how much memory should be allocated
+     The memLevel parameter specifies how much memory should be allocated
    for the internal compression state. memLevel=1 uses minimum memory but
    is slow and reduces compression ratio; memLevel=9 uses maximum memory
    for optimal speed. The default value is 8. See zconf.h for total memory
    usage as a function of windowBits and memLevel.
 
-     The strategy parameter is used to tune the compression algorithm. Use
-   the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data
-   produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman
-   encoding only (no string match).  Filtered data consists mostly of small
-   values with a somewhat random distribution. In this case, the
-   compression algorithm is tuned to compress them better. The strategy
-   parameter only affects the compression ratio but not the correctness of
-   the compressed output even if it is not set appropriately.
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match).  Filtered data consists mostly of small values with a
+   somewhat random distribution. In this case, the compression algorithm is
+   tuned to compress them better. The effect of Z_FILTERED is to force more
+   Huffman coding and less string matching; it is somewhat intermediate
+   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+   the compression ratio but not the correctness of the compressed output even
+   if it is not set appropriately.
 
      If next_in is not null, the library will use this buffer to hold also
    some history information; the buffer must either hold the entire input
@@ -385,9 +414,38 @@
    not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
    an invalid method). msg is set to null if there is no error message.
    deflateInit2 does not perform any compression: this will be done by
-   deflate().
+   deflate(). 
 */
                             
+extern int deflateSetDictionary OF((z_stream *strm,
+				    const Bytef *dictionary,
+				    uInt  dictLength));
+/*
+     Initializes the compression dictionary (history buffer) from the given
+   byte sequence without producing any compressed output. This function must
+   be called immediately after deflateInit or deflateInit2, before any call
+   of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and
+   can be predicted with good accuracy; the data can then be compressed better
+   than with the default empty dictionary. In this version of the library,
+   only the last 32K bytes of the dictionary are used.
+     Upon return of this function, strm->adler is set to the Adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The Adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.)
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state
+   is inconsistent (for example if deflate has already been called for this
+   stream). deflateSetDictionary does not perform any compression: this will
+   be done by deflate(). 
+*/
+
 extern int deflateCopy OF((z_stream *dest,
                            z_stream *source));
 /*
@@ -398,14 +456,14 @@
    application to provide the correct values of next_out and avail_out for the
    next call of deflate.
 
-     This function is useful when several compression strategies will be
+     This function can be useful when several compression strategies will be
    tried, for example when there are several ways of pre-processing the input
    data with a filter. The streams that will be discarded should then be freed
    by calling deflateEnd.  Note that deflateCopy duplicates the internal
    compression state which can be quite large, so this strategy is slow and
    can consume lots of memory.
 
-      deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
    enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
    (such as zalloc being NULL). msg is left unchanged in both source and
    destination.
@@ -431,13 +489,19 @@
    available so far is compressed with the old level (and may be flushed);
    the new level will take effect only at the next call of deflate().
 
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
      deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-   stream state was inconsistent or if a parameter was invalid.
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
 */
 
+/*   
 extern int inflateInit2 OF((z_stream *strm,
                             int  windowBits));
-/*   
+
      This is another version of inflateInit with more compression options. The
    fields next_out, zalloc, zfree and opaque must be initialized before by
    the caller.
@@ -469,6 +533,25 @@
    inflate().
 */
 
+extern int inflateSetDictionary OF((z_stream *strm,
+				    const Bytef *dictionary,
+				    uInt  dictLength));
+/*
+     Initializes the decompression dictionary (history buffer) from the given
+   uncompressed byte sequence. This function must be called immediately after
+   a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen
+   by the compressor can be determined from the Adler32 value returned by this
+   call of inflate. The compressor and decompressor must use exactly the same
+   dictionary (see deflateSetDictionary).
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
 extern int inflateSync OF((z_stream *strm));
 /* 
     Skips invalid compressed data until the special marker (see deflate()
@@ -506,7 +589,7 @@
 */
 
 extern int compress OF((Bytef *dest,   uLongf *destLen,
-                        Bytef *source, uLong sourceLen));
+                        const Bytef *source, uLong sourceLen));
 /*
      Compresses the source buffer into the destination buffer.  sourceLen is
    the byte length of the source buffer. Upon entry, destLen is the total
@@ -521,7 +604,7 @@
 */
 
 extern int uncompress OF((Bytef *dest,   uLongf *destLen,
-                          Bytef *source, uLong sourceLen));
+                          const Bytef *source, uLong sourceLen));
 /*
      Decompresses the source buffer into the destination buffer.  sourceLen is
    the byte length of the source buffer. Upon entry, destLen is the total
@@ -541,7 +624,7 @@
 
 typedef voidp gzFile;
 
-extern gzFile gzopen  OF((char *path, char *mode));
+extern gzFile gzopen  OF((const char *path, const char *mode));
 /*
      Opens a gzip (.gz) file for reading or writing. The mode parameter
    is as in fopen ("rb" or "wb") but can also include a compression level
@@ -553,12 +636,15 @@
    zlib error is Z_MEM_ERROR).
 */
 
-extern gzFile gzdopen  OF((int fd, char *mode));
+extern gzFile gzdopen  OF((int fd, const char *mode));
 /*
      gzdopen() associates a gzFile with the file descriptor fd.  File
    descriptors are obtained from calls like open, dup, creat, pipe or
    fileno (in the file has been previously opened with fopen).
-   The mode parameter is as in fopen ("rb" or "wb").
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
      gzdopen returns NULL if there was insufficient memory to allocate
    the (de)compression state.
 */
@@ -571,7 +657,7 @@
      gzread returns the number of uncompressed bytes actually read (0 for
    end of file, -1 for error). */
 
-extern int    gzwrite OF((gzFile file, voidp buf, unsigned len));
+extern int    gzwrite OF((gzFile file, const voidp buf, unsigned len));
 /*
      Writes the given number of uncompressed bytes into the compressed file.
    gzwrite returns the number of uncompressed bytes actually written
@@ -612,7 +698,7 @@
    compression library.
 */
 
-extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
+extern uLong adler32 OF((uLong adler, const Bytef *buf, uInt len));
 
 /*
      Update a running Adler-32 checksum with the bytes buf[0..len-1] and
@@ -629,7 +715,7 @@
      if (adler != original_adler) error();
 */
 
-extern uLong crc32   OF((uLong crc, Bytef *buf, uInt len));
+extern uLong crc32   OF((uLong crc, const Bytef *buf, uInt len));
 /*
      Update a running crc with the bytes buf[0..len-1] and return the updated
    crc. If buf is NULL, this function returns the required initial value
@@ -645,10 +731,37 @@
      if (crc != original_crc) error();
 */
 
-#ifndef _Z_UTIL_H
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+extern int deflateInit_ OF((z_stream *strm, int level,
+			    const char *version, int stream_size));
+extern int inflateInit_ OF((z_stream *strm,
+			    const char *version, int stream_size));
+extern int deflateInit2_ OF((z_stream *strm, int  level, int  method,
+                             int  windowBits, int  memLevel, int  strategy,
+			     const char *version, int stream_size));
+extern int inflateInit2_ OF((z_stream *strm, int  windowBits,
+			     const char *version, int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+		      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
     struct internal_state {int dummy;}; /* hack for buggy compilers */
 #endif
 
+uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/zutil.c b/zutil.c
index 97e74ea..66ddae4 100644
--- a/zutil.c
+++ b/zutil.c
@@ -1,9 +1,9 @@
 /* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h 
  */
 
-/* $Id: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp $ */
+/* $Id: zutil.c,v 1.12 1996/01/30 21:59:29 me Exp $ */
 
 #include <stdio.h>
 
@@ -15,16 +15,18 @@
 extern void exit OF((int));
 #endif
 
-char *zlib_version = ZLIB_VERSION;
+const char *zlib_version = ZLIB_VERSION;
 
-char *z_errmsg[] = {
-"stream end",          /* Z_STREAM_END    1 */
-"",                    /* Z_OK            0 */
-"file error",          /* Z_ERRNO        (-1) */
-"stream error",        /* Z_STREAM_ERROR (-2) */
-"data error",          /* Z_DATA_ERROR   (-3) */
-"insufficient memory", /* Z_MEM_ERROR    (-4) */
-"buffer error",        /* Z_BUF_ERROR    (-5) */
+const char *z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
 ""};
 
 
@@ -60,9 +62,9 @@
 #endif
 
 #ifdef __TURBOC__
-#if !defined(__SMALL__) && !defined(__MEDIUM__) && !defined(__32BIT__)
-/* Small and medium model are for now limited to near allocation with
- * reduced MAX_WBITS and MAX_MEM_LEVEL
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
+/* Small and medium model in Turbo C are for now limited to near allocation
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
  */
 #  define MY_ZCALLOC
 
@@ -100,9 +102,6 @@
      */
     if (bsize < 65520L) {
         buf = farmalloc(bsize);
-#ifdef DEBUG
-        zmemzero(buf, (uInt)bsize);
-#endif
         if (*(ush*)&buf != 0) return buf;
     } else {
         buf = farmalloc(bsize + 16L);
@@ -114,10 +113,6 @@
     *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
     *(ush*)&buf = 0;
     table[next_ptr++].new_ptr = buf;
-#ifdef DEBUG
-    zmemzero(buf, (uInt)65535);
-    ((uch*)buf)[65535] = 0;
-#endif
     return buf;
 }
 
@@ -146,7 +141,8 @@
 #endif /* __TURBOC__ */
 
 
-#ifdef M_I86 /* Microsoft C */
+#if defined(M_I86) && !(defined(__WATCOMC__) && defined(__386__))
+/* Microsoft C */
 
 #  define MY_ZCALLOC
 
@@ -182,6 +178,7 @@
     unsigned items;
     unsigned size;
 {
+    if (opaque) items += size - size; /* make compiler happy */
     return (voidpf)calloc(items, size);
 }
 
@@ -190,6 +187,7 @@
     voidpf ptr;
 {
     free(ptr);
+    if (opaque) return; /* make compiler happy */
 }
 
 #endif /* MY_ZCALLOC */
diff --git a/zutil.h b/zutil.h
index bc2d772..3abd8c4 100644
--- a/zutil.h
+++ b/zutil.h
@@ -1,5 +1,5 @@
 /* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995 Jean-loup Gailly.
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -8,14 +8,14 @@
    subject to change. Applications should only use zlib.h.
  */
 
-/* $Id: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp $ */
+/* $Id: zutil.h,v 1.13 1996/01/30 21:59:29 me Exp $ */
 
 #ifndef _Z_UTIL_H
 #define _Z_UTIL_H
 
 #include "zlib.h"
 
-#if defined(MSDOS) || defined(VMS) || defined(CRAY)
+#if defined(MSDOS) || defined(VMS) || defined(CRAY) || defined(WIN32)
 #   include <stddef.h>
 #   include <errno.h>
 #else
@@ -37,9 +37,13 @@
 typedef ush FAR ushf;
 typedef unsigned long  ulg;
 
-extern char *z_errmsg[]; /* indexed by 1-zlib_error */
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
 
-#define ERR_RETURN(strm,err) return (strm->msg = z_errmsg[1-(err)], (err))
+#define ERR_MSG(err) (char*)z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = ERR_MSG(err), (err))
 /* To be used only when the state is known to be valid */
 
         /* common constants */
@@ -65,6 +69,8 @@
 #define MAX_MATCH  258
 /* The minimum and maximum match lengths */
 
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
         /* target dependencies */
 
 #ifdef MSDOS
@@ -110,6 +116,10 @@
 #  define OS_CODE  0x0a
 #endif
 
+#ifdef _BEOS_
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
         /* Common defaults */
 
 #ifndef OS_CODE
@@ -142,11 +152,13 @@
 #  define HAVE_MEMCPY
 #endif
 #ifdef HAVE_MEMCPY
-#  if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
 #    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
 #    define zmemzero(dest, len) _fmemset(dest, 0, len)
 #  else
 #    define zmemcpy memcpy
+#    define zmemcmp memcmp
 #    define zmemzero(dest, len) memset(dest, 0, len)
 #  endif
 #else
@@ -176,7 +188,7 @@
 #endif
 
 
-typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
+typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len));
 
 extern void z_error    OF((char *m));