zlib 0.99
This commit is contained in:
parent
25e5325501
commit
56bcb184fa
61
ChangeLog
61
ChangeLog
@ -1,6 +1,67 @@
|
||||
|
||||
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)
|
||||
- fix MSDOS small and medium model (now easier to adapt to any compiler)
|
||||
- inlined send_bits
|
||||
|
@ -4,7 +4,7 @@ $!
|
||||
$! Look for the compiler used
|
||||
$!
|
||||
$ ccopt = ""
|
||||
$ if f$trnlnm("HW_MODEL").ge.1024
|
||||
$ if f$getsyi("HW_MODEL").ge.1024
|
||||
$ then
|
||||
$ ccopt = "/prefix=all"+ccopt
|
||||
$ comp = "__decc__=1"
|
||||
|
119
Makefile
119
Makefile
@ -1,72 +1,129 @@
|
||||
# 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
|
||||
|
||||
CC=cc
|
||||
CFLAGS=-O
|
||||
#use -O3 for gcc to take advantage of inlining
|
||||
#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
#CFLAGS=-g -DDEBUG
|
||||
LDFLAGS=-L. -lz
|
||||
# To compile and test, type:
|
||||
# ./configure; make test
|
||||
# The call of configure is optional if you don't have special requirements
|
||||
|
||||
# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
|
||||
# make install
|
||||
# To install in $HOME instead of /usr/local, use:
|
||||
# make install prefix=$HOME
|
||||
|
||||
CC=cc
|
||||
|
||||
CFLAGS=-O
|
||||
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
|
||||
#CFLAGS=-g -DDEBUG
|
||||
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
|
||||
# -Wstrict-prototypes -Wmissing-prototypes
|
||||
|
||||
LDFLAGS=-L. -lz
|
||||
LDSHARED=$(CC)
|
||||
|
||||
VER=1.0
|
||||
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
|
||||
|
||||
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)
|
||||
ar rc $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
$(AR) $@ $(OBJS)
|
||||
-@ ($(RANLIB) $@ || true) 2>/dev/null
|
||||
|
||||
example: example.o libz.a
|
||||
libz.so.$(VER): $(OBJS)
|
||||
$(LDSHARED) -o $@ $(OBJS)
|
||||
rm -f libz.so; ln -s $@ libz.so
|
||||
|
||||
example: example.o $(LIBS)
|
||||
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
|
||||
|
||||
minigzip: minigzip.o libz.a
|
||||
minigzip: minigzip.o $(LIBS)
|
||||
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
|
||||
|
||||
install: $(LIBS)
|
||||
-@if [ ! $(prefix)/include ]; then mkdir $(prefix)/include; fi
|
||||
-@if [ ! $(exec_prefix)/lib ]; then mkdir $(exec_prefix)/lib; fi
|
||||
cp zlib.h zconf.h $(prefix)/include
|
||||
chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
|
||||
cp $(LIBS) $(exec_prefix)/lib
|
||||
cd $(exec_prefix)/lib; chmod 644 $(LIBS)
|
||||
-@(cd $(exec_prefix)/lib; $(RANLIB) libz.a || true) >/dev/null 2>&1
|
||||
cd $(exec_prefix)/lib; if test -f libz.so.$(VER); then \
|
||||
ln -s libz.so.$(VER) libz.so; \
|
||||
fi
|
||||
# The ranlib in install is needed on NeXTSTEP which checks file times
|
||||
|
||||
uninstall:
|
||||
cd $(exec_prefix)/lib; rm -f $(LIBS); \
|
||||
if test -f libz.so; then \
|
||||
v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p'<$(prefix)/include/zlib.h`;\
|
||||
rm -f libz.so.$$v libz.so; \
|
||||
fi
|
||||
cd $(prefix)/include; rm -f zlib.h zconf.h
|
||||
|
||||
clean:
|
||||
rm -f *.o example minigzip libz.a foo.gz
|
||||
rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
|
||||
|
||||
zip:
|
||||
zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
|
||||
descrip.mms *.[ch]
|
||||
mv Makefile Makefile~; cp -p Makefile.in Makefile
|
||||
v=`sed -n -e 's/\./-/' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
|
||||
zip -ul9 zlib-$$v $(DISTFILES)
|
||||
mv Makefile~ Makefile
|
||||
|
||||
tgz:
|
||||
cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
|
||||
zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
|
||||
dist:
|
||||
mv Makefile Makefile~; cp -p Makefile.in Makefile
|
||||
d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
|
||||
rm -f $$d.tar.gz; \
|
||||
if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
|
||||
files=""; \
|
||||
for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
|
||||
cd ..; \
|
||||
GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
|
||||
if test ! -d $$d; then rm -f $$d; fi
|
||||
mv Makefile~ Makefile
|
||||
|
||||
tags:
|
||||
etags *.[ch]
|
||||
|
||||
depend:
|
||||
makedepend -- $(CFLAGS) -- *.[ch]
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
adler32.o: zutil.h zlib.h zconf.h
|
||||
adler32.o: zlib.h zconf.h
|
||||
compress.o: zlib.h zconf.h
|
||||
crc32.o: zutil.h zlib.h zconf.h
|
||||
crc32.o: zlib.h zconf.h
|
||||
deflate.o: deflate.h zutil.h zlib.h zconf.h
|
||||
example.o: zlib.h zconf.h
|
||||
gzio.o: zutil.h zlib.h zconf.h
|
||||
infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
|
||||
infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
|
||||
inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
|
||||
infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
|
||||
infcodes.o: zutil.h zlib.h zconf.h
|
||||
infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
|
||||
inffast.o: zutil.h zlib.h zconf.h inftrees.h
|
||||
inffast.o: infblock.h infcodes.h infutil.h inffast.h
|
||||
inflate.o: zutil.h zlib.h zconf.h infblock.h
|
||||
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
|
||||
infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h
|
||||
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
|
||||
|
@ -18,7 +18,7 @@ CFLAGS=-O2 -Z $(MODEL)
|
||||
CC=bcc
|
||||
LD=bcc
|
||||
LIB=tlib
|
||||
# replace bcc with tcc for Turbo C++ 1.0
|
||||
# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
|
||||
LDFLAGS=$(MODEL)
|
||||
O=.obj
|
||||
|
||||
|
130
Makefile.in
Normal file
130
Makefile.in
Normal file
@ -0,0 +1,130 @@
|
||||
# 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
|
75
Makefile.qnx
75
Makefile.qnx
@ -1,75 +0,0 @@
|
||||
# Makefile for zlib
|
||||
# Copyright (C) 1995 Jean-loup Gailly.
|
||||
# For conditions of distribution and use, see copyright notice in zlib.h
|
||||
|
||||
# Modified slightly for QNX by Chris Herborth (chrish@qnx.com)
|
||||
|
||||
CC=cc
|
||||
CFLAGS=-4 -O -Q
|
||||
#use -O3 for gcc to take advantage of inlining
|
||||
#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
#CFLAGS=-g -DDEBUG
|
||||
LDFLAGS=-L. -lz
|
||||
|
||||
#RANLIB=ranlib
|
||||
|
||||
prefix=/usr/local
|
||||
|
||||
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
|
||||
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
|
||||
|
||||
TEST_OBJS = example.o minigzip.o
|
||||
|
||||
all: example minigzip
|
||||
|
||||
test: all
|
||||
./example
|
||||
echo hello world | ./minigzip | ./minigzip -d
|
||||
|
||||
install: zlib.lib
|
||||
-@mkdir $(prefix)/include
|
||||
-@mkdir $(prefix)/lib
|
||||
cp zlib.h zconf.h $(prefix)/include
|
||||
chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
|
||||
cp zlib.lib $(prefix)/lib
|
||||
chmod 644 $(prefix)/lib/zlib.lib
|
||||
|
||||
zlib.lib: $(OBJS)
|
||||
cc -A $@ $(OBJS)
|
||||
# ar rc $@ $(OBJS)
|
||||
# $(RANLIB) $@
|
||||
|
||||
example: example.o zlib.lib
|
||||
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
|
||||
|
||||
minigzip: minigzip.o zlib.lib
|
||||
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o example minigzip zlib.lib foo.gz
|
||||
|
||||
zip:
|
||||
zip -ul9 zlib README ChangeLog Makefile Makefile.??? Makefile.?? *.[ch]
|
||||
|
||||
tgz:
|
||||
cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
|
||||
zlib/Makefile.??? zlib/Makefile.?? zlib/*.[ch]
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
adler32.o: zutil.h zlib.h zconf.h
|
||||
compress.o: zlib.h zconf.h
|
||||
crc32.o: zutil.h zlib.h zconf.h
|
||||
deflate.o: deflate.h zutil.h zlib.h zconf.h
|
||||
example.o: zlib.h zconf.h
|
||||
gzio.o: zutil.h zlib.h zconf.h
|
||||
infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
|
||||
infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
|
||||
inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
|
||||
inflate.o: zutil.h zlib.h zconf.h infblock.h
|
||||
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
|
||||
infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h
|
||||
minigzip.o: zlib.h zconf.h
|
||||
trees.o: deflate.h zutil.h zlib.h zconf.h
|
||||
uncompr.o: zlib.h zconf.h
|
||||
zutil.o: zutil.h zlib.h zconf.h
|
91
README
91
README
@ -1,40 +1,75 @@
|
||||
zlib 0.95 is a beta version of a general purpose compression library.
|
||||
This should be the last version before the first official
|
||||
version (1.0), so please test it now. (At least compile and run it with
|
||||
"make test"). This version has no known bugs.
|
||||
|
||||
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.
|
||||
zlib 1.0 is a general purpose data compression library. All the code
|
||||
is reentrant (thread safe). The data format used by the zlib library
|
||||
is described in the files zlib-3.3.doc, deflate-1.3.doc and
|
||||
gzip-4.3.doc, available in ftp://ftp.uu.net/pub/archiving/zip/doc/
|
||||
|
||||
All functions of the compression library are documented in the file
|
||||
zlib.h. A usage example of the library is given in the file example.c
|
||||
which also tests that the library is working correctly. Another
|
||||
example is given in the file minigzip.c.
|
||||
example is given in the file minigzip.c. The compression library itself
|
||||
is composed of all source files except example.c and minigzip.c.
|
||||
|
||||
To compile all files and run the test program, just type: make test
|
||||
(For MSDOS, use one of the special makefiles such as Makefile.msc;
|
||||
for VMS, use Make_vms.com or descrip.mms.)
|
||||
To install the zlib library (libz.a) in /usr/local/lib, type: make install
|
||||
To install in a different directory, use for example:
|
||||
make install prefix=$HOME
|
||||
This will install in $HOME/lib instead of /usr/local/lib.
|
||||
To compile all files and run the test program, follow the instructions
|
||||
given at the top of Makefile. In short "make test; make install"
|
||||
should work for most machines. For MSDOS, use one of the special
|
||||
makefiles such as Makefile.msc; for VMS, use Make_vms.com or descrip.mms.
|
||||
|
||||
The changes made in version 0.95 are documented in the file ChangeLog.
|
||||
The main changes since 0.94 are:
|
||||
- fix MSDOS small and medium model (now easier to adapt to any compiler)
|
||||
- inlined send_bits
|
||||
- fix the final (:-) bug for deflate with flush (output was correct but
|
||||
not completely flushed in rare occasions).
|
||||
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.
|
||||
|
||||
For MSDOS, the small and medium models have been tested only with Microsoft C.
|
||||
(This should now work for Borland C also, but I don't have a recent Borland
|
||||
compiler to test with.) The small model was tested with Turbo C but only with
|
||||
reduced performance to avoid any far allocation; it was tested with
|
||||
-DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
|
||||
The changes made in version 1.0 are documented in the file ChangeLog.
|
||||
The main changes since 0.95 are:
|
||||
- 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
|
||||
- fixes for 64-bit systems (needed for Alpha and Cray)
|
||||
- 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
|
||||
- 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:
|
||||
|
||||
(C) 1995 Jean-loup Gailly and Mark Adler
|
||||
- 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
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
/* ========================================================================= */
|
||||
uLong adler32(adler, buf, len)
|
||||
uLong adler;
|
||||
Bytef *buf;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
unsigned long s1 = adler & 0xffff;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
@ -22,13 +22,13 @@
|
||||
int compress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
Bytef *source;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = source;
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
@ -39,6 +39,7 @@ int compress (dest, destLen, source, sourceLen)
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
stream.opaque = (voidpf)0;
|
||||
|
||||
err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
|
||||
if (err != Z_OK) return err;
|
||||
|
81
configure
vendored
Executable file
81
configure
vendored
Executable file
@ -0,0 +1,81 @@
|
||||
#!/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
|
62
crc32.c
62
crc32.c
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
@ -10,23 +10,53 @@
|
||||
#define local static
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
/* =========================================================================
|
||||
* Make the crc table. This function is needed only if you want to compute
|
||||
* the table dynamically.
|
||||
*/
|
||||
local int crc_table_empty = 1;
|
||||
local uLong crc_table[256];
|
||||
|
||||
local int crc_table_empty = 1;
|
||||
local uLongf crc_table[256];
|
||||
local void make_crc_table OF((void));
|
||||
|
||||
/*
|
||||
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
|
||||
|
||||
Polynomials over GF(2) are represented in binary, one bit per coefficient,
|
||||
with the lowest powers in the most significant bit. Then adding polynomials
|
||||
is just exclusive-or, and multiplying a polynomial by x is a right shift by
|
||||
one. If we call the above polynomial p, and represent a byte as the
|
||||
polynomial q, also with the lowest power in the most significant bit (so the
|
||||
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
|
||||
where a mod b means the remainder after dividing a by b.
|
||||
|
||||
This calculation is done using the shift-register method of multiplying and
|
||||
taking the remainder. The register is initialized to zero, and for each
|
||||
incoming bit, x^32 is added mod p to the register if the bit is a one (where
|
||||
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
|
||||
x (which is shifting right by one and adding x^32 mod p if the bit shifted
|
||||
out is a one). We start with the highest power (least significant bit) of
|
||||
q and repeat for all eight bits of q.
|
||||
|
||||
The table is simply the CRC of all possible eight bit values. This is all
|
||||
the information needed to generate CRC's on data a byte at a time for all
|
||||
combinations of CRC register values and incoming bytes.
|
||||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
uLong c;
|
||||
int n, k;
|
||||
uLong poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320L) */
|
||||
poly = 0L;
|
||||
for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
|
||||
poly |= 1L << (31 - p[n]);
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
{
|
||||
c = (uLong)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1;
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[n] = c;
|
||||
}
|
||||
crc_table_empty = 0;
|
||||
@ -35,7 +65,7 @@ local void 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,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
@ -91,6 +121,18 @@ local uLong crc_table[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
uLongf *get_crc_table()
|
||||
{
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty) make_crc_table();
|
||||
#endif
|
||||
return (uLongf *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||||
#define DO2(buf) DO1(buf); DO1(buf);
|
||||
#define DO4(buf) DO2(buf); DO2(buf);
|
||||
@ -99,7 +141,7 @@ local uLong crc_table[] = {
|
||||
/* ========================================================================= */
|
||||
uLong crc32(crc, buf, len)
|
||||
uLong crc;
|
||||
Bytef *buf;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
if (buf == Z_NULL) return 0L;
|
||||
|
425
deflate.c
425
deflate.c
@ -1,5 +1,5 @@
|
||||
/* deflate.c -- compress data using the deflation algorithm
|
||||
* Copyright (C) 1995 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-1996 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
|
||||
#include "deflate.h"
|
||||
|
||||
char copyright[] = " deflate Copyright 1995 Jean-loup Gailly ";
|
||||
char deflate_copyright[] = " deflate 1.0 Copyright 1995-1996 Jean-loup Gailly ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@ -59,61 +59,11 @@ char copyright[] = " deflate Copyright 1995 Jean-loup Gailly ";
|
||||
copyright string in the executable of your product.
|
||||
*/
|
||||
|
||||
#define NIL 0
|
||||
/* Tail of hash chains */
|
||||
|
||||
#ifndef TOO_FAR
|
||||
# define TOO_FAR 4096
|
||||
#endif
|
||||
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
/* Values for max_lazy_match, good_match and max_chain_length, depending on
|
||||
* the desired pack level (0..9). The values given below have been tuned to
|
||||
* exclude worst case performance for pathological files. Better values may be
|
||||
* found for specific files.
|
||||
*/
|
||||
|
||||
typedef struct config_s {
|
||||
ush good_length; /* reduce lazy search above this match length */
|
||||
ush max_lazy; /* do not perform lazy search above this match length */
|
||||
ush nice_length; /* quit search above this match length */
|
||||
ush max_chain;
|
||||
} config;
|
||||
|
||||
local config configuration_table[10] = {
|
||||
/* good lazy nice chain */
|
||||
/* 0 */ {0, 0, 0, 0}, /* store only */
|
||||
/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */
|
||||
/* 2 */ {4, 5, 16, 8},
|
||||
/* 3 */ {4, 6, 32, 32},
|
||||
|
||||
/* 4 */ {4, 4, 16, 16}, /* lazy matches */
|
||||
/* 5 */ {8, 16, 32, 32},
|
||||
/* 6 */ {8, 16, 128, 128},
|
||||
/* 7 */ {8, 32, 128, 256},
|
||||
/* 8 */ {32, 128, 258, 1024},
|
||||
/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
|
||||
|
||||
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
|
||||
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different
|
||||
* meaning.
|
||||
*/
|
||||
|
||||
#define EQUAL 0
|
||||
/* result of memcmp for equal strings */
|
||||
|
||||
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
||||
|
||||
/* ===========================================================================
|
||||
* Prototypes for local functions.
|
||||
* Function prototypes.
|
||||
*/
|
||||
|
||||
local void fill_window OF((deflate_state *s));
|
||||
local int deflate_stored OF((deflate_state *s, int flush));
|
||||
local int deflate_fast OF((deflate_state *s, int flush));
|
||||
local int deflate_slow OF((deflate_state *s, int flush));
|
||||
local void lm_init OF((deflate_state *s));
|
||||
@ -130,6 +80,62 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
|
||||
int length));
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Local data
|
||||
*/
|
||||
|
||||
#define NIL 0
|
||||
/* Tail of hash chains */
|
||||
|
||||
#ifndef TOO_FAR
|
||||
# define TOO_FAR 4096
|
||||
#endif
|
||||
/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
typedef int (*compress_func) OF((deflate_state *s, int flush));
|
||||
/* Compressing function */
|
||||
|
||||
/* Values for max_lazy_match, good_match and max_chain_length, depending on
|
||||
* the desired pack level (0..9). The values given below have been tuned to
|
||||
* exclude worst case performance for pathological files. Better values may be
|
||||
* found for specific files.
|
||||
*/
|
||||
typedef struct config_s {
|
||||
ush good_length; /* reduce lazy search above this match length */
|
||||
ush max_lazy; /* do not perform lazy search above this match length */
|
||||
ush nice_length; /* quit search above this match length */
|
||||
ush max_chain;
|
||||
compress_func func;
|
||||
} config;
|
||||
|
||||
local config configuration_table[10] = {
|
||||
/* good lazy nice chain */
|
||||
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
|
||||
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
|
||||
/* 2 */ {4, 5, 16, 8, deflate_fast},
|
||||
/* 3 */ {4, 6, 32, 32, deflate_fast},
|
||||
|
||||
/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
|
||||
/* 5 */ {8, 16, 32, 32, deflate_slow},
|
||||
/* 6 */ {8, 16, 128, 128, deflate_slow},
|
||||
/* 7 */ {8, 32, 128, 256, deflate_slow},
|
||||
/* 8 */ {32, 128, 258, 1024, deflate_slow},
|
||||
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
|
||||
|
||||
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
|
||||
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different
|
||||
* meaning.
|
||||
*/
|
||||
|
||||
#define EQUAL 0
|
||||
/* result of memcmp for equal strings */
|
||||
|
||||
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
||||
|
||||
/* ===========================================================================
|
||||
* Update a hash value with the given input byte
|
||||
@ -162,30 +168,43 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
|
||||
zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
|
||||
|
||||
/* ========================================================================= */
|
||||
int deflateInit (strm, level)
|
||||
int deflateInit_(strm, level, version, stream_size)
|
||||
z_stream *strm;
|
||||
int level;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
return deflateInit2 (strm, level, DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, 0);
|
||||
return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
|
||||
Z_DEFAULT_STRATEGY, version, stream_size);
|
||||
/* To do: ignore strm->next_in if we use it as window */
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
|
||||
int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||
version, stream_size)
|
||||
z_stream *strm;
|
||||
int level;
|
||||
int method;
|
||||
int windowBits;
|
||||
int memLevel;
|
||||
int strategy;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
deflate_state *s;
|
||||
int noheader = 0;
|
||||
|
||||
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
||||
stream_size != sizeof(z_stream)) {
|
||||
return Z_VERSION_ERROR;
|
||||
}
|
||||
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
||||
|
||||
strm->msg = Z_NULL;
|
||||
if (strm->zalloc == Z_NULL) strm->zalloc = zcalloc;
|
||||
if (strm->zalloc == Z_NULL) {
|
||||
strm->zalloc = zcalloc;
|
||||
strm->opaque = (voidpf)0;
|
||||
}
|
||||
if (strm->zfree == Z_NULL) strm->zfree = zcfree;
|
||||
|
||||
if (level == Z_DEFAULT_COMPRESSION) level = 6;
|
||||
@ -194,8 +213,9 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
|
||||
noheader = 1;
|
||||
windowBits = -windowBits;
|
||||
}
|
||||
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED ||
|
||||
windowBits < 8 || windowBits > 15 || level < 1 || level > 9) {
|
||||
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
|
||||
windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
|
||||
strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
|
||||
@ -223,15 +243,15 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
|
||||
|
||||
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
|
||||
s->pending_buf == Z_NULL) {
|
||||
strm->msg = z_errmsg[1-Z_MEM_ERROR];
|
||||
strm->msg = ERR_MSG(Z_MEM_ERROR);
|
||||
deflateEnd (strm);
|
||||
return Z_MEM_ERROR;
|
||||
}
|
||||
s->d_buf = (ushf *) &(s->pending_buf[s->lit_bufsize]);
|
||||
s->l_buf = (uchf *) &(s->pending_buf[3*s->lit_bufsize]);
|
||||
s->l_buf = (uchf *) &(s->pending_buf[s->lit_bufsize]);
|
||||
s->d_buf = (ushf *) &(s->pending_buf[2*s->lit_bufsize]);
|
||||
/* We overlay pending_buf and d_buf+l_buf. This works since the average
|
||||
* output size for (length,distance) codes is <= 32 bits (worst case
|
||||
* is 15+15+13=33).
|
||||
* is 15+15+13=33). d_buf is put last in case sizeof(short)>2.
|
||||
*/
|
||||
|
||||
s->level = level;
|
||||
@ -241,6 +261,44 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
|
||||
return deflateReset(strm);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int deflateSetDictionary (strm, dictionary, dictLength)
|
||||
z_stream *strm;
|
||||
const Bytef *dictionary;
|
||||
uInt dictLength;
|
||||
{
|
||||
deflate_state *s;
|
||||
uInt length = dictLength;
|
||||
uInt n;
|
||||
IPos hash_head;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
|
||||
strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
|
||||
|
||||
s = strm->state;
|
||||
strm->adler = adler32(strm->adler, dictionary, dictLength);
|
||||
|
||||
if (length < MIN_MATCH) return Z_OK;
|
||||
if (length > MAX_DIST(s)) {
|
||||
length = MAX_DIST(s);
|
||||
dictionary += dictLength - length;
|
||||
}
|
||||
zmemcpy((charf *)s->window, dictionary, length);
|
||||
s->strstart = length;
|
||||
s->block_start = (long)length;
|
||||
|
||||
/* Insert all strings in the hash table (except for the last two bytes).
|
||||
* s->lookahead stays null, so s->ins_h will be recomputed at the next
|
||||
* call of fill_window.
|
||||
*/
|
||||
s->ins_h = s->window[0];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[1]);
|
||||
for (n = 0; n <= length - MIN_MATCH; n++) {
|
||||
INSERT_STRING(s, n, hash_head);
|
||||
}
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int deflateReset (strm)
|
||||
z_stream *strm;
|
||||
@ -262,14 +320,52 @@ int deflateReset (strm)
|
||||
s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
|
||||
}
|
||||
s->status = s->noheader ? BUSY_STATE : INIT_STATE;
|
||||
s->adler = 1;
|
||||
strm->adler = 1;
|
||||
s->last_flush = Z_NO_FLUSH;
|
||||
|
||||
ct_init(s);
|
||||
_tr_init(s);
|
||||
lm_init(s);
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int deflateParams(strm, level, strategy)
|
||||
z_stream *strm;
|
||||
int level;
|
||||
int strategy;
|
||||
{
|
||||
deflate_state *s;
|
||||
compress_func func;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
s = strm->state;
|
||||
|
||||
if (level == Z_DEFAULT_COMPRESSION) {
|
||||
level = 6;
|
||||
}
|
||||
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
|
||||
return Z_STREAM_ERROR;
|
||||
}
|
||||
func = configuration_table[s->level].func;
|
||||
|
||||
if (func != configuration_table[level].func
|
||||
&& strm->state->lookahead != 0) {
|
||||
|
||||
/* Flush the last buffer: */
|
||||
(void)(*func)(strm->state, Z_PARTIAL_FLUSH);
|
||||
}
|
||||
if (s->level != level) {
|
||||
s->level = level;
|
||||
s->max_lazy_match = configuration_table[level].max_lazy;
|
||||
s->good_match = configuration_table[level].good_length;
|
||||
s->nice_match = configuration_table[level].nice_length;
|
||||
s->max_chain_length = configuration_table[level].max_chain;
|
||||
}
|
||||
s->strategy = strategy;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* Put a short in the pending buffer. The 16-bit value is put in MSB order.
|
||||
* IN assertion: the stream state is correct and there is enough room in
|
||||
@ -284,7 +380,10 @@ local void putShortMSB (s, b)
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* Flush as much pending output as possible.
|
||||
* Flush as much pending output as possible. All deflate() output goes
|
||||
* through this function so some applications may wish to modify it
|
||||
* to avoid allocating a large strm->next_out buffer and copying into it.
|
||||
* (See also read_buf()).
|
||||
*/
|
||||
local void flush_pending(strm)
|
||||
z_stream *strm;
|
||||
@ -310,55 +409,76 @@ int deflate (strm, flush)
|
||||
z_stream *strm;
|
||||
int flush;
|
||||
{
|
||||
int old_flush; /* value of flush param for previous deflate call */
|
||||
deflate_state *s;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
|
||||
s = strm->state;
|
||||
|
||||
if (strm->next_out == Z_NULL ||
|
||||
(strm->next_in == Z_NULL && strm->avail_in != 0)) {
|
||||
(strm->next_in == Z_NULL && strm->avail_in != 0) ||
|
||||
(s->status == FINISH_STATE && flush != Z_FINISH)) {
|
||||
ERR_RETURN(strm, Z_STREAM_ERROR);
|
||||
}
|
||||
if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
|
||||
|
||||
strm->state->strm = strm; /* just in case */
|
||||
s->strm = strm; /* just in case */
|
||||
old_flush = s->last_flush;
|
||||
s->last_flush = flush;
|
||||
|
||||
/* Write the zlib header */
|
||||
if (strm->state->status == INIT_STATE) {
|
||||
if (s->status == INIT_STATE) {
|
||||
|
||||
uInt header = (DEFLATED + ((strm->state->w_bits-8)<<4)) << 8;
|
||||
uInt level_flags = (strm->state->level-1) >> 1;
|
||||
uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
|
||||
uInt level_flags = (s->level-1) >> 1;
|
||||
|
||||
if (level_flags > 3) level_flags = 3;
|
||||
header |= (level_flags << 6);
|
||||
if (s->strstart != 0) header |= PRESET_DICT;
|
||||
header += 31 - (header % 31);
|
||||
|
||||
strm->state->status = BUSY_STATE;
|
||||
putShortMSB(strm->state, header);
|
||||
s->status = BUSY_STATE;
|
||||
putShortMSB(s, header);
|
||||
|
||||
/* Save the adler32 of the preset dictionary: */
|
||||
if (s->strstart != 0) {
|
||||
putShortMSB(s, (uInt)(strm->adler >> 16));
|
||||
putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
||||
strm->adler = 1L;
|
||||
}
|
||||
}
|
||||
|
||||
/* Flush as much pending output as possible */
|
||||
if (strm->state->pending != 0) {
|
||||
if (s->pending != 0) {
|
||||
flush_pending(strm);
|
||||
if (strm->avail_out == 0) return Z_OK;
|
||||
|
||||
/* Make sure there is something to do and avoid duplicate consecutive
|
||||
* flushes. For repeated and useless calls with Z_FINISH, we keep
|
||||
* returning Z_STREAM_END instead of Z_BUFF_ERROR.
|
||||
*/
|
||||
} else if (strm->avail_in == 0 && flush <= old_flush &&
|
||||
flush != Z_FINISH) {
|
||||
ERR_RETURN(strm, Z_BUF_ERROR);
|
||||
}
|
||||
|
||||
/* User must not provide more input after the first FINISH: */
|
||||
if (strm->state->status == FINISH_STATE && strm->avail_in != 0) {
|
||||
if (s->status == FINISH_STATE && strm->avail_in != 0) {
|
||||
ERR_RETURN(strm, Z_BUF_ERROR);
|
||||
}
|
||||
|
||||
/* Start a new block or continue the current one.
|
||||
*/
|
||||
if (strm->avail_in != 0 || strm->state->lookahead != 0 ||
|
||||
(flush != Z_NO_FLUSH && strm->state->status != FINISH_STATE)) {
|
||||
if (strm->avail_in != 0 || s->lookahead != 0 ||
|
||||
(flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
|
||||
int quit;
|
||||
|
||||
if (flush == Z_FINISH) {
|
||||
strm->state->status = FINISH_STATE;
|
||||
}
|
||||
if (strm->state->level <= 3) {
|
||||
quit = deflate_fast(strm->state, flush);
|
||||
} else {
|
||||
quit = deflate_slow(strm->state, flush);
|
||||
s->status = FINISH_STATE;
|
||||
}
|
||||
quit = (*(configuration_table[s->level].func))(s, flush);
|
||||
|
||||
if (quit || strm->avail_out == 0) return Z_OK;
|
||||
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call
|
||||
* of deflate should use the same flush parameter to make sure
|
||||
@ -367,16 +487,16 @@ int deflate (strm, flush)
|
||||
* ensures that for a very small output buffer, we emit at most
|
||||
* one empty block.
|
||||
*/
|
||||
if (flush != Z_OK && flush != Z_FINISH) {
|
||||
if (flush != Z_NO_FLUSH && flush != Z_FINISH) {
|
||||
if (flush == Z_PARTIAL_FLUSH) {
|
||||
ct_align(strm->state);
|
||||
_tr_align(s);
|
||||
} else { /* FULL_FLUSH or SYNC_FLUSH */
|
||||
ct_stored_block(strm->state, (char*)0, 0L, 0);
|
||||
_tr_stored_block(s, (char*)0, 0L, 0);
|
||||
/* For a full flush, this empty block will be recognized
|
||||
* as a special marker by inflate_sync().
|
||||
*/
|
||||
if (flush == Z_FULL_FLUSH) {
|
||||
CLEAR_HASH(strm->state); /* forget history */
|
||||
CLEAR_HASH(s); /* forget history */
|
||||
}
|
||||
}
|
||||
flush_pending(strm);
|
||||
@ -386,34 +506,38 @@ int deflate (strm, flush)
|
||||
Assert(strm->avail_out > 0, "bug2");
|
||||
|
||||
if (flush != Z_FINISH) return Z_OK;
|
||||
if (strm->state->noheader) return Z_STREAM_END;
|
||||
if (s->noheader) return Z_STREAM_END;
|
||||
|
||||
/* Write the zlib trailer (adler32) */
|
||||
putShortMSB(strm->state, (uInt)(strm->state->adler >> 16));
|
||||
putShortMSB(strm->state, (uInt)(strm->state->adler & 0xffff));
|
||||
putShortMSB(s, (uInt)(strm->adler >> 16));
|
||||
putShortMSB(s, (uInt)(strm->adler & 0xffff));
|
||||
flush_pending(strm);
|
||||
/* If avail_out is zero, the application will call deflate again
|
||||
* to flush the rest.
|
||||
*/
|
||||
strm->state->noheader = -1; /* write the trailer only once! */
|
||||
return strm->state->pending != 0 ? Z_OK : Z_STREAM_END;
|
||||
s->noheader = -1; /* write the trailer only once! */
|
||||
return s->pending != 0 ? Z_OK : Z_STREAM_END;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int deflateEnd (strm)
|
||||
z_stream *strm;
|
||||
{
|
||||
int status;
|
||||
|
||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||
|
||||
TRY_FREE(strm, strm->state->window);
|
||||
TRY_FREE(strm, strm->state->prev);
|
||||
TRY_FREE(strm, strm->state->head);
|
||||
/* Deallocate in reverse order of allocations: */
|
||||
TRY_FREE(strm, strm->state->pending_buf);
|
||||
TRY_FREE(strm, strm->state->head);
|
||||
TRY_FREE(strm, strm->state->prev);
|
||||
TRY_FREE(strm, strm->state->window);
|
||||
|
||||
status = strm->state->status;
|
||||
ZFREE(strm, strm->state);
|
||||
strm->state = Z_NULL;
|
||||
|
||||
return Z_OK;
|
||||
return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@ -438,7 +562,10 @@ int deflateCopy (dest, source)
|
||||
|
||||
/* ===========================================================================
|
||||
* Read a new buffer from the current input stream, update the adler32
|
||||
* and total number of bytes read.
|
||||
* and total number of bytes read. All deflate() input goes through
|
||||
* this function so some applications may wish to modify it to avoid
|
||||
* allocating a large strm->next_in buffer and copying from it.
|
||||
* (See also flush_pending()).
|
||||
*/
|
||||
local int read_buf(strm, buf, size)
|
||||
z_stream *strm;
|
||||
@ -453,7 +580,7 @@ local int read_buf(strm, buf, size)
|
||||
strm->avail_in -= len;
|
||||
|
||||
if (!strm->state->noheader) {
|
||||
strm->state->adler = adler32(strm->state->adler, strm->next_in, len);
|
||||
strm->adler = adler32(strm->adler, strm->next_in, len);
|
||||
}
|
||||
zmemcpy(buf, strm->next_in, len);
|
||||
strm->next_in += len;
|
||||
@ -482,7 +609,7 @@ local void lm_init (s)
|
||||
s->strstart = 0;
|
||||
s->block_start = 0L;
|
||||
s->lookahead = 0;
|
||||
s->match_length = MIN_MATCH-1;
|
||||
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||
s->match_available = 0;
|
||||
s->ins_h = 0;
|
||||
#ifdef ASMV
|
||||
@ -497,6 +624,7 @@ local void lm_init (s)
|
||||
* garbage.
|
||||
* IN assertions: cur_match is the head of the hash chain for the current
|
||||
* string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
|
||||
* OUT assertion: the match length is not greater than s->lookahead.
|
||||
*/
|
||||
#ifndef ASMV
|
||||
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
|
||||
@ -511,6 +639,7 @@ local int longest_match(s, cur_match)
|
||||
register Bytef *match; /* matched string */
|
||||
register int len; /* length of current match */
|
||||
int best_len = s->prev_length; /* best match length so far */
|
||||
int nice_match = s->nice_match; /* stop if match long enough */
|
||||
IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
|
||||
s->strstart - (IPos)MAX_DIST(s) : NIL;
|
||||
/* Stop when cur_match becomes <= limit. To simplify the code,
|
||||
@ -541,6 +670,11 @@ local int longest_match(s, cur_match)
|
||||
if (s->prev_length >= s->good_match) {
|
||||
chain_length >>= 2;
|
||||
}
|
||||
/* Do not look for matches beyond the end of the input. This is necessary
|
||||
* to make deflate deterministic.
|
||||
*/
|
||||
if (nice_match > s->lookahead) nice_match = s->lookahead;
|
||||
|
||||
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
|
||||
|
||||
do {
|
||||
@ -619,7 +753,7 @@ local int longest_match(s, cur_match)
|
||||
if (len > best_len) {
|
||||
s->match_start = cur_match;
|
||||
best_len = len;
|
||||
if (len >= s->nice_match) break;
|
||||
if (len >= nice_match) break;
|
||||
#ifdef UNALIGNED_OK
|
||||
scan_end = *(ushf*)(scan+best_len-1);
|
||||
#else
|
||||
@ -630,7 +764,8 @@ local int longest_match(s, cur_match)
|
||||
} while ((cur_match = prev[cur_match & wmask]) > limit
|
||||
&& --chain_length != 0);
|
||||
|
||||
return best_len;
|
||||
if (best_len <= s->lookahead) return best_len;
|
||||
return s->lookahead;
|
||||
}
|
||||
#endif /* ASMV */
|
||||
|
||||
@ -644,13 +779,13 @@ local void check_match(s, start, match, length)
|
||||
int length;
|
||||
{
|
||||
/* check that the match is indeed a match */
|
||||
if (memcmp((charf *)s->window + match,
|
||||
if (zmemcmp((charf *)s->window + match,
|
||||
(charf *)s->window + start, length) != EQUAL) {
|
||||
fprintf(stderr,
|
||||
" start %u, match %u, length %d\n",
|
||||
fprintf(stderr, " start %u, match %u, length %d\n",
|
||||
start, match, length);
|
||||
do { fprintf(stderr, "%c%c", s->window[match++],
|
||||
s->window[start++]); } while (--length != 0);
|
||||
do {
|
||||
fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
|
||||
} while (--length != 0);
|
||||
z_error("invalid match");
|
||||
}
|
||||
if (verbose > 1) {
|
||||
@ -686,6 +821,7 @@ local void fill_window(s)
|
||||
/* Deal with !@#$% 64K limit: */
|
||||
if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
|
||||
more = wsize;
|
||||
|
||||
} else if (more == (unsigned)(-1)) {
|
||||
/* Very unlikely, but possible on 16 bit machine if strstart == 0
|
||||
* and lookahead == 1 (input done one byte at time)
|
||||
@ -697,9 +833,6 @@ local void fill_window(s)
|
||||
*/
|
||||
} else if (s->strstart >= wsize+MAX_DIST(s)) {
|
||||
|
||||
/* By the IN assertion, the window is not empty so we can't confuse
|
||||
* more == 0 with more == 64K on a 16 bit machine.
|
||||
*/
|
||||
zmemcpy((charf *)s->window, (charf *)s->window+wsize,
|
||||
(unsigned)wsize);
|
||||
s->match_start -= wsize;
|
||||
@ -768,9 +901,11 @@ local void fill_window(s)
|
||||
* IN assertion: strstart is set to the end of the current match.
|
||||
*/
|
||||
#define FLUSH_BLOCK_ONLY(s, eof) { \
|
||||
ct_flush_block(s, (s->block_start >= 0L ? \
|
||||
_tr_flush_block(s, (s->block_start >= 0L ? \
|
||||
(charf *)&s->window[(unsigned)s->block_start] : \
|
||||
(charf *)Z_NULL), (long)s->strstart - s->block_start, (eof)); \
|
||||
(charf *)Z_NULL), \
|
||||
(ulg)((long)s->strstart - s->block_start), \
|
||||
(eof)); \
|
||||
s->block_start = s->strstart; \
|
||||
flush_pending(s->strm); \
|
||||
Tracev((stderr,"[FLUSH]")); \
|
||||
@ -782,10 +917,55 @@ local void fill_window(s)
|
||||
if (s->strm->avail_out == 0) return 1; \
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Copy without compression as much as possible from the input stream, return
|
||||
* true if processing was terminated prematurely (no more input or output
|
||||
* space). This function does not insert new strings in the dictionary
|
||||
* since uncompressible data is probably not useful. This function is used
|
||||
* only for the level=0 compression option.
|
||||
* NOTE: this function should be optimized to avoid extra copying.
|
||||
*/
|
||||
local int deflate_stored(s, flush)
|
||||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
for (;;) {
|
||||
/* Fill the window as much as possible: */
|
||||
if (s->lookahead <= 1) {
|
||||
|
||||
Assert(s->strstart < s->w_size+MAX_DIST(s) ||
|
||||
s->block_start >= (long)s->w_size, "slide too late");
|
||||
|
||||
fill_window(s);
|
||||
if (s->lookahead == 0 && flush == Z_NO_FLUSH) return 1;
|
||||
|
||||
if (s->lookahead == 0) break; /* flush the current block */
|
||||
}
|
||||
Assert(s->block_start >= 0L, "block gone");
|
||||
|
||||
s->strstart += s->lookahead;
|
||||
s->lookahead = 0;
|
||||
|
||||
/* Stored blocks are limited to 0xffff bytes: */
|
||||
if (s->strstart == 0 || s->strstart > 0xffff) {
|
||||
/* strstart == 0 is possible when wraparound on 16-bit machine */
|
||||
s->lookahead = s->strstart - 0xffff;
|
||||
s->strstart = 0xffff;
|
||||
}
|
||||
|
||||
/* Emit a stored block if it is large enough: */
|
||||
if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
|
||||
FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return 0; /* normal exit */
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Compress as much as possible from the input stream, return true if
|
||||
* processing was terminated prematurely (no more input or output space).
|
||||
* This function does not perform lazy evaluationof matches and inserts
|
||||
* This function does not perform lazy evaluation of matches and inserts
|
||||
* new strings in the dictionary only for unmatched strings or for short
|
||||
* matches. It is used only for the fast compression options.
|
||||
*/
|
||||
@ -793,11 +973,9 @@ local int deflate_fast(s, flush)
|
||||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
IPos hash_head; /* head of the hash chain */
|
||||
IPos hash_head = NIL; /* head of the hash chain */
|
||||
int bflush; /* set if current block must be flushed */
|
||||
|
||||
s->prev_length = MIN_MATCH-1;
|
||||
|
||||
for (;;) {
|
||||
/* Make sure that we always have enough lookahead, except
|
||||
* at the end of the input file. We need MAX_MATCH bytes
|
||||
@ -830,13 +1008,11 @@ local int deflate_fast(s, flush)
|
||||
s->match_length = longest_match (s, hash_head);
|
||||
}
|
||||
/* longest_match() sets match_start */
|
||||
|
||||
if (s->match_length > s->lookahead) s->match_length = s->lookahead;
|
||||
}
|
||||
if (s->match_length >= MIN_MATCH) {
|
||||
check_match(s, s->strstart, s->match_start, s->match_length);
|
||||
|
||||
bflush = ct_tally(s, s->strstart - s->match_start,
|
||||
bflush = _tr_tally(s, s->strstart - s->match_start,
|
||||
s->match_length - MIN_MATCH);
|
||||
|
||||
s->lookahead -= s->match_length;
|
||||
@ -870,7 +1046,7 @@ local int deflate_fast(s, flush)
|
||||
} else {
|
||||
/* No match, output a literal byte */
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
bflush = ct_tally (s, 0, s->window[s->strstart]);
|
||||
bflush = _tr_tally (s, 0, s->window[s->strstart]);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
}
|
||||
@ -889,7 +1065,7 @@ local int deflate_slow(s, flush)
|
||||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
IPos hash_head; /* head of hash chain */
|
||||
IPos hash_head = NIL; /* head of hash chain */
|
||||
int bflush; /* set if current block must be flushed */
|
||||
|
||||
/* Process the input block. */
|
||||
@ -928,7 +1104,6 @@ local int deflate_slow(s, flush)
|
||||
s->match_length = longest_match (s, hash_head);
|
||||
}
|
||||
/* longest_match() sets match_start */
|
||||
if (s->match_length > s->lookahead) s->match_length = s->lookahead;
|
||||
|
||||
if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
|
||||
(s->match_length == MIN_MATCH &&
|
||||
@ -949,7 +1124,7 @@ local int deflate_slow(s, flush)
|
||||
|
||||
check_match(s, s->strstart-1, s->prev_match, s->prev_length);
|
||||
|
||||
bflush = ct_tally(s, s->strstart -1 - s->prev_match,
|
||||
bflush = _tr_tally(s, s->strstart -1 - s->prev_match,
|
||||
s->prev_length - MIN_MATCH);
|
||||
|
||||
/* Insert in hash table all strings up to the end of the match.
|
||||
@ -976,7 +1151,7 @@ local int deflate_slow(s, flush)
|
||||
* is longer, truncate the previous match to a single literal.
|
||||
*/
|
||||
Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||||
if (ct_tally (s, 0, s->window[s->strstart-1])) {
|
||||
if (_tr_tally (s, 0, s->window[s->strstart-1])) {
|
||||
FLUSH_BLOCK_ONLY(s, 0);
|
||||
}
|
||||
s->strstart++;
|
||||
@ -994,7 +1169,7 @@ local int deflate_slow(s, flush)
|
||||
Assert (flush != Z_NO_FLUSH, "no flush?");
|
||||
if (s->match_available) {
|
||||
Tracevv((stderr,"%c", s->window[s->strstart-1]));
|
||||
ct_tally (s, 0, s->window[s->strstart-1]);
|
||||
_tr_tally (s, 0, s->window[s->strstart-1]);
|
||||
s->match_available = 0;
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
|
24
deflate.h
24
deflate.h
@ -1,5 +1,5 @@
|
||||
/* deflate.h -- internal compression state
|
||||
* Copyright (C) 1995 Jean-loup Gailly
|
||||
* Copyright (C) 1995-1996 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -10,17 +10,15 @@
|
||||
|
||||
/* $Id: deflate.h,v 1.5 1995/05/03 17:27:09 jloup Exp $ */
|
||||
|
||||
#ifndef _DEFLATE_H
|
||||
#define _DEFLATE_H
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
/* ===========================================================================
|
||||
* Internal compression state.
|
||||
*/
|
||||
|
||||
/* Data type */
|
||||
#define BINARY 0
|
||||
#define ASCII 1
|
||||
#define UNKNOWN 2
|
||||
|
||||
#define LENGTH_CODES 29
|
||||
/* number of length codes, not counting the special END_BLOCK code */
|
||||
|
||||
@ -87,10 +85,10 @@ typedef struct internal_state {
|
||||
Bytef *pending_buf; /* output still pending */
|
||||
Bytef *pending_out; /* next pending byte to output to the stream */
|
||||
int pending; /* nb of bytes in the pending buffer */
|
||||
uLong adler; /* adler32 of uncompressed data */
|
||||
int noheader; /* suppress zlib header and adler32 */
|
||||
Byte data_type; /* UNKNOWN, BINARY or ASCII */
|
||||
Byte method; /* STORED (for zip only) or DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
|
||||
/* used by deflate.c: */
|
||||
|
||||
@ -267,9 +265,11 @@ typedef struct internal_state {
|
||||
*/
|
||||
|
||||
/* in trees.c */
|
||||
void ct_init OF((deflate_state *s));
|
||||
int ct_tally OF((deflate_state *s, int dist, int lc));
|
||||
ulg ct_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof));
|
||||
void ct_align OF((deflate_state *s));
|
||||
void ct_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
void _tr_init OF((deflate_state *s));
|
||||
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||
ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
void _tr_align OF((deflate_state *s));
|
||||
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
#endif
|
||||
|
320
example.c
320
example.c
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
@ -10,20 +10,11 @@
|
||||
|
||||
#ifdef STDC
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
extern void exit OF((int));
|
||||
#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) { \
|
||||
if (err != Z_OK) { \
|
||||
fprintf(stderr, "%s error: %d\n", msg, err); \
|
||||
@ -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"
|
||||
* stresses the compression code better, sorry...
|
||||
*/
|
||||
|
||||
void test_compress OF((void));
|
||||
void test_gzio OF((char *out, char *in));
|
||||
void test_deflate OF((Byte compr[]));
|
||||
void test_inflate OF((Byte compr[]));
|
||||
void test_flush OF((Byte compr[]));
|
||||
void test_sync OF((Byte compr[]));
|
||||
const char dictionary[] = "hello";
|
||||
uLong dictId; /* Adler32 value of the dictionary */
|
||||
|
||||
void test_compress OF((Bytef *compr, uLong comprLen,
|
||||
Bytef *uncompr, uLong uncomprLen));
|
||||
void test_gzio OF((const char *out, const char *in,
|
||||
Bytef *uncompr, int uncomprLen));
|
||||
void test_deflate OF((Bytef *compr, uLong comprLen));
|
||||
void test_inflate OF((Bytef *compr, uLong comprLen,
|
||||
Bytef *uncompr, uLong uncomprLen));
|
||||
void test_large_deflate OF((Bytef *compr, uLong comprLen,
|
||||
Bytef *uncompr, uLong uncomprLen));
|
||||
void test_large_inflate OF((Bytef *compr, uLong comprLen,
|
||||
Bytef *uncompr, uLong uncomprLen));
|
||||
void test_flush OF((Bytef *compr, uLong comprLen));
|
||||
void test_sync OF((Bytef *compr, uLong comprLen,
|
||||
Bytef *uncompr, uLong uncomprLen));
|
||||
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()
|
||||
*/
|
||||
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;
|
||||
uLong len = strlen(hello)+1;
|
||||
|
||||
err = compress(compr, &comprLen, (Byte*)hello, len);
|
||||
err = compress(compr, &comprLen, (const Bytef*)hello, len);
|
||||
CHECK_ERR(err, "compress");
|
||||
|
||||
strcpy((char*)uncompr, "garbage");
|
||||
@ -74,12 +77,12 @@ void test_compress()
|
||||
/* ===========================================================================
|
||||
* Test read/write of .gz files
|
||||
*/
|
||||
void test_gzio(out, in)
|
||||
char *out; /* output file */
|
||||
char *in; /* input file */
|
||||
void test_gzio(out, in, uncompr, uncomprLen)
|
||||
const char *out; /* output file */
|
||||
const char *in; /* input file */
|
||||
Bytef *uncompr;
|
||||
int uncomprLen;
|
||||
{
|
||||
local Byte uncompr[BUFLEN];
|
||||
int uncomprLen = sizeof(uncompr);
|
||||
int err;
|
||||
int len = strlen(hello)+1;
|
||||
gzFile file;
|
||||
@ -90,7 +93,7 @@ void test_gzio(out, in)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (gzwrite(file, hello, len) != len) {
|
||||
if (gzwrite(file, (const voidp)hello, (unsigned)len) != len) {
|
||||
fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
|
||||
}
|
||||
gzclose(file);
|
||||
@ -101,7 +104,7 @@ void test_gzio(out, in)
|
||||
}
|
||||
strcpy((char*)uncompr, "garbage");
|
||||
|
||||
uncomprLen = gzread(file, uncompr, uncomprLen);
|
||||
uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
|
||||
if (uncomprLen != len) {
|
||||
fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
|
||||
}
|
||||
@ -117,8 +120,9 @@ void test_gzio(out, in)
|
||||
/* ===========================================================================
|
||||
* Test deflate() with small buffers
|
||||
*/
|
||||
void test_deflate(compr)
|
||||
Byte compr[];
|
||||
void test_deflate(compr, comprLen)
|
||||
Bytef *compr;
|
||||
uLong comprLen;
|
||||
{
|
||||
z_stream c_stream; /* compression stream */
|
||||
int err;
|
||||
@ -126,14 +130,15 @@ void test_deflate(compr)
|
||||
|
||||
c_stream.zalloc = (alloc_func)0;
|
||||
c_stream.zfree = (free_func)0;
|
||||
c_stream.opaque = (voidpf)0;
|
||||
|
||||
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
|
||||
CHECK_ERR(err, "deflateInit");
|
||||
|
||||
c_stream.next_in = (Byte*)hello;
|
||||
c_stream.next_in = (Bytef*)hello;
|
||||
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 */
|
||||
err = deflate(&c_stream, Z_NO_FLUSH);
|
||||
CHECK_ERR(err, "deflate");
|
||||
@ -153,10 +158,10 @@ void test_deflate(compr)
|
||||
/* ===========================================================================
|
||||
* Test inflate() with small buffers
|
||||
*/
|
||||
void test_inflate(compr)
|
||||
Byte compr[];
|
||||
void test_inflate(compr, comprLen, uncompr, uncomprLen)
|
||||
Bytef *compr, *uncompr;
|
||||
uLong comprLen, uncomprLen;
|
||||
{
|
||||
local Byte uncompr[BUFLEN];
|
||||
int err;
|
||||
z_stream d_stream; /* decompression stream */
|
||||
|
||||
@ -164,6 +169,7 @@ void test_inflate(compr)
|
||||
|
||||
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");
|
||||
@ -171,7 +177,7 @@ void test_inflate(compr)
|
||||
d_stream.next_in = compr;
|
||||
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 */
|
||||
err = inflate(&d_stream, Z_NO_FLUSH);
|
||||
if (err == Z_STREAM_END) break;
|
||||
@ -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
|
||||
*/
|
||||
void test_flush(compr)
|
||||
Byte compr[];
|
||||
void test_flush(compr, comprLen)
|
||||
Bytef *compr;
|
||||
uLong comprLen;
|
||||
{
|
||||
z_stream c_stream; /* compression stream */
|
||||
int err;
|
||||
@ -200,14 +300,15 @@ void test_flush(compr)
|
||||
|
||||
c_stream.zalloc = (alloc_func)0;
|
||||
c_stream.zfree = (free_func)0;
|
||||
c_stream.opaque = (voidpf)0;
|
||||
|
||||
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
|
||||
CHECK_ERR(err, "deflateInit");
|
||||
|
||||
c_stream.next_in = (Byte*)hello;
|
||||
c_stream.next_in = (Bytef*)hello;
|
||||
c_stream.next_out = compr;
|
||||
c_stream.avail_in = 3;
|
||||
c_stream.avail_out = BUFLEN;
|
||||
c_stream.avail_out = (uInt)comprLen;
|
||||
err = deflate(&c_stream, Z_FULL_FLUSH);
|
||||
CHECK_ERR(err, "deflate");
|
||||
|
||||
@ -225,10 +326,10 @@ void test_flush(compr)
|
||||
/* ===========================================================================
|
||||
* Test inflateSync()
|
||||
*/
|
||||
void test_sync(compr)
|
||||
Byte compr[];
|
||||
void test_sync(compr, comprLen, uncompr, uncomprLen)
|
||||
Bytef *compr, *uncompr;
|
||||
uLong comprLen, uncomprLen;
|
||||
{
|
||||
local Byte uncompr[BUFLEN];
|
||||
int err;
|
||||
z_stream d_stream; /* decompression stream */
|
||||
|
||||
@ -236,6 +337,7 @@ void test_sync(compr)
|
||||
|
||||
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");
|
||||
@ -243,13 +345,13 @@ void test_sync(compr)
|
||||
d_stream.next_in = compr;
|
||||
d_stream.next_out = uncompr;
|
||||
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);
|
||||
CHECK_ERR(err, "inflate");
|
||||
|
||||
d_stream.avail_in = BUFLEN-2; /* let inflate read all compressed data */
|
||||
err = inflateSync(&d_stream); /* skip the damaged part */
|
||||
d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
|
||||
err = inflateSync(&d_stream); /* but skip the damaged part */
|
||||
CHECK_ERR(err, "inflateSync");
|
||||
|
||||
err = inflate(&d_stream, Z_FINISH);
|
||||
@ -263,6 +365,91 @@ void test_sync(compr)
|
||||
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]]
|
||||
*/
|
||||
@ -271,7 +458,9 @@ int main(argc, argv)
|
||||
int argc;
|
||||
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]) {
|
||||
fprintf(stderr, "incompatible zlib version\n");
|
||||
@ -280,16 +469,31 @@ int main(argc, argv)
|
||||
} else if (strcmp(zlib_version, ZLIB_VERSION) != 0) {
|
||||
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"),
|
||||
(argc > 2 ? argv[2] : "foo.gz"));
|
||||
(argc > 2 ? argv[2] : "foo.gz"),
|
||||
uncompr, (int)uncomprLen);
|
||||
|
||||
test_deflate(compr);
|
||||
test_inflate(compr);
|
||||
test_deflate(compr, comprLen);
|
||||
test_inflate(compr, comprLen, uncompr, uncomprLen);
|
||||
|
||||
test_flush(compr);
|
||||
test_sync(compr);
|
||||
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
|
||||
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
|
||||
|
||||
test_flush(compr, comprLen);
|
||||
test_sync(compr, comprLen, uncompr, uncomprLen);
|
||||
|
||||
test_dict_deflate(compr, comprLen);
|
||||
test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
|
||||
|
||||
exit(0);
|
||||
return 0; /* to avoid warning */
|
||||
|
360
gzio.c
360
gzio.c
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
@ -16,8 +16,7 @@ struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#define ALLOC(size) malloc(size)
|
||||
#define TRYFREE(p) {if (p) free(p);}
|
||||
|
||||
#define GZ_MAGIC_1 0x1f
|
||||
#define GZ_MAGIC_2 0x8b
|
||||
static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
|
||||
|
||||
/* gzip flag byte */
|
||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
|
||||
@ -27,10 +26,6 @@ struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||
#define RESERVED 0xE0 /* bits 5..7: reserved */
|
||||
|
||||
#ifndef SEEK_CUR
|
||||
# define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
typedef struct gz_stream {
|
||||
z_stream stream;
|
||||
int z_err; /* error code for last stream operation */
|
||||
@ -46,44 +41,16 @@ typedef struct gz_stream {
|
||||
} gz_stream;
|
||||
|
||||
|
||||
local gzFile gz_open OF((const char *path, const char *mode, int fd));
|
||||
local int get_byte OF((gz_stream *s));
|
||||
local void check_header OF((gz_stream *s));
|
||||
local int destroy OF((gz_stream *s));
|
||||
local gzFile gz_open OF((char *path, char *mode, int fd));
|
||||
local void putLong OF((FILE *file, uLong x));
|
||||
local uLong getLong OF((Bytef *buf));
|
||||
|
||||
/* ===========================================================================
|
||||
* Cleanup then free the given gz_stream. Return a zlib error code.
|
||||
*/
|
||||
local int destroy (s)
|
||||
gz_stream *s;
|
||||
{
|
||||
int err = Z_OK;
|
||||
|
||||
if (!s) return Z_STREAM_ERROR;
|
||||
|
||||
TRYFREE(s->inbuf);
|
||||
TRYFREE(s->outbuf);
|
||||
TRYFREE(s->path);
|
||||
TRYFREE(s->msg);
|
||||
|
||||
if (s->stream.state != NULL) {
|
||||
if (s->mode == 'w') {
|
||||
err = deflateEnd(&(s->stream));
|
||||
} else if (s->mode == 'r') {
|
||||
err = inflateEnd(&(s->stream));
|
||||
}
|
||||
}
|
||||
if (s->file != NULL && fclose(s->file)) {
|
||||
err = Z_ERRNO;
|
||||
}
|
||||
if (s->z_err < 0) err = s->z_err;
|
||||
TRYFREE(s);
|
||||
return err;
|
||||
}
|
||||
local uLong getLong OF((gz_stream *s));
|
||||
|
||||
/* ===========================================================================
|
||||
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).
|
||||
gz_open return NULL if the file could not be opened or if there was
|
||||
insufficient memory to allocate the (de)compression state; errno
|
||||
@ -91,19 +58,25 @@ local int destroy (s)
|
||||
zlib error is Z_MEM_ERROR).
|
||||
*/
|
||||
local gzFile gz_open (path, mode, fd)
|
||||
char *path;
|
||||
char *mode;
|
||||
const char *path;
|
||||
const char *mode;
|
||||
int fd;
|
||||
{
|
||||
int err;
|
||||
int level = Z_DEFAULT_COMPRESSION; /* compression level */
|
||||
char *p = mode;
|
||||
gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream));
|
||||
char *p = (char*)mode;
|
||||
gz_stream *s;
|
||||
char fmode[80]; /* copy of mode, without the compression level */
|
||||
char *m = fmode;
|
||||
|
||||
if (!path || !mode) return Z_NULL;
|
||||
|
||||
s = (gz_stream *)ALLOC(sizeof(gz_stream));
|
||||
if (!s) return Z_NULL;
|
||||
|
||||
s->stream.zalloc = (alloc_func)0;
|
||||
s->stream.zfree = (free_func)0;
|
||||
s->stream.opaque = (voidpf)0;
|
||||
s->stream.next_in = s->inbuf = Z_NULL;
|
||||
s->stream.next_out = s->outbuf = Z_NULL;
|
||||
s->stream.avail_in = s->stream.avail_out = 0;
|
||||
@ -123,14 +96,18 @@ local gzFile gz_open (path, mode, fd)
|
||||
s->mode = '\0';
|
||||
do {
|
||||
if (*p == 'r') s->mode = 'r';
|
||||
if (*p == 'w') s->mode = 'w';
|
||||
if (*p >= '1' && *p <= '9') level = *p - '0';
|
||||
} while (*p++);
|
||||
if (*p == 'w' || *p == 'a') s->mode = 'w';
|
||||
if (*p >= '0' && *p <= '9') {
|
||||
level = *p - '0';
|
||||
} else {
|
||||
*m++ = *p; /* copy the mode */
|
||||
}
|
||||
} while (*p++ && m != fmode + sizeof(fmode));
|
||||
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
|
||||
|
||||
if (s->mode == 'w') {
|
||||
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 */
|
||||
|
||||
s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
|
||||
@ -149,7 +126,7 @@ local gzFile gz_open (path, mode, fd)
|
||||
s->stream.avail_out = Z_BUFSIZE;
|
||||
|
||||
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) {
|
||||
return destroy(s), (gzFile)Z_NULL;
|
||||
@ -157,50 +134,10 @@ local gzFile gz_open (path, mode, fd)
|
||||
if (s->mode == 'w') {
|
||||
/* Write a very simple .gz header:
|
||||
*/
|
||||
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2,
|
||||
DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
|
||||
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
|
||||
Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
|
||||
} else {
|
||||
/* Check and skip the header:
|
||||
*/
|
||||
Byte c1 = 0, c2 = 0;
|
||||
Byte method = 0;
|
||||
Byte flags = 0;
|
||||
Byte xflags = 0;
|
||||
Byte time[4];
|
||||
Byte osCode;
|
||||
int c;
|
||||
|
||||
s->stream.avail_in = fread(s->inbuf, 1, 2, s->file);
|
||||
if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1
|
||||
|| s->inbuf[1] != GZ_MAGIC_2) {
|
||||
s->transparent = 1;
|
||||
return (gzFile)s;
|
||||
}
|
||||
s->stream.avail_in = 0;
|
||||
fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode);
|
||||
|
||||
if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) {
|
||||
s->z_err = Z_DATA_ERROR;
|
||||
return (gzFile)s;
|
||||
}
|
||||
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
|
||||
long len;
|
||||
fscanf(s->file, "%c%c", &c1, &c2);
|
||||
len = c1 + ((long)c2<<8);
|
||||
fseek(s->file, len, SEEK_CUR);
|
||||
}
|
||||
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
|
||||
while ((c = getc(s->file)) != 0 && c != EOF) ;
|
||||
}
|
||||
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
|
||||
while ((c = getc(s->file)) != 0 && c != EOF) ;
|
||||
}
|
||||
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
|
||||
fscanf(s->file, "%c%c", &c1, &c2);
|
||||
}
|
||||
if (feof(s->file)) {
|
||||
s->z_err = Z_DATA_ERROR;
|
||||
}
|
||||
check_header(s); /* skip the .gz header */
|
||||
}
|
||||
return (gzFile)s;
|
||||
}
|
||||
@ -209,25 +146,138 @@ local gzFile gz_open (path, mode, fd)
|
||||
Opens a gzip (.gz) file for reading or writing.
|
||||
*/
|
||||
gzFile gzopen (path, mode)
|
||||
char *path;
|
||||
char *mode;
|
||||
const char *path;
|
||||
const char *mode;
|
||||
{
|
||||
return gz_open (path, mode, -1);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
Associate a gzFile with the file descriptor fd.
|
||||
Associate a gzFile with the file descriptor fd. fd is not dup'ed here
|
||||
to mimic the behavio(u)r of fdopen.
|
||||
*/
|
||||
gzFile gzdopen (fd, mode)
|
||||
int fd;
|
||||
char *mode;
|
||||
const char *mode;
|
||||
{
|
||||
char name[20];
|
||||
|
||||
if (fd < 0) return (gzFile)Z_NULL;
|
||||
sprintf(name, "<fd:%d>", fd); /* for debugging */
|
||||
|
||||
return gz_open (name, mode, fd);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
|
||||
for end of file.
|
||||
IN assertion: the stream s has been sucessfully opened for reading.
|
||||
*/
|
||||
local int get_byte(s)
|
||||
gz_stream *s;
|
||||
{
|
||||
if (s->z_eof) return EOF;
|
||||
if (s->stream.avail_in == 0) {
|
||||
errno = 0;
|
||||
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
|
||||
if (s->stream.avail_in == 0) {
|
||||
s->z_eof = 1;
|
||||
if (ferror(s->file)) s->z_err = Z_ERRNO;
|
||||
return EOF;
|
||||
}
|
||||
s->stream.next_in = s->inbuf;
|
||||
}
|
||||
s->stream.avail_in--;
|
||||
return *(s->stream.next_in)++;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
Check the gzip header of a gz_stream opened for reading. Set the stream
|
||||
mode to transparent if the gzip magic header is not present; set s->err
|
||||
to Z_DATA_ERROR if the magic header is present but the rest of the header
|
||||
is incorrect.
|
||||
IN assertion: the stream s has already been created sucessfully;
|
||||
s->stream.avail_in is zero for the first time, but may be non-zero
|
||||
for concatenated .gz files.
|
||||
*/
|
||||
local void check_header(s)
|
||||
gz_stream *s;
|
||||
{
|
||||
int method = 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.
|
||||
gzread returns the number of bytes actually read (0 for end of file).
|
||||
@ -238,52 +288,71 @@ int gzread (file, buf, len)
|
||||
unsigned len;
|
||||
{
|
||||
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->transparent) {
|
||||
int n = 0;
|
||||
Byte *b = (Byte*)buf;
|
||||
/* Copy the first two (non-magic) bytes if not done already */
|
||||
while (s->stream.avail_in > 0 && len > 0) {
|
||||
*b++ = *s->stream.next_in++;
|
||||
s->stream.avail_in--;
|
||||
len--; n++;
|
||||
}
|
||||
if (len == 0) return n;
|
||||
return n + fread(b, 1, len, s->file);
|
||||
}
|
||||
if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
|
||||
if (s->z_err == Z_STREAM_END) return 0; /* don't read crc as data */
|
||||
if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
|
||||
if (s->z_err == Z_STREAM_END) return 0; /* EOF */
|
||||
|
||||
s->stream.next_out = buf;
|
||||
s->stream.avail_out = len;
|
||||
|
||||
while (s->stream.avail_out != 0) {
|
||||
|
||||
if (s->transparent) {
|
||||
/* Copy first the lookahead bytes: */
|
||||
uInt n = s->stream.avail_in;
|
||||
if (n > s->stream.avail_out) n = s->stream.avail_out;
|
||||
if (n > 0) {
|
||||
zmemcpy(s->stream.next_out, s->stream.next_in, n);
|
||||
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) {
|
||||
|
||||
errno = 0;
|
||||
s->stream.avail_in =
|
||||
fread(s->inbuf, 1, Z_BUFSIZE, s->file);
|
||||
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
|
||||
if (s->stream.avail_in == 0) {
|
||||
s->z_eof = 1;
|
||||
} else if (s->stream.avail_in == (uInt)EOF) {
|
||||
s->stream.avail_in = 0;
|
||||
s->z_eof = 1;
|
||||
if (ferror(s->file)) {
|
||||
s->z_err = Z_ERRNO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s->stream.next_in = s->inbuf;
|
||||
}
|
||||
s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
|
||||
|
||||
if (s->z_err == Z_STREAM_END ||
|
||||
s->z_err != Z_OK || s->z_eof) break;
|
||||
if (s->z_err == Z_STREAM_END) {
|
||||
/* Check CRC and original size */
|
||||
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
|
||||
start = s->stream.next_out;
|
||||
|
||||
if (getLong(s) != s->crc || getLong(s) != s->stream.total_out) {
|
||||
s->z_err = Z_DATA_ERROR;
|
||||
} else {
|
||||
/* Check for concatenated .gz files: */
|
||||
check_header(s);
|
||||
if (s->z_err == Z_OK) {
|
||||
inflateReset(&(s->stream));
|
||||
s->crc = crc32(0L, Z_NULL, 0);
|
||||
}
|
||||
len -= s->stream.avail_out;
|
||||
s->crc = crc32(s->crc, buf, len);
|
||||
return (int)len;
|
||||
}
|
||||
}
|
||||
if (s->z_err != Z_OK || s->z_eof) break;
|
||||
}
|
||||
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
|
||||
|
||||
return (int)(len - s->stream.avail_out);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -292,7 +361,7 @@ int gzread (file, buf, len)
|
||||
*/
|
||||
int gzwrite (file, buf, len)
|
||||
gzFile file;
|
||||
voidp buf;
|
||||
const voidp buf;
|
||||
unsigned len;
|
||||
{
|
||||
gz_stream *s = (gz_stream*)file;
|
||||
@ -343,7 +412,7 @@ int gzflush (file, flush)
|
||||
len = Z_BUFSIZE - s->stream.avail_out;
|
||||
|
||||
if (len != 0) {
|
||||
if (fwrite(s->outbuf, 1, len, s->file) != len) {
|
||||
if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
|
||||
s->z_err = Z_ERRNO;
|
||||
return Z_ERRNO;
|
||||
}
|
||||
@ -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)
|
||||
Bytef *buf;
|
||||
local uLong getLong (s)
|
||||
gz_stream *s;
|
||||
{
|
||||
uLong x = 0;
|
||||
Bytef *p = buf+4;
|
||||
uLong x = (uLong)get_byte(s);
|
||||
int c;
|
||||
|
||||
do {
|
||||
x <<= 8;
|
||||
x |= *--p;
|
||||
} while (p != buf);
|
||||
x += ((uLong)get_byte(s))<<8;
|
||||
x += ((uLong)get_byte(s))<<16;
|
||||
c = get_byte(s);
|
||||
if (c == EOF) s->z_err = Z_DATA_ERROR;
|
||||
x += ((uLong)c)<<24;
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -401,7 +471,6 @@ local uLong getLong (buf)
|
||||
int gzclose (file)
|
||||
gzFile file;
|
||||
{
|
||||
uInt n;
|
||||
int err;
|
||||
gz_stream *s = (gz_stream*)file;
|
||||
|
||||
@ -414,25 +483,6 @@ int gzclose (file)
|
||||
putLong (s->file, s->crc);
|
||||
putLong (s->file, s->stream.total_in);
|
||||
|
||||
} else if (s->mode == 'r' && s->z_err == Z_STREAM_END) {
|
||||
|
||||
/* slide CRC and original size if they are at the end of inbuf */
|
||||
if ((n = s->stream.avail_in) < 8 && !s->z_eof) {
|
||||
Byte *p = s->inbuf;
|
||||
Bytef *q = s->stream.next_in;
|
||||
while (n--) { *p++ = *q++; };
|
||||
|
||||
n = s->stream.avail_in;
|
||||
n += fread(p, 1, 8, s->file);
|
||||
s->stream.next_in = s->inbuf;
|
||||
}
|
||||
/* check CRC and original size */
|
||||
if (n < 8 ||
|
||||
getLong(s->stream.next_in) != s->crc ||
|
||||
getLong(s->stream.next_in + 4) != s->stream.total_out) {
|
||||
|
||||
s->z_err = Z_DATA_ERROR;
|
||||
}
|
||||
}
|
||||
return destroy(file);
|
||||
}
|
||||
@ -453,14 +503,14 @@ char* gzerror (file, errnum)
|
||||
|
||||
if (s == NULL) {
|
||||
*errnum = Z_STREAM_ERROR;
|
||||
return z_errmsg[1-Z_STREAM_ERROR];
|
||||
return ERR_MSG(Z_STREAM_ERROR);
|
||||
}
|
||||
*errnum = s->z_err;
|
||||
if (*errnum == Z_OK) return "";
|
||||
if (*errnum == Z_OK) return (char*)"";
|
||||
|
||||
m = *errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg;
|
||||
m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
|
||||
|
||||
if (m == NULL || *m == '\0') m = z_errmsg[1-s->z_err];
|
||||
if (m == NULL || *m == '\0') m = (char*)z_errmsg[1-s->z_err];
|
||||
|
||||
TRYFREE(s->msg);
|
||||
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
|
||||
|
25
infblock.c
25
infblock.c
@ -1,5 +1,5 @@
|
||||
/* infblock.c -- interpret and process block types to last block
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -81,7 +81,7 @@ uLongf *c;
|
||||
s->bitb = 0;
|
||||
s->read = s->write = s->window;
|
||||
if (s->checkfn != Z_NULL)
|
||||
s->check = (*s->checkfn)(0L, Z_NULL, 0);
|
||||
z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
|
||||
Trace((stderr, "inflate: blocks reset\n"));
|
||||
}
|
||||
|
||||
@ -172,17 +172,17 @@ int r;
|
||||
case 3: /* illegal */
|
||||
DUMPBITS(3)
|
||||
s->mode = BAD;
|
||||
z->msg = "invalid block type";
|
||||
z->msg = (char*)"invalid block type";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
break;
|
||||
case LENS:
|
||||
NEEDBITS(32)
|
||||
if (((~b) >> 16) != (b & 0xffff))
|
||||
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
|
||||
{
|
||||
s->mode = BAD;
|
||||
z->msg = "invalid stored block lengths";
|
||||
z->msg = (char*)"invalid stored block lengths";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
@ -215,7 +215,7 @@ int r;
|
||||
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
|
||||
{
|
||||
s->mode = BAD;
|
||||
z->msg = "too many length or distance symbols";
|
||||
z->msg = (char*)"too many length or distance symbols";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
@ -285,7 +285,7 @@ int r;
|
||||
(c == 16 && i < 1))
|
||||
{
|
||||
s->mode = BAD;
|
||||
z->msg = "invalid bit length repeat";
|
||||
z->msg = (char*)"invalid bit length repeat";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
@ -383,3 +383,14 @@ uLongf *c;
|
||||
Trace((stderr, "inflate: blocks freed\n"));
|
||||
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;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* infblock.h -- header to use infblock.c
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -30,3 +30,9 @@ extern int inflate_blocks_free OF((
|
||||
inflate_blocks_statef *,
|
||||
z_stream *,
|
||||
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 */
|
||||
|
11
infcodes.c
11
infcodes.c
@ -1,5 +1,5 @@
|
||||
/* infcodes.c -- process literals and length/distance pairs
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -58,7 +58,8 @@ struct inflate_codes_state {
|
||||
|
||||
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
|
||||
uInt bl, bd;
|
||||
inflate_huft *tl, *td;
|
||||
inflate_huft *tl;
|
||||
inflate_huft *td; /* need separate declaration for Borland C++ */
|
||||
z_stream *z;
|
||||
{
|
||||
inflate_codes_statef *c;
|
||||
@ -152,7 +153,7 @@ int r;
|
||||
break;
|
||||
}
|
||||
c->mode = BADCODE; /* invalid code */
|
||||
z->msg = "invalid literal/length code";
|
||||
z->msg = (char*)"invalid literal/length code";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
case LENEXT: /* i: getting length extra (have base) */
|
||||
@ -184,7 +185,7 @@ int r;
|
||||
break;
|
||||
}
|
||||
c->mode = BADCODE; /* invalid code */
|
||||
z->msg = "invalid distance code";
|
||||
z->msg = (char*)"invalid distance code";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
case DISTEXT: /* i: getting distance extra */
|
||||
@ -202,7 +203,7 @@ int r;
|
||||
#else
|
||||
f = q - 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
|
||||
while (c->len)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* infcodes.h -- header to use infcodes.c
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
11
inffast.c
11
inffast.c
@ -1,5 +1,5 @@
|
||||
/* inffast.c -- process literals and length/distance pairs fast
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -29,7 +29,8 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
int inflate_fast(bl, bd, tl, td, s, z)
|
||||
uInt bl, bd;
|
||||
inflate_huft *tl, *td;
|
||||
inflate_huft *tl;
|
||||
inflate_huft *td; /* need separate declaration for Borland C++ */
|
||||
inflate_blocks_statef *s;
|
||||
z_stream *z;
|
||||
{
|
||||
@ -102,7 +103,7 @@ z_stream *z;
|
||||
}
|
||||
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 */
|
||||
if (c > e) /* if source crosses, */
|
||||
{
|
||||
@ -122,7 +123,7 @@ z_stream *z;
|
||||
e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
|
||||
else
|
||||
{
|
||||
z->msg = "invalid distance code";
|
||||
z->msg = (char*)"invalid distance code";
|
||||
UNGRAB
|
||||
UPDATE
|
||||
return Z_DATA_ERROR;
|
||||
@ -152,7 +153,7 @@ z_stream *z;
|
||||
}
|
||||
else
|
||||
{
|
||||
z->msg = "invalid literal/length code";
|
||||
z->msg = (char*)"invalid literal/length code";
|
||||
UNGRAB
|
||||
UPDATE
|
||||
return Z_DATA_ERROR;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
101
inflate.c
101
inflate.c
@ -1,5 +1,5 @@
|
||||
/* inflate.c -- zlib interface to inflate modules
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -15,6 +15,11 @@ struct internal_state {
|
||||
enum {
|
||||
METHOD, /* waiting for method byte */
|
||||
FLAG, /* waiting for flag byte */
|
||||
DICT4, /* four dictionary check bytes to go */
|
||||
DICT3, /* three dictionary check bytes to go */
|
||||
DICT2, /* two dictionary check bytes to go */
|
||||
DICT1, /* one dictionary check byte to go */
|
||||
DICT0, /* waiting for inflateSetDictionary */
|
||||
BLOCKS, /* decompressing blocks */
|
||||
CHECK4, /* four check bytes to go */
|
||||
CHECK3, /* three check bytes to go */
|
||||
@ -75,14 +80,25 @@ z_stream *z;
|
||||
}
|
||||
|
||||
|
||||
int inflateInit2(z, w)
|
||||
int inflateInit2_(z, w, version, stream_size)
|
||||
z_stream *z;
|
||||
int w;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
|
||||
stream_size != sizeof(z_stream))
|
||||
return Z_VERSION_ERROR;
|
||||
|
||||
/* initialize state */
|
||||
if (z == Z_NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
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->state = (struct internal_state FAR *)
|
||||
ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
|
||||
@ -107,7 +123,7 @@ int w;
|
||||
|
||||
/* create inflate_blocks state */
|
||||
if ((z->state->blocks =
|
||||
inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
|
||||
inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
|
||||
== Z_NULL)
|
||||
{
|
||||
inflateEnd(z);
|
||||
@ -121,10 +137,12 @@ int w;
|
||||
}
|
||||
|
||||
|
||||
int inflateInit(z)
|
||||
int inflateInit_(z, version, stream_size)
|
||||
z_stream *z;
|
||||
const char *version;
|
||||
int stream_size;
|
||||
{
|
||||
return inflateInit2(z, DEF_WBITS);
|
||||
return inflateInit2_(z, DEF_WBITS, version, stream_size);
|
||||
}
|
||||
|
||||
|
||||
@ -138,46 +156,68 @@ int f;
|
||||
int r = f; /* to avoid warning about unused f */
|
||||
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;
|
||||
r = Z_BUF_ERROR;
|
||||
while (1) switch (z->state->mode)
|
||||
{
|
||||
case METHOD:
|
||||
NEEDBYTE
|
||||
if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
|
||||
if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->msg = "unknown compression method";
|
||||
z->msg = (char*)"unknown compression method";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
}
|
||||
if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->msg = "invalid window size";
|
||||
z->msg = (char*)"invalid window size";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
}
|
||||
z->state->mode = FLAG;
|
||||
case FLAG:
|
||||
NEEDBYTE
|
||||
if ((b = NEXTBYTE) & 0x20)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->msg = "invalid reserved bit";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
}
|
||||
b = NEXTBYTE;
|
||||
if (((z->state->sub.method << 8) + b) % 31)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->msg = "incorrect header check";
|
||||
z->msg = (char*)"incorrect header check";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
}
|
||||
Trace((stderr, "inflate: zlib header ok\n"));
|
||||
if (!(b & PRESET_DICT))
|
||||
{
|
||||
z->state->mode = BLOCKS;
|
||||
break;
|
||||
}
|
||||
z->state->mode = DICT4;
|
||||
case DICT4:
|
||||
NEEDBYTE
|
||||
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
|
||||
z->state->mode = DICT3;
|
||||
case DICT3:
|
||||
NEEDBYTE
|
||||
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
|
||||
z->state->mode = DICT2;
|
||||
case DICT2:
|
||||
NEEDBYTE
|
||||
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
|
||||
z->state->mode = DICT1;
|
||||
case DICT1:
|
||||
NEEDBYTE
|
||||
z->state->sub.check.need += (uLong)NEXTBYTE;
|
||||
z->adler = z->state->sub.check.need;
|
||||
z->state->mode = DICT0;
|
||||
return Z_NEED_DICT;
|
||||
case DICT0:
|
||||
z->state->mode = BAD;
|
||||
z->msg = (char*)"need dictionary";
|
||||
z->state->sub.marker = 0; /* can try inflateSync */
|
||||
return Z_STREAM_ERROR;
|
||||
case BLOCKS:
|
||||
r = inflate_blocks(z->state->blocks, z, r);
|
||||
if (r == Z_DATA_ERROR)
|
||||
@ -215,7 +255,7 @@ int f;
|
||||
if (z->state->sub.check.was != z->state->sub.check.need)
|
||||
{
|
||||
z->state->mode = BAD;
|
||||
z->msg = "incorrect data check";
|
||||
z->msg = (char*)"incorrect data check";
|
||||
z->state->sub.marker = 5; /* can't try inflateSync */
|
||||
break;
|
||||
}
|
||||
@ -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)
|
||||
z_stream *z;
|
||||
{
|
||||
|
77
inftrees.c
77
inftrees.c
@ -1,11 +1,18 @@
|
||||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
|
||||
char inflate_copyright[] = " inflate 1.0 Copyright 1995-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 */
|
||||
|
||||
/* simplify the use of the inflate_huft type with some defines */
|
||||
@ -30,23 +37,19 @@ local voidpf falloc OF((
|
||||
uInt, /* number of items */
|
||||
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. */
|
||||
local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
|
||||
local uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
/* actually lengths - 2; also see note #13 above about 258 */
|
||||
local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
|
||||
local uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
|
||||
local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
|
||||
local uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577};
|
||||
local uInt cpdext[] = { /* Extra bits for distance codes */
|
||||
local uInt cpdext[30] = { /* Extra bits for distance codes */
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||
12, 12, 13, 13};
|
||||
@ -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);
|
||||
if (r == Z_DATA_ERROR)
|
||||
z->msg = "oversubscribed dynamic bit lengths tree";
|
||||
z->msg = (char*)"oversubscribed dynamic bit lengths tree";
|
||||
else if (r == Z_BUF_ERROR)
|
||||
{
|
||||
inflate_trees_free(*tb, z);
|
||||
z->msg = "incomplete dynamic bit lengths tree";
|
||||
z->msg = (char*)"incomplete dynamic bit lengths tree";
|
||||
r = Z_DATA_ERROR;
|
||||
}
|
||||
return r;
|
||||
@ -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 == Z_DATA_ERROR)
|
||||
z->msg = "oversubscribed literal/length tree";
|
||||
z->msg = (char*)"oversubscribed literal/length tree";
|
||||
else if (r == Z_BUF_ERROR)
|
||||
{
|
||||
inflate_trees_free(*tl, z);
|
||||
z->msg = "incomplete literal/length tree";
|
||||
z->msg = (char*)"incomplete literal/length tree";
|
||||
r = Z_DATA_ERROR;
|
||||
}
|
||||
return r;
|
||||
@ -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 == Z_DATA_ERROR)
|
||||
z->msg = "oversubscribed literal/length tree";
|
||||
z->msg = (char*)"oversubscribed literal/length tree";
|
||||
else if (r == Z_BUF_ERROR) {
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
r = Z_OK;
|
||||
}
|
||||
#else
|
||||
inflate_trees_free(*td, z);
|
||||
z->msg = "incomplete literal/length tree";
|
||||
z->msg = (char*)"incomplete literal/length tree";
|
||||
r = Z_DATA_ERROR;
|
||||
}
|
||||
inflate_trees_free(*tl, z);
|
||||
@ -366,10 +369,8 @@ z_stream *z; /* for zfree function */
|
||||
|
||||
|
||||
/* build fixed tables only once--keep them here */
|
||||
local int fixed_lock = 0;
|
||||
local int fixed_built = 0;
|
||||
#define FIXEDH 530 /* number of hufts used by fixed tables */
|
||||
local uInt fixed_left = FIXEDH;
|
||||
local inflate_huft fixed_mem[FIXEDH];
|
||||
local uInt fixed_bl;
|
||||
local uInt fixed_bd;
|
||||
@ -378,24 +379,14 @@ local inflate_huft *fixed_td;
|
||||
|
||||
|
||||
local voidpf falloc(q, n, s)
|
||||
voidpf q; /* opaque pointer (not used) */
|
||||
voidpf q; /* opaque pointer */
|
||||
uInt n; /* number of items */
|
||||
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");
|
||||
if (q) s++; /* to make some compilers happy */
|
||||
fixed_left -= n;
|
||||
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 */
|
||||
*(intf *)q -= n+s-s; /* s-s to avoid warning */
|
||||
return (voidpf)(fixed_mem + *(intf *)q);
|
||||
}
|
||||
|
||||
|
||||
@ -405,19 +396,18 @@ uIntf *bd; /* distance desired/actual bit depth */
|
||||
inflate_huft * FAR *tl; /* literal/length tree result */
|
||||
inflate_huft * FAR *td; /* distance tree result */
|
||||
{
|
||||
/* build fixed tables if not built already--lock out other instances */
|
||||
while (++fixed_lock > 1)
|
||||
fixed_lock--;
|
||||
/* build fixed tables if not already (multiple overlapped executions ok) */
|
||||
if (!fixed_built)
|
||||
{
|
||||
int k; /* temporary variable */
|
||||
unsigned c[288]; /* length list for huft_build */
|
||||
z_stream z; /* for falloc function */
|
||||
int f = FIXEDH; /* number of hufts left in fixed_mem */
|
||||
|
||||
/* set up fake z_stream for memory routines */
|
||||
z.zalloc = falloc;
|
||||
z.zfree = ffree;
|
||||
z.opaque = Z_NULL;
|
||||
z.zfree = Z_NULL;
|
||||
z.opaque = (voidpf)&f;
|
||||
|
||||
/* literal table */
|
||||
for (k = 0; k < 144; k++)
|
||||
@ -438,9 +428,9 @@ inflate_huft * FAR *td; /* distance tree result */
|
||||
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
|
||||
|
||||
/* done */
|
||||
Assert(f == 0, "invalid build of fixed tables");
|
||||
fixed_built = 1;
|
||||
}
|
||||
fixed_lock--;
|
||||
*bl = fixed_bl;
|
||||
*bd = fixed_bd;
|
||||
*tl = fixed_tl;
|
||||
@ -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
|
||||
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. */
|
||||
p = t;
|
||||
while (p != Z_NULL)
|
||||
{
|
||||
q = (--p)->next;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* inflate_util.c -- data and routines common to blocks and codes
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
/* And'ing with mask[n] masks the lower n bits */
|
||||
uInt inflate_mask[] = {
|
||||
uInt inflate_mask[17] = {
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
@ -43,7 +43,7 @@ int r;
|
||||
|
||||
/* update check information */
|
||||
if (s->checkfn != Z_NULL)
|
||||
s->check = (*s->checkfn)(s->check, q, n);
|
||||
z->adler = s->check = (*s->checkfn)(s->check, q, n);
|
||||
|
||||
/* copy as far as end of window */
|
||||
zmemcpy(p, q, n);
|
||||
@ -69,7 +69,7 @@ int r;
|
||||
|
||||
/* update check information */
|
||||
if (s->checkfn != Z_NULL)
|
||||
s->check = (*s->checkfn)(s->check, q, n);
|
||||
z->adler = s->check = (*s->checkfn)(s->check, q, n);
|
||||
|
||||
/* copy */
|
||||
zmemcpy(p, q, n);
|
||||
|
29
infutil.h
29
infutil.h
@ -1,5 +1,5 @@
|
||||
/* infutil.h -- types and macros common to blocks and codes
|
||||
* Copyright (C) 1995 Mark Adler
|
||||
* Copyright (C) 1995-1996 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -8,11 +8,10 @@
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* inflate blocks semi-private state */
|
||||
struct inflate_blocks_state {
|
||||
#ifndef _INFUTIL_H
|
||||
#define _INFUTIL_H
|
||||
|
||||
/* mode */
|
||||
enum {
|
||||
typedef enum {
|
||||
TYPE, /* get type bits (3, including end bit) */
|
||||
LENS, /* get lengths for stored */
|
||||
STORED, /* processing stored block */
|
||||
@ -23,7 +22,13 @@ struct inflate_blocks_state {
|
||||
DRY, /* output remaining window bytes */
|
||||
DONE, /* finished last block, done */
|
||||
BAD} /* got a data error--stuck here */
|
||||
mode; /* current inflate_block mode */
|
||||
inflate_block_mode;
|
||||
|
||||
/* inflate blocks semi-private state */
|
||||
struct inflate_blocks_state {
|
||||
|
||||
/* mode */
|
||||
inflate_block_mode mode; /* current inflate_block mode */
|
||||
|
||||
/* mode dependent information */
|
||||
union {
|
||||
@ -70,17 +75,17 @@ struct inflate_blocks_state {
|
||||
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
|
||||
#define DUMPBITS(j) {b>>=(j);k-=(j);}
|
||||
/* output bytes */
|
||||
#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
|
||||
#define LOADOUT {q=s->write;m=WAVAIL;}
|
||||
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
|
||||
#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
|
||||
#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
|
||||
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
|
||||
#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
|
||||
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
|
||||
#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
|
||||
/* load local pointers */
|
||||
#define LOAD {LOADIN LOADOUT}
|
||||
|
||||
/* masks for lower bits */
|
||||
extern uInt inflate_mask[];
|
||||
/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
|
||||
extern uInt inflate_mask[17];
|
||||
|
||||
/* copy as much as possible from the sliding window to the output area */
|
||||
extern int inflate_flush OF((
|
||||
@ -89,3 +94,5 @@ extern int inflate_flush OF((
|
||||
int));
|
||||
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
#endif
|
||||
|
21
minigzip.c
21
minigzip.c
@ -1,5 +1,5 @@
|
||||
/* minigzip.c -- simulate gzip using the zlib compression library
|
||||
* Copyright (C) 1995 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-1996 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -18,14 +18,13 @@
|
||||
#include <stdio.h>
|
||||
#include "zlib.h"
|
||||
|
||||
#ifndef __GO32__
|
||||
extern void exit OF((int));
|
||||
#endif
|
||||
extern int unlink OF((const char *));
|
||||
|
||||
#ifdef STDC
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
extern void exit OF((int));
|
||||
#endif
|
||||
extern int unlink OF((const char *));
|
||||
|
||||
#if defined(MSDOS) || defined(OS2) || defined(WIN32)
|
||||
# include <fcntl.h>
|
||||
@ -53,7 +52,7 @@ extern int unlink OF((const char *));
|
||||
|
||||
char *prog;
|
||||
|
||||
void error OF((char *msg));
|
||||
void error OF((const char *msg));
|
||||
void gz_compress OF((FILE *in, gzFile out));
|
||||
void gz_uncompress OF((gzFile in, FILE *out));
|
||||
void file_compress OF((char *file));
|
||||
@ -64,7 +63,7 @@ int main OF((int argc, char *argv[]));
|
||||
* Display error message and exit
|
||||
*/
|
||||
void error(msg)
|
||||
char *msg;
|
||||
const char *msg;
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", prog, msg);
|
||||
exit(1);
|
||||
@ -89,7 +88,7 @@ void gz_compress(in, out)
|
||||
}
|
||||
if (len == 0) break;
|
||||
|
||||
if (gzwrite(out, buf, len) != len) error(gzerror(out, &err));
|
||||
if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
|
||||
}
|
||||
fclose(in);
|
||||
if (gzclose(out) != Z_OK) error("failed gzclose");
|
||||
@ -111,7 +110,9 @@ void gz_uncompress(in, out)
|
||||
if (len < 0) error (gzerror(in, &err));
|
||||
if (len == 0) break;
|
||||
|
||||
if (fwrite(buf, 1, len, out) != (uInt)len) error("failed fwrite");
|
||||
if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
|
||||
error("failed fwrite");
|
||||
}
|
||||
}
|
||||
if (fclose(out)) error("failed fclose");
|
||||
|
||||
|
92
trees.c
92
trees.c
@ -1,5 +1,5 @@
|
||||
/* trees.c -- output deflated data using Huffman coding
|
||||
* Copyright (C) 1995 Jean-loup Gailly
|
||||
* Copyright (C) 1995-1996 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -78,13 +78,12 @@ local uch bl_order[BL_CODES]
|
||||
|
||||
/* ===========================================================================
|
||||
* 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];
|
||||
/* The static literal tree. Since the bit lengths are imposed, there is no
|
||||
* need for the L_CODES extra codes used during heap construction. However
|
||||
* The codes 286 and 287 are needed to build a canonical tree (see ct_init
|
||||
* The codes 286 and 287 are needed to build a canonical tree (see _tr_init
|
||||
* below).
|
||||
*/
|
||||
|
||||
@ -129,7 +128,7 @@ local static_tree_desc static_bl_desc =
|
||||
* 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 pqdownheap OF((deflate_state *s, ct_data *tree, int k));
|
||||
local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
|
||||
@ -187,7 +186,7 @@ local void send_bits(s, value, length)
|
||||
int value; /* value to send */
|
||||
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");
|
||||
s->bits_sent += (ulg)length;
|
||||
|
||||
@ -227,11 +226,13 @@ local void send_bits(s, value, length)
|
||||
/* the arguments must not have side effects */
|
||||
|
||||
/* ===========================================================================
|
||||
* Initialize the various 'constant' tables.
|
||||
* To do: do this at compile time.
|
||||
* Initialize the various 'constant' tables. In a multi-threaded environment,
|
||||
* 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 bits; /* bit counter */
|
||||
int length; /* length value */
|
||||
@ -240,6 +241,8 @@ local void ct_static_init()
|
||||
ush bl_count[MAX_BITS+1];
|
||||
/* 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) */
|
||||
length = 0;
|
||||
for (code = 0; code < LENGTH_CODES-1; code++) {
|
||||
@ -248,7 +251,7 @@ local void ct_static_init()
|
||||
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
|
||||
* in two different ways: code 284 + 5 bits or code 285, so we
|
||||
* overwrite length_code[255] to use the best encoding:
|
||||
@ -263,7 +266,7 @@ local void ct_static_init()
|
||||
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 */
|
||||
for ( ; code < D_CODES; code++) {
|
||||
base_dist[code] = dist << 7;
|
||||
@ -271,7 +274,7 @@ local void ct_static_init()
|
||||
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 */
|
||||
for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
|
||||
@ -289,19 +292,18 @@ local void ct_static_init()
|
||||
/* The static distance tree is trivial: */
|
||||
for (n = 0; n < D_CODES; n++) {
|
||||
static_dtree[n].Len = 5;
|
||||
static_dtree[n].Code = bi_reverse(n, 5);
|
||||
static_dtree[n].Code = bi_reverse((unsigned)n, 5);
|
||||
}
|
||||
static_init_done = 1;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
* Initialize the tree data structures for a new zlib stream.
|
||||
*/
|
||||
void ct_init(s)
|
||||
void _tr_init(s)
|
||||
deflate_state *s;
|
||||
{
|
||||
if (static_dtree[0].Len == 0) {
|
||||
ct_static_init(); /* To do: at compile time */
|
||||
}
|
||||
tr_static_init();
|
||||
|
||||
s->compressed_len = 0L;
|
||||
|
||||
@ -523,7 +525,7 @@ local void gen_codes (tree, max_code, bl_count)
|
||||
/* Now reverse the bits */
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -783,14 +785,14 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
|
||||
/* ===========================================================================
|
||||
* 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;
|
||||
charf *buf; /* input block */
|
||||
ulg stored_len; /* length of input block */
|
||||
int eof; /* true if this is the last block for a file */
|
||||
{
|
||||
send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
|
||||
s->compressed_len = (s->compressed_len + 3 + 7) & ~7L;
|
||||
s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
|
||||
s->compressed_len += (stored_len + 4) << 3;
|
||||
|
||||
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
||||
@ -799,12 +801,15 @@ void ct_stored_block(s, buf, stored_len, eof)
|
||||
/* ===========================================================================
|
||||
* Send one empty static block to give enough lookahead for inflate.
|
||||
* 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
|
||||
* code for the previous block was coded on 5 bits or less, inflate
|
||||
* may have only 5+3 bits of lookahead to decode this EOB.
|
||||
* (There are no problems if the previous block is stored or fixed.)
|
||||
* The current inflate code requires 9 bits of lookahead. If the
|
||||
* last two codes for the previous block (real code plus EOB) were coded
|
||||
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
|
||||
* 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;
|
||||
{
|
||||
send_bits(s, STATIC_TREES<<1, 3);
|
||||
@ -812,10 +817,11 @@ void ct_align(s)
|
||||
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
||||
bi_flush(s);
|
||||
/* Of the 10 bits for the empty block, we have already sent
|
||||
* (10 - bi_valid) bits. The lookahead for the EOB of the previous
|
||||
* block was thus its length plus what we have just sent.
|
||||
* (10 - bi_valid) bits. The lookahead for the last real code (before
|
||||
* 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_code(s, END_BLOCK, static_ltree);
|
||||
s->compressed_len += 10L;
|
||||
@ -829,17 +835,20 @@ void ct_align(s)
|
||||
* trees or store, and output the encoded block to the zip file. This function
|
||||
* returns the total compressed length for the file so far.
|
||||
*/
|
||||
ulg ct_flush_block(s, buf, stored_len, eof)
|
||||
ulg _tr_flush_block(s, buf, stored_len, eof)
|
||||
deflate_state *s;
|
||||
charf *buf; /* input block, or NULL if too old */
|
||||
ulg stored_len; /* length of input block */
|
||||
int eof; /* true if this is the last block for a file */
|
||||
{
|
||||
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
|
||||
int max_blindex; /* index of last bit length code of non zero freq */
|
||||
int max_blindex = 0; /* index of last bit length code of non zero freq */
|
||||
|
||||
/* Build the Huffman trees unless a stored block is forced */
|
||||
if (s->level > 0) {
|
||||
|
||||
/* Check if the file is ascii or binary */
|
||||
if (s->data_type == UNKNOWN) set_data_type(s);
|
||||
if (s->data_type == Z_UNKNOWN) set_data_type(s);
|
||||
|
||||
/* Construct the literal and distance trees */
|
||||
build_tree(s, (tree_desc *)(&(s->l_desc)));
|
||||
@ -858,7 +867,7 @@ ulg ct_flush_block(s, buf, stored_len, eof)
|
||||
*/
|
||||
max_blindex = build_bl_tree(s);
|
||||
|
||||
/* Determine the best encoding. Compute first the block length in bytes */
|
||||
/* Determine the best encoding. Compute first the block length in bytes*/
|
||||
opt_lenb = (s->opt_len+3+7)>>3;
|
||||
static_lenb = (s->static_len+3+7)>>3;
|
||||
|
||||
@ -868,13 +877,18 @@ ulg ct_flush_block(s, buf, stored_len, eof)
|
||||
|
||||
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,
|
||||
* and if the .zip file can be seeked (to rewrite the local header),
|
||||
* the whole file is transformed into a stored file:
|
||||
*/
|
||||
#ifdef STORED_FILE_OK
|
||||
# ifdef FORCE_STORED_FILE
|
||||
if (eof && compressed_len == 0L) { /* force stored file */
|
||||
if (eof && s->compressed_len == 0L) { /* force stored file */
|
||||
# else
|
||||
if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
|
||||
# endif
|
||||
@ -899,7 +913,7 @@ ulg ct_flush_block(s, buf, stored_len, eof)
|
||||
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
|
||||
* 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
|
||||
} else if (static_lenb >= 0) { /* force static trees */
|
||||
@ -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
|
||||
* the current block must be flushed.
|
||||
*/
|
||||
int ct_tally (s, dist, lc)
|
||||
int _tr_tally (s, dist, lc)
|
||||
deflate_state *s;
|
||||
int dist; /* distance of matched string */
|
||||
int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||
unsigned dist; /* distance of matched string */
|
||||
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||
{
|
||||
s->d_buf[s->last_lit] = (ush)dist;
|
||||
s->l_buf[s->last_lit++] = (uch)lc;
|
||||
@ -949,7 +963,7 @@ int ct_tally (s, dist, lc)
|
||||
dist--; /* dist = match distance - 1 */
|
||||
Assert((ush)dist < (ush)MAX_DIST(s) &&
|
||||
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
|
||||
(ush)d_code(dist) < (ush)D_CODES, "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_dtree[d_code(dist)].Freq++;
|
||||
@ -959,7 +973,7 @@ int ct_tally (s, dist, lc)
|
||||
if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
|
||||
/* Compute an upper bound for the compressed length */
|
||||
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;
|
||||
for (dcode = 0; dcode < D_CODES; dcode++) {
|
||||
out_length += (ulg)s->dyn_dtree[dcode].Freq *
|
||||
@ -1043,7 +1057,7 @@ local void set_data_type(s)
|
||||
while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
|
||||
while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
|
||||
while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
|
||||
s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII);
|
||||
s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
@ -25,13 +25,13 @@
|
||||
int uncompress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
Bytef *source;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = source;
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
|
74
zconf.h
74
zconf.h
@ -1,5 +1,5 @@
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-1996 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -9,22 +9,55 @@
|
||||
#define _ZCONF_H
|
||||
|
||||
/*
|
||||
The library does not install any signal handler. It is recommended to
|
||||
add at least a handler for SIGSEGV when decompressing; the library checks
|
||||
the consistency of the input data whenever possible but may go nuts
|
||||
for some forms of corrupted input.
|
||||
* People prefering a unique prefix for all types and library functions
|
||||
* should compile with -DZ_PREFIX
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
* 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(_GNUC__) && !defined(__32BIT__)
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||
# define WIN32
|
||||
#endif
|
||||
#if (defined(__GNUC__) || defined(WIN32)) && !defined(__32BIT__)
|
||||
# define __32BIT__
|
||||
#endif
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#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__)
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
@ -32,20 +65,20 @@
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
|
||||
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
|
||||
# define STDC
|
||||
#endif
|
||||
#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
|
||||
# define STDC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const
|
||||
#if !defined(STDC) && !defined(const)
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
|
||||
# include <unix.h>
|
||||
# define Byte _Byte /* Byte already used on Mac */
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
@ -92,6 +125,7 @@
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR __far
|
||||
# else
|
||||
@ -99,11 +133,17 @@
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
# define FAR __far /* completely untested, just a best guess */
|
||||
# define SMALL_MEDIUM
|
||||
# define FAR __far
|
||||
#endif
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
/* The Watcom compiler defines M_I86SM and __SMALL__ even in 32 bit mode */
|
||||
#if defined(__WATCOMC__) && defined(__386__)
|
||||
# undef FAR
|
||||
# undef SMALL_MEDIUM
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
|
253
zlib.h
253
zlib.h
@ -1,7 +1,7 @@
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 0.95, Aug 16th, 1995.
|
||||
version 1.0, Jan 27th, 1996.
|
||||
|
||||
Copyright (C) 1995 Jean-loup Gailly and Mark Adler
|
||||
Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -26,9 +26,13 @@
|
||||
#ifndef _ZLIB_H
|
||||
#define _ZLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "zconf.h"
|
||||
|
||||
#define ZLIB_VERSION "0.95"
|
||||
#define ZLIB_VERSION "1.0"
|
||||
|
||||
/*
|
||||
The 'zlib' compression library provides in-memory compression and
|
||||
@ -47,6 +51,11 @@
|
||||
repeated calls of the compression function. In the latter case, the
|
||||
application must provide more input and/or consume the output
|
||||
(providing more output space) before each call.
|
||||
|
||||
The library does not install any signal handler. It is recommended to
|
||||
add at least a handler for SIGSEGV when decompressing; the library checks
|
||||
the consistency of the input data whenever possible but may go nuts
|
||||
for some forms of corrupted input.
|
||||
*/
|
||||
|
||||
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
|
||||
@ -68,10 +77,11 @@ typedef struct z_stream_s {
|
||||
|
||||
alloc_func zalloc; /* used to allocate the internal state */
|
||||
free_func zfree; /* used to free the internal state */
|
||||
voidp opaque; /* private data object passed to zalloc and zfree */
|
||||
|
||||
Byte data_type; /* best guess about the data type: ascii or binary */
|
||||
voidpf opaque; /* private data object passed to zalloc and zfree */
|
||||
|
||||
int data_type; /* best guess about the data type: ascii or binary */
|
||||
uLong adler; /* adler32 value of the uncompressed data */
|
||||
uLong reserved; /* reserved for future use */
|
||||
} z_stream;
|
||||
|
||||
/*
|
||||
@ -107,20 +117,25 @@ typedef struct z_stream_s {
|
||||
|
||||
#define Z_NO_FLUSH 0
|
||||
#define Z_PARTIAL_FLUSH 1
|
||||
#define Z_FULL_FLUSH 2
|
||||
#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
|
||||
#define Z_SYNC_FLUSH 2
|
||||
#define Z_FULL_FLUSH 3
|
||||
#define Z_FINISH 4
|
||||
/* See deflate() below for the usage of these constants */
|
||||
/* Allowed flush values; see deflate() below for details */
|
||||
|
||||
#define Z_OK 0
|
||||
#define Z_STREAM_END 1
|
||||
#define Z_NEED_DICT 2
|
||||
#define Z_ERRNO (-1)
|
||||
#define Z_STREAM_ERROR (-2)
|
||||
#define Z_DATA_ERROR (-3)
|
||||
#define Z_MEM_ERROR (-4)
|
||||
#define Z_BUF_ERROR (-5)
|
||||
/* error codes for the compression/decompression functions */
|
||||
#define Z_VERSION_ERROR (-6)
|
||||
/* Return codes for the compression/decompression functions. Negative
|
||||
* values are errors, positive values are used for special but normal events.
|
||||
*/
|
||||
|
||||
#define Z_NO_COMPRESSION 0
|
||||
#define Z_BEST_SPEED 1
|
||||
#define Z_BEST_COMPRESSION 9
|
||||
#define Z_DEFAULT_COMPRESSION (-1)
|
||||
@ -129,15 +144,19 @@ typedef struct z_stream_s {
|
||||
#define Z_FILTERED 1
|
||||
#define Z_HUFFMAN_ONLY 2
|
||||
#define Z_DEFAULT_STRATEGY 0
|
||||
/* compression strategy; see deflateInit2() below for details */
|
||||
|
||||
#define Z_BINARY 0
|
||||
#define Z_ASCII 1
|
||||
#define Z_UNKNOWN 2
|
||||
/* Used to set the data_type field */
|
||||
/* Possible values of the data_type field */
|
||||
|
||||
#define Z_DEFLATED 8
|
||||
/* The deflate compression method (the only one supported in this version) */
|
||||
|
||||
#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
|
||||
|
||||
extern char *zlib_version;
|
||||
extern const char *zlib_version;
|
||||
/* The application can compare zlib_version and ZLIB_VERSION for consistency.
|
||||
If the first character differs, the library code actually used is
|
||||
not compatible with the zlib.h header file used by the application.
|
||||
@ -145,20 +164,24 @@ extern char *zlib_version;
|
||||
|
||||
/* basic functions */
|
||||
|
||||
extern int deflateInit OF((z_stream *strm, int level));
|
||||
/*
|
||||
extern int deflateInit OF((z_stream *strm, int level));
|
||||
|
||||
Initializes the internal stream state for compression. The fields
|
||||
zalloc, zfree and opaque must be initialized before by the caller.
|
||||
If zalloc and zfree are set to Z_NULL, deflateInit updates them to
|
||||
use default allocation functions.
|
||||
|
||||
The compression level must be Z_DEFAULT_COMPRESSION, or between 1 and 9:
|
||||
1 gives best speed, 9 gives best compression. Z_DEFAULT_COMPRESSION requests
|
||||
a default compromise between speed and compression (currently equivalent
|
||||
to level 6).
|
||||
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
|
||||
1 gives best speed, 9 gives best compression, 0 gives no compression at
|
||||
all (the input data is simply copied a block at a time).
|
||||
Z_DEFAULT_COMPRESSION requests a default compromise between speed and
|
||||
compression (currently equivalent to level 6).
|
||||
|
||||
deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_STREAM_ERROR if level is not a valid compression level.
|
||||
enough memory, Z_STREAM_ERROR if level is not a valid compression level,
|
||||
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
|
||||
with the version assumed by the caller (ZLIB_VERSION).
|
||||
msg is set to null if there is no error message. deflateInit does not
|
||||
perform any compression: this will be done by deflate().
|
||||
*/
|
||||
@ -190,6 +213,11 @@ extern int deflate OF((z_stream *strm, int flush));
|
||||
block is terminated and flushed to the output buffer so that the
|
||||
decompressor can get all input data available so far. For method 9, a future
|
||||
variant on method 8, the current block will be flushed but not terminated.
|
||||
Z_SYNC_FLUSH has the same effect as partial flush except that the compressed
|
||||
output is byte aligned (the compressor can clear its internal bit buffer)
|
||||
and the current block is always terminated; this can be useful if the
|
||||
compressor has to be restarted from scratch after an interruption (in which
|
||||
case the internal state of the compressor may be lost).
|
||||
If flush is set to Z_FULL_FLUSH, the compression block is terminated, a
|
||||
special marker is output and the compression dictionary is discarded; this
|
||||
is useful to allow the decompressor to synchronize if one compressed block
|
||||
@ -233,22 +261,26 @@ extern int deflateEnd OF((z_stream *strm));
|
||||
pending output.
|
||||
|
||||
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
|
||||
stream state was inconsistent. In the error case, msg may be set
|
||||
but then points to a static string (which must not be deallocated).
|
||||
stream state was inconsistent, Z_DATA_ERROR if the stream was freed
|
||||
prematurely (some input or output was discarded). In the error case,
|
||||
msg may be set but then points to a static string (which must not be
|
||||
deallocated).
|
||||
*/
|
||||
|
||||
|
||||
extern int inflateInit OF((z_stream *strm));
|
||||
/*
|
||||
extern int inflateInit OF((z_stream *strm));
|
||||
|
||||
Initializes the internal stream state for decompression. The fields
|
||||
zalloc and zfree must be initialized before by the caller. If zalloc and
|
||||
zfree are set to Z_NULL, inflateInit updates them to use default allocation
|
||||
functions.
|
||||
zalloc, zfree and opaque must be initialized before by the caller. If
|
||||
zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
|
||||
allocation functions.
|
||||
|
||||
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory. msg is set to null if there is no error message.
|
||||
inflateInit does not perform any decompression: this will be done by
|
||||
inflate().
|
||||
enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
|
||||
with the version assumed by the caller. msg is set to null if there is no
|
||||
error message. inflateInit does not perform any decompression: this will be
|
||||
done by inflate().
|
||||
*/
|
||||
|
||||
|
||||
@ -292,12 +324,15 @@ extern int inflate OF((z_stream *strm, int flush));
|
||||
inflate() returns Z_OK if some progress has been made (more input
|
||||
processed or more output produced), Z_STREAM_END if the end of the
|
||||
compressed data has been reached and all uncompressed output has been
|
||||
produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
|
||||
the stream structure was inconsistent (for example if next_in or next_out
|
||||
was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
|
||||
progress is possible or if there was not enough room in the output buffer
|
||||
when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
|
||||
call inflateSync to look for a good compression block.
|
||||
produced, Z_NEED_DICT if a preset dictionary is needed at this point (see
|
||||
inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted,
|
||||
Z_STREAM_ERROR if the stream structure was inconsistent (for example if
|
||||
next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
|
||||
Z_BUF_ERROR if no progress is possible or if there was not enough room in
|
||||
the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the
|
||||
application may then call inflateSync to look for a good compression block.
|
||||
In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the
|
||||
dictionary chosen by the compressor.
|
||||
*/
|
||||
|
||||
|
||||
@ -312,24 +347,26 @@ extern int inflateEnd OF((z_stream *strm));
|
||||
static string (which must not be deallocated).
|
||||
*/
|
||||
|
||||
/* advanced functions */
|
||||
/* Advanced functions */
|
||||
|
||||
/*
|
||||
The following functions are needed only in some special applications.
|
||||
*/
|
||||
|
||||
/*
|
||||
extern int deflateInit2 OF((z_stream *strm,
|
||||
int level,
|
||||
int method,
|
||||
int windowBits,
|
||||
int memLevel,
|
||||
int strategy));
|
||||
/*
|
||||
This is another version of deflateInit with more compression options. The
|
||||
fields next_in, zalloc and zfree must be initialized before by the caller.
|
||||
|
||||
The method parameter is the compression method. It must be 8 in this
|
||||
version of the library. (Method 9 will allow a 64K history buffer and
|
||||
This is another version of deflateInit with more compression options. The
|
||||
fields next_in, zalloc, zfree and opaque must be initialized before by
|
||||
the caller.
|
||||
|
||||
The method parameter is the compression method. It must be Z_DEFLATED in
|
||||
this version of the library. (Method 9 will allow a 64K history buffer and
|
||||
partial block flushes.)
|
||||
|
||||
The windowBits parameter is the base two logarithm of the window size
|
||||
@ -344,14 +381,16 @@ extern int deflateInit2 OF((z_stream *strm,
|
||||
for optimal speed. The default value is 8. See zconf.h for total memory
|
||||
usage as a function of windowBits and memLevel.
|
||||
|
||||
The strategy parameter is used to tune the compression algorithm. Use
|
||||
the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data
|
||||
produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman
|
||||
encoding only (no string match). Filtered data consists mostly of small
|
||||
values with a somewhat random distribution. In this case, the
|
||||
compression algorithm is tuned to compress them better. The strategy
|
||||
parameter only affects the compression ratio but not the correctness of
|
||||
the compressed output even if it is not set appropriately.
|
||||
The strategy parameter is used to tune the compression algorithm. Use the
|
||||
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
|
||||
filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
|
||||
string match). Filtered data consists mostly of small values with a
|
||||
somewhat random distribution. In this case, the compression algorithm is
|
||||
tuned to compress them better. The effect of Z_FILTERED is to force more
|
||||
Huffman coding and less string matching; it is somewhat intermediate
|
||||
between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
|
||||
the compression ratio but not the correctness of the compressed output even
|
||||
if it is not set appropriately.
|
||||
|
||||
If next_in is not null, the library will use this buffer to hold also
|
||||
some history information; the buffer must either hold the entire input
|
||||
@ -373,6 +412,35 @@ extern int deflateInit2 OF((z_stream *strm,
|
||||
deflate().
|
||||
*/
|
||||
|
||||
extern int deflateSetDictionary OF((z_stream *strm,
|
||||
const Bytef *dictionary,
|
||||
uInt dictLength));
|
||||
/*
|
||||
Initializes the compression dictionary (history buffer) from the given
|
||||
byte sequence without producing any compressed output. This function must
|
||||
be called immediately after deflateInit or deflateInit2, before any call
|
||||
of deflate. The compressor and decompressor must use exactly the same
|
||||
dictionary (see inflateSetDictionary).
|
||||
The dictionary should consist of strings (byte sequences) that are likely
|
||||
to be encountered later in the data to be compressed, with the most commonly
|
||||
used strings preferably put towards the end of the dictionary. Using a
|
||||
dictionary is most useful when the data to be compressed is short and
|
||||
can be predicted with good accuracy; the data can then be compressed better
|
||||
than with the default empty dictionary. In this version of the library,
|
||||
only the last 32K bytes of the dictionary are used.
|
||||
Upon return of this function, strm->adler is set to the Adler32 value
|
||||
of the dictionary; the decompressor may later use this value to determine
|
||||
which dictionary has been used by the compressor. (The Adler32 value
|
||||
applies to the whole dictionary even if only a subset of the dictionary is
|
||||
actually used by the compressor.)
|
||||
|
||||
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
||||
parameter is invalid (such as NULL dictionary) or the stream state
|
||||
is inconsistent (for example if deflate has already been called for this
|
||||
stream). deflateSetDictionary does not perform any compression: this will
|
||||
be done by deflate().
|
||||
*/
|
||||
|
||||
extern int deflateCopy OF((z_stream *dest,
|
||||
z_stream *source));
|
||||
/*
|
||||
@ -383,7 +451,7 @@ extern int deflateCopy OF((z_stream *dest,
|
||||
application to provide the correct values of next_out and avail_out for the
|
||||
next call of deflate.
|
||||
|
||||
This function is useful when several compression strategies will be
|
||||
This function can be useful when several compression strategies will be
|
||||
tried, for example when there are several ways of pre-processing the input
|
||||
data with a filter. The streams that will be discarded should then be freed
|
||||
by calling deflateEnd. Note that deflateCopy duplicates the internal
|
||||
@ -407,11 +475,26 @@ extern int deflateReset OF((z_stream *strm));
|
||||
stream state was inconsistent (such as zalloc or state being NULL).
|
||||
*/
|
||||
|
||||
extern int deflateParams OF((z_stream *strm, int level, int strategy));
|
||||
/*
|
||||
Dynamically update the compression level and compression strategy.
|
||||
This can be used to switch between compression and straight copy of
|
||||
the input data, or to switch to a different kind of input data requiring
|
||||
a different strategy. If the compression level is changed, the input
|
||||
available so far is compressed with the old level (and may be flushed);
|
||||
the new level will take effect only at the next call of deflate().
|
||||
|
||||
deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
|
||||
stream state was inconsistent or if a parameter was invalid.
|
||||
*/
|
||||
|
||||
/*
|
||||
extern int inflateInit2 OF((z_stream *strm,
|
||||
int windowBits));
|
||||
/*
|
||||
|
||||
This is another version of inflateInit with more compression options. The
|
||||
fields next_out, zalloc and zfree must be initialized before by the caller.
|
||||
fields next_out, zalloc, zfree and opaque must be initialized before by
|
||||
the caller.
|
||||
|
||||
The windowBits parameter is the base two logarithm of the maximum window
|
||||
size (the size of the history buffer). It should be in the range 8..15 for
|
||||
@ -440,6 +523,25 @@ extern int inflateInit2 OF((z_stream *strm,
|
||||
inflate().
|
||||
*/
|
||||
|
||||
extern int inflateSetDictionary OF((z_stream *strm,
|
||||
const Bytef *dictionary,
|
||||
uInt dictLength));
|
||||
/*
|
||||
Initializes the decompression dictionary (history buffer) from the given
|
||||
uncompressed byte sequence. This function must be called immediately after
|
||||
a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen
|
||||
by the compressor can be determined from the Adler32 value returned by this
|
||||
call of inflate. The compressor and decompressor must use exactly the same
|
||||
dictionary (see deflateSetDictionary).
|
||||
|
||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||
parameter is invalid (such as NULL dictionary) or the stream state is
|
||||
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
|
||||
expected one (incorrect Adler32 value). inflateSetDictionary does not
|
||||
perform any decompression: this will be done by subsequent calls of
|
||||
inflate().
|
||||
*/
|
||||
|
||||
extern int inflateSync OF((z_stream *strm));
|
||||
/*
|
||||
Skips invalid compressed data until the special marker (see deflate()
|
||||
@ -477,7 +579,7 @@ extern int inflateReset OF((z_stream *strm));
|
||||
*/
|
||||
|
||||
extern int compress OF((Bytef *dest, uLongf *destLen,
|
||||
Bytef *source, uLong sourceLen));
|
||||
const Bytef *source, uLong sourceLen));
|
||||
/*
|
||||
Compresses the source buffer into the destination buffer. sourceLen is
|
||||
the byte length of the source buffer. Upon entry, destLen is the total
|
||||
@ -492,7 +594,7 @@ extern int compress OF((Bytef *dest, uLongf *destLen,
|
||||
*/
|
||||
|
||||
extern int uncompress OF((Bytef *dest, uLongf *destLen,
|
||||
Bytef *source, uLong sourceLen));
|
||||
const Bytef *source, uLong sourceLen));
|
||||
/*
|
||||
Decompresses the source buffer into the destination buffer. sourceLen is
|
||||
the byte length of the source buffer. Upon entry, destLen is the total
|
||||
@ -512,7 +614,7 @@ extern int uncompress OF((Bytef *dest, uLongf *destLen,
|
||||
|
||||
typedef voidp gzFile;
|
||||
|
||||
extern gzFile gzopen OF((char *path, char *mode));
|
||||
extern gzFile gzopen OF((const char *path, const char *mode));
|
||||
/*
|
||||
Opens a gzip (.gz) file for reading or writing. The mode parameter
|
||||
is as in fopen ("rb" or "wb") but can also include a compression level
|
||||
@ -524,11 +626,15 @@ extern gzFile gzopen OF((char *path, char *mode));
|
||||
zlib error is Z_MEM_ERROR).
|
||||
*/
|
||||
|
||||
extern gzFile gzdopen OF((int fd, char *mode));
|
||||
extern gzFile gzdopen OF((int fd, const char *mode));
|
||||
/*
|
||||
gzdopen() associates a gzFile with the file descriptor fd. File
|
||||
descriptors are obtained from calls like open, dup, creat, or pipe.
|
||||
descriptors are obtained from calls like open, dup, creat, pipe or
|
||||
fileno (in the file has been previously opened with fopen).
|
||||
The mode parameter is as in fopen ("rb" or "wb").
|
||||
The next call of gzclose on the returned gzFile will also close the
|
||||
file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
|
||||
descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
|
||||
gzdopen returns NULL if there was insufficient memory to allocate
|
||||
the (de)compression state.
|
||||
*/
|
||||
@ -541,7 +647,7 @@ extern int gzread OF((gzFile file, voidp buf, unsigned len));
|
||||
gzread returns the number of uncompressed bytes actually read (0 for
|
||||
end of file, -1 for error). */
|
||||
|
||||
extern int gzwrite OF((gzFile file, voidp buf, unsigned len));
|
||||
extern int gzwrite OF((gzFile file, const voidp buf, unsigned len));
|
||||
/*
|
||||
Writes the given number of uncompressed bytes into the compressed file.
|
||||
gzwrite returns the number of uncompressed bytes actually written
|
||||
@ -582,7 +688,7 @@ extern char* gzerror OF((gzFile file, int *errnum));
|
||||
compression library.
|
||||
*/
|
||||
|
||||
extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
|
||||
extern uLong adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
||||
|
||||
/*
|
||||
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
||||
@ -599,7 +705,7 @@ extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
|
||||
if (adler != original_adler) error();
|
||||
*/
|
||||
|
||||
extern uLong crc32 OF((uLong crc, Bytef *buf, uInt len));
|
||||
extern uLong crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||
/*
|
||||
Update a running crc with the bytes buf[0..len-1] and return the updated
|
||||
crc. If buf is NULL, this function returns the required initial value
|
||||
@ -615,8 +721,39 @@ extern uLong crc32 OF((uLong crc, Bytef *buf, uInt len));
|
||||
if (crc != original_crc) error();
|
||||
*/
|
||||
|
||||
|
||||
/* various hacks, don't look :) */
|
||||
|
||||
/* deflateInit and inflateInit are macros to allow checking the zlib version
|
||||
* and the compiler's view of z_stream:
|
||||
*/
|
||||
extern int deflateInit_ OF((z_stream *strm, int level,
|
||||
const char *version, int stream_size));
|
||||
extern int inflateInit_ OF((z_stream *strm,
|
||||
const char *version, int stream_size));
|
||||
extern int deflateInit2_ OF((z_stream *strm, int level, int method,
|
||||
int windowBits, int memLevel, int strategy,
|
||||
const char *version, int stream_size));
|
||||
extern int inflateInit2_ OF((z_stream *strm, int windowBits,
|
||||
const char *version, int stream_size));
|
||||
#define deflateInit(strm, level) \
|
||||
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
|
||||
#define inflateInit(strm) \
|
||||
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
|
||||
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
||||
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
||||
(strategy), ZLIB_VERSION, sizeof(z_stream))
|
||||
#define inflateInit2(strm, windowBits) \
|
||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
|
||||
|
||||
#ifndef _Z_UTIL_H
|
||||
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
||||
#endif
|
||||
|
||||
uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZLIB_H */
|
||||
|
30
zutil.c
30
zutil.c
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
@ -11,13 +11,14 @@
|
||||
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
#ifndef __GO32__
|
||||
#ifndef STDC
|
||||
extern void exit OF((int));
|
||||
#endif
|
||||
|
||||
char *zlib_version = ZLIB_VERSION;
|
||||
const char *zlib_version = ZLIB_VERSION;
|
||||
|
||||
char *z_errmsg[] = {
|
||||
const char *z_errmsg[10] = {
|
||||
"need dictionary", /* Z_NEED_DICT 2 */
|
||||
"stream end", /* Z_STREAM_END 1 */
|
||||
"", /* Z_OK 0 */
|
||||
"file error", /* Z_ERRNO (-1) */
|
||||
@ -25,6 +26,7 @@ char *z_errmsg[] = {
|
||||
"data error", /* Z_DATA_ERROR (-3) */
|
||||
"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)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined( __TURBOC__) && !defined(__SMALL__) && !defined(__MEDIUM__)
|
||||
/* Small and medium model are for now limited to near allocation with
|
||||
* reduced MAX_WBITS and MAX_MEM_LEVEL
|
||||
#ifdef __TURBOC__
|
||||
#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
|
||||
/* Small and medium model in Turbo C are for now limited to near allocation
|
||||
* with reduced MAX_WBITS and MAX_MEM_LEVEL
|
||||
*/
|
||||
# define MY_ZCALLOC
|
||||
|
||||
@ -94,7 +97,10 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
voidpf buf = opaque; /* just to make some compilers happy */
|
||||
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);
|
||||
if (*(ush*)&buf != 0) return buf;
|
||||
} else {
|
||||
@ -131,9 +137,11 @@ void zcfree (voidpf opaque, voidpf ptr)
|
||||
ptr = opaque; /* just to make some compilers happy */
|
||||
z_error("zcfree: ptr not found");
|
||||
}
|
||||
#endif
|
||||
#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 */
|
||||
|
||||
# define MY_ZCALLOC
|
||||
@ -160,7 +168,7 @@ void zcfree (voidpf opaque, voidpf ptr)
|
||||
|
||||
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
|
||||
|
||||
#ifndef __GO32__
|
||||
#ifndef STDC
|
||||
extern voidp calloc OF((uInt items, uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
@ -170,6 +178,7 @@ voidpf zcalloc (opaque, items, size)
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
return (voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
@ -177,6 +186,7 @@ void zcfree (opaque, ptr)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
25
zutil.h
25
zutil.h
@ -1,5 +1,5 @@
|
||||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995 Jean-loup Gailly.
|
||||
* Copyright (C) 1995-1996 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
#if defined(MSDOS) || defined(VMS)
|
||||
#if defined(MSDOS) || defined(VMS) || defined(CRAY) || defined(WIN32)
|
||||
# include <stddef.h>
|
||||
# include <errno.h>
|
||||
#else
|
||||
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
#ifdef STDC
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
@ -36,15 +37,17 @@ typedef unsigned short ush;
|
||||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern char *z_errmsg[]; /* indexed by 1-zlib_error */
|
||||
extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
/* (size given to avoid silly warnings with Visual C++) */
|
||||
|
||||
#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
|
||||
#define ERR_MSG(err) (char*)z_errmsg[Z_NEED_DICT-(err)]
|
||||
|
||||
#define ERR_RETURN(strm,err) \
|
||||
return (strm->msg = ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
|
||||
#define DEFLATED 8
|
||||
|
||||
#ifndef DEF_WBITS
|
||||
# define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
@ -66,6 +69,8 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
/* target dependencies */
|
||||
|
||||
#ifdef MSDOS
|
||||
@ -81,7 +86,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
|
||||
# define OS_CODE 0x06
|
||||
#endif
|
||||
|
||||
#ifdef WIN32 /* Windows NT */
|
||||
#ifdef WIN32 /* Window 95 & Windows NT */
|
||||
# define OS_CODE 0x0b
|
||||
#endif
|
||||
|
||||
@ -143,11 +148,13 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
|
||||
# define HAVE_MEMCPY
|
||||
#endif
|
||||
#ifdef HAVE_MEMCPY
|
||||
# if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */
|
||||
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
|
||||
# define zmemcpy _fmemcpy
|
||||
# define zmemcmp _fmemcmp
|
||||
# define zmemzero(dest, len) _fmemset(dest, 0, len)
|
||||
# else
|
||||
# define zmemcpy memcpy
|
||||
# define zmemcmp memcmp
|
||||
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||
# endif
|
||||
#else
|
||||
@ -177,7 +184,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
|
||||
#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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user