提交 56bcb184 编写于 作者: M Mark Adler

zlib 0.99

上级 25e53255
ChangeLog file for zlib ChangeLog file for zlib
Changes in 1.0 (15 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
- 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
- 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
- include stdlib.h for STDC compilers
- include errno.h for Cray
- 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 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__)
- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
- 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) Changes in 0.95 (16 Aug 95)
- fix MSDOS small and medium model (now easier to adapt to any compiler) - fix MSDOS small and medium model (now easier to adapt to any compiler)
- inlined send_bits - inlined send_bits
......
...@@ -4,7 +4,7 @@ $! ...@@ -4,7 +4,7 @@ $!
$! Look for the compiler used $! Look for the compiler used
$! $!
$ ccopt = "" $ ccopt = ""
$ if f$trnlnm("HW_MODEL").ge.1024 $ if f$getsyi("HW_MODEL").ge.1024
$ then $ then
$ ccopt = "/prefix=all"+ccopt $ ccopt = "/prefix=all"+ccopt
$ comp = "__decc__=1" $ comp = "__decc__=1"
......
# Makefile for zlib # Makefile for zlib
# 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 # 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 CC=cc
CFLAGS=-O CFLAGS=-O
#use -O3 for gcc to take advantage of inlining #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
#CFLAGS=-g -DDEBUG #CFLAGS=-g -DDEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
# -Wstrict-prototypes -Wmissing-prototypes
LDFLAGS=-L. -lz LDFLAGS=-L. -lz
LDSHARED=$(CC)
VER=1.0
LIBS=libz.a
AR=ar rc
RANLIB=ranlib RANLIB=ranlib
TAR=tar
prefix=/usr/local prefix=/usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
TEST_OBJS = example.o minigzip.o TEST_OBJS = example.o minigzip.o
DISTFILES = README ChangeLog configure Makefile.in Makefile Makefile.msc \
Makefile.bor Makefile.tc Make_vms.com descrip.mms *.[ch]
all: example minigzip all: example minigzip
test: all test: all
./example ./example
echo hello world | ./minigzip | ./minigzip -d echo hello world | ./minigzip | ./minigzip -d
install: libz.a
-@mkdir $(prefix)/include
-@mkdir $(prefix)/lib
cp zlib.h zconf.h $(prefix)/include
chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
cp libz.a $(prefix)/lib
chmod 644 $(prefix)/lib/libz.a
libz.a: $(OBJS) libz.a: $(OBJS)
ar rc $@ $(OBJS) $(AR) $@ $(OBJS)
$(RANLIB) $@ -@ ($(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) $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
minigzip: minigzip.o libz.a minigzip: minigzip.o $(LIBS)
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) $(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: clean:
rm -f *.o example minigzip libz.a foo.gz rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
zip: zip:
zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ mv Makefile Makefile~; cp -p Makefile.in Makefile
descrip.mms *.[ch] v=`sed -n -e 's/\./-/' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
zip -ul9 zlib-$$v $(DISTFILES)
tgz: mv Makefile~ Makefile
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:
etags *.[ch]
depend:
makedepend -- $(CFLAGS) -- *.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it. # 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 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 deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h example.o: zlib.h zconf.h
gzio.o: zutil.h zlib.h zconf.h gzio.o: zutil.h zlib.h zconf.h
infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.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 inftrees.h infutil.h infcodes.h inffast.h infcodes.o: zutil.h zlib.h zconf.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.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 inflate.o: zutil.h zlib.h zconf.h infblock.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h inftrees.o: zutil.h zlib.h zconf.h inftrees.h
infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
minigzip.o: zlib.h zconf.h minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.o: deflate.h zutil.h zlib.h zconf.h
uncompr.o: 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
...@@ -18,7 +18,7 @@ CFLAGS=-O2 -Z $(MODEL) ...@@ -18,7 +18,7 @@ CFLAGS=-O2 -Z $(MODEL)
CC=bcc CC=bcc
LD=bcc LD=bcc
LIB=tlib 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) LDFLAGS=$(MODEL)
O=.obj O=.obj
......
# 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
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 ChangeLog configure Makefile.in Makefile Makefile.msc \
Makefile.bor Makefile.tc Make_vms.com 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/\./-/' -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
# 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
zlib 0.95 is a beta version of a general purpose compression library. zlib 1.0 is a general purpose data compression library. All the code
This should be the last version before the first official is reentrant (thread safe). The data format used by the zlib library
version (1.0), so please test it now. (At least compile and run it with is described in the files zlib-3.3.doc, deflate-1.3.doc and
"make test"). This version has no known bugs. gzip-4.3.doc, available in ftp://ftp.uu.net/pub/archiving/zip/doc/
The data format used by the zlib library is described in the
files zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available
in ftp.uu.net:/pub/archiving/zip/doc.
All functions of the compression library are documented in the file 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 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 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; To compile all files and run the test program, follow the instructions
for VMS, use Make_vms.com or descrip.mms.) given at the top of Makefile. In short "make test; make install"
To install the zlib library (libz.a) in /usr/local/lib, type: make install should work for most machines. For MSDOS, use one of the special
To install in a different directory, use for example: makefiles such as Makefile.msc; for VMS, use Make_vms.com or descrip.mms.
make install prefix=$HOME
This will install in $HOME/lib instead of /usr/local/lib. 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 0.95 are documented in the file ChangeLog.
The main changes since 0.94 are: The changes made in version 1.0 are documented in the file ChangeLog.
- fix MSDOS small and medium model (now easier to adapt to any compiler) The main changes since 0.95 are:
- inlined send_bits - allow preset dictionary shared between compressor and decompressor
- fix the final (:-) bug for deflate with flush (output was correct but - allow compression level 0 (no compression)
not completely flushed in rare occasions). - add deflateParams in zlib.h: allow dynamic change of compression level
and compression strategy.
For MSDOS, the small and medium models have been tested only with Microsoft C. - test large buffers and deflateParams in example.c
(This should now work for Borland C also, but I don't have a recent Borland - add optional "configure" to build zlib as a shared library
compiler to test with.) The small model was tested with Turbo C but only with - suppress Makefile.qnx, use configure instead
reduced performance to avoid any far allocation; it was tested with - fixes for 64-bit systems (needed for Alpha and Cray)
-DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 - 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
(C) 1995 Jean-loup Gailly and Mark Adler - prefix all global functions and types with z_ with -DZ_PREFIX
- fix some very unlikely race conditions in multi-threaded environment
- several minor fixes for better portability
- 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
Notes for some targets:
- 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).
- 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:
(C) 1995-1996 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
......
/* adler32.c -- compute the Adler-32 checksum of a data stream /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
/* ========================================================================= */ /* ========================================================================= */
uLong adler32(adler, buf, len) uLong adler32(adler, buf, len)
uLong adler; uLong adler;
Bytef *buf; const Bytef *buf;
uInt len; uInt len;
{ {
unsigned long s1 = adler & 0xffff; unsigned long s1 = adler & 0xffff;
......
/* compress.c -- compress a memory buffer /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -22,13 +22,13 @@ ...@@ -22,13 +22,13 @@
int compress (dest, destLen, source, sourceLen) int compress (dest, destLen, source, sourceLen)
Bytef *dest; Bytef *dest;
uLongf *destLen; uLongf *destLen;
Bytef *source; const Bytef *source;
uLong sourceLen; uLong sourceLen;
{ {
z_stream stream; z_stream stream;
int err; int err;
stream.next_in = source; stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen; stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */ /* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
...@@ -39,6 +39,7 @@ int compress (dest, destLen, source, sourceLen) ...@@ -39,6 +39,7 @@ int compress (dest, destLen, source, sourceLen)
stream.zalloc = (alloc_func)0; stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0; stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
if (err != Z_OK) return err; if (err != Z_OK) return err;
......
#!/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"}
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-"-O2 -rpath ."}
CFLAGS=${CFLAGS-"-O2"}
LDSHARED=${LDSHARED-"cc -shared"};;
QNX*) SFLAGS=${CFLAGS-"-4 -O -Q"}
CFLAGS=${CFLAGS-"-4 -O -Q"}
LDSHARED=${LDSHARED-"cc"}
LIBS=zlib.lib
AR="cc -A";;
# send working options for other systems to gzip@prep.ai.mit.edu
*) SFLAGS=${CFLAGS-"-O"}
CFLAGS=${CFLAGS-"-O"}
LDSHARED=${LDSHARED-"-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
# ed -s Makefile <<EOF
sed < Makefile.in "
/^CC *=/s/=.*/=$CC/
/^CFLAGS *=/s/=.*/=$CFLAGS/
/^LDSHARED *=/s/=.*/=$LDSHARED/
/^LIBS *=/s,=.*,=$LIBS,
/^AR *=/s/=.*/=$AR/
/^VER *=/s/=.*/=$VER/
/^prefix *=/s,=.*,=$prefix,
/^exec_prefix *=/s,=.*,=$exec_prefix,
" > Makefile
#w
#q
#EOF
/* crc32.c -- compute the CRC-32 of a data stream /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -10,23 +10,53 @@ ...@@ -10,23 +10,53 @@
#define local static #define local static
#ifdef DYNAMIC_CRC_TABLE #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 int crc_table_empty = 1;
local uLong crc_table[256]; 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() local void make_crc_table()
{ {
uLong c; uLong c;
int n, k; 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++) for (n = 0; n < 256; n++)
{ {
c = (uLong)n; c = (uLong)n;
for (k = 0; k < 8; k++) 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[n] = c;
} }
crc_table_empty = 0; crc_table_empty = 0;
...@@ -35,7 +65,7 @@ local void make_crc_table() ...@@ -35,7 +65,7 @@ local void make_crc_table()
/* ======================================================================== /* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table) * 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, 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
...@@ -91,6 +121,18 @@ local uLong crc_table[] = { ...@@ -91,6 +121,18 @@ local uLong crc_table[] = {
}; };
#endif #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 DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf); #define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf); #define DO4(buf) DO2(buf); DO2(buf);
...@@ -99,7 +141,7 @@ local uLong crc_table[] = { ...@@ -99,7 +141,7 @@ local uLong crc_table[] = {
/* ========================================================================= */ /* ========================================================================= */
uLong crc32(crc, buf, len) uLong crc32(crc, buf, len)
uLong crc; uLong crc;
Bytef *buf; const Bytef *buf;
uInt len; uInt len;
{ {
if (buf == Z_NULL) return 0L; if (buf == Z_NULL) return 0L;
......
此差异已折叠。
/* deflate.h -- internal compression state /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -10,17 +10,15 @@ ...@@ -10,17 +10,15 @@
/* $Id: deflate.h,v 1.5 1995/05/03 17:27:09 jloup Exp $ */ /* $Id: deflate.h,v 1.5 1995/05/03 17:27:09 jloup Exp $ */
#ifndef _DEFLATE_H
#define _DEFLATE_H
#include "zutil.h" #include "zutil.h"
/* =========================================================================== /* ===========================================================================
* Internal compression state. * Internal compression state.
*/ */
/* Data type */
#define BINARY 0
#define ASCII 1
#define UNKNOWN 2
#define LENGTH_CODES 29 #define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */ /* number of length codes, not counting the special END_BLOCK code */
...@@ -87,10 +85,10 @@ typedef struct internal_state { ...@@ -87,10 +85,10 @@ typedef struct internal_state {
Bytef *pending_buf; /* output still pending */ Bytef *pending_buf; /* output still pending */
Bytef *pending_out; /* next pending byte to output to the stream */ Bytef *pending_out; /* next pending byte to output to the stream */
int pending; /* nb of bytes in the pending buffer */ int pending; /* nb of bytes in the pending buffer */
uLong adler; /* adler32 of uncompressed data */
int noheader; /* suppress zlib header and adler32 */ int noheader; /* suppress zlib header and adler32 */
Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte data_type; /* UNKNOWN, BINARY or ASCII */
Byte method; /* STORED (for zip only) or DEFLATED */ Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */ /* used by deflate.c: */
...@@ -173,7 +171,7 @@ typedef struct internal_state { ...@@ -173,7 +171,7 @@ typedef struct internal_state {
uInt good_match; uInt good_match;
/* Use a faster search when the previous match is longer than this */ /* Use a faster search when the previous match is longer than this */
int nice_match; /* Stop searching when current match exceeds this */ int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */ /* used by trees.c: */
/* Didn't use ct_data typedef below to supress compiler warning */ /* Didn't use ct_data typedef below to supress compiler warning */
...@@ -267,9 +265,11 @@ typedef struct internal_state { ...@@ -267,9 +265,11 @@ typedef struct internal_state {
*/ */
/* in trees.c */ /* in trees.c */
void ct_init OF((deflate_state *s)); void _tr_init OF((deflate_state *s));
int ct_tally OF((deflate_state *s, int dist, int lc)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
ulg ct_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
void ct_align OF((deflate_state *s)); int eof));
void ct_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof)); int eof));
#endif
/* example.c -- usage example of the zlib compression library /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -10,20 +10,11 @@ ...@@ -10,20 +10,11 @@
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h>
#else
extern void exit OF((int));
#endif #endif
#ifndef __GO32__
extern void exit OF((int));
#endif
#define BUFLEN 4096
#define local static
/* For MSDOS and other systems with limitation on stack size. For Unix,
#define local
works also.
*/
#define CHECK_ERR(err, msg) { \ #define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \ if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \ fprintf(stderr, "%s error: %d\n", msg, err); \
...@@ -31,32 +22,44 @@ extern void exit OF((int)); ...@@ -31,32 +22,44 @@ extern void exit OF((int));
} \ } \
} }
char *hello = "hello, hello!"; const char hello[] = "hello, hello!";
/* "hello world" would be more standard, but the repeated "hello" /* "hello world" would be more standard, but the repeated "hello"
* stresses the compression code better, sorry... * stresses the compression code better, sorry...
*/ */
void test_compress OF((void)); const char dictionary[] = "hello";
void test_gzio OF((char *out, char *in)); uLong dictId; /* Adler32 value of the dictionary */
void test_deflate OF((Byte compr[]));
void test_inflate OF((Byte compr[])); void test_compress OF((Bytef *compr, uLong comprLen,
void test_flush OF((Byte compr[])); Bytef *uncompr, uLong uncomprLen));
void test_sync OF((Byte compr[])); void test_gzio OF((const char *out, const char *in,
int main OF((int argc, char *argv[])); 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));
void test_dict_deflate OF((Bytef *compr, uLong comprLen));
void test_dict_inflate OF((Bytef *compr, uLong comprLen,
Bytef *uncompr, uLong uncomprLen));
int main OF((int argc, char *argv[]));
/* =========================================================================== /* ===========================================================================
* Test compress() and uncompress() * Test compress() and uncompress()
*/ */
void test_compress() void test_compress(compr, comprLen, uncompr, uncomprLen)
Bytef *compr, *uncompr;
uLong comprLen, uncomprLen;
{ {
local Byte compr[BUFLEN];
uLong comprLen = sizeof(compr);
local Byte uncompr[BUFLEN];
uLong uncomprLen = sizeof(uncompr);
int err; int err;
uLong len = strlen(hello)+1; uLong len = strlen(hello)+1;
err = compress(compr, &comprLen, (Byte*)hello, len); err = compress(compr, &comprLen, (const Bytef*)hello, len);
CHECK_ERR(err, "compress"); CHECK_ERR(err, "compress");
strcpy((char*)uncompr, "garbage"); strcpy((char*)uncompr, "garbage");
...@@ -74,12 +77,12 @@ void test_compress() ...@@ -74,12 +77,12 @@ void test_compress()
/* =========================================================================== /* ===========================================================================
* Test read/write of .gz files * Test read/write of .gz files
*/ */
void test_gzio(out, in) void test_gzio(out, in, uncompr, uncomprLen)
char *out; /* output file */ const char *out; /* output file */
char *in; /* input file */ const char *in; /* input file */
Bytef *uncompr;
int uncomprLen;
{ {
local Byte uncompr[BUFLEN];
int uncomprLen = sizeof(uncompr);
int err; int err;
int len = strlen(hello)+1; int len = strlen(hello)+1;
gzFile file; gzFile file;
...@@ -90,7 +93,7 @@ void test_gzio(out, in) ...@@ -90,7 +93,7 @@ void test_gzio(out, in)
exit(1); 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)); fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
} }
gzclose(file); gzclose(file);
...@@ -101,7 +104,7 @@ void test_gzio(out, in) ...@@ -101,7 +104,7 @@ void test_gzio(out, in)
} }
strcpy((char*)uncompr, "garbage"); strcpy((char*)uncompr, "garbage");
uncomprLen = gzread(file, uncompr, uncomprLen); uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
if (uncomprLen != len) { if (uncomprLen != len) {
fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
} }
...@@ -117,8 +120,9 @@ void test_gzio(out, in) ...@@ -117,8 +120,9 @@ void test_gzio(out, in)
/* =========================================================================== /* ===========================================================================
* Test deflate() with small buffers * Test deflate() with small buffers
*/ */
void test_deflate(compr) void test_deflate(compr, comprLen)
Byte compr[]; Bytef *compr;
uLong comprLen;
{ {
z_stream c_stream; /* compression stream */ z_stream c_stream; /* compression stream */
int err; int err;
...@@ -126,14 +130,15 @@ void test_deflate(compr) ...@@ -126,14 +130,15 @@ void test_deflate(compr)
c_stream.zalloc = (alloc_func)0; c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0; c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit"); CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Byte*)hello; c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr; c_stream.next_out = compr;
while (c_stream.total_in != (uLong)len) { while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = deflate(&c_stream, Z_NO_FLUSH); err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate"); CHECK_ERR(err, "deflate");
...@@ -153,10 +158,10 @@ void test_deflate(compr) ...@@ -153,10 +158,10 @@ void test_deflate(compr)
/* =========================================================================== /* ===========================================================================
* Test inflate() with small buffers * Test inflate() with small buffers
*/ */
void test_inflate(compr) void test_inflate(compr, comprLen, uncompr, uncomprLen)
Byte compr[]; Bytef *compr, *uncompr;
uLong comprLen, uncomprLen;
{ {
local Byte uncompr[BUFLEN];
int err; int err;
z_stream d_stream; /* decompression stream */ z_stream d_stream; /* decompression stream */
...@@ -164,6 +169,7 @@ void test_inflate(compr) ...@@ -164,6 +169,7 @@ void test_inflate(compr)
d_stream.zalloc = (alloc_func)0; d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0; d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream); err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit"); CHECK_ERR(err, "inflateInit");
...@@ -171,7 +177,7 @@ void test_inflate(compr) ...@@ -171,7 +177,7 @@ void test_inflate(compr)
d_stream.next_in = compr; d_stream.next_in = compr;
d_stream.next_out = uncompr; d_stream.next_out = uncompr;
for (;;) { while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = inflate(&d_stream, Z_NO_FLUSH); err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break; if (err == Z_STREAM_END) break;
...@@ -188,11 +194,105 @@ void test_inflate(compr) ...@@ -188,11 +194,105 @@ void test_inflate(compr)
} }
} }
/* ===========================================================================
* Test deflate() with large buffers and dynamic change of compression level
*/
void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
Bytef *compr, *uncompr;
uLong comprLen, uncomprLen;
{
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_SPEED);
CHECK_ERR(err, "deflateInit");
c_stream.next_out = compr;
c_stream.avail_out = (uInt)comprLen;
/* At this point, uncompr is still mostly zeroes, so it should compress
* very well:
*/
c_stream.next_in = uncompr;
c_stream.avail_in = (uInt)uncomprLen;
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
if (c_stream.avail_in != 0) {
fprintf(stderr, "deflate not greedy\n");
}
/* Feed in already compressed data and switch to no compression: */
deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
c_stream.next_in = compr;
c_stream.avail_in = (uInt)comprLen/2;
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
/* Switch back to compressing mode: */
deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
c_stream.next_in = uncompr;
c_stream.avail_in = (uInt)uncomprLen;
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate");
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 large buffers
*/
void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
Bytef *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;
for (;;) {
d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (uInt)uncomprLen;
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "large inflate");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
} else {
printf("large_inflate(): OK\n");
}
}
/* =========================================================================== /* ===========================================================================
* Test deflate() with full flush * Test deflate() with full flush
*/ */
void test_flush(compr) void test_flush(compr, comprLen)
Byte compr[]; Bytef *compr;
uLong comprLen;
{ {
z_stream c_stream; /* compression stream */ z_stream c_stream; /* compression stream */
int err; int err;
...@@ -200,14 +300,15 @@ void test_flush(compr) ...@@ -200,14 +300,15 @@ void test_flush(compr)
c_stream.zalloc = (alloc_func)0; c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0; c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit"); CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Byte*)hello; c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr; c_stream.next_out = compr;
c_stream.avail_in = 3; c_stream.avail_in = 3;
c_stream.avail_out = BUFLEN; c_stream.avail_out = (uInt)comprLen;
err = deflate(&c_stream, Z_FULL_FLUSH); err = deflate(&c_stream, Z_FULL_FLUSH);
CHECK_ERR(err, "deflate"); CHECK_ERR(err, "deflate");
...@@ -225,10 +326,10 @@ void test_flush(compr) ...@@ -225,10 +326,10 @@ void test_flush(compr)
/* =========================================================================== /* ===========================================================================
* Test inflateSync() * Test inflateSync()
*/ */
void test_sync(compr) void test_sync(compr, comprLen, uncompr, uncomprLen)
Byte compr[]; Bytef *compr, *uncompr;
uLong comprLen, uncomprLen;
{ {
local Byte uncompr[BUFLEN];
int err; int err;
z_stream d_stream; /* decompression stream */ z_stream d_stream; /* decompression stream */
...@@ -236,6 +337,7 @@ void test_sync(compr) ...@@ -236,6 +337,7 @@ void test_sync(compr)
d_stream.zalloc = (alloc_func)0; d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0; d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream); err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit"); CHECK_ERR(err, "inflateInit");
...@@ -243,13 +345,13 @@ void test_sync(compr) ...@@ -243,13 +345,13 @@ void test_sync(compr)
d_stream.next_in = compr; d_stream.next_in = compr;
d_stream.next_out = uncompr; d_stream.next_out = uncompr;
d_stream.avail_in = 2; /* just read the zlib header */ d_stream.avail_in = 2; /* just read the zlib header */
d_stream.avail_out = sizeof(uncompr); d_stream.avail_out = (uInt)uncomprLen;
inflate(&d_stream, Z_NO_FLUSH); inflate(&d_stream, Z_NO_FLUSH);
CHECK_ERR(err, "inflate"); CHECK_ERR(err, "inflate");
d_stream.avail_in = BUFLEN-2; /* let inflate read all compressed data */ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
err = inflateSync(&d_stream); /* skip the damaged part */ err = inflateSync(&d_stream); /* but skip the damaged part */
CHECK_ERR(err, "inflateSync"); CHECK_ERR(err, "inflateSync");
err = inflate(&d_stream, Z_FINISH); err = inflate(&d_stream, Z_FINISH);
...@@ -263,6 +365,91 @@ void test_sync(compr) ...@@ -263,6 +365,91 @@ void test_sync(compr)
printf("after inflateSync(): hel%s\n", uncompr); printf("after inflateSync(): hel%s\n", uncompr);
} }
/* ===========================================================================
* Test deflate() with preset dictionary
*/
void test_dict_deflate(compr, comprLen)
Bytef *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)
Bytef *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]] * Usage: example [output.gz [input.gz]]
*/ */
...@@ -271,7 +458,9 @@ int main(argc, argv) ...@@ -271,7 +458,9 @@ int main(argc, argv)
int argc; int argc;
char *argv[]; char *argv[];
{ {
local Byte compr[BUFLEN]; Bytef *compr, *uncompr;
uLong comprLen = 32750*sizeof(int); /* don't overflow on MSDOS */
uLong uncomprLen = comprLen;
if (zlib_version[0] != ZLIB_VERSION[0]) { if (zlib_version[0] != ZLIB_VERSION[0]) {
fprintf(stderr, "incompatible zlib version\n"); fprintf(stderr, "incompatible zlib version\n");
...@@ -280,16 +469,31 @@ int main(argc, argv) ...@@ -280,16 +469,31 @@ int main(argc, argv)
} else if (strcmp(zlib_version, ZLIB_VERSION) != 0) { } else if (strcmp(zlib_version, ZLIB_VERSION) != 0) {
fprintf(stderr, "warning: different zlib version\n"); fprintf(stderr, "warning: different zlib version\n");
} }
test_compress();
compr = (Bytef*)malloc((uInt)comprLen);
uncompr = (Bytef*)calloc((uInt)uncomprLen, 1); /* must be cleared */
if (compr == Z_NULL || uncompr == Z_NULL) {
printf("out of memory\n");
exit(1);
}
test_compress(compr, comprLen, uncompr, uncomprLen);
test_gzio((argc > 1 ? argv[1] : "foo.gz"), test_gzio((argc > 1 ? argv[1] : "foo.gz"),
(argc > 2 ? argv[2] : "foo.gz")); (argc > 2 ? argv[2] : "foo.gz"),
uncompr, (int)uncomprLen);
test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen);
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
test_deflate(compr); test_flush(compr, comprLen);
test_inflate(compr); test_sync(compr, comprLen, uncompr, uncomprLen);
test_flush(compr); test_dict_deflate(compr, comprLen);
test_sync(compr); test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
exit(0); exit(0);
return 0; /* to avoid warning */ return 0; /* to avoid warning */
......
/* gzio.c -- IO on .gz files /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -16,8 +16,7 @@ struct internal_state {int dummy;}; /* for buggy compilers */ ...@@ -16,8 +16,7 @@ struct internal_state {int dummy;}; /* for buggy compilers */
#define ALLOC(size) malloc(size) #define ALLOC(size) malloc(size)
#define TRYFREE(p) {if (p) free(p);} #define TRYFREE(p) {if (p) free(p);}
#define GZ_MAGIC_1 0x1f static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
#define GZ_MAGIC_2 0x8b
/* gzip flag byte */ /* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
...@@ -27,10 +26,6 @@ struct internal_state {int dummy;}; /* for buggy compilers */ ...@@ -27,10 +26,6 @@ struct internal_state {int dummy;}; /* for buggy compilers */
#define COMMENT 0x10 /* bit 4 set: file comment present */ #define COMMENT 0x10 /* bit 4 set: file comment present */
#define RESERVED 0xE0 /* bits 5..7: reserved */ #define RESERVED 0xE0 /* bits 5..7: reserved */
#ifndef SEEK_CUR
# define SEEK_CUR 1
#endif
typedef struct gz_stream { typedef struct gz_stream {
z_stream stream; z_stream stream;
int z_err; /* error code for last stream operation */ int z_err; /* error code for last stream operation */
...@@ -46,44 +41,16 @@ typedef struct gz_stream { ...@@ -46,44 +41,16 @@ typedef struct gz_stream {
} gz_stream; } gz_stream;
local int destroy OF((gz_stream *s)); local gzFile gz_open OF((const char *path, const char *mode, int fd));
local gzFile gz_open OF((char *path, char *mode, int fd)); local int get_byte OF((gz_stream *s));
local void putLong OF((FILE *file, uLong x)); local void check_header OF((gz_stream *s));
local uLong getLong OF((Bytef *buf)); local int destroy OF((gz_stream *s));
local void putLong OF((FILE *file, uLong x));
/* =========================================================================== local uLong getLong OF((gz_stream *s));
* 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;
}
/* =========================================================================== /* ===========================================================================
Opens a gzip (.gz) file for reading or writing. The mode parameter Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descritor is as in fopen ("rb" or "wb"). The file is given either by file descriptor
or path name (if fd == -1). or path name (if fd == -1).
gz_open return NULL if the file could not be opened or if there was gz_open return NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno insufficient memory to allocate the (de)compression state; errno
...@@ -91,19 +58,25 @@ local int destroy (s) ...@@ -91,19 +58,25 @@ local int destroy (s)
zlib error is Z_MEM_ERROR). zlib error is Z_MEM_ERROR).
*/ */
local gzFile gz_open (path, mode, fd) local gzFile gz_open (path, mode, fd)
char *path; const char *path;
char *mode; const char *mode;
int fd; int fd;
{ {
int err; int err;
int level = Z_DEFAULT_COMPRESSION; /* compression level */ int level = Z_DEFAULT_COMPRESSION; /* compression level */
char *p = mode; char *p = (char*)mode;
gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream)); 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; if (!s) return Z_NULL;
s->stream.zalloc = (alloc_func)0; s->stream.zalloc = (alloc_func)0;
s->stream.zfree = (free_func)0; s->stream.zfree = (free_func)0;
s->stream.opaque = (voidpf)0;
s->stream.next_in = s->inbuf = Z_NULL; s->stream.next_in = s->inbuf = Z_NULL;
s->stream.next_out = s->outbuf = Z_NULL; s->stream.next_out = s->outbuf = Z_NULL;
s->stream.avail_in = s->stream.avail_out = 0; s->stream.avail_in = s->stream.avail_out = 0;
...@@ -123,14 +96,18 @@ local gzFile gz_open (path, mode, fd) ...@@ -123,14 +96,18 @@ local gzFile gz_open (path, mode, fd)
s->mode = '\0'; s->mode = '\0';
do { do {
if (*p == 'r') s->mode = 'r'; if (*p == 'r') s->mode = 'r';
if (*p == 'w') s->mode = 'w'; if (*p == 'w' || *p == 'a') s->mode = 'w';
if (*p >= '1' && *p <= '9') level = *p - '0'; if (*p >= '0' && *p <= '9') {
} while (*p++); 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 == '\0') return destroy(s), (gzFile)Z_NULL;
if (s->mode == 'w') { if (s->mode == 'w') {
err = deflateInit2(&(s->stream), level, err = deflateInit2(&(s->stream), level,
DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
/* windowBits is passed < 0 to suppress zlib header */ /* windowBits is passed < 0 to suppress zlib header */
s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
...@@ -149,7 +126,7 @@ local gzFile gz_open (path, mode, fd) ...@@ -149,7 +126,7 @@ local gzFile gz_open (path, mode, fd)
s->stream.avail_out = Z_BUFSIZE; s->stream.avail_out = Z_BUFSIZE;
errno = 0; errno = 0;
s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode); s->file = fd < 0 ? FOPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
if (s->file == NULL) { if (s->file == NULL) {
return destroy(s), (gzFile)Z_NULL; return destroy(s), (gzFile)Z_NULL;
...@@ -157,50 +134,10 @@ local gzFile gz_open (path, mode, fd) ...@@ -157,50 +134,10 @@ local gzFile gz_open (path, mode, fd)
if (s->mode == 'w') { if (s->mode == 'w') {
/* Write a very simple .gz header: /* 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],
DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
} else { } else {
/* Check and skip the header: check_header(s); /* skip the .gz 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 != 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;
}
} }
return (gzFile)s; return (gzFile)s;
} }
...@@ -209,25 +146,138 @@ local gzFile gz_open (path, mode, fd) ...@@ -209,25 +146,138 @@ local gzFile gz_open (path, mode, fd)
Opens a gzip (.gz) file for reading or writing. Opens a gzip (.gz) file for reading or writing.
*/ */
gzFile gzopen (path, mode) gzFile gzopen (path, mode)
char *path; const char *path;
char *mode; const char *mode;
{ {
return gz_open (path, mode, -1); 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) gzFile gzdopen (fd, mode)
int fd; int fd;
char *mode; const char *mode;
{ {
char name[20]; char name[20];
if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */ sprintf(name, "<fd:%d>", fd); /* for debugging */
return gz_open (name, mode, fd); 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 = 0;
int flags = 0;
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. Reads the given number of uncompressed bytes from the compressed file.
gzread returns the number of bytes actually read (0 for end of file). gzread returns the number of bytes actually read (0 for end of file).
...@@ -238,52 +288,71 @@ int gzread (file, buf, len) ...@@ -238,52 +288,71 @@ int gzread (file, buf, len)
unsigned len; unsigned len;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
Byte *start = buf; /* starting point for crc computation */
if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
if (s->transparent) { if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
int n = 0; if (s->z_err == Z_STREAM_END) return 0; /* EOF */
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 */
s->stream.next_out = buf; s->stream.next_out = buf;
s->stream.avail_out = len; s->stream.avail_out = len;
while (s->stream.avail_out != 0) { 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);
s->stream.next_out += n;
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(s->stream.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) { if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0; errno = 0;
s->stream.avail_in = s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
} else if (s->stream.avail_in == (uInt)EOF) { if (ferror(s->file)) {
s->stream.avail_in = 0; s->z_err = Z_ERRNO;
s->z_eof = 1; break;
s->z_err = Z_ERRNO; }
break;
} }
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
} }
s->z_err = inflate(&(s->stream), Z_NO_FLUSH); s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
if (s->z_err == Z_STREAM_END || if (s->z_err == Z_STREAM_END) {
s->z_err != Z_OK || s->z_eof) break; /* 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, start, (uInt)(s->stream.next_out - start));
s->crc = crc32(s->crc, buf, len);
return (int)len; return (int)(len - s->stream.avail_out);
} }
/* =========================================================================== /* ===========================================================================
...@@ -292,7 +361,7 @@ int gzread (file, buf, len) ...@@ -292,7 +361,7 @@ int gzread (file, buf, len)
*/ */
int gzwrite (file, buf, len) int gzwrite (file, buf, len)
gzFile file; gzFile file;
voidp buf; const voidp buf;
unsigned len; unsigned len;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
...@@ -343,7 +412,7 @@ int gzflush (file, flush) ...@@ -343,7 +412,7 @@ int gzflush (file, flush)
len = Z_BUFSIZE - s->stream.avail_out; len = Z_BUFSIZE - s->stream.avail_out;
if (len != 0) { 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; s->z_err = Z_ERRNO;
return Z_ERRNO; return Z_ERRNO;
} }
...@@ -379,18 +448,19 @@ local void putLong (file, x) ...@@ -379,18 +448,19 @@ local void putLong (file, x)
} }
/* =========================================================================== /* ===========================================================================
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) local uLong getLong (s)
Bytef *buf; gz_stream *s;
{ {
uLong x = 0; uLong x = (uLong)get_byte(s);
Bytef *p = buf+4; int c;
do { x += ((uLong)get_byte(s))<<8;
x <<= 8; x += ((uLong)get_byte(s))<<16;
x |= *--p; c = get_byte(s);
} while (p != buf); if (c == EOF) s->z_err = Z_DATA_ERROR;
x += ((uLong)c)<<24;
return x; return x;
} }
...@@ -401,7 +471,6 @@ local uLong getLong (buf) ...@@ -401,7 +471,6 @@ local uLong getLong (buf)
int gzclose (file) int gzclose (file)
gzFile file; gzFile file;
{ {
uInt n;
int err; int err;
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
...@@ -414,25 +483,6 @@ int gzclose (file) ...@@ -414,25 +483,6 @@ int gzclose (file)
putLong (s->file, s->crc); putLong (s->file, s->crc);
putLong (s->file, s->stream.total_in); 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); return destroy(file);
} }
...@@ -453,14 +503,14 @@ char* gzerror (file, errnum) ...@@ -453,14 +503,14 @@ char* gzerror (file, errnum)
if (s == NULL) { if (s == NULL) {
*errnum = Z_STREAM_ERROR; *errnum = Z_STREAM_ERROR;
return z_errmsg[1-Z_STREAM_ERROR]; return ERR_MSG(Z_STREAM_ERROR);
} }
*errnum = s->z_err; *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 = (char*)z_errmsg[1-s->z_err];
TRYFREE(s->msg); TRYFREE(s->msg);
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
......
/* infblock.c -- interpret and process block types to last block /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -81,7 +81,7 @@ uLongf *c; ...@@ -81,7 +81,7 @@ uLongf *c;
s->bitb = 0; s->bitb = 0;
s->read = s->write = s->window; s->read = s->write = s->window;
if (s->checkfn != Z_NULL) 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")); Trace((stderr, "inflate: blocks reset\n"));
} }
...@@ -172,17 +172,17 @@ int r; ...@@ -172,17 +172,17 @@ int r;
case 3: /* illegal */ case 3: /* illegal */
DUMPBITS(3) DUMPBITS(3)
s->mode = BAD; s->mode = BAD;
z->msg = "invalid block type"; z->msg = (char*)"invalid block type";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
break; break;
case LENS: case LENS:
NEEDBITS(32) NEEDBITS(32)
if (((~b) >> 16) != (b & 0xffff)) if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
{ {
s->mode = BAD; s->mode = BAD;
z->msg = "invalid stored block lengths"; z->msg = (char*)"invalid stored block lengths";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
...@@ -215,7 +215,7 @@ int r; ...@@ -215,7 +215,7 @@ int r;
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
{ {
s->mode = BAD; s->mode = BAD;
z->msg = "too many length or distance symbols"; z->msg = (char*)"too many length or distance symbols";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
...@@ -285,7 +285,7 @@ int r; ...@@ -285,7 +285,7 @@ int r;
(c == 16 && i < 1)) (c == 16 && i < 1))
{ {
s->mode = BAD; s->mode = BAD;
z->msg = "invalid bit length repeat"; z->msg = (char*)"invalid bit length repeat";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
...@@ -383,3 +383,14 @@ uLongf *c; ...@@ -383,3 +383,14 @@ uLongf *c;
Trace((stderr, "inflate: blocks freed\n")); Trace((stderr, "inflate: blocks freed\n"));
return Z_OK; return Z_OK;
} }
void inflate_set_dictionary(s, z, d, n)
inflate_blocks_statef *s;
z_stream *z;
const Bytef *d;
uInt n;
{
zmemcpy((charf *)s->window, d, n);
s->read = s->write = s->window + n;
}
/* infblock.h -- header to use infblock.c /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -30,3 +30,9 @@ extern int inflate_blocks_free OF(( ...@@ -30,3 +30,9 @@ extern int inflate_blocks_free OF((
inflate_blocks_statef *, inflate_blocks_statef *,
z_stream *, z_stream *,
uLongf *)); /* check value on output */ uLongf *)); /* check value on output */
extern void inflate_set_dictionary OF((
inflate_blocks_statef *s,
z_stream *z,
const Bytef *d, /* dictionary */
uInt n)); /* dictionary length */
/* infcodes.c -- process literals and length/distance pairs /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -58,7 +58,8 @@ struct inflate_codes_state { ...@@ -58,7 +58,8 @@ struct inflate_codes_state {
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
uInt bl, bd; uInt bl, bd;
inflate_huft *tl, *td; inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
z_stream *z; z_stream *z;
{ {
inflate_codes_statef *c; inflate_codes_statef *c;
...@@ -152,7 +153,7 @@ int r; ...@@ -152,7 +153,7 @@ int r;
break; break;
} }
c->mode = BADCODE; /* invalid code */ c->mode = BADCODE; /* invalid code */
z->msg = "invalid literal/length code"; z->msg = (char*)"invalid literal/length code";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
case LENEXT: /* i: getting length extra (have base) */ case LENEXT: /* i: getting length extra (have base) */
...@@ -184,7 +185,7 @@ int r; ...@@ -184,7 +185,7 @@ int r;
break; break;
} }
c->mode = BADCODE; /* invalid code */ c->mode = BADCODE; /* invalid code */
z->msg = "invalid distance code"; z->msg = (char*)"invalid distance code";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
case DISTEXT: /* i: getting distance extra */ case DISTEXT: /* i: getting distance extra */
...@@ -202,7 +203,7 @@ int r; ...@@ -202,7 +203,7 @@ int r;
#else #else
f = q - c->sub.copy.dist; f = q - c->sub.copy.dist;
if ((uInt)(q - s->window) < c->sub.copy.dist) if ((uInt)(q - s->window) < c->sub.copy.dist)
f = s->end - (c->sub.copy.dist - (q - s->window)); f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
#endif #endif
while (c->len) while (c->len)
{ {
......
/* infcodes.h -- header to use infcodes.c /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
......
/* inffast.c -- process literals and length/distance pairs fast /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -29,7 +29,8 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */ ...@@ -29,7 +29,8 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */
int inflate_fast(bl, bd, tl, td, s, z) int inflate_fast(bl, bd, tl, td, s, z)
uInt bl, bd; uInt bl, bd;
inflate_huft *tl, *td; inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
inflate_blocks_statef *s; inflate_blocks_statef *s;
z_stream *z; z_stream *z;
{ {
...@@ -102,7 +103,7 @@ z_stream *z; ...@@ -102,7 +103,7 @@ z_stream *z;
} }
else /* else offset after destination */ else /* else offset after destination */
{ {
e = d - (q - s->window); /* bytes from offset to end */ e = d - (uInt)(q - s->window); /* bytes from offset to end */
r = s->end - e; /* pointer to offset */ r = s->end - e; /* pointer to offset */
if (c > e) /* if source crosses, */ if (c > e) /* if source crosses, */
{ {
...@@ -122,7 +123,7 @@ z_stream *z; ...@@ -122,7 +123,7 @@ z_stream *z;
e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
else else
{ {
z->msg = "invalid distance code"; z->msg = (char*)"invalid distance code";
UNGRAB UNGRAB
UPDATE UPDATE
return Z_DATA_ERROR; return Z_DATA_ERROR;
...@@ -152,7 +153,7 @@ z_stream *z; ...@@ -152,7 +153,7 @@ z_stream *z;
} }
else else
{ {
z->msg = "invalid literal/length code"; z->msg = (char*)"invalid literal/length code";
UNGRAB UNGRAB
UPDATE UPDATE
return Z_DATA_ERROR; return Z_DATA_ERROR;
......
/* inffast.h -- header to use inffast.c /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
......
/* inflate.c -- zlib interface to inflate modules /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -15,6 +15,11 @@ struct internal_state { ...@@ -15,6 +15,11 @@ struct internal_state {
enum { enum {
METHOD, /* waiting for method byte */ METHOD, /* waiting for method byte */
FLAG, /* waiting for flag 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 */ BLOCKS, /* decompressing blocks */
CHECK4, /* four check bytes to go */ CHECK4, /* four check bytes to go */
CHECK3, /* three check bytes to go */ CHECK3, /* three check bytes to go */
...@@ -75,14 +80,25 @@ z_stream *z; ...@@ -75,14 +80,25 @@ z_stream *z;
} }
int inflateInit2(z, w) int inflateInit2_(z, w, version, stream_size)
z_stream *z; z_stream *z;
int w; 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 */ /* initialize state */
if (z == Z_NULL) if (z == Z_NULL)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
if (z->zalloc == Z_NULL) z->zalloc = zcalloc; z->msg = Z_NULL;
if (z->zalloc == Z_NULL)
{
z->zalloc = zcalloc;
z->opaque = (voidpf)0;
}
if (z->zfree == Z_NULL) z->zfree = zcfree; if (z->zfree == Z_NULL) z->zfree = zcfree;
if ((z->state = (struct internal_state FAR *) if ((z->state = (struct internal_state FAR *)
ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
...@@ -107,7 +123,7 @@ int w; ...@@ -107,7 +123,7 @@ int w;
/* create inflate_blocks state */ /* create inflate_blocks state */
if ((z->state->blocks = 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) == Z_NULL)
{ {
inflateEnd(z); inflateEnd(z);
...@@ -121,10 +137,12 @@ int w; ...@@ -121,10 +137,12 @@ int w;
} }
int inflateInit(z) int inflateInit_(z, version, stream_size)
z_stream *z; z_stream *z;
const char *version;
int stream_size;
{ {
return inflateInit2(z, DEF_WBITS); return inflateInit2_(z, DEF_WBITS, version, stream_size);
} }
...@@ -138,46 +156,68 @@ int f; ...@@ -138,46 +156,68 @@ int f;
int r = f; /* to avoid warning about unused f */ int r = f; /* to avoid warning about unused f */
uInt b; uInt b;
if (z == Z_NULL || z->next_in == Z_NULL) if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
r = Z_BUF_ERROR; r = Z_BUF_ERROR;
while (1) switch (z->state->mode) while (1) switch (z->state->mode)
{ {
case METHOD: case METHOD:
NEEDBYTE NEEDBYTE
if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "unknown compression method"; z->msg = (char*)"unknown compression method";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
if ((z->state->sub.method >> 4) + 8 > z->state->wbits) if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "invalid window size"; z->msg = (char*)"invalid window size";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
z->state->mode = FLAG; z->state->mode = FLAG;
case FLAG: case FLAG:
NEEDBYTE NEEDBYTE
if ((b = NEXTBYTE) & 0x20) b = NEXTBYTE;
{
z->state->mode = BAD;
z->msg = "invalid reserved bit";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
if (((z->state->sub.method << 8) + b) % 31) if (((z->state->sub.method << 8) + b) % 31)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "incorrect header check"; z->msg = (char*)"incorrect header check";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
Trace((stderr, "inflate: zlib header ok\n")); 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: case BLOCKS:
r = inflate_blocks(z->state->blocks, z, r); r = inflate_blocks(z->state->blocks, z, r);
if (r == Z_DATA_ERROR) if (r == Z_DATA_ERROR)
...@@ -215,7 +255,7 @@ int f; ...@@ -215,7 +255,7 @@ int f;
if (z->state->sub.check.was != z->state->sub.check.need) if (z->state->sub.check.was != z->state->sub.check.need)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "incorrect data check"; z->msg = (char*)"incorrect data check";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
...@@ -231,6 +271,29 @@ int f; ...@@ -231,6 +271,29 @@ int f;
} }
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 >= (1<<z->state->wbits))
{
length = (1<<z->state->wbits)-1;
dictionary += dictLength - length;
}
inflate_set_dictionary(z->state->blocks, z, dictionary, length);
z->state->mode = BLOCKS;
return Z_OK;
}
int inflateSync(z) int inflateSync(z)
z_stream *z; z_stream *z;
{ {
......
/* inftrees.c -- generate Huffman trees for efficient decoding /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
#include "zutil.h" #include "zutil.h"
#include "inftrees.h" #include "inftrees.h"
char inflate_copyright[] = " inflate 1.0 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
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */ /* simplify the use of the inflate_huft type with some defines */
...@@ -30,23 +37,19 @@ local voidpf falloc OF(( ...@@ -30,23 +37,19 @@ local voidpf falloc OF((
uInt, /* number of items */ uInt, /* number of items */
uInt)); /* size of item */ uInt)); /* size of item */
local void ffree OF((
voidpf q, /* opaque pointer (not used) */
voidpf p)); /* what to free (not used) */
/* Tables for deflate from PKZIP's appnote.txt. */ /* 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, 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}; 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 */ /* 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, 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 */ 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, 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, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577}; 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, 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, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13}; 12, 12, 13, 13};
...@@ -304,11 +307,11 @@ z_stream *z; /* for zfree function */ ...@@ -304,11 +307,11 @@ z_stream *z; /* for zfree function */
r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
if (r == Z_DATA_ERROR) 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) else if (r == Z_BUF_ERROR)
{ {
inflate_trees_free(*tb, z); inflate_trees_free(*tb, z);
z->msg = "incomplete dynamic bit lengths tree"; z->msg = (char*)"incomplete dynamic bit lengths tree";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
} }
return r; return r;
...@@ -331,11 +334,11 @@ z_stream *z; /* for zfree function */ ...@@ -331,11 +334,11 @@ z_stream *z; /* for zfree function */
if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
{ {
if (r == Z_DATA_ERROR) if (r == Z_DATA_ERROR)
z->msg = "oversubscribed literal/length tree"; z->msg = (char*)"oversubscribed literal/length tree";
else if (r == Z_BUF_ERROR) else if (r == Z_BUF_ERROR)
{ {
inflate_trees_free(*tl, z); inflate_trees_free(*tl, z);
z->msg = "incomplete literal/length tree"; z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
} }
return r; return r;
...@@ -345,14 +348,14 @@ z_stream *z; /* for zfree function */ ...@@ -345,14 +348,14 @@ z_stream *z; /* for zfree function */
if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
{ {
if (r == Z_DATA_ERROR) if (r == Z_DATA_ERROR)
z->msg = "oversubscribed literal/length tree"; z->msg = (char*)"oversubscribed literal/length tree";
else if (r == Z_BUF_ERROR) { else if (r == Z_BUF_ERROR) {
#ifdef PKZIP_BUG_WORKAROUND #ifdef PKZIP_BUG_WORKAROUND
r = Z_OK; r = Z_OK;
} }
#else #else
inflate_trees_free(*td, z); inflate_trees_free(*td, z);
z->msg = "incomplete literal/length tree"; z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
} }
inflate_trees_free(*tl, z); inflate_trees_free(*tl, z);
...@@ -366,10 +369,8 @@ z_stream *z; /* for zfree function */ ...@@ -366,10 +369,8 @@ z_stream *z; /* for zfree function */
/* build fixed tables only once--keep them here */ /* build fixed tables only once--keep them here */
local int fixed_lock = 0;
local int fixed_built = 0; local int fixed_built = 0;
#define FIXEDH 530 /* number of hufts used by fixed tables */ #define FIXEDH 530 /* number of hufts used by fixed tables */
local uInt fixed_left = FIXEDH;
local inflate_huft fixed_mem[FIXEDH]; local inflate_huft fixed_mem[FIXEDH];
local uInt fixed_bl; local uInt fixed_bl;
local uInt fixed_bd; local uInt fixed_bd;
...@@ -378,24 +379,14 @@ local inflate_huft *fixed_td; ...@@ -378,24 +379,14 @@ local inflate_huft *fixed_td;
local voidpf falloc(q, n, s) local voidpf falloc(q, n, s)
voidpf q; /* opaque pointer (not used) */ voidpf q; /* opaque pointer */
uInt n; /* number of items */ uInt n; /* number of items */
uInt s; /* size of item */ uInt s; /* size of item */
{ {
Assert(s == sizeof(inflate_huft) && n <= fixed_left, Assert(s == sizeof(inflate_huft) && n <= *(intf *)q,
"inflate_trees falloc overflow"); "inflate_trees falloc overflow");
if (q) s++; /* to make some compilers happy */ *(intf *)q -= n+s-s; /* s-s to avoid warning */
fixed_left -= n; return (voidpf)(fixed_mem + *(intf *)q);
return (voidpf)(fixed_mem + fixed_left);
}
local void ffree(q, p)
voidpf q;
voidpf p;
{
Assert(0, "inflate_trees ffree called!");
if (q) q = p; /* to make some compilers happy */
} }
...@@ -405,19 +396,18 @@ uIntf *bd; /* distance desired/actual bit depth */ ...@@ -405,19 +396,18 @@ uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */ inflate_huft * FAR *td; /* distance tree result */
{ {
/* build fixed tables if not built already--lock out other instances */ /* build fixed tables if not already (multiple overlapped executions ok) */
while (++fixed_lock > 1)
fixed_lock--;
if (!fixed_built) if (!fixed_built)
{ {
int k; /* temporary variable */ int k; /* temporary variable */
unsigned c[288]; /* length list for huft_build */ unsigned c[288]; /* length list for huft_build */
z_stream z; /* for falloc function */ z_stream z; /* for falloc function */
int f = FIXEDH; /* number of hufts left in fixed_mem */
/* set up fake z_stream for memory routines */ /* set up fake z_stream for memory routines */
z.zalloc = falloc; z.zalloc = falloc;
z.zfree = ffree; z.zfree = Z_NULL;
z.opaque = Z_NULL; z.opaque = (voidpf)&f;
/* literal table */ /* literal table */
for (k = 0; k < 144; k++) for (k = 0; k < 144; k++)
...@@ -438,9 +428,9 @@ inflate_huft * FAR *td; /* distance tree result */ ...@@ -438,9 +428,9 @@ inflate_huft * FAR *td; /* distance tree result */
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
/* done */ /* done */
Assert(f == 0, "invalid build of fixed tables");
fixed_built = 1; fixed_built = 1;
} }
fixed_lock--;
*bl = fixed_bl; *bl = fixed_bl;
*bd = fixed_bd; *bd = fixed_bd;
*tl = fixed_tl; *tl = fixed_tl;
...@@ -456,10 +446,19 @@ z_stream *z; /* for zfree function */ ...@@ -456,10 +446,19 @@ z_stream *z; /* for zfree function */
list of the tables it made, with the links in a dummy first entry of list of the tables it made, with the links in a dummy first entry of
each table. */ each table. */
{ {
register inflate_huft *p, *q; register inflate_huft *p, *q, *r;
/* Reverse linked list */
p = Z_NULL;
q = t;
while (q != Z_NULL)
{
r = (q - 1)->next;
(q - 1)->next = p;
p = q;
q = r;
}
/* Go through linked list, freeing from the malloced (t[-1]) address. */ /* Go through linked list, freeing from the malloced (t[-1]) address. */
p = t;
while (p != Z_NULL) while (p != Z_NULL)
{ {
q = (--p)->next; q = (--p)->next;
......
/* inftrees.h -- header to use inftrees.c /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
......
/* inflate_util.c -- data and routines common to blocks and codes /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
struct inflate_codes_state {int dummy;}; /* for buggy compilers */ struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* And'ing with mask[n] masks the lower n bits */ /* And'ing with mask[n] masks the lower n bits */
uInt inflate_mask[] = { uInt inflate_mask[17] = {
0x0000, 0x0000,
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
...@@ -43,7 +43,7 @@ int r; ...@@ -43,7 +43,7 @@ int r;
/* update check information */ /* update check information */
if (s->checkfn != Z_NULL) 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 */ /* copy as far as end of window */
zmemcpy(p, q, n); zmemcpy(p, q, n);
...@@ -69,7 +69,7 @@ int r; ...@@ -69,7 +69,7 @@ int r;
/* update check information */ /* update check information */
if (s->checkfn != Z_NULL) if (s->checkfn != Z_NULL)
s->check = (*s->checkfn)(s->check, q, n); z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy */ /* copy */
zmemcpy(p, q, n); zmemcpy(p, q, n);
......
/* infutil.h -- types and macros common to blocks and codes /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -8,11 +8,10 @@ ...@@ -8,11 +8,10 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
/* inflate blocks semi-private state */ #ifndef _INFUTIL_H
struct inflate_blocks_state { #define _INFUTIL_H
/* mode */ typedef enum {
enum {
TYPE, /* get type bits (3, including end bit) */ TYPE, /* get type bits (3, including end bit) */
LENS, /* get lengths for stored */ LENS, /* get lengths for stored */
STORED, /* processing stored block */ STORED, /* processing stored block */
...@@ -23,7 +22,13 @@ struct inflate_blocks_state { ...@@ -23,7 +22,13 @@ struct inflate_blocks_state {
DRY, /* output remaining window bytes */ DRY, /* output remaining window bytes */
DONE, /* finished last block, done */ DONE, /* finished last block, done */
BAD} /* got a data error--stuck here */ 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 */ /* mode dependent information */
union { union {
...@@ -70,17 +75,17 @@ struct inflate_blocks_state { ...@@ -70,17 +75,17 @@ struct inflate_blocks_state {
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
#define DUMPBITS(j) {b>>=(j);k-=(j);} #define DUMPBITS(j) {b>>=(j);k-=(j);}
/* output bytes */ /* output bytes */
#define WAVAIL (q<s->read?s->read-q-1:s->end-q) #define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
#define LOADOUT {q=s->write;m=WAVAIL;} #define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=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 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 NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
#define OUTBYTE(a) {*q++=(Byte)(a);m--;} #define OUTBYTE(a) {*q++=(Byte)(a);m--;}
/* load local pointers */ /* load local pointers */
#define LOAD {LOADIN LOADOUT} #define LOAD {LOADIN LOADOUT}
/* masks for lower bits */ /* masks for lower bits (size given to avoid silly warnings with Visual C++) */
extern uInt inflate_mask[]; extern uInt inflate_mask[17];
/* copy as much as possible from the sliding window to the output area */ /* copy as much as possible from the sliding window to the output area */
extern int inflate_flush OF(( extern int inflate_flush OF((
...@@ -89,3 +94,5 @@ extern int inflate_flush OF(( ...@@ -89,3 +94,5 @@ extern int inflate_flush OF((
int)); int));
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#endif
/* minigzip.c -- simulate gzip using the zlib compression library /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -18,14 +18,13 @@ ...@@ -18,14 +18,13 @@
#include <stdio.h> #include <stdio.h>
#include "zlib.h" #include "zlib.h"
#ifndef __GO32__
extern void exit OF((int));
#endif
extern int unlink OF((const char *));
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h>
#else
extern void exit OF((int));
#endif #endif
extern int unlink OF((const char *));
#if defined(MSDOS) || defined(OS2) || defined(WIN32) #if defined(MSDOS) || defined(OS2) || defined(WIN32)
# include <fcntl.h> # include <fcntl.h>
...@@ -53,7 +52,7 @@ extern int unlink OF((const char *)); ...@@ -53,7 +52,7 @@ extern int unlink OF((const char *));
char *prog; char *prog;
void error OF((char *msg)); void error OF((const char *msg));
void gz_compress OF((FILE *in, gzFile out)); void gz_compress OF((FILE *in, gzFile out));
void gz_uncompress OF((gzFile in, FILE *out)); void gz_uncompress OF((gzFile in, FILE *out));
void file_compress OF((char *file)); void file_compress OF((char *file));
...@@ -64,7 +63,7 @@ int main OF((int argc, char *argv[])); ...@@ -64,7 +63,7 @@ int main OF((int argc, char *argv[]));
* Display error message and exit * Display error message and exit
*/ */
void error(msg) void error(msg)
char *msg; const char *msg;
{ {
fprintf(stderr, "%s: %s\n", prog, msg); fprintf(stderr, "%s: %s\n", prog, msg);
exit(1); exit(1);
...@@ -89,7 +88,7 @@ void gz_compress(in, out) ...@@ -89,7 +88,7 @@ void gz_compress(in, out)
} }
if (len == 0) break; 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); fclose(in);
if (gzclose(out) != Z_OK) error("failed gzclose"); if (gzclose(out) != Z_OK) error("failed gzclose");
...@@ -111,7 +110,9 @@ void gz_uncompress(in, out) ...@@ -111,7 +110,9 @@ void gz_uncompress(in, out)
if (len < 0) error (gzerror(in, &err)); if (len < 0) error (gzerror(in, &err));
if (len == 0) break; 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"); if (fclose(out)) error("failed fclose");
......
/* trees.c -- output deflated data using Huffman coding /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -78,13 +78,12 @@ local uch bl_order[BL_CODES] ...@@ -78,13 +78,12 @@ local uch bl_order[BL_CODES]
/* =========================================================================== /* ===========================================================================
* Local data. These are initialized only once. * Local data. These are initialized only once.
* To do: initialize at compile time to be completely reentrant. ???
*/ */
local ct_data static_ltree[L_CODES+2]; local ct_data static_ltree[L_CODES+2];
/* The static literal tree. Since the bit lengths are imposed, there is no /* 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 * 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 ct_init * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
* below). * below).
*/ */
...@@ -129,7 +128,7 @@ local static_tree_desc static_bl_desc = ...@@ -129,7 +128,7 @@ local static_tree_desc static_bl_desc =
* Local (static) routines in this file. * Local (static) routines in this file.
*/ */
local void ct_static_init OF((void)); local void tr_static_init OF((void));
local void init_block OF((deflate_state *s)); local void init_block OF((deflate_state *s));
local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
...@@ -187,7 +186,7 @@ local void send_bits(s, value, length) ...@@ -187,7 +186,7 @@ local void send_bits(s, value, length)
int value; /* value to send */ int value; /* value to send */
int length; /* number of bits */ int length; /* number of bits */
{ {
Tracev((stderr," l %2d v %4x ", length, value)); Tracevv((stderr," l %2d v %4x ", length, value));
Assert(length > 0 && length <= 15, "invalid length"); Assert(length > 0 && length <= 15, "invalid length");
s->bits_sent += (ulg)length; s->bits_sent += (ulg)length;
...@@ -227,11 +226,13 @@ local void send_bits(s, value, length) ...@@ -227,11 +226,13 @@ local void send_bits(s, value, length)
/* the arguments must not have side effects */ /* the arguments must not have side effects */
/* =========================================================================== /* ===========================================================================
* Initialize the various 'constant' tables. * Initialize the various 'constant' tables. In a multi-threaded environment,
* To do: do this at compile time. * this function may be called by two threads concurrently, but this is
* harmless since both invocations do exactly the same thing.
*/ */
local void ct_static_init() local void tr_static_init()
{ {
static static_init_done = 0;
int n; /* iterates over tree elements */ int n; /* iterates over tree elements */
int bits; /* bit counter */ int bits; /* bit counter */
int length; /* length value */ int length; /* length value */
...@@ -240,6 +241,8 @@ local void ct_static_init() ...@@ -240,6 +241,8 @@ local void ct_static_init()
ush bl_count[MAX_BITS+1]; ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */ /* number of codes at each bit length for an optimal tree */
if (static_init_done) return;
/* Initialize the mapping length (0..255) -> length code (0..28) */ /* Initialize the mapping length (0..255) -> length code (0..28) */
length = 0; length = 0;
for (code = 0; code < LENGTH_CODES-1; code++) { for (code = 0; code < LENGTH_CODES-1; code++) {
...@@ -248,7 +251,7 @@ local void ct_static_init() ...@@ -248,7 +251,7 @@ local void ct_static_init()
length_code[length++] = (uch)code; length_code[length++] = (uch)code;
} }
} }
Assert (length == 256, "ct_static_init: length != 256"); Assert (length == 256, "tr_static_init: length != 256");
/* Note that the length 255 (match length 258) can be represented /* Note that the length 255 (match length 258) can be represented
* in two different ways: code 284 + 5 bits or code 285, so we * in two different ways: code 284 + 5 bits or code 285, so we
* overwrite length_code[255] to use the best encoding: * overwrite length_code[255] to use the best encoding:
...@@ -263,7 +266,7 @@ local void ct_static_init() ...@@ -263,7 +266,7 @@ local void ct_static_init()
dist_code[dist++] = (uch)code; dist_code[dist++] = (uch)code;
} }
} }
Assert (dist == 256, "ct_static_init: dist != 256"); Assert (dist == 256, "tr_static_init: dist != 256");
dist >>= 7; /* from now on, all distances are divided by 128 */ dist >>= 7; /* from now on, all distances are divided by 128 */
for ( ; code < D_CODES; code++) { for ( ; code < D_CODES; code++) {
base_dist[code] = dist << 7; base_dist[code] = dist << 7;
...@@ -271,7 +274,7 @@ local void ct_static_init() ...@@ -271,7 +274,7 @@ local void ct_static_init()
dist_code[256 + dist++] = (uch)code; dist_code[256 + dist++] = (uch)code;
} }
} }
Assert (dist == 256, "ct_static_init: 256+dist != 512"); Assert (dist == 256, "tr_static_init: 256+dist != 512");
/* Construct the codes of the static literal tree */ /* Construct the codes of the static literal tree */
for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
...@@ -289,19 +292,18 @@ local void ct_static_init() ...@@ -289,19 +292,18 @@ local void ct_static_init()
/* The static distance tree is trivial: */ /* The static distance tree is trivial: */
for (n = 0; n < D_CODES; n++) { for (n = 0; n < D_CODES; n++) {
static_dtree[n].Len = 5; 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;
} }
/* =========================================================================== /* ===========================================================================
* Initialize the tree data structures for a new zlib stream. * Initialize the tree data structures for a new zlib stream.
*/ */
void ct_init(s) void _tr_init(s)
deflate_state *s; deflate_state *s;
{ {
if (static_dtree[0].Len == 0) { tr_static_init();
ct_static_init(); /* To do: at compile time */
}
s->compressed_len = 0L; s->compressed_len = 0L;
...@@ -523,7 +525,7 @@ local void gen_codes (tree, max_code, bl_count) ...@@ -523,7 +525,7 @@ local void gen_codes (tree, max_code, bl_count)
/* Now reverse the bits */ /* Now reverse the bits */
tree[n].Code = bi_reverse(next_code[len]++, len); tree[n].Code = bi_reverse(next_code[len]++, len);
Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
} }
} }
...@@ -783,14 +785,14 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) ...@@ -783,14 +785,14 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
/* =========================================================================== /* ===========================================================================
* Send a stored block * Send a stored block
*/ */
void ct_stored_block(s, buf, stored_len, eof) void _tr_stored_block(s, buf, stored_len, eof)
deflate_state *s; deflate_state *s;
charf *buf; /* input block */ charf *buf; /* input block */
ulg stored_len; /* length of input block */ ulg stored_len; /* length of input block */
int eof; /* true if this is the last block for a file */ int eof; /* true if this is the last block for a file */
{ {
send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ 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; s->compressed_len += (stored_len + 4) << 3;
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
...@@ -799,12 +801,15 @@ void ct_stored_block(s, buf, stored_len, eof) ...@@ -799,12 +801,15 @@ void ct_stored_block(s, buf, stored_len, eof)
/* =========================================================================== /* ===========================================================================
* Send one empty static block to give enough lookahead for inflate. * Send one empty static block to give enough lookahead for inflate.
* This takes 10 bits, of which 7 may remain in the bit buffer. * This takes 10 bits, of which 7 may remain in the bit buffer.
* The current inflate code requires 9 bits of lookahead. If the EOB * The current inflate code requires 9 bits of lookahead. If the
* code for the previous block was coded on 5 bits or less, inflate * last two codes for the previous block (real code plus EOB) were coded
* may have only 5+3 bits of lookahead to decode this EOB. * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
* (There are no problems if the previous block is stored or fixed.) * the last real code. In this case we send two empty static blocks instead
* of one. (There are no problems if the previous block is stored or fixed.)
* To simplify the code, we assume the worst case of last real code encoded
* on one bit only.
*/ */
void ct_align(s) void _tr_align(s)
deflate_state *s; deflate_state *s;
{ {
send_bits(s, STATIC_TREES<<1, 3); send_bits(s, STATIC_TREES<<1, 3);
...@@ -812,10 +817,11 @@ void ct_align(s) ...@@ -812,10 +817,11 @@ void ct_align(s)
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
bi_flush(s); bi_flush(s);
/* Of the 10 bits for the empty block, we have already sent /* Of the 10 bits for the empty block, we have already sent
* (10 - bi_valid) bits. The lookahead for the EOB of the previous * (10 - bi_valid) bits. The lookahead for the last real code (before
* block was thus its length plus what we have just sent. * the EOB of the previous block) was thus at least one plus the length
* of the EOB plus what we have just sent of the empty static block.
*/ */
if (s->last_eob_len + 10 - s->bi_valid < 9) { if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
send_bits(s, STATIC_TREES<<1, 3); send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree); send_code(s, END_BLOCK, static_ltree);
s->compressed_len += 10L; s->compressed_len += 10L;
...@@ -829,44 +835,52 @@ void ct_align(s) ...@@ -829,44 +835,52 @@ void ct_align(s)
* trees or store, and output the encoded block to the zip file. This function * trees or store, and output the encoded block to the zip file. This function
* returns the total compressed length for the file so far. * returns the total compressed length for the file so far.
*/ */
ulg ct_flush_block(s, buf, stored_len, eof) ulg _tr_flush_block(s, buf, stored_len, eof)
deflate_state *s; deflate_state *s;
charf *buf; /* input block, or NULL if too old */ charf *buf; /* input block, or NULL if too old */
ulg stored_len; /* length of input block */ ulg stored_len; /* length of input block */
int eof; /* true if this is the last block for a file */ int eof; /* true if this is the last block for a file */
{ {
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ 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 */
/* Check if the file is ascii or binary */ /* Build the Huffman trees unless a stored block is forced */
if (s->data_type == UNKNOWN) set_data_type(s); if (s->level > 0) {
/* Construct the literal and distance trees */ /* Check if the file is ascii or binary */
build_tree(s, (tree_desc *)(&(s->l_desc))); if (s->data_type == Z_UNKNOWN) set_data_type(s);
Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
s->static_len));
build_tree(s, (tree_desc *)(&(s->d_desc))); /* Construct the literal and distance trees */
Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, build_tree(s, (tree_desc *)(&(s->l_desc)));
s->static_len)); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
/* At this point, opt_len and static_len are the total bit lengths of s->static_len));
* the compressed block data, excluding the tree representations.
*/
/* Build the bit length tree for the above two trees, and get the index build_tree(s, (tree_desc *)(&(s->d_desc)));
* in bl_order of the last bit length code to send. Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
*/ s->static_len));
max_blindex = build_bl_tree(s); /* At this point, opt_len and static_len are the total bit lengths of
* the compressed block data, excluding the tree representations.
*/
/* Determine the best encoding. Compute first the block length in bytes */ /* Build the bit length tree for the above two trees, and get the index
opt_lenb = (s->opt_len+3+7)>>3; * in bl_order of the last bit length code to send.
static_lenb = (s->static_len+3+7)>>3; */
max_blindex = build_bl_tree(s);
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", /* Determine the best encoding. Compute first the block length in bytes*/
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, opt_lenb = (s->opt_len+3+7)>>3;
s->last_lit)); static_lenb = (s->static_len+3+7)>>3;
if (static_lenb <= opt_lenb) opt_lenb = static_lenb; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
s->last_lit));
if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
} else {
Assert(buf != (char*)0, "lost buf");
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
}
/* If compression failed and this is the first and last block, /* If compression failed and this is the first and last block,
* and if the .zip file can be seeked (to rewrite the local header), * and if the .zip file can be seeked (to rewrite the local header),
...@@ -874,7 +888,7 @@ ulg ct_flush_block(s, buf, stored_len, eof) ...@@ -874,7 +888,7 @@ ulg ct_flush_block(s, buf, stored_len, eof)
*/ */
#ifdef STORED_FILE_OK #ifdef STORED_FILE_OK
# ifdef FORCE_STORED_FILE # ifdef FORCE_STORED_FILE
if (eof && compressed_len == 0L) { /* force stored file */ if (eof && s->compressed_len == 0L) { /* force stored file */
# else # else
if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
# endif # endif
...@@ -899,7 +913,7 @@ ulg ct_flush_block(s, buf, stored_len, eof) ...@@ -899,7 +913,7 @@ ulg ct_flush_block(s, buf, stored_len, eof)
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
* transform a block into a stored block. * transform a block into a stored block.
*/ */
ct_stored_block(s, buf, stored_len, eof); _tr_stored_block(s, buf, stored_len, eof);
#ifdef FORCE_STATIC #ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */ } else if (static_lenb >= 0) { /* force static trees */
...@@ -933,10 +947,10 @@ ulg ct_flush_block(s, buf, stored_len, eof) ...@@ -933,10 +947,10 @@ ulg ct_flush_block(s, buf, stored_len, eof)
* Save the match info and tally the frequency counts. Return true if * Save the match info and tally the frequency counts. Return true if
* the current block must be flushed. * the current block must be flushed.
*/ */
int ct_tally (s, dist, lc) int _tr_tally (s, dist, lc)
deflate_state *s; deflate_state *s;
int dist; /* distance of matched string */ unsigned dist; /* distance of matched string */
int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
{ {
s->d_buf[s->last_lit] = (ush)dist; s->d_buf[s->last_lit] = (ush)dist;
s->l_buf[s->last_lit++] = (uch)lc; s->l_buf[s->last_lit++] = (uch)lc;
...@@ -949,7 +963,7 @@ int ct_tally (s, dist, lc) ...@@ -949,7 +963,7 @@ int ct_tally (s, dist, lc)
dist--; /* dist = match distance - 1 */ dist--; /* dist = match distance - 1 */
Assert((ush)dist < (ush)MAX_DIST(s) && Assert((ush)dist < (ush)MAX_DIST(s) &&
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
(ush)d_code(dist) < (ush)D_CODES, "ct_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_ltree[length_code[lc]+LITERALS+1].Freq++;
s->dyn_dtree[d_code(dist)].Freq++; s->dyn_dtree[d_code(dist)].Freq++;
...@@ -959,7 +973,7 @@ int ct_tally (s, dist, lc) ...@@ -959,7 +973,7 @@ int ct_tally (s, dist, lc)
if (s->level > 2 && (s->last_lit & 0xfff) == 0) { if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
/* Compute an upper bound for the compressed length */ /* Compute an upper bound for the compressed length */
ulg out_length = (ulg)s->last_lit*8L; ulg out_length = (ulg)s->last_lit*8L;
ulg in_length = (ulg)s->strstart - s->block_start; ulg in_length = (ulg)((long)s->strstart - s->block_start);
int dcode; int dcode;
for (dcode = 0; dcode < D_CODES; dcode++) { for (dcode = 0; dcode < D_CODES; dcode++) {
out_length += (ulg)s->dyn_dtree[dcode].Freq * out_length += (ulg)s->dyn_dtree[dcode].Freq *
...@@ -1043,7 +1057,7 @@ local void set_data_type(s) ...@@ -1043,7 +1057,7 @@ local void set_data_type(s)
while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
while (n < 128) ascii_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; 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);
} }
/* =========================================================================== /* ===========================================================================
......
/* uncompr.c -- decompress a memory buffer /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -25,13 +25,13 @@ ...@@ -25,13 +25,13 @@
int uncompress (dest, destLen, source, sourceLen) int uncompress (dest, destLen, source, sourceLen)
Bytef *dest; Bytef *dest;
uLongf *destLen; uLongf *destLen;
Bytef *source; const Bytef *source;
uLong sourceLen; uLong sourceLen;
{ {
z_stream stream; z_stream stream;
int err; int err;
stream.next_in = source; stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen; stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */ /* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
......
/* zconf.h -- configuration of the zlib compression library /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -9,22 +9,55 @@ ...@@ -9,22 +9,55 @@
#define _ZCONF_H #define _ZCONF_H
/* /*
The library does not install any signal handler. It is recommended to * People prefering a unique prefix for all types and library functions
add at least a handler for SIGSEGV when decompressing; the library checks * should compile with -DZ_PREFIX
the consistency of the input data whenever possible but may go nuts
for some forms of corrupted input.
*/ */
#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 deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define inflateInit2_ z_inflateInit2_
# 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)
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more # define WIN32
* than 64k bytes at a time (needed on systems with 16-bit int). #endif
*/ #if (defined(__GNUC__) || defined(WIN32)) && !defined(__32BIT__)
#if defined(_GNUC__) && !defined(__32BIT__)
# define __32BIT__ # define __32BIT__
#endif #endif
#if defined(__MSDOS__) && !defined(MSDOS) #if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS # define MSDOS
#endif #endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#if defined(MSDOS) && !defined(__32BIT__) #if defined(MSDOS) && !defined(__32BIT__)
# define MAXSEG_64K # define MAXSEG_64K
#endif #endif
...@@ -32,20 +65,20 @@ ...@@ -32,20 +65,20 @@
# define UNALIGNED_OK # define UNALIGNED_OK
#endif #endif
#ifndef STDC #if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) # define STDC
# define STDC #endif
# endif #if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
# define STDC
#endif #endif
#ifndef STDC #if !defined(STDC) && !defined(const)
# ifndef const # define const
# define const
# endif
#endif #endif
#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ #ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
# include <unix.h> # include <unix.h>
# define Byte _Byte /* Byte already used on Mac */
#endif #endif
/* Maximum value for memLevel in deflateInit2 */ /* Maximum value for memLevel in deflateInit2 */
...@@ -92,6 +125,7 @@ ...@@ -92,6 +125,7 @@
* just define FAR to be empty. * just define FAR to be empty.
*/ */
#if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ #if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER # ifdef _MSC_VER
# define FAR __far # define FAR __far
# else # else
...@@ -99,20 +133,26 @@ ...@@ -99,20 +133,26 @@
# endif # endif
#endif #endif
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) #if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
# define FAR __far /* completely untested, just a best guess */ # define SMALL_MEDIUM
# define FAR __far
#endif #endif
#ifndef FAR #ifndef FAR
# define FAR # define FAR
#endif #endif
/* The Watcom compiler defines M_I86SM and __SMALL__ even in 32 bit mode */
#if defined(__WATCOMC__) && defined(__386__)
# undef FAR
# undef SMALL_MEDIUM
#endif
typedef unsigned char Byte; /* 8 bits */ typedef unsigned char Byte; /* 8 bits */
typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */ typedef unsigned long uLong; /* 32 bits or more */
typedef Byte FAR Bytef; typedef Byte FAR Bytef;
typedef char FAR charf; typedef char FAR charf;
typedef int FAR intf; typedef int FAR intf;
typedef uInt FAR uIntf; typedef uInt FAR uIntf;
typedef uLong FAR uLongf; typedef uLong FAR uLongf;
#ifdef STDC #ifdef STDC
......
此差异已折叠。
/* zutil.c -- target dependent utility functions for the compression library /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -11,20 +11,22 @@ ...@@ -11,20 +11,22 @@
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#ifndef __GO32__ #ifndef STDC
extern void exit OF((int)); extern void exit OF((int));
#endif #endif
char *zlib_version = ZLIB_VERSION; const char *zlib_version = ZLIB_VERSION;
char *z_errmsg[] = { const char *z_errmsg[10] = {
"stream end", /* Z_STREAM_END 1 */ "need dictionary", /* Z_NEED_DICT 2 */
"", /* Z_OK 0 */ "stream end", /* Z_STREAM_END 1 */
"file error", /* Z_ERRNO (-1) */ "", /* Z_OK 0 */
"stream error", /* Z_STREAM_ERROR (-2) */ "file error", /* Z_ERRNO (-1) */
"data error", /* Z_DATA_ERROR (-3) */ "stream error", /* Z_STREAM_ERROR (-2) */
"insufficient memory", /* Z_MEM_ERROR (-4) */ "data error", /* Z_DATA_ERROR (-3) */
"buffer error", /* Z_BUF_ERROR (-5) */ "insufficient memory", /* Z_MEM_ERROR (-4) */
"buffer error", /* Z_BUF_ERROR (-5) */
"incompatible version",/* Z_VERSION_ERROR (-6) */
""}; ""};
...@@ -59,9 +61,10 @@ void zmemzero(dest, len) ...@@ -59,9 +61,10 @@ void zmemzero(dest, len)
} }
#endif #endif
#if defined( __TURBOC__) && !defined(__SMALL__) && !defined(__MEDIUM__) #ifdef __TURBOC__
/* Small and medium model are for now limited to near allocation with #if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
* reduced MAX_WBITS and MAX_MEM_LEVEL /* 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 # define MY_ZCALLOC
...@@ -94,7 +97,10 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) ...@@ -94,7 +97,10 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
voidpf buf = opaque; /* just to make some compilers happy */ voidpf buf = opaque; /* just to make some compilers happy */
ulg bsize = (ulg)items*size; ulg bsize = (ulg)items*size;
if (bsize < 65536L) { /* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
if (bsize < 65520L) {
buf = farmalloc(bsize); buf = farmalloc(bsize);
if (*(ush*)&buf != 0) return buf; if (*(ush*)&buf != 0) return buf;
} else { } else {
...@@ -131,9 +137,11 @@ void zcfree (voidpf opaque, voidpf ptr) ...@@ -131,9 +137,11 @@ void zcfree (voidpf opaque, voidpf ptr)
ptr = opaque; /* just to make some compilers happy */ ptr = opaque; /* just to make some compilers happy */
z_error("zcfree: ptr not found"); z_error("zcfree: ptr not found");
} }
#endif
#endif /* __TURBOC__ */ #endif /* __TURBOC__ */
#if defined(M_I86SM)||defined(M_I86MM)||defined(M_I86CM)||defined(M_I86LM)
#if defined(M_I86) && !(defined(__WATCOMC__) && defined(__386__))
/* Microsoft C */ /* Microsoft C */
# define MY_ZCALLOC # define MY_ZCALLOC
...@@ -160,7 +168,7 @@ void zcfree (voidpf opaque, voidpf ptr) ...@@ -160,7 +168,7 @@ void zcfree (voidpf opaque, voidpf ptr)
#ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef __GO32__ #ifndef STDC
extern voidp calloc OF((uInt items, uInt size)); extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr)); extern void free OF((voidpf ptr));
#endif #endif
...@@ -170,6 +178,7 @@ voidpf zcalloc (opaque, items, size) ...@@ -170,6 +178,7 @@ voidpf zcalloc (opaque, items, size)
unsigned items; unsigned items;
unsigned size; unsigned size;
{ {
if (opaque) opaque = 0; /* to make compiler happy */
return (voidpf)calloc(items, size); return (voidpf)calloc(items, size);
} }
...@@ -177,6 +186,7 @@ void zcfree (opaque, ptr) ...@@ -177,6 +186,7 @@ void zcfree (opaque, ptr)
voidpf opaque; voidpf opaque;
voidpf ptr; voidpf ptr;
{ {
if (opaque) opaque = 0; /* to make compiler happy */
free(ptr); free(ptr);
} }
......
/* zutil.h -- internal interface and configuration of the compression library /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include "zlib.h" #include "zlib.h"
#if defined(MSDOS) || defined(VMS) #if defined(MSDOS) || defined(VMS) || defined(CRAY) || defined(WIN32)
# include <stddef.h> # include <stddef.h>
# include <errno.h> # include <errno.h>
#else #else
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#endif #endif
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h>
#endif #endif
#ifndef local #ifndef local
...@@ -36,15 +37,17 @@ typedef unsigned short ush; ...@@ -36,15 +37,17 @@ typedef unsigned short ush;
typedef ush FAR ushf; typedef ush FAR ushf;
typedef unsigned long ulg; 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 */ /* To be used only when the state is known to be valid */
/* common constants */ /* common constants */
#define DEFLATED 8
#ifndef DEF_WBITS #ifndef DEF_WBITS
# define DEF_WBITS MAX_WBITS # define DEF_WBITS MAX_WBITS
#endif #endif
...@@ -66,6 +69,8 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ ...@@ -66,6 +69,8 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
#define MAX_MATCH 258 #define MAX_MATCH 258
/* The minimum and maximum match lengths */ /* The minimum and maximum match lengths */
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
/* target dependencies */ /* target dependencies */
#ifdef MSDOS #ifdef MSDOS
...@@ -81,7 +86,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ ...@@ -81,7 +86,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
# define OS_CODE 0x06 # define OS_CODE 0x06
#endif #endif
#ifdef WIN32 /* Windows NT */ #ifdef WIN32 /* Window 95 & Windows NT */
# define OS_CODE 0x0b # define OS_CODE 0x0b
#endif #endif
...@@ -143,11 +148,13 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ ...@@ -143,11 +148,13 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
# define HAVE_MEMCPY # define HAVE_MEMCPY
#endif #endif
#ifdef HAVE_MEMCPY #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 zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
# define zmemzero(dest, len) _fmemset(dest, 0, len) # define zmemzero(dest, len) _fmemset(dest, 0, len)
# else # else
# define zmemcpy memcpy # define zmemcpy memcpy
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len) # define zmemzero(dest, len) memset(dest, 0, len)
# endif # endif
#else #else
...@@ -177,7 +184,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */ ...@@ -177,7 +184,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
#endif #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)); extern void z_error OF((char *m));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册