Compare commits

..

5 Commits

Author SHA1 Message Date
Mark Adler
ff11b0a61f zlib 1.0.4 2011-09-09 23:17:02 -07:00
Mark Adler
e26a448e96 zlib 1.0.2 2011-09-09 23:15:17 -07:00
Mark Adler
423eb40306 zlib 1.0.1 2011-09-09 23:14:39 -07:00
Mark Adler
8a2acbffc8 zlib 1.0-pre 2011-09-09 23:13:27 -07:00
Mark Adler
56bcb184fa zlib 0.99 2011-09-09 23:11:37 -07:00
43 changed files with 2801 additions and 926 deletions

111
ChangeLog
View File

@@ -1,6 +1,117 @@
ChangeLog file for zlib ChangeLog file for zlib
Changes in 1.0.4 (24 Jul 96)
- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
bit, so the decompressor could decompress all the correct data but went
on to attempt decompressing extra garbage data. This affected minigzip too.
- zlibVersion and gzerror return const char* (needed for DLL)
- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
- use z_error only for DEBUG (avoid problem with DLLs)
Changes in 1.0.3 (2 Jul 96)
- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
small and medium models; this makes the library incompatible with previous
versions for these models. (No effect in large model or on other systems.)
- return OK instead of BUF_ERROR if previous deflate call returned with
avail_out as zero but there is nothing to do
- added memcmp for non STDC compilers
- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
- better check for 16-bit mode MSC (avoids problem with Symantec)
Changes in 1.0.2 (23 May 96)
- added Windows DLL support
- added a function zlibVersion (for the DLL support)
- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
- Bytef is define's instead of typedef'd only for Borland C
- avoid reading uninitialized memory in example.c
- mention in README that the zlib format is now RFC1950
- updated Makefile.dj2
- added algorithm.doc
Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
- fix array overlay in deflate.c which sometimes caused bad compressed data
- fix inflate bug with empty stored block
- fix MSDOS medium model which was broken in 0.99
- fix deflateParams() which could generated bad compressed data.
- Bytef is define'd instead of typedef'ed (work around Borland bug)
- added an INDEX file
- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
- speed up adler32 for modern machines without auto-increment
- added -ansi for IRIX in configure
- static_init_done in trees.c is an int
- define unlink as delete for VMS
- fix configure for QNX
- add configure branch for SCO and HPUX
- avoid many warnings (unused variables, dead assignments, etc...)
- no fdopen for BeOS
- fix the Watcom fix for 32 bit mode (define FAR as empty)
- removed redefinition of Byte for MKWERKS
- work around an MWKERKS bug (incorrect merge of all .h files)
Changes in 0.99 (27 Jan 96)
- allow preset dictionary shared between compressor and decompressor
- allow compression level 0 (no compression)
- add deflateParams in zlib.h: allow dynamic change of compression level
and compression strategy.
- test large buffers and deflateParams in example.c
- add optional "configure" to build zlib as a shared library
- suppress Makefile.qnx, use configure instead
- fixed deflate for 64-bit systems (detected on Cray)
- fixed inflate_blocks for 64-bit systems (detected on Alpha)
- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
- always return Z_BUF_ERROR when deflate() has nothing to do
- deflateInit and inflateInit are now macros to allow version checking
- prefix all global functions and types with z_ with -DZ_PREFIX
- make falloc completely reentrant (inftrees.c)
- fixed very unlikely race condition in ct_static_init
- free in reverse order of allocation to help memory manager
- use zlib-1.0/* instead of zlib/* inside the tar.gz
- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
-Wconversion -Wstrict-prototypes -Wmissing-prototypes"
- allow gzread on concatenated .gz files
- deflateEnd now returns Z_DATA_ERROR if it was premature
- deflate is finally (?) fully deterministic (no matches beyond end of input)
- Document Z_SYNC_FLUSH
- add uninstall in Makefile
- Check for __cpluplus in zlib.h
- Better test in ct_align for partial flush
- avoid harmless warnings for Borland C++
- initialize hash_head in deflate.c
- avoid warning on fdopen (gzio.c) for HP cc -Aa
- include stdlib.h for STDC compilers
- include errno.h for Cray
- ignore error if ranlib doesn't exist
- call ranlib twice for NeXTSTEP
- use exec_prefix instead of prefix for libz.a
- renamed ct_* as _tr_* to avoid conflict with applications
- clear z->msg in inflateInit2 before any error return
- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
- fixed typo in zconf.h (_GNUC__ => __GNUC__)
- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
- in fcalloc, normalize pointer if size > 65520 bytes
- don't use special fcalloc for 32 bit Borland C++
- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
- use Z_BINARY instead of BINARY
- document that gzclose after gzdopen will close the file
- allow "a" as mode in gzopen.
- fix error checking in gzread
- allow skipping .gz extra-field on pipes
- added reference to Perl interface in README
- put the crc table in FAR data (I dislike more and more the medium model :)
- added get_crc_table
- added a dimension to all arrays (Borland C can't count).
- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
- guard against multiple inclusion of *.h (for precompiled header on Mac)
- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
- don't use unsized arrays to avoid silly warnings by Visual C++:
warning C4746: 'inflate_mask' : unsized array treated as '__far'
(what's wrong with far data in far model?).
- define enum out of inflate_blocks_state to allow compilation with C++
Changes in 0.95 (16 Aug 95) Changes in 0.95 (16 Aug 95)
- fix MSDOS small and medium model (now easier to adapt to any compiler) - fix MSDOS small and medium model (now easier to adapt to any compiler)
- inlined send_bits - inlined send_bits

51
INDEX Normal file
View File

@@ -0,0 +1,51 @@
ChangeLog history of changes
INDEX this file
Make_vms.com script for Vax/VMS
Makefile makefile for Unix (generated by configure)
Makefile.b32 makefile for Borland C++ 32-bit
Makefile.bor makefile for Borland C/C++ 16-bit
Makefile.dj2 makefile for DJGPP 2.x
Makefile.in makefile for Unix (template for configure)
Makefile.msc makefile for Microsoft C 16-bit
Makefile.riscos makefile for RISCOS
Makefile.sas makefile for Amiga SAS/C
Makefile.tc makefile for Turbo C
Makefile.wat makefile for Watcom C
README guess what
algorithm.doc description of the compression & decompression algorithms
configure configure script for Unix
descrip.mms makefile for Vax/VMS
zlib.def definition file for Windows DLL
zlib.rc definition file for Windows DLL
zlib public header files (must be kept):
zconf.h
zlib.h
private source files used to build the zlib library:
adler32.c
compress.c
crc32.c
deflate.c
deflate.h
gzio.c
infblock.c
infblock.h
infcodes.c
infcodes.h
inffast.c
inffast.h
inflate.c
inftrees.c
inftrees.h
infutil.c
infutil.h
trees.c
uncompr.c
zutil.c
zutil.h
source files for sample programs:
example.c
minigzip.c

View File

@@ -4,7 +4,7 @@ $!
$! Look for the compiler used $! Look for the compiler used
$! $!
$ ccopt = "" $ ccopt = ""
$ if f$trnlnm("HW_MODEL").ge.1024 $ if f$getsyi("HW_MODEL").ge.1024
$ then $ then
$ ccopt = "/prefix=all"+ccopt $ ccopt = "/prefix=all"+ccopt
$ comp = "__decc__=1" $ comp = "__decc__=1"

121
Makefile
View File

@@ -1,73 +1,130 @@
# Makefile for zlib # Makefile for zlib
# Copyright (C) 1995 Jean-loup Gailly. # Copyright (C) 1995-1996 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h # For conditions of distribution and use, see copyright notice in zlib.h
CC=cc # To compile and test, type:
CFLAGS=-O # ./configure; make test
#use -O3 for gcc to take advantage of inlining # The call of configure is optional if you don't have special requirements
#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
#CFLAGS=-g -DDEBUG
LDFLAGS=-L. -lz
# 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.4
LIBS=libz.a
AR=ar rc
RANLIB=ranlib RANLIB=ranlib
TAR=tar
prefix=/usr/local prefix=/usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
TEST_OBJS = example.o minigzip.o TEST_OBJS = example.o minigzip.o
DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] descrip.mms \
zlib.def zlib.rc algorithm.doc *.[ch]
all: example minigzip all: example minigzip
test: all test: all
./example ./example
echo hello world | ./minigzip | ./minigzip -d echo hello world | ./minigzip | ./minigzip -d
install: libz.a
-@mkdir $(prefix)/include
-@mkdir $(prefix)/lib
cp zlib.h zconf.h $(prefix)/include
chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
cp libz.a $(prefix)/lib
chmod 644 $(prefix)/lib/libz.a
libz.a: $(OBJS) libz.a: $(OBJS)
ar rc $@ $(OBJS) $(AR) $@ $(OBJS)
$(RANLIB) $@ -@ ($(RANLIB) $@ || true) 2>/dev/null
example: example.o libz.a libz.so.$(VER): $(OBJS)
$(LDSHARED) -o $@ $(OBJS)
rm -f libz.so; ln -s $@ libz.so
example: example.o $(LIBS)
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
minigzip: minigzip.o libz.a minigzip: minigzip.o $(LIBS)
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
install: $(LIBS)
-@if [ ! $(prefix)/include ]; then mkdir $(prefix)/include; fi
-@if [ ! $(exec_prefix)/lib ]; then mkdir $(exec_prefix)/lib; fi
cp zlib.h zconf.h $(prefix)/include
chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
cp $(LIBS) $(exec_prefix)/lib
cd $(exec_prefix)/lib; chmod 644 $(LIBS)
-@(cd $(exec_prefix)/lib; $(RANLIB) libz.a || true) >/dev/null 2>&1
cd $(exec_prefix)/lib; if test -f libz.so.$(VER); then \
ln -s libz.so.$(VER) libz.so; \
fi
# The ranlib in install is needed on NeXTSTEP which checks file times
uninstall:
cd $(exec_prefix)/lib; rm -f $(LIBS); \
if test -f libz.so; then \
v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p'<$(prefix)/include/zlib.h`;\
rm -f libz.so.$$v libz.so; \
fi
cd $(prefix)/include; rm -f zlib.h zconf.h
clean: clean:
rm -f *.o example minigzip libz.a foo.gz rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
zip: zip:
zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ mv Makefile Makefile~; cp -p Makefile.in Makefile
descrip.mms *.[ch] v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
zip -ul9 zlib$$v $(DISTFILES)
mv Makefile~ Makefile
tgz: dist:
cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ mv Makefile Makefile~; cp -p Makefile.in Makefile
zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch] d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
rm -f $$d.tar.gz; \
if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
files=""; \
for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
cd ..; \
GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
if test ! -d $$d; then rm -f $$d; fi
mv Makefile~ Makefile
tags:
etags *.[ch]
depend:
makedepend -- $(CFLAGS) -- *.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it. # DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zutil.h zlib.h zconf.h adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h compress.o: zlib.h zconf.h
crc32.o: zutil.h zlib.h zconf.h crc32.o: zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h example.o: zlib.h zconf.h
gzio.o: zutil.h zlib.h zconf.h gzio.o: zutil.h zlib.h zconf.h
infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h infcodes.o: zutil.h zlib.h zconf.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h
inffast.o: infblock.h infcodes.h infutil.h inffast.h
inflate.o: zutil.h zlib.h zconf.h infblock.h inflate.o: zutil.h zlib.h zconf.h infblock.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h inftrees.o: zutil.h zlib.h zconf.h inftrees.h
infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
minigzip.o: zlib.h zconf.h minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.o: deflate.h zutil.h zlib.h zconf.h
uncompr.o: zlib.h zconf.h uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h zutil.o: zutil.h zlib.h zconf.h

104
Makefile.b32 Normal file
View File

@@ -0,0 +1,104 @@
# Makefile for zlib
# Borland C++
# This version of the zlib makefile was adapted by Chris Young for use
# with Borland C 4.5x with the Dos Power Pack for a 32-bit protected mode
# flat memory model. It was created for use with POV-Ray ray tracer and
# you may choose to edit the CFLAGS to suit your needs but the
# switches -WX and -DMSDOS are required.
# -- Chris Young 76702.1655@compuserve.com
# To use, do "make -fmakefile.b32"
# See zconf.h for details about the memory requirements.
# ------------- Borland C++ -------------
MODEL=-WX
CFLAGS= $(MODEL) -P-C -K -N- -k- -d -3 -r- -v- -f -DMSDOS
CC=bcc32
LD=bcc32
LIB=tlib
LDFLAGS= $(MODEL)
O=.obj
# variables
OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
trees$(O)
OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
trees$(O)
OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
infutil$(O) inffast$(O)
OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
infutil$(O)+inffast$(O)
all: test
adler32.obj: adler32.c zutil.h zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
compress.obj: compress.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
crc32.obj: crc32.c zutil.h zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
gzio.obj: gzio.c zutil.h zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
infcodes.h infutil.h
$(CC) -c $(CFLAGS) $*.c
infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
infcodes.h inffast.h
$(CC) -c $(CFLAGS) $*.c
inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
$(CC) -c $(CFLAGS) $*.c
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
$(CC) -c $(CFLAGS) $*.c
infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
$(CC) -c $(CFLAGS) $*.c
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
$(CC) -c $(CFLAGS) $*.c
trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
uncompr.obj: uncompr.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
zutil.obj: zutil.c zutil.h zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
example.obj: example.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
minigzip.obj: minigzip.c zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c
# we must cut the command line to fit in the MS/DOS 128 byte limit:
zlib.lib: $(OBJ1) $(OBJ2)
del zlib.lib
$(LIB) zlib +$(OBJP1)
$(LIB) zlib +$(OBJP2)
example.exe: example.obj zlib.lib
$(LD) $(LDFLAGS) example.obj zlib.lib
minigzip.exe: minigzip.obj zlib.lib
$(LD) $(LDFLAGS) minigzip.obj zlib.lib
test: example.exe minigzip.exe
example
echo hello world | minigzip | minigzip -d
#clean:
# del *.obj
# del *.exe

View File

@@ -18,7 +18,7 @@ CFLAGS=-O2 -Z $(MODEL)
CC=bcc CC=bcc
LD=bcc LD=bcc
LIB=tlib LIB=tlib
# replace bcc with tcc for Turbo C++ 1.0 # replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
LDFLAGS=$(MODEL) LDFLAGS=$(MODEL)
O=.obj O=.obj

93
Makefile.dj2 Normal file
View File

@@ -0,0 +1,93 @@
# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
# Copyright (C) 1995-1996 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile, or to compile and test, type:
#
# make -fmakefile.dj2; make test -fmakefile.dj2
#
# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
#
# make install -fmakefile.dj2
#
# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
# in the sample below if the pattern of the DJGPP distribution is to
# be followed. Remember that, while <sp>'es around <=> are ignored in
# makefiles, they are *not* in batch files or in djgpp.env.
# - - - - -
# [make]
# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
# BUTT=-m486
# - - - - -
# Alternately, these variables may be defined below, overriding the values
# in djgpp.env, as
INCLUDE_PATH=c:\usr\include
CC=gcc
#CFLAGS=-MMD -O
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-MMD -g -DDEBUG
CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-Wstrict-prototypes -Wmissing-prototypes
# If cp.exe is not found, replace with copy /Y .
CP=cp -f
# If install.exe is not found, replace with $(CP).
INSTALL=install
# The default value of RM is "rm -f." If "rm.exe" is not found, uncomment:
# RM=del
LDLIBS=-L. -lz
LD=$(CC) -s -o
LDSHARED=$(CC)
INCL=zlib.h zconf.h
LIBS=libz.a
AR=ar rcs
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
all: example.exe minigzip.exe
test: all
./example
echo hello world | .\minigzip | .\minigzip -d
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
libz.a: $(OBJS)
$(AR) $@ $(OBJS)
%.exe : %.o $(LIBS)
$(LD) $@ $< $(LDLIBS)
# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
.PHONY : uninstall clean
install: $(INCL) $(LIBS)
-@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
-@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
for %%f in ($(INCL)) do $(INSTALL) %%f $(INCLUDE_PATH)
for %%p in ($(LIBS)) do $(INSTALL) %%p $(LIBRARY_PATH)
uninstall:
for %%f in ($(INCL)) do $(RM) $(INCLUDE_PATH)\%%f
for %%p in ($(LIBS)) do $(RM) $(LIBRARY_PATH)\%%p
clean:
for %%p in (*.d *.o *.exe libz.a libz.so* foo.gz) do $(RM) %%p
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

130
Makefile.in Normal file
View 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.4
LIBS=libz.a
AR=ar rc
RANLIB=ranlib
TAR=tar
prefix=/usr/local
exec_prefix = $(prefix)
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
TEST_OBJS = example.o minigzip.o
DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] descrip.mms \
zlib.def zlib.rc algorithm.doc *.[ch]
all: example minigzip
test: all
./example
echo hello world | ./minigzip | ./minigzip -d
libz.a: $(OBJS)
$(AR) $@ $(OBJS)
-@ ($(RANLIB) $@ || true) 2>/dev/null
libz.so.$(VER): $(OBJS)
$(LDSHARED) -o $@ $(OBJS)
rm -f libz.so; ln -s $@ libz.so
example: example.o $(LIBS)
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
minigzip: minigzip.o $(LIBS)
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
install: $(LIBS)
-@if [ ! $(prefix)/include ]; then mkdir $(prefix)/include; fi
-@if [ ! $(exec_prefix)/lib ]; then mkdir $(exec_prefix)/lib; fi
cp zlib.h zconf.h $(prefix)/include
chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
cp $(LIBS) $(exec_prefix)/lib
cd $(exec_prefix)/lib; chmod 644 $(LIBS)
-@(cd $(exec_prefix)/lib; $(RANLIB) libz.a || true) >/dev/null 2>&1
cd $(exec_prefix)/lib; if test -f libz.so.$(VER); then \
ln -s libz.so.$(VER) libz.so; \
fi
# The ranlib in install is needed on NeXTSTEP which checks file times
uninstall:
cd $(exec_prefix)/lib; rm -f $(LIBS); \
if test -f libz.so; then \
v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p'<$(prefix)/include/zlib.h`;\
rm -f libz.so.$$v libz.so; \
fi
cd $(prefix)/include; rm -f zlib.h zconf.h
clean:
rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
zip:
mv Makefile Makefile~; cp -p Makefile.in Makefile
v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
zip -ul9 zlib$$v $(DISTFILES)
mv Makefile~ Makefile
dist:
mv Makefile Makefile~; cp -p Makefile.in Makefile
d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
rm -f $$d.tar.gz; \
if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
files=""; \
for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
cd ..; \
GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
if test ! -d $$d; then rm -f $$d; fi
mv Makefile~ Makefile
tags:
etags *.[ch]
depend:
makedepend -- $(CFLAGS) -- *.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h
gzio.o: zutil.h zlib.h zconf.h
infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
infcodes.o: zutil.h zlib.h zconf.h
infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h
inffast.o: infblock.h infcodes.h infutil.h inffast.h
inflate.o: zutil.h zlib.h zconf.h infblock.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

View File

@@ -28,6 +28,8 @@ OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
infutil$(O)+inffast$(O) infutil$(O)+inffast$(O)
all: zlib.lib example.exe minigzip.exe
adler32.obj: adler32.c zutil.h zlib.h zconf.h adler32.obj: adler32.c zutil.h zlib.h zconf.h
$(CC) -c $(CFLAGS) $*.c $(CC) -c $(CFLAGS) $*.c
@@ -80,7 +82,7 @@ minigzip.obj: minigzip.c zlib.h zconf.h
# we must cut the command line to fit in the MS/DOS 128 byte limit: # we must cut the command line to fit in the MS/DOS 128 byte limit:
zlib.lib: $(OBJ1) $(OBJ2) zlib.lib: $(OBJ1) $(OBJ2)
del zlib.lib if exist zlib.lib del zlib.lib
lib zlib $(OBJ1); lib zlib $(OBJ1);
lib zlib $(OBJ2); lib zlib $(OBJ2);

View File

@@ -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

46
Makefile.riscos Normal file
View File

@@ -0,0 +1,46 @@
# Project: zlib_1_03
# Toolflags:
CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fnah
C++flags = -c -depend !Depend -IC: -throwback
Linkflags = -aif -c++ -o $@
ObjAsmflags = -throwback -NoCache -depend !Depend
CMHGflags =
LibFileflags = -c -l -o $@
Squeezeflags = -o $@
# Final targets:
@.zlib_lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
@.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
@.o.uncompress @.o.zutil
LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
@.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
@.o.trees @.o.uncompress @.o.zutil
@.test: @.tests.minigzip @.tests.example
echo Please run "Test" in directory tests
@.tests.minigzip: @.o.minigzip @.zlib_lib C:o.Stubs
Link $(Linkflags) @.o.minigzip @.zlib_lib C:o.Stubs
@.tests.example: @.o.example @.zlib_lib C:o.Stubs
Link $(Linkflags) @.o.example @.zlib_lib C:o.Stubs
# User-editable dependencies:
.c.o:
cc $(ccflags) -o $@ $<
# Static dependencies:
@.o.example: @.tests.c.example
cc $(ccflags) -o @.o.example @.tests.c.example
@.o.minigzip: @.tests.c.minigzip
cc $(ccflags) -o @.o.minigzip @.tests.c.minigzip
# Dynamic dependencies:
o.minigzip: tests.c.minigzip
o.minigzip: h.zlib
o.minigzip: h.zconf
o.example: tests.c.example
o.example: h.zlib
o.example: h.zconf

64
Makefile.sas Normal file
View File

@@ -0,0 +1,64 @@
# SMakefile for zlib
# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
# Amiga, SAS/C 6.56 & Smake
CC=sc
CFLAGS=OPT
#CFLAGS=OPT CPU=68030
#CFLAGS=DEBUG=LINE
LDFLAGS=LIB z.lib
SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
TEST_OBJS = example.o minigzip.o
all: SCOPTIONS example minigzip
test: all
`cd`/example
echo hello world | minigzip | minigzip -d
install: z.lib
copy zlib.h zconf.h INCLUDE: clone
copy z.lib LIB: clone
z.lib: $(OBJS)
oml z.lib r $(OBJS)
example: example.o z.lib
$(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
minigzip: minigzip.o z.lib
$(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
clean:
-delete force quiet *.o example minigzip z.lib foo.gz *.lnk SCOPTIONS
SCOPTIONS: Smakefile
copy to $@ <from <
$(SCOPTIONS)
<
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zutil.h zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: zutil.h zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h
gzio.o: zutil.h zlib.h zconf.h
infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
inflate.o: zutil.h zlib.h zconf.h infblock.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h
minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

103
Makefile.wat Normal file
View File

@@ -0,0 +1,103 @@
# Makefile for zlib
# Watcom 10a
# This version of the zlib makefile was adapted by Chris Young for use
# with Watcom 10a 32-bit protected mode flat memory model. It was created
# for use with POV-Ray ray tracer and you may choose to edit the CFLAGS to
# suit your needs but the -DMSDOS is required.
# -- Chris Young 76702.1655@compuserve.com
# To use, do "wmake -f makefile.wat"
# See zconf.h for details about the memory requirements.
# ------------- Watcom 10a -------------
MODEL=-mf
CFLAGS= $(MODEL) -fpi87 -fp5 -zp4 -5r -w5 -oneatx -DMSDOS
CC=wcc386
LD=wcl386
LIB=wlib -b -c
LDFLAGS=
O=.obj
# variables
OBJ1=adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O)
OBJ2=trees$(O) zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O)
OBJ3=infutil$(O) inffast$(O)
OBJP1=adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)
OBJP2=trees$(O)+zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)
OBJP3=infutil$(O)+inffast$(O)
all: test
adler32.obj: adler32.c zutil.h zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
compress.obj: compress.c zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
crc32.obj: crc32.c zutil.h zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
gzio.obj: gzio.c zutil.h zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h &
infcodes.h infutil.h
$(CC) $(CFLAGS) $*.c
infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h &
infcodes.h inffast.h
$(CC) $(CFLAGS) $*.c
inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
$(CC) $(CFLAGS) $*.c
inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
$(CC) $(CFLAGS) $*.c
infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
$(CC) $(CFLAGS) $*.c
inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
$(CC) $(CFLAGS) $*.c
trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
uncompr.obj: uncompr.c zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
zutil.obj: zutil.c zutil.h zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
example.obj: example.c zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
minigzip.obj: minigzip.c zlib.h zconf.h
$(CC) $(CFLAGS) $*.c
# we must cut the command line to fit in the MS/DOS 128 byte limit:
zlib.lib: $(OBJ1) $(OBJ2) $(OBJ3)
del zlib.lib
$(LIB) zlib.lib +$(OBJP1)
$(LIB) zlib.lib +$(OBJP2)
$(LIB) zlib.lib +$(OBJP3)
example.exe: example.obj zlib.lib
$(LD) $(LDFLAGS) example.obj zlib.lib
minigzip.exe: minigzip.obj zlib.lib
$(LD) $(LDFLAGS) minigzip.obj zlib.lib
test: minigzip.exe example.exe
example
echo hello world | minigzip | minigzip -d >test
type test
#clean:
# del *.obj
# del *.exe

90
README
View File

@@ -1,40 +1,74 @@
zlib 0.95 is a beta version of a general purpose compression library. zlib 1.0.4 is a general purpose data compression library. All the code
This should be the last version before the first official is reentrant (thread safe). The data format used by the zlib library
version (1.0), so please test it now. (At least compile and run it with is described by RFCs (Request for Comments) 1950 to 1952 in the files
"make test"). This version has no known bugs. ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
format) and rfc1952.txt (gzip format). These documents are also available in
The data format used by the zlib library is described in the other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
files zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available
in ftp.uu.net:/pub/archiving/zip/doc.
All functions of the compression library are documented in the file All functions of the compression library are documented in the file
zlib.h. A usage example of the library is given in the file example.c zlib.h. A usage example of the library is given in the file example.c
which also tests that the library is working correctly. Another which also tests that the library is working correctly. Another
example is given in the file minigzip.c. example is given in the file minigzip.c. The compression library itself
is composed of all source files except example.c and minigzip.c.
To compile all files and run the test program, just type: make test To compile all files and run the test program, follow the instructions
(For MSDOS, use one of the special makefiles such as Makefile.msc; given at the top of Makefile. In short "make test; make install"
for VMS, use Make_vms.com or descrip.mms.) should work for most machines. For MSDOS, use one of the special
To install the zlib library (libz.a) in /usr/local/lib, type: make install makefiles such as Makefile.msc; for VMS, use Make_vms.com or descrip.mms.
To install in a different directory, use for example:
make install prefix=$HOME
This will install in $HOME/lib instead of /usr/local/lib.
The changes made in version 0.95 are documented in the file ChangeLog. Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov> or,
The main changes since 0.94 are: if this fails, to the addresses given below in the Copyright section.
- fix MSDOS small and medium model (now easier to adapt to any compiler) The zlib home page is http://quest.jpl.nasa.gov/zlib/
- inlined send_bits
- fix the final (:-) bug for deflate with flush (output was correct but
not completely flushed in rare occasions).
For MSDOS, the small and medium models have been tested only with Microsoft C. The changes made in version 1.0.4 are documented in the file ChangeLog.
(This should now work for Borland C also, but I don't have a recent Borland The main changes since 1.0.3 are:
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 - In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
-DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 bit, so the decompressor could decompress all the correct data but went
on to attempt decompressing extra garbage data. This affected minigzip too.
- zlibVersion and gzerror return const char* (needed for DLL)
- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
(C) 1995 Jean-loup Gailly and Mark Adler 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*
Notes for some targets:
- For Turbo C the small model is supported only with reduced performance to
avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
- For 64-bit Iris, deflate.c must be compiled without any optimization.
With -O, one libpng test fails. The test works in 32 bit mode (with
the -32 compiler flag). The compiler bug has been reported to SGI.
- 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.
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
For help on building a zlib DLL, contact Alessandro Iacopetti
<iaco@email.alessandria.alpcom.it> http://lisa.unial.it/iaco ,
or contact Brad Clarke <bclarke@cyberus.ca>.
- gzdopen is not supported on RISCOS
Acknowledgments:
The deflate format used by zlib was defined by Phil Katz. The deflate
and zlib specifications were written by Peter Deutsch. Thanks to all the
people who reported problems and suggested various improvements in zlib;
they are too numerous to cite here.
Copyright notice:
(C) 1995-1996 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages

View File

@@ -1,9 +1,9 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream /* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp $ */ /* $Id: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */
#include "zlib.h" #include "zlib.h"
@@ -11,16 +11,16 @@
#define NMAX 5552 #define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf) {s1 += *buf++; s2 += s1;} #define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO2(buf) DO1(buf); DO1(buf); #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf) DO2(buf); DO2(buf); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf) DO4(buf); DO4(buf); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf); DO8(buf); #define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */ /* ========================================================================= */
uLong adler32(adler, buf, len) uLong adler32(adler, buf, len)
uLong adler; uLong adler;
Bytef *buf; const Bytef *buf;
uInt len; uInt len;
{ {
unsigned long s1 = adler & 0xffff; unsigned long s1 = adler & 0xffff;
@@ -34,10 +34,12 @@ uLong adler32(adler, buf, len)
len -= k; len -= k;
while (k >= 16) { while (k >= 16) {
DO16(buf); DO16(buf);
buf += 16;
k -= 16; k -= 16;
} }
if (k != 0) do { if (k != 0) do {
DO1(buf); s1 += *buf++;
s2 += s1;
} while (--k); } while (--k);
s1 %= BASE; s1 %= BASE;
s2 %= BASE; s2 %= BASE;

105
algorithm.doc Normal file
View File

@@ -0,0 +1,105 @@
1. Compression algorithm (deflate)
The deflation algorithm used by zlib (also zip and gzip) is a variation of
LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
the input data. The second occurrence of a string is replaced by a
pointer to the previous string, in the form of a pair (distance,
length). Distances are limited to 32K bytes, and lengths are limited
to 258 bytes. When a string does not occur anywhere in the previous
32K bytes, it is emitted as a sequence of literal bytes. (In this
description, `string' must be taken as an arbitrary sequence of bytes,
and is not restricted to printable characters.)
Literals or match lengths are compressed with one Huffman tree, and
match distances are compressed with another tree. The trees are stored
in a compact form at the start of each block. The blocks can have any
size (except that the compressed data for one block must fit in
available memory). A block is terminated when deflate() determines that
it would be useful to start another block with fresh trees. (This is
somewhat similar to the behavior of LZW-based _compress_.)
Duplicated strings are found using a hash table. All input strings of
length 3 are inserted in the hash table. A hash index is computed for
the next 3 bytes. If the hash chain for this index is not empty, all
strings in the chain are compared with the current input string, and
the longest match is selected.
The hash chains are searched starting with the most recent strings, to
favor small distances and thus take advantage of the Huffman encoding.
The hash chains are singly linked. There are no deletions from the
hash chains, the algorithm simply discards matches that are too old.
To avoid a worst-case situation, very long hash chains are arbitrarily
truncated at a certain length, determined by a runtime option (level
parameter of deflateInit). So deflate() does not always find the longest
possible match but generally finds a match which is long enough.
deflate() also defers the selection of matches with a lazy evaluation
mechanism. After a match of length N has been found, deflate() searches for a
longer match at the next input byte. If a longer match is found, the
previous match is truncated to a length of one (thus producing a single
literal byte) and the longer match is emitted afterwards. Otherwise,
the original match is kept, and the next match search is attempted only
N steps later.
The lazy match evaluation is also subject to a runtime parameter. If
the current match is long enough, deflate() reduces the search for a longer
match, thus speeding up the whole process. If compression ratio is more
important than speed, deflate() attempts a complete second search even if
the first match is already long enough.
The lazy match evaluation is not performed for the fastest compression
modes (level parameter 1 to 3). For these fast modes, new strings
are inserted in the hash table only when no match was found, or
when the match is not too long. This degrades the compression ratio
but saves time since there are both fewer insertions and fewer searches.
2. Decompression algorithm (inflate)
The real question is, given a Huffman tree, how to decode fast. The most
important realization is that shorter codes are much more common than
longer codes, so pay attention to decoding the short codes fast, and let
the long codes take longer to decode.
inflate() sets up a first level table that covers some number of bits of
input less than the length of longest code. It gets that many bits from the
stream, and looks it up in the table. The table will tell if the next
code is that many bits or less and how many, and if it is, it will tell
the value, else it will point to the next level table for which inflate()
grabs more bits and tries to decode a longer code.
How many bits to make the first lookup is a tradeoff between the time it
takes to decode and the time it takes to build the table. If building the
table took no time (and if you had infinite memory), then there would only
be a first level table to cover all the way to the longest code. However,
building the table ends up taking a lot longer for more bits since short
codes are replicated many times in such a table. What inflate() does is
simply to make the number of bits in the first table a variable, and set it
for the maximum speed.
inflate() sends new trees relatively often, so it is possibly set for a
smaller first level table than an application that has only one tree for
all the data. For inflate, which has 286 possible codes for the
literal/length tree, the size of the first table is nine bits. Also the
distance trees have 30 possible values, and the size of the first table is
six bits. Note that for each of those cases, the table ended up one bit
longer than the ``average'' code length, i.e. the code length of an
approximately flat code which would be a little more than eight bits for
286 symbols and a little less than five bits for 30 symbols. It would be
interesting to see if optimizing the first level table for other
applications gave values within a bit or two of the flat code size.
Jean-loup Gailly Mark Adler
gzip@prep.ai.mit.edu madler@alumni.caltech.edu
References:
[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
pp. 337-343.
``DEFLATE Compressed Data Format Specification'' available in
ftp://ds.internic.net/rfc/rfc1951.txt

View File

@@ -1,9 +1,9 @@
/* compress.c -- compress a memory buffer /* compress.c -- compress a memory buffer
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: compress.c,v 1.6 1995/05/03 17:27:08 jloup Exp $ */ /* $Id: compress.c,v 1.10 1996/05/23 16:51:12 me Exp $ */
#include "zlib.h" #include "zlib.h"
@@ -22,23 +22,25 @@
int compress (dest, destLen, source, sourceLen) int compress (dest, destLen, source, sourceLen)
Bytef *dest; Bytef *dest;
uLongf *destLen; uLongf *destLen;
Bytef *source; const Bytef *source;
uLong sourceLen; uLong sourceLen;
{ {
z_stream stream; z_stream stream;
int err; int err;
stream.next_in = source; stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen; stream.avail_in = (uInt)sourceLen;
#ifdef MAXSEG_64K
/* Check for source > 64K on 16-bit machine: */ /* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
#endif
stream.next_out = dest; stream.next_out = dest;
stream.avail_out = (uInt)*destLen; stream.avail_out = (uInt)*destLen;
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.zalloc = (alloc_func)0; stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0; stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
if (err != Z_OK) return err; if (err != Z_OK) return err;

86
configure vendored Executable file
View File

@@ -0,0 +1,86 @@
#!/bin/sh
# configure script for zlib. This script is needed only if
# you wish to build a shared library and your system supports them,
# of if you need special compiler, flags or install directory.
# Otherwise, you can just use directly "make test; make install"
#
# To impose specific compiler or flags or install directory, use for example:
# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
# or for csh/tcsh users:
# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
# LDSHARED is the command to be used to create a shared library
LIBS=libz.a
VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
AR=${AR-"ar rc"}
RANLIB=${RANLIB-"ranlib"}
prefix=${prefix-/usr/local}
exec_prefix=${exec_prefix-$prefix}
test -z "$CC" && echo Checking for gcc...
test=ztest$$
cat > $test.c <<EOF
int hello() { printf("hello\n"); }
EOF
if test -z "$CC" && (gcc -c -O3 $test.c) 2>/dev/null; then
CC=gcc
SFLAGS=${CFLAGS-"-fPIC -O3"}
CFLAGS=${CFLAGS-"-O3"}
LDSHARED=${LDSHARED-"gcc -shared"}
else
# find system name and corresponding cc options
CC=${CC-cc}
case `(uname -sr || echo unknown) 2>/dev/null` in
SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
CFLAGS=${CFLAGS-"-fast -xcg89"}
LDSHARED=${LDSHARED-"cc -G"};;
SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
CFLAGS=${CFLAGS-"-O2"}
LDSHARED=${LDSHARED-"ld"};;
IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
CFLAGS=${CFLAGS-"-ansi -O2"}
LDSHARED=${LDSHARED-"cc -shared"};;
QNX*) SFLAGS=${CFLAGS-"-4 -O"}
CFLAGS=${CFLAGS-"-4 -O"}
LDSHARED=${LDSHARED-"cc"}
RANLIB=${RANLIB-"true"}
AR="cc -A";;
SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
CFLAGS=${CFLAGS-"-O3"}
LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
CFLAGS=${CFLAGS-"-O"}
LDSHARED=${LDSHARED-"ld -b"}
SHAREDLIBS='libz.sl';;
# send working options for other systems to gzip@prep.ai.mit.edu
*) SFLAGS=${CFLAGS-"-O"}
CFLAGS=${CFLAGS-"-O"}
LDSHARED=${LDSHARED-"cc -shared"};;
esac
fi
echo Checking for shared library support...
# we must test in two steps (cc then ld), required at least on SunOS 4.x
if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
test "`($LDSHARED -o $test.so $test.o) 2>&1`" = ""; then
CFLAGS="$SFLAGS"
LIBS='libz.so.$(VER)'
echo Building shared library libz.so.$VER with $CC.
else
LDSHARED="$CC"
echo Building static library $LIBS version $VER with $CC.
fi
rm -f $test.[co] $test.so
# udpate Makefile
sed < Makefile.in "
/^CC *=/s/=.*/=$CC/
/^CFLAGS *=/s/=.*/=$CFLAGS/
/^LDSHARED *=/s/=.*/=$LDSHARED/
/^LIBS *=/s,=.*,=$LIBS,
/^AR *=/s/=.*/=$AR/
/^RANLIB *=/s,=.*,=$RANLIB,
/^VER *=/s/=.*/=$VER/
/^prefix *=/s,=.*,=$prefix,
/^exec_prefix *=/s,=.*,=$exec_prefix,
" > Makefile

64
crc32.c
View File

@@ -1,32 +1,62 @@
/* crc32.c -- compute the CRC-32 of a data stream /* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: crc32.c,v 1.4 1995/04/14 14:55:12 jloup Exp $ */ /* $Id: crc32.c,v 1.8 1996/01/30 21:59:10 me Exp $ */
#include "zlib.h" #include "zlib.h"
#define local static #define local static
#ifdef DYNAMIC_CRC_TABLE #ifdef DYNAMIC_CRC_TABLE
/* =========================================================================
* Make the crc table. This function is needed only if you want to compute
* the table dynamically.
*/
local int crc_table_empty = 1;
local 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() local void make_crc_table()
{ {
uLong c; uLong c;
int n, k; int n, k;
uLong poly; /* polynomial exclusive-or pattern */
/* terms of polynomial defining this crc (except x^32): */
static Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
/* make exclusive-or pattern from polynomial (0xedb88320L) */
poly = 0L;
for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
poly |= 1L << (31 - p[n]);
for (n = 0; n < 256; n++) for (n = 0; n < 256; n++)
{ {
c = (uLong)n; c = (uLong)n;
for (k = 0; k < 8; k++) for (k = 0; k < 8; k++)
c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1; c = c & 1 ? poly ^ (c >> 1) : c >> 1;
crc_table[n] = c; crc_table[n] = c;
} }
crc_table_empty = 0; crc_table_empty = 0;
@@ -35,7 +65,7 @@ local void make_crc_table()
/* ======================================================================== /* ========================================================================
* Table of CRC-32's of all single-byte values (made by make_crc_table) * Table of CRC-32's of all single-byte values (made by make_crc_table)
*/ */
local uLong crc_table[] = { local uLongf crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
@@ -91,6 +121,18 @@ local uLong crc_table[] = {
}; };
#endif #endif
/* =========================================================================
* This function can be used by asm versions of crc32()
*/
uLongf *get_crc_table()
{
#ifdef DYNAMIC_CRC_TABLE
if (crc_table_empty) make_crc_table();
#endif
return (uLongf *)crc_table;
}
/* ========================================================================= */
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
#define DO2(buf) DO1(buf); DO1(buf); #define DO2(buf) DO1(buf); DO1(buf);
#define DO4(buf) DO2(buf); DO2(buf); #define DO4(buf) DO2(buf); DO2(buf);
@@ -99,7 +141,7 @@ local uLong crc_table[] = {
/* ========================================================================= */ /* ========================================================================= */
uLong crc32(crc, buf, len) uLong crc32(crc, buf, len)
uLong crc; uLong crc;
Bytef *buf; const Bytef *buf;
uInt len; uInt len;
{ {
if (buf == Z_NULL) return 0L; if (buf == Z_NULL) return 0L;

512
deflate.c
View File

@@ -1,5 +1,5 @@
/* deflate.c -- compress data using the deflation algorithm /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -47,11 +47,11 @@
* *
*/ */
/* $Id: deflate.c,v 1.8 1995/05/03 17:27:08 jloup Exp $ */ /* $Id: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */
#include "deflate.h" #include "deflate.h"
char copyright[] = " deflate Copyright 1995 Jean-loup Gailly "; char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome 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 in the documentation of your product. If for some reason you cannot
@@ -59,6 +59,41 @@ char copyright[] = " deflate Copyright 1995 Jean-loup Gailly ";
copyright string in the executable of your product. copyright string in the executable of your product.
*/ */
/* ===========================================================================
* Function prototypes.
*/
typedef enum {
need_more, /* block not completed, need more input or more output */
block_done, /* block flush performed */
finish_started, /* finish started, need only more output at next deflate */
finish_done /* finish done, accept no more input or output */
} block_state;
typedef block_state (*compress_func) OF((deflate_state *s, int flush));
/* Compression function. Returns the block state after the call. */
local void fill_window OF((deflate_state *s));
local block_state deflate_stored OF((deflate_state *s, int flush));
local block_state deflate_fast OF((deflate_state *s, int flush));
local block_state deflate_slow OF((deflate_state *s, int flush));
local void lm_init OF((deflate_state *s));
local uInt longest_match OF((deflate_state *s, IPos cur_match));
local void putShortMSB OF((deflate_state *s, uInt b));
local void flush_pending OF((z_streamp strm));
local int read_buf OF((z_streamp strm, charf *buf, unsigned size));
#ifdef ASMV
void match_init OF((void)); /* asm code initialization */
#endif
#ifdef DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match,
int length));
#endif
/* ===========================================================================
* Local data
*/
#define NIL 0 #define NIL 0
/* Tail of hash chains */ /* Tail of hash chains */
@@ -77,27 +112,27 @@ char copyright[] = " deflate Copyright 1995 Jean-loup Gailly ";
* exclude worst case performance for pathological files. Better values may be * exclude worst case performance for pathological files. Better values may be
* found for specific files. * found for specific files.
*/ */
typedef struct config_s { typedef struct config_s {
ush good_length; /* reduce lazy search above this match length */ ush good_length; /* reduce lazy search above this match length */
ush max_lazy; /* do not perform 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 nice_length; /* quit search above this match length */
ush max_chain; ush max_chain;
compress_func func;
} config; } config;
local config configuration_table[10] = { local config configuration_table[10] = {
/* good lazy nice chain */ /* good lazy nice chain */
/* 0 */ {0, 0, 0, 0}, /* store only */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
/* 2 */ {4, 5, 16, 8}, /* 2 */ {4, 5, 16, 8, deflate_fast},
/* 3 */ {4, 6, 32, 32}, /* 3 */ {4, 6, 32, 32, deflate_fast},
/* 4 */ {4, 4, 16, 16}, /* lazy matches */ /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
/* 5 */ {8, 16, 32, 32}, /* 5 */ {8, 16, 32, 32, deflate_slow},
/* 6 */ {8, 16, 128, 128}, /* 6 */ {8, 16, 128, 128, deflate_slow},
/* 7 */ {8, 32, 128, 256}, /* 7 */ {8, 32, 128, 256, deflate_slow},
/* 8 */ {32, 128, 258, 1024}, /* 8 */ {32, 128, 258, 1024, deflate_slow},
/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 /* 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 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
@@ -109,28 +144,6 @@ local config configuration_table[10] = {
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
/* ===========================================================================
* Prototypes for local functions.
*/
local void fill_window OF((deflate_state *s));
local int deflate_fast OF((deflate_state *s, int flush));
local int deflate_slow OF((deflate_state *s, int flush));
local void lm_init OF((deflate_state *s));
local int longest_match OF((deflate_state *s, IPos cur_match));
local void putShortMSB OF((deflate_state *s, uInt b));
local void flush_pending OF((z_stream *strm));
local int read_buf OF((z_stream *strm, charf *buf, unsigned size));
#ifdef ASMV
void match_init OF((void)); /* asm code initialization */
#endif
#ifdef DEBUG
local void check_match OF((deflate_state *s, IPos start, IPos match,
int length));
#endif
/* =========================================================================== /* ===========================================================================
* Update a hash value with the given input byte * Update a hash value with the given input byte
* IN assertion: all calls to to UPDATE_HASH are made with consecutive * IN assertion: all calls to to UPDATE_HASH are made with consecutive
@@ -151,7 +164,7 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
#define INSERT_STRING(s, str, match_head) \ #define INSERT_STRING(s, str, match_head) \
(UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
s->head[s->ins_h] = (str)) s->head[s->ins_h] = (Pos)(str))
/* =========================================================================== /* ===========================================================================
* Initialize the hash table (avoiding 64K overflow for 16 bit systems). * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
@@ -162,30 +175,48 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); 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; z_streamp strm;
int level; 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 */ /* 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,
z_stream *strm; version, stream_size)
z_streamp strm;
int level; int level;
int method; int method;
int windowBits; int windowBits;
int memLevel; int memLevel;
int strategy; int strategy;
const char *version;
int stream_size;
{ {
deflate_state *s; deflate_state *s;
int noheader = 0; int noheader = 0;
ushf *overlay;
/* We overlay pending_buf and d_buf+l_buf. This works since the average
* output size for (length,distance) codes is <= 24 bits.
*/
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != sizeof(z_stream)) {
return Z_VERSION_ERROR;
}
if (strm == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL; 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 (strm->zfree == Z_NULL) strm->zfree = zcfree;
if (level == Z_DEFAULT_COMPRESSION) level = 6; if (level == Z_DEFAULT_COMPRESSION) level = 6;
@@ -194,8 +225,9 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
noheader = 1; noheader = 1;
windowBits = -windowBits; windowBits = -windowBits;
} }
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED || if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
windowBits < 8 || windowBits > 15 || level < 1 || level > 9) { windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
@@ -219,20 +251,17 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush)); overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
s->pending_buf = (uchf *) overlay;
if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
s->pending_buf == Z_NULL) { s->pending_buf == Z_NULL) {
strm->msg = z_errmsg[1-Z_MEM_ERROR]; strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
deflateEnd (strm); deflateEnd (strm);
return Z_MEM_ERROR; return Z_MEM_ERROR;
} }
s->d_buf = (ushf *) &(s->pending_buf[s->lit_bufsize]); s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
s->l_buf = (uchf *) &(s->pending_buf[3*s->lit_bufsize]); s->l_buf = s->pending_buf + (1+sizeof(ush))*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).
*/
s->level = level; s->level = level;
s->strategy = strategy; s->strategy = strategy;
@@ -241,9 +270,48 @@ int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
return deflateReset(strm); return deflateReset(strm);
} }
/* ========================================================================= */
int deflateSetDictionary (strm, dictionary, dictLength)
z_streamp strm;
const Bytef *dictionary;
uInt dictLength;
{
deflate_state *s;
uInt length = dictLength;
uInt n;
IPos hash_head = 0;
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);
}
if (hash_head) hash_head = 0; /* to make compiler happy */
return Z_OK;
}
/* ========================================================================= */ /* ========================================================================= */
int deflateReset (strm) int deflateReset (strm)
z_stream *strm; z_streamp strm;
{ {
deflate_state *s; deflate_state *s;
@@ -262,14 +330,51 @@ int deflateReset (strm)
s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
} }
s->status = s->noheader ? BUSY_STATE : INIT_STATE; 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); lm_init(s);
return Z_OK; return Z_OK;
} }
/* ========================================================================= */
int deflateParams(strm, level, strategy)
z_streamp strm;
int level;
int strategy;
{
deflate_state *s;
compress_func func;
int err = Z_OK;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
s = strm->state;
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->total_in != 0) {
/* Flush the last buffer: */
err = deflate(strm, 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 err;
}
/* ========================================================================= /* =========================================================================
* Put a short in the pending buffer. The 16-bit value is put in MSB order. * 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 * IN assertion: the stream state is correct and there is enough room in
@@ -284,10 +389,13 @@ 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) local void flush_pending(strm)
z_stream *strm; z_streamp strm;
{ {
unsigned len = strm->state->pending; unsigned len = strm->state->pending;
@@ -307,119 +415,163 @@ local void flush_pending(strm)
/* ========================================================================= */ /* ========================================================================= */
int deflate (strm, flush) int deflate (strm, flush)
z_stream *strm; z_streamp strm;
int flush; int flush;
{ {
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; int old_flush; /* value of flush param for previous deflate call */
deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL ||
flush > Z_FINISH || flush < 0) {
return Z_STREAM_ERROR;
}
s = strm->state;
if (strm->next_out == Z_NULL || 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); ERR_RETURN(strm, Z_STREAM_ERROR);
} }
if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_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 */ /* 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 header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
uInt level_flags = (strm->state->level-1) >> 1; uInt level_flags = (s->level-1) >> 1;
if (level_flags > 3) level_flags = 3; if (level_flags > 3) level_flags = 3;
header |= (level_flags << 6); header |= (level_flags << 6);
if (s->strstart != 0) header |= PRESET_DICT;
header += 31 - (header % 31); header += 31 - (header % 31);
strm->state->status = BUSY_STATE; s->status = BUSY_STATE;
putShortMSB(strm->state, header); 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 */ /* Flush as much pending output as possible */
if (strm->state->pending != 0) { if (s->pending != 0) {
flush_pending(strm); flush_pending(strm);
if (strm->avail_out == 0) return Z_OK; if (strm->avail_out == 0) {
/* Since avail_out is 0, deflate will be called again with
* more output space, but possibly with both pending and
* avail_in equal to zero. There won't be anything to do,
* but this is not an error situation so make sure we
* return OK instead of BUF_ERROR at next call of deflate:
*/
s->last_flush = -1;
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: */ /* 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); ERR_RETURN(strm, Z_BUF_ERROR);
} }
/* Start a new block or continue the current one. /* Start a new block or continue the current one.
*/ */
if (strm->avail_in != 0 || strm->state->lookahead != 0 || if (strm->avail_in != 0 || s->lookahead != 0 ||
(flush != Z_NO_FLUSH && strm->state->status != FINISH_STATE)) { (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
int quit; block_state bstate;
if (flush == Z_FINISH) { bstate = (*(configuration_table[s->level].func))(s, flush);
strm->state->status = FINISH_STATE;
if (bstate == finish_started || bstate == finish_done) {
s->status = FINISH_STATE;
} }
if (strm->state->level <= 3) { if (bstate == need_more || bstate == finish_started) {
quit = deflate_fast(strm->state, flush); if (strm->avail_out == 0) {
} else { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
quit = deflate_slow(strm->state, flush); }
} return Z_OK;
if (quit || strm->avail_out == 0) return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure
* of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an
* that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also
* empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most
* ensures that for a very small output buffer, we emit at most * one empty block.
* one empty block. */
*/ }
if (flush != Z_OK && flush != Z_FINISH) { if (bstate == block_done) {
if (flush == Z_PARTIAL_FLUSH) { if (flush == Z_PARTIAL_FLUSH) {
ct_align(strm->state); _tr_align(s);
} else { /* FULL_FLUSH or SYNC_FLUSH */ } 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 /* For a full flush, this empty block will be recognized
* as a special marker by inflate_sync(). * as a special marker by inflate_sync().
*/ */
if (flush == Z_FULL_FLUSH) { if (flush == Z_FULL_FLUSH) {
CLEAR_HASH(strm->state); /* forget history */ CLEAR_HASH(s); /* forget history */
} }
} }
flush_pending(strm); flush_pending(strm);
if (strm->avail_out == 0) return Z_OK; if (strm->avail_out == 0) {
s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
return Z_OK;
}
} }
} }
Assert(strm->avail_out > 0, "bug2"); Assert(strm->avail_out > 0, "bug2");
if (flush != Z_FINISH) return Z_OK; 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) */ /* Write the zlib trailer (adler32) */
putShortMSB(strm->state, (uInt)(strm->state->adler >> 16)); putShortMSB(s, (uInt)(strm->adler >> 16));
putShortMSB(strm->state, (uInt)(strm->state->adler & 0xffff)); putShortMSB(s, (uInt)(strm->adler & 0xffff));
flush_pending(strm); flush_pending(strm);
/* If avail_out is zero, the application will call deflate again /* If avail_out is zero, the application will call deflate again
* to flush the rest. * to flush the rest.
*/ */
strm->state->noheader = -1; /* write the trailer only once! */ s->noheader = -1; /* write the trailer only once! */
return strm->state->pending != 0 ? Z_OK : Z_STREAM_END; return s->pending != 0 ? Z_OK : Z_STREAM_END;
} }
/* ========================================================================= */ /* ========================================================================= */
int deflateEnd (strm) int deflateEnd (strm)
z_stream *strm; z_streamp strm;
{ {
int status;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
TRY_FREE(strm, strm->state->window); /* Deallocate in reverse order of allocations: */
TRY_FREE(strm, strm->state->prev);
TRY_FREE(strm, strm->state->head);
TRY_FREE(strm, strm->state->pending_buf); 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); ZFREE(strm, strm->state);
strm->state = Z_NULL; strm->state = Z_NULL;
return Z_OK; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
} }
/* ========================================================================= */ /* ========================================================================= */
int deflateCopy (dest, source) int deflateCopy (dest, source)
z_stream *dest; z_streamp dest;
z_stream *source; z_streamp source;
{ {
if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
@@ -438,10 +590,13 @@ int deflateCopy (dest, source)
/* =========================================================================== /* ===========================================================================
* Read a new buffer from the current input stream, update the adler32 * 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) local int read_buf(strm, buf, size)
z_stream *strm; z_streamp strm;
charf *buf; charf *buf;
unsigned size; unsigned size;
{ {
@@ -453,7 +608,7 @@ local int read_buf(strm, buf, size)
strm->avail_in -= len; strm->avail_in -= len;
if (!strm->state->noheader) { 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); zmemcpy(buf, strm->next_in, len);
strm->next_in += len; strm->next_in += len;
@@ -482,7 +637,7 @@ local void lm_init (s)
s->strstart = 0; s->strstart = 0;
s->block_start = 0L; s->block_start = 0L;
s->lookahead = 0; s->lookahead = 0;
s->match_length = MIN_MATCH-1; s->match_length = s->prev_length = MIN_MATCH-1;
s->match_available = 0; s->match_available = 0;
s->ins_h = 0; s->ins_h = 0;
#ifdef ASMV #ifdef ASMV
@@ -497,12 +652,13 @@ local void lm_init (s)
* garbage. * garbage.
* IN assertions: cur_match is the head of the hash chain for the current * 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 * 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 #ifndef ASMV
/* For 80x86 and 680x0, an optimized version will be provided in match.asm or /* For 80x86 and 680x0, an optimized version will be provided in match.asm or
* match.S. The code will be functionally equivalent. * match.S. The code will be functionally equivalent.
*/ */
local int longest_match(s, cur_match) local uInt longest_match(s, cur_match)
deflate_state *s; deflate_state *s;
IPos cur_match; /* current match */ IPos cur_match; /* current match */
{ {
@@ -511,6 +667,7 @@ local int longest_match(s, cur_match)
register Bytef *match; /* matched string */ register Bytef *match; /* matched string */
register int len; /* length of current match */ register int len; /* length of current match */
int best_len = s->prev_length; /* best match length so far */ 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) ? IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
s->strstart - (IPos)MAX_DIST(s) : NIL; s->strstart - (IPos)MAX_DIST(s) : NIL;
/* Stop when cur_match becomes <= limit. To simplify the code, /* Stop when cur_match becomes <= limit. To simplify the code,
@@ -541,6 +698,11 @@ local int longest_match(s, cur_match)
if (s->prev_length >= s->good_match) { if (s->prev_length >= s->good_match) {
chain_length >>= 2; chain_length >>= 2;
} }
/* Do not look for matches beyond the end of the input. This is necessary
* to make deflate deterministic.
*/
if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
do { do {
@@ -619,7 +781,7 @@ local int longest_match(s, cur_match)
if (len > best_len) { if (len > best_len) {
s->match_start = cur_match; s->match_start = cur_match;
best_len = len; best_len = len;
if (len >= s->nice_match) break; if (len >= nice_match) break;
#ifdef UNALIGNED_OK #ifdef UNALIGNED_OK
scan_end = *(ushf*)(scan+best_len-1); scan_end = *(ushf*)(scan+best_len-1);
#else #else
@@ -630,7 +792,8 @@ local int longest_match(s, cur_match)
} while ((cur_match = prev[cur_match & wmask]) > limit } while ((cur_match = prev[cur_match & wmask]) > limit
&& --chain_length != 0); && --chain_length != 0);
return best_len; if ((uInt)best_len <= s->lookahead) return best_len;
return s->lookahead;
} }
#endif /* ASMV */ #endif /* ASMV */
@@ -644,13 +807,13 @@ local void check_match(s, start, match, length)
int length; int length;
{ {
/* check that the match is indeed a match */ /* 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) { (charf *)s->window + start, length) != EQUAL) {
fprintf(stderr, fprintf(stderr, " start %u, match %u, length %d\n",
" start %u, match %u, length %d\n", start, match, length);
start, match, length); do {
do { fprintf(stderr, "%c%c", s->window[match++], fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
s->window[start++]); } while (--length != 0); } while (--length != 0);
z_error("invalid match"); z_error("invalid match");
} }
if (verbose > 1) { if (verbose > 1) {
@@ -686,6 +849,7 @@ local void fill_window(s)
/* Deal with !@#$% 64K limit: */ /* Deal with !@#$% 64K limit: */
if (more == 0 && s->strstart == 0 && s->lookahead == 0) { if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
more = wsize; more = wsize;
} else if (more == (unsigned)(-1)) { } else if (more == (unsigned)(-1)) {
/* Very unlikely, but possible on 16 bit machine if strstart == 0 /* Very unlikely, but possible on 16 bit machine if strstart == 0
* and lookahead == 1 (input done one byte at time) * and lookahead == 1 (input done one byte at time)
@@ -697,9 +861,6 @@ local void fill_window(s)
*/ */
} else if (s->strstart >= wsize+MAX_DIST(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, zmemcpy((charf *)s->window, (charf *)s->window+wsize,
(unsigned)wsize); (unsigned)wsize);
s->match_start -= wsize; s->match_start -= wsize;
@@ -768,9 +929,11 @@ local void fill_window(s)
* IN assertion: strstart is set to the end of the current match. * IN assertion: strstart is set to the end of the current match.
*/ */
#define FLUSH_BLOCK_ONLY(s, eof) { \ #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 *)&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; \ s->block_start = s->strstart; \
flush_pending(s->strm); \ flush_pending(s->strm); \
Tracev((stderr,"[FLUSH]")); \ Tracev((stderr,"[FLUSH]")); \
@@ -779,24 +942,67 @@ local void fill_window(s)
/* Same but force premature exit if necessary. */ /* Same but force premature exit if necessary. */
#define FLUSH_BLOCK(s, eof) { \ #define FLUSH_BLOCK(s, eof) { \
FLUSH_BLOCK_ONLY(s, eof); \ FLUSH_BLOCK_ONLY(s, eof); \
if (s->strm->avail_out == 0) return 1; \ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
} }
/* =========================================================================== /* ===========================================================================
* Compress as much as possible from the input stream, return true if * Copy without compression as much as possible from the input stream, return
* processing was terminated prematurely (no more input or output space). * the current block state.
* This function does not perform lazy evaluationof matches and inserts * This function does not insert new strings in the dictionary since
* new strings in the dictionary only for unmatched strings or for short * uncompressible data is probably not useful. This function is used
* matches. It is used only for the fast compression options. * only for the level=0 compression option.
* NOTE: this function should be optimized to avoid extra copying.
*/ */
local int deflate_fast(s, flush) local block_state deflate_stored(s, flush)
deflate_state *s; deflate_state *s;
int flush; int flush;
{ {
IPos hash_head; /* head of the hash chain */ for (;;) {
int bflush; /* set if current block must be flushed */ /* Fill the window as much as possible: */
if (s->lookahead <= 1) {
s->prev_length = MIN_MATCH-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 need_more;
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 > 0xfffe) {
/* 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 flush == Z_FINISH ? finish_done : block_done;
}
/* ===========================================================================
* Compress as much as possible from the input stream, return the current
* block state.
* 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.
*/
local block_state deflate_fast(s, flush)
deflate_state *s;
int flush;
{
IPos hash_head = NIL; /* head of the hash chain */
int bflush; /* set if current block must be flushed */
for (;;) { for (;;) {
/* Make sure that we always have enough lookahead, except /* Make sure that we always have enough lookahead, except
@@ -806,8 +1012,9 @@ local int deflate_fast(s, flush)
*/ */
if (s->lookahead < MIN_LOOKAHEAD) { if (s->lookahead < MIN_LOOKAHEAD) {
fill_window(s); fill_window(s);
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */ if (s->lookahead == 0) break; /* flush the current block */
} }
@@ -830,14 +1037,12 @@ local int deflate_fast(s, flush)
s->match_length = longest_match (s, hash_head); s->match_length = longest_match (s, hash_head);
} }
/* longest_match() sets match_start */ /* longest_match() sets match_start */
if (s->match_length > s->lookahead) s->match_length = s->lookahead;
} }
if (s->match_length >= MIN_MATCH) { if (s->match_length >= MIN_MATCH) {
check_match(s, s->strstart, s->match_start, s->match_length); 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->match_length - MIN_MATCH);
s->lookahead -= s->match_length; s->lookahead -= s->match_length;
@@ -870,14 +1075,14 @@ local int deflate_fast(s, flush)
} else { } else {
/* No match, output a literal byte */ /* No match, output a literal byte */
Tracevv((stderr,"%c", s->window[s->strstart])); 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->lookahead--;
s->strstart++; s->strstart++;
} }
if (bflush) FLUSH_BLOCK(s, 0); if (bflush) FLUSH_BLOCK(s, 0);
} }
FLUSH_BLOCK(s, flush == Z_FINISH); FLUSH_BLOCK(s, flush == Z_FINISH);
return 0; /* normal exit */ return flush == Z_FINISH ? finish_done : block_done;
} }
/* =========================================================================== /* ===========================================================================
@@ -885,11 +1090,11 @@ local int deflate_fast(s, flush)
* evaluation for matches: a match is finally adopted only if there is * evaluation for matches: a match is finally adopted only if there is
* no better match at the next window position. * no better match at the next window position.
*/ */
local int deflate_slow(s, flush) local block_state deflate_slow(s, flush)
deflate_state *s; deflate_state *s;
int flush; 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 */ int bflush; /* set if current block must be flushed */
/* Process the input block. */ /* Process the input block. */
@@ -901,8 +1106,9 @@ local int deflate_slow(s, flush)
*/ */
if (s->lookahead < MIN_LOOKAHEAD) { if (s->lookahead < MIN_LOOKAHEAD) {
fill_window(s); fill_window(s);
if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
return need_more;
}
if (s->lookahead == 0) break; /* flush the current block */ if (s->lookahead == 0) break; /* flush the current block */
} }
@@ -928,7 +1134,6 @@ local int deflate_slow(s, flush)
s->match_length = longest_match (s, hash_head); s->match_length = longest_match (s, hash_head);
} }
/* longest_match() sets match_start */ /* 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 || if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
(s->match_length == MIN_MATCH && (s->match_length == MIN_MATCH &&
@@ -949,8 +1154,8 @@ local int deflate_slow(s, flush)
check_match(s, s->strstart-1, s->prev_match, s->prev_length); 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); s->prev_length - MIN_MATCH);
/* Insert in hash table all strings up to the end of the match. /* Insert in hash table all strings up to the end of the match.
* strstart-1 and strstart are already inserted. If there is not * strstart-1 and strstart are already inserted. If there is not
@@ -976,12 +1181,12 @@ local int deflate_slow(s, flush)
* is longer, truncate the previous match to a single literal. * is longer, truncate the previous match to a single literal.
*/ */
Tracevv((stderr,"%c", s->window[s->strstart-1])); 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); FLUSH_BLOCK_ONLY(s, 0);
} }
s->strstart++; s->strstart++;
s->lookahead--; s->lookahead--;
if (s->strm->avail_out == 0) return 1; if (s->strm->avail_out == 0) return need_more;
} else { } else {
/* There is no previous match to compare with, wait for /* There is no previous match to compare with, wait for
* the next step to decide. * the next step to decide.
@@ -994,10 +1199,9 @@ local int deflate_slow(s, flush)
Assert (flush != Z_NO_FLUSH, "no flush?"); Assert (flush != Z_NO_FLUSH, "no flush?");
if (s->match_available) { if (s->match_available) {
Tracevv((stderr,"%c", s->window[s->strstart-1])); 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; s->match_available = 0;
} }
FLUSH_BLOCK(s, flush == Z_FINISH); FLUSH_BLOCK(s, flush == Z_FINISH);
return 0; return flush == Z_FINISH ? finish_done : block_done;
} }

View File

@@ -1,5 +1,5 @@
/* deflate.h -- internal compression state /* deflate.h -- internal compression state
* Copyright (C) 1995 Jean-loup Gailly * Copyright (C) 1995-1996 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -8,7 +8,10 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
/* $Id: deflate.h,v 1.5 1995/05/03 17:27:09 jloup Exp $ */ /* $Id: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */
#ifndef _DEFLATE_H
#define _DEFLATE_H
#include "zutil.h" #include "zutil.h"
@@ -16,11 +19,6 @@
* Internal compression state. * Internal compression state.
*/ */
/* Data type */
#define BINARY 0
#define ASCII 1
#define UNKNOWN 2
#define LENGTH_CODES 29 #define LENGTH_CODES 29
/* number of length codes, not counting the special END_BLOCK code */ /* number of length codes, not counting the special END_BLOCK code */
@@ -82,15 +80,15 @@ typedef unsigned IPos;
*/ */
typedef struct internal_state { typedef struct internal_state {
z_stream *strm; /* pointer back to this zlib stream */ z_streamp strm; /* pointer back to this zlib stream */
int status; /* as the name implies */ int status; /* as the name implies */
Bytef *pending_buf; /* output still pending */ Bytef *pending_buf; /* output still pending */
Bytef *pending_out; /* next pending byte to output to the stream */ Bytef *pending_out; /* next pending byte to output to the stream */
int pending; /* nb of bytes in the pending buffer */ int pending; /* nb of bytes in the pending buffer */
uLong adler; /* adler32 of uncompressed data */
int noheader; /* suppress zlib header and adler32 */ int noheader; /* suppress zlib header and adler32 */
Byte data_type; /* UNKNOWN, BINARY or ASCII */ Byte data_type; /* UNKNOWN, BINARY or ASCII */
Byte method; /* STORED (for zip only) or DEFLATED */ Byte method; /* STORED (for zip only) or DEFLATED */
int last_flush; /* value of flush param for previous deflate call */
/* used by deflate.c: */ /* used by deflate.c: */
@@ -173,7 +171,7 @@ typedef struct internal_state {
uInt good_match; uInt good_match;
/* Use a faster search when the previous match is longer than this */ /* Use a faster search when the previous match is longer than this */
int nice_match; /* Stop searching when current match exceeds this */ int nice_match; /* Stop searching when current match exceeds this */
/* used by trees.c: */ /* used by trees.c: */
/* Didn't use ct_data typedef below to supress compiler warning */ /* Didn't use ct_data typedef below to supress compiler warning */
@@ -267,9 +265,11 @@ typedef struct internal_state {
*/ */
/* in trees.c */ /* in trees.c */
void ct_init OF((deflate_state *s)); void _tr_init OF((deflate_state *s));
int ct_tally OF((deflate_state *s, int dist, int lc)); int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
ulg ct_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int eof)); ulg _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
void ct_align OF((deflate_state *s)); int eof));
void ct_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, void _tr_align OF((deflate_state *s));
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
int eof)); int eof));
#endif

331
example.c
View File

@@ -1,29 +1,20 @@
/* example.c -- usage example of the zlib compression library /* example.c -- usage example of the zlib compression library
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: example.c,v 1.9 1995/05/03 17:27:09 jloup Exp $ */ /* $Id: example.c,v 1.16 1996/05/23 17:11:28 me Exp $ */
#include <stdio.h> #include <stdio.h>
#include "zlib.h" #include "zlib.h"
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h>
#else
extern void exit OF((int));
#endif #endif
#ifndef __GO32__
extern void exit OF((int));
#endif
#define BUFLEN 4096
#define local static
/* For MSDOS and other systems with limitation on stack size. For Unix,
#define local
works also.
*/
#define CHECK_ERR(err, msg) { \ #define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \ if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \ fprintf(stderr, "%s error: %d\n", msg, err); \
@@ -31,32 +22,44 @@ extern void exit OF((int));
} \ } \
} }
char *hello = "hello, hello!"; const char hello[] = "hello, hello!";
/* "hello world" would be more standard, but the repeated "hello" /* "hello world" would be more standard, but the repeated "hello"
* stresses the compression code better, sorry... * stresses the compression code better, sorry...
*/ */
void test_compress OF((void)); const char dictionary[] = "hello";
void test_gzio OF((char *out, char *in)); uLong dictId; /* Adler32 value of the dictionary */
void test_deflate OF((Byte compr[]));
void test_inflate OF((Byte compr[])); void test_compress OF((Byte *compr, uLong comprLen,
void test_flush OF((Byte compr[])); Byte *uncompr, uLong uncomprLen));
void test_sync OF((Byte compr[])); void test_gzio OF((const char *out, const char *in,
int main OF((int argc, char *argv[])); Byte *uncompr, int uncomprLen));
void test_deflate OF((Byte *compr, uLong comprLen));
void test_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_large_deflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_large_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_flush OF((Byte *compr, uLong comprLen));
void test_sync OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
void test_dict_deflate OF((Byte *compr, uLong comprLen));
void test_dict_inflate OF((Byte *compr, uLong comprLen,
Byte *uncompr, uLong uncomprLen));
int main OF((int argc, char *argv[]));
/* =========================================================================== /* ===========================================================================
* Test compress() and uncompress() * Test compress() and uncompress()
*/ */
void test_compress() void test_compress(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{ {
local Byte compr[BUFLEN];
uLong comprLen = sizeof(compr);
local Byte uncompr[BUFLEN];
uLong uncomprLen = sizeof(uncompr);
int err; int err;
uLong len = strlen(hello)+1; uLong len = strlen(hello)+1;
err = compress(compr, &comprLen, (Byte*)hello, len); err = compress(compr, &comprLen, (const Bytef*)hello, len);
CHECK_ERR(err, "compress"); CHECK_ERR(err, "compress");
strcpy((char*)uncompr, "garbage"); strcpy((char*)uncompr, "garbage");
@@ -74,12 +77,12 @@ void test_compress()
/* =========================================================================== /* ===========================================================================
* Test read/write of .gz files * Test read/write of .gz files
*/ */
void test_gzio(out, in) void test_gzio(out, in, uncompr, uncomprLen)
char *out; /* output file */ const char *out; /* output file */
char *in; /* input file */ const char *in; /* input file */
Byte *uncompr;
int uncomprLen;
{ {
local Byte uncompr[BUFLEN];
int uncomprLen = sizeof(uncompr);
int err; int err;
int len = strlen(hello)+1; int len = strlen(hello)+1;
gzFile file; gzFile file;
@@ -90,7 +93,7 @@ void test_gzio(out, in)
exit(1); exit(1);
} }
if (gzwrite(file, hello, len) != len) { if (gzwrite(file, (const voidp)hello, (unsigned)len) != len) {
fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err)); fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
} }
gzclose(file); gzclose(file);
@@ -101,7 +104,7 @@ void test_gzio(out, in)
} }
strcpy((char*)uncompr, "garbage"); strcpy((char*)uncompr, "garbage");
uncomprLen = gzread(file, uncompr, uncomprLen); uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
if (uncomprLen != len) { if (uncomprLen != len) {
fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
} }
@@ -117,8 +120,9 @@ void test_gzio(out, in)
/* =========================================================================== /* ===========================================================================
* Test deflate() with small buffers * Test deflate() with small buffers
*/ */
void test_deflate(compr) void test_deflate(compr, comprLen)
Byte compr[]; Byte *compr;
uLong comprLen;
{ {
z_stream c_stream; /* compression stream */ z_stream c_stream; /* compression stream */
int err; int err;
@@ -126,14 +130,15 @@ void test_deflate(compr)
c_stream.zalloc = (alloc_func)0; c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0; c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit"); CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Byte*)hello; c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr; c_stream.next_out = compr;
while (c_stream.total_in != (uLong)len) { while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = deflate(&c_stream, Z_NO_FLUSH); err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate"); CHECK_ERR(err, "deflate");
@@ -153,10 +158,10 @@ void test_deflate(compr)
/* =========================================================================== /* ===========================================================================
* Test inflate() with small buffers * Test inflate() with small buffers
*/ */
void test_inflate(compr) void test_inflate(compr, comprLen, uncompr, uncomprLen)
Byte compr[]; Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{ {
local Byte uncompr[BUFLEN];
int err; int err;
z_stream d_stream; /* decompression stream */ z_stream d_stream; /* decompression stream */
@@ -164,6 +169,7 @@ void test_inflate(compr)
d_stream.zalloc = (alloc_func)0; d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0; d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream); err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit"); CHECK_ERR(err, "inflateInit");
@@ -171,7 +177,7 @@ void test_inflate(compr)
d_stream.next_in = compr; d_stream.next_in = compr;
d_stream.next_out = uncompr; d_stream.next_out = uncompr;
for (;;) { while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = inflate(&d_stream, Z_NO_FLUSH); err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break; if (err == Z_STREAM_END) break;
@@ -188,11 +194,105 @@ void test_inflate(compr)
} }
} }
/* ===========================================================================
* Test deflate() with large buffers and dynamic change of compression level
*/
void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
Byte *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)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
int err;
z_stream d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage");
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_in = compr;
d_stream.avail_in = (uInt)comprLen;
for (;;) {
d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (uInt)uncomprLen;
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "large inflate");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
} else {
printf("large_inflate(): OK\n");
}
}
/* =========================================================================== /* ===========================================================================
* Test deflate() with full flush * Test deflate() with full flush
*/ */
void test_flush(compr) void test_flush(compr, comprLen)
Byte compr[]; Byte *compr;
uLong comprLen;
{ {
z_stream c_stream; /* compression stream */ z_stream c_stream; /* compression stream */
int err; int err;
@@ -200,14 +300,15 @@ void test_flush(compr)
c_stream.zalloc = (alloc_func)0; c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0; c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit"); CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Byte*)hello; c_stream.next_in = (Bytef*)hello;
c_stream.next_out = compr; c_stream.next_out = compr;
c_stream.avail_in = 3; c_stream.avail_in = 3;
c_stream.avail_out = BUFLEN; c_stream.avail_out = (uInt)comprLen;
err = deflate(&c_stream, Z_FULL_FLUSH); err = deflate(&c_stream, Z_FULL_FLUSH);
CHECK_ERR(err, "deflate"); CHECK_ERR(err, "deflate");
@@ -225,10 +326,10 @@ void test_flush(compr)
/* =========================================================================== /* ===========================================================================
* Test inflateSync() * Test inflateSync()
*/ */
void test_sync(compr) void test_sync(compr, comprLen, uncompr, uncomprLen)
Byte compr[]; Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{ {
local Byte uncompr[BUFLEN];
int err; int err;
z_stream d_stream; /* decompression stream */ z_stream d_stream; /* decompression stream */
@@ -236,6 +337,7 @@ void test_sync(compr)
d_stream.zalloc = (alloc_func)0; d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0; d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream); err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit"); CHECK_ERR(err, "inflateInit");
@@ -243,13 +345,13 @@ void test_sync(compr)
d_stream.next_in = compr; d_stream.next_in = compr;
d_stream.next_out = uncompr; d_stream.next_out = uncompr;
d_stream.avail_in = 2; /* just read the zlib header */ d_stream.avail_in = 2; /* just read the zlib header */
d_stream.avail_out = sizeof(uncompr); d_stream.avail_out = (uInt)uncomprLen;
inflate(&d_stream, Z_NO_FLUSH); inflate(&d_stream, Z_NO_FLUSH);
CHECK_ERR(err, "inflate"); CHECK_ERR(err, "inflate");
d_stream.avail_in = BUFLEN-2; /* let inflate read all compressed data */ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
err = inflateSync(&d_stream); /* skip the damaged part */ err = inflateSync(&d_stream); /* but skip the damaged part */
CHECK_ERR(err, "inflateSync"); CHECK_ERR(err, "inflateSync");
err = inflate(&d_stream, Z_FINISH); err = inflate(&d_stream, Z_FINISH);
@@ -263,6 +365,91 @@ void test_sync(compr)
printf("after inflateSync(): hel%s\n", uncompr); printf("after inflateSync(): hel%s\n", uncompr);
} }
/* ===========================================================================
* Test deflate() with preset dictionary
*/
void test_dict_deflate(compr, comprLen)
Byte *compr;
uLong comprLen;
{
z_stream c_stream; /* compression stream */
int err;
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
err = deflateSetDictionary(&c_stream,
(const Bytef*)dictionary, sizeof(dictionary));
CHECK_ERR(err, "deflateSetDictionary");
dictId = c_stream.adler;
c_stream.next_out = compr;
c_stream.avail_out = (uInt)comprLen;
c_stream.next_in = (Bytef*)hello;
c_stream.avail_in = (uInt)strlen(hello)+1;
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END) {
fprintf(stderr, "deflate should report Z_STREAM_END\n");
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* ===========================================================================
* Test inflate() with a preset dictionary
*/
void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
Byte *compr, *uncompr;
uLong comprLen, uncomprLen;
{
int err;
z_stream d_stream; /* decompression stream */
strcpy((char*)uncompr, "garbage");
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
d_stream.next_in = compr;
d_stream.avail_in = (uInt)comprLen;
d_stream.next_out = uncompr;
d_stream.avail_out = (uInt)uncomprLen;
for (;;) {
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
if (err == Z_NEED_DICT) {
if (d_stream.adler != dictId) {
fprintf(stderr, "unexpected dictionary");
exit(1);
}
err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
sizeof(dictionary));
}
CHECK_ERR(err, "inflate with dict");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (strcmp((char*)uncompr, hello)) {
fprintf(stderr, "bad inflate with dict\n");
} else {
printf("inflate with dictionary: %s\n", uncompr);
}
}
/* =========================================================================== /* ===========================================================================
* Usage: example [output.gz [input.gz]] * Usage: example [output.gz [input.gz]]
*/ */
@@ -271,25 +458,45 @@ int main(argc, argv)
int argc; int argc;
char *argv[]; char *argv[];
{ {
local Byte compr[BUFLEN]; Byte *compr, *uncompr;
uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
uLong uncomprLen = comprLen;
if (zlib_version[0] != ZLIB_VERSION[0]) { if (zlibVersion()[0] != ZLIB_VERSION[0]) {
fprintf(stderr, "incompatible zlib version\n"); fprintf(stderr, "incompatible zlib version\n");
exit(1); exit(1);
} else if (strcmp(zlib_version, ZLIB_VERSION) != 0) { } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
fprintf(stderr, "warning: different zlib version\n"); fprintf(stderr, "warning: different zlib version\n");
} }
test_compress();
compr = (Byte*)calloc((uInt)comprLen, 1);
uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
/* compr and uncompr are cleared to avoid reading uninitialized
* data and to ensure that uncompr compresses well.
*/
if (compr == Z_NULL || uncompr == Z_NULL) {
printf("out of memory\n");
exit(1);
}
test_compress(compr, comprLen, uncompr, uncomprLen);
test_gzio((argc > 1 ? argv[1] : "foo.gz"), test_gzio((argc > 1 ? argv[1] : "foo.gz"),
(argc > 2 ? argv[2] : "foo.gz")); (argc > 2 ? argv[2] : "foo.gz"),
uncompr, (int)uncomprLen);
test_deflate(compr); test_deflate(compr, comprLen);
test_inflate(compr); test_inflate(compr, comprLen, uncompr, uncomprLen);
test_flush(compr); test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_sync(compr); 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); exit(0);
return 0; /* to avoid warning */ return 0; /* to avoid warning */

378
gzio.c
View File

@@ -1,9 +1,9 @@
/* gzio.c -- IO on .gz files /* gzio.c -- IO on .gz files
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: gzio.c,v 1.8 1995/05/03 17:27:09 jloup Exp $ */ /* $Id: gzio.c,v 1.14 1996/07/24 13:41:01 me Exp $ */
#include <stdio.h> #include <stdio.h>
@@ -16,8 +16,7 @@ struct internal_state {int dummy;}; /* for buggy compilers */
#define ALLOC(size) malloc(size) #define ALLOC(size) malloc(size)
#define TRYFREE(p) {if (p) free(p);} #define TRYFREE(p) {if (p) free(p);}
#define GZ_MAGIC_1 0x1f static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
#define GZ_MAGIC_2 0x8b
/* gzip flag byte */ /* gzip flag byte */
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
@@ -27,10 +26,6 @@ struct internal_state {int dummy;}; /* for buggy compilers */
#define COMMENT 0x10 /* bit 4 set: file comment present */ #define COMMENT 0x10 /* bit 4 set: file comment present */
#define RESERVED 0xE0 /* bits 5..7: reserved */ #define RESERVED 0xE0 /* bits 5..7: reserved */
#ifndef SEEK_CUR
# define SEEK_CUR 1
#endif
typedef struct gz_stream { typedef struct gz_stream {
z_stream stream; z_stream stream;
int z_err; /* error code for last stream operation */ int z_err; /* error code for last stream operation */
@@ -46,44 +41,16 @@ typedef struct gz_stream {
} gz_stream; } gz_stream;
local int destroy OF((gz_stream *s)); local gzFile gz_open OF((const char *path, const char *mode, int fd));
local gzFile gz_open OF((char *path, char *mode, int fd)); local int get_byte OF((gz_stream *s));
local void putLong OF((FILE *file, uLong x)); local void check_header OF((gz_stream *s));
local uLong getLong OF((Bytef *buf)); local int destroy OF((gz_stream *s));
local void putLong OF((FILE *file, uLong x));
/* =========================================================================== local uLong getLong OF((gz_stream *s));
* Cleanup then free the given gz_stream. Return a zlib error code.
*/
local int destroy (s)
gz_stream *s;
{
int err = Z_OK;
if (!s) return Z_STREAM_ERROR;
TRYFREE(s->inbuf);
TRYFREE(s->outbuf);
TRYFREE(s->path);
TRYFREE(s->msg);
if (s->stream.state != NULL) {
if (s->mode == 'w') {
err = deflateEnd(&(s->stream));
} else if (s->mode == 'r') {
err = inflateEnd(&(s->stream));
}
}
if (s->file != NULL && fclose(s->file)) {
err = Z_ERRNO;
}
if (s->z_err < 0) err = s->z_err;
TRYFREE(s);
return err;
}
/* =========================================================================== /* ===========================================================================
Opens a gzip (.gz) file for reading or writing. The mode parameter Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descritor is as in fopen ("rb" or "wb"). The file is given either by file descriptor
or path name (if fd == -1). or path name (if fd == -1).
gz_open return NULL if the file could not be opened or if there was gz_open return NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno insufficient memory to allocate the (de)compression state; errno
@@ -91,19 +58,25 @@ local int destroy (s)
zlib error is Z_MEM_ERROR). zlib error is Z_MEM_ERROR).
*/ */
local gzFile gz_open (path, mode, fd) local gzFile gz_open (path, mode, fd)
char *path; const char *path;
char *mode; const char *mode;
int fd; int fd;
{ {
int err; int err;
int level = Z_DEFAULT_COMPRESSION; /* compression level */ int level = Z_DEFAULT_COMPRESSION; /* compression level */
char *p = mode; char *p = (char*)mode;
gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream)); gz_stream *s;
char fmode[80]; /* copy of mode, without the compression level */
char *m = fmode;
if (!path || !mode) return Z_NULL;
s = (gz_stream *)ALLOC(sizeof(gz_stream));
if (!s) return Z_NULL; if (!s) return Z_NULL;
s->stream.zalloc = (alloc_func)0; s->stream.zalloc = (alloc_func)0;
s->stream.zfree = (free_func)0; s->stream.zfree = (free_func)0;
s->stream.opaque = (voidpf)0;
s->stream.next_in = s->inbuf = Z_NULL; s->stream.next_in = s->inbuf = Z_NULL;
s->stream.next_out = s->outbuf = Z_NULL; s->stream.next_out = s->outbuf = Z_NULL;
s->stream.avail_in = s->stream.avail_out = 0; s->stream.avail_in = s->stream.avail_out = 0;
@@ -123,14 +96,18 @@ local gzFile gz_open (path, mode, fd)
s->mode = '\0'; s->mode = '\0';
do { do {
if (*p == 'r') s->mode = 'r'; if (*p == 'r') s->mode = 'r';
if (*p == 'w') s->mode = 'w'; if (*p == 'w' || *p == 'a') s->mode = 'w';
if (*p >= '1' && *p <= '9') level = *p - '0'; if (*p >= '0' && *p <= '9') {
} while (*p++); level = *p - '0';
} else {
*m++ = *p; /* copy the mode */
}
} while (*p++ && m != fmode + sizeof(fmode));
if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
if (s->mode == 'w') { if (s->mode == 'w') {
err = deflateInit2(&(s->stream), level, err = deflateInit2(&(s->stream), level,
DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
/* windowBits is passed < 0 to suppress zlib header */ /* windowBits is passed < 0 to suppress zlib header */
s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
@@ -149,7 +126,7 @@ local gzFile gz_open (path, mode, fd)
s->stream.avail_out = Z_BUFSIZE; s->stream.avail_out = Z_BUFSIZE;
errno = 0; errno = 0;
s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode); s->file = fd < 0 ? FOPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
if (s->file == NULL) { if (s->file == NULL) {
return destroy(s), (gzFile)Z_NULL; return destroy(s), (gzFile)Z_NULL;
@@ -157,50 +134,10 @@ local gzFile gz_open (path, mode, fd)
if (s->mode == 'w') { if (s->mode == 'w') {
/* Write a very simple .gz header: /* Write a very simple .gz header:
*/ */
fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2, fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
} else { } else {
/* Check and skip the header: check_header(s); /* skip the .gz header */
*/
Byte c1 = 0, c2 = 0;
Byte method = 0;
Byte flags = 0;
Byte xflags = 0;
Byte time[4];
Byte osCode;
int c;
s->stream.avail_in = fread(s->inbuf, 1, 2, s->file);
if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1
|| s->inbuf[1] != GZ_MAGIC_2) {
s->transparent = 1;
return (gzFile)s;
}
s->stream.avail_in = 0;
fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode);
if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) {
s->z_err = Z_DATA_ERROR;
return (gzFile)s;
}
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
long len;
fscanf(s->file, "%c%c", &c1, &c2);
len = c1 + ((long)c2<<8);
fseek(s->file, len, SEEK_CUR);
}
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
while ((c = getc(s->file)) != 0 && c != EOF) ;
}
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
while ((c = getc(s->file)) != 0 && c != EOF) ;
}
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
fscanf(s->file, "%c%c", &c1, &c2);
}
if (feof(s->file)) {
s->z_err = Z_DATA_ERROR;
}
} }
return (gzFile)s; return (gzFile)s;
} }
@@ -209,25 +146,138 @@ local gzFile gz_open (path, mode, fd)
Opens a gzip (.gz) file for reading or writing. Opens a gzip (.gz) file for reading or writing.
*/ */
gzFile gzopen (path, mode) gzFile gzopen (path, mode)
char *path; const char *path;
char *mode; const char *mode;
{ {
return gz_open (path, mode, -1); return gz_open (path, mode, -1);
} }
/* =========================================================================== /* ===========================================================================
Associate a gzFile with the file descriptor fd. Associate a gzFile with the file descriptor fd. fd is not dup'ed here
to mimic the behavio(u)r of fdopen.
*/ */
gzFile gzdopen (fd, mode) gzFile gzdopen (fd, mode)
int fd; int fd;
char *mode; const char *mode;
{ {
char name[20]; char name[20];
if (fd < 0) return (gzFile)Z_NULL;
sprintf(name, "<fd:%d>", fd); /* for debugging */ sprintf(name, "<fd:%d>", fd); /* for debugging */
return gz_open (name, mode, fd); return gz_open (name, mode, fd);
} }
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
IN assertion: the stream s has been sucessfully opened for reading.
*/
local int get_byte(s)
gz_stream *s;
{
if (s->z_eof) return EOF;
if (s->stream.avail_in == 0) {
errno = 0;
s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) {
s->z_eof = 1;
if (ferror(s->file)) s->z_err = Z_ERRNO;
return EOF;
}
s->stream.next_in = s->inbuf;
}
s->stream.avail_in--;
return *(s->stream.next_in)++;
}
/* ===========================================================================
Check the gzip header of a gz_stream opened for reading. Set the stream
mode to transparent if the gzip magic header is not present; set s->err
to Z_DATA_ERROR if the magic header is present but the rest of the header
is incorrect.
IN assertion: the stream s has already been created sucessfully;
s->stream.avail_in is zero for the first time, but may be non-zero
for concatenated .gz files.
*/
local void check_header(s)
gz_stream *s;
{
int method; /* method byte */
int flags; /* flags byte */
uInt len;
int c;
/* Check the gzip magic header */
for (len = 0; len < 2; len++) {
c = get_byte(s);
if (c != gz_magic[len]) {
s->transparent = 1;
if (c != EOF) s->stream.avail_in++, s->stream.next_in--;
s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
return;
}
}
method = get_byte(s);
flags = get_byte(s);
if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
s->z_err = Z_DATA_ERROR;
return;
}
/* Discard time, xflags and OS code: */
for (len = 0; len < 6; len++) (void)get_byte(s);
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
len = (uInt)get_byte(s);
len += ((uInt)get_byte(s))<<8;
/* len is garbage if EOF but the loop below will quit anyway */
while (len-- != 0 && get_byte(s) != EOF) ;
}
if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
while ((c = get_byte(s)) != 0 && c != EOF) ;
}
if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
while ((c = get_byte(s)) != 0 && c != EOF) ;
}
if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
for (len = 0; len < 2; len++) (void)get_byte(s);
}
s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
}
/* ===========================================================================
* Cleanup then free the given gz_stream. Return a zlib error code.
Try freeing in the reverse order of allocations.
*/
local int destroy (s)
gz_stream *s;
{
int err = Z_OK;
if (!s) return Z_STREAM_ERROR;
TRYFREE(s->msg);
if (s->stream.state != NULL) {
if (s->mode == 'w') {
err = deflateEnd(&(s->stream));
} else if (s->mode == 'r') {
err = inflateEnd(&(s->stream));
}
}
if (s->file != NULL && fclose(s->file)) {
err = Z_ERRNO;
}
if (s->z_err < 0) err = s->z_err;
TRYFREE(s->inbuf);
TRYFREE(s->outbuf);
TRYFREE(s->path);
TRYFREE(s);
return err;
}
/* =========================================================================== /* ===========================================================================
Reads the given number of uncompressed bytes from the compressed file. Reads the given number of uncompressed bytes from the compressed file.
gzread returns the number of bytes actually read (0 for end of file). gzread returns the number of bytes actually read (0 for end of file).
@@ -238,52 +288,73 @@ int gzread (file, buf, len)
unsigned len; unsigned len;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
Bytef *start = buf; /* starting point for crc computation */
Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
if (s->transparent) { if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
int n = 0; if (s->z_err == Z_STREAM_END) return 0; /* EOF */
Byte *b = (Byte*)buf;
/* Copy the first two (non-magic) bytes if not done already */
while (s->stream.avail_in > 0 && len > 0) {
*b++ = *s->stream.next_in++;
s->stream.avail_in--;
len--; n++;
}
if (len == 0) return n;
return n + fread(b, 1, len, s->file);
}
if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
if (s->z_err == Z_STREAM_END) return 0; /* don't read crc as data */
s->stream.next_out = buf; s->stream.next_out = next_out = buf;
s->stream.avail_out = len; s->stream.avail_out = len;
while (s->stream.avail_out != 0) { while (s->stream.avail_out != 0) {
if (s->transparent) {
/* Copy first the lookahead bytes: */
uInt n = s->stream.avail_in;
if (n > s->stream.avail_out) n = s->stream.avail_out;
if (n > 0) {
zmemcpy(s->stream.next_out, s->stream.next_in, n);
next_out += n;
s->stream.next_out = next_out;
s->stream.next_in += n;
s->stream.avail_out -= n;
s->stream.avail_in -= n;
}
if (s->stream.avail_out > 0) {
s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
s->file);
}
return (int)(len - s->stream.avail_out);
}
if (s->stream.avail_in == 0 && !s->z_eof) { if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0; errno = 0;
s->stream.avail_in = s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
fread(s->inbuf, 1, Z_BUFSIZE, s->file);
if (s->stream.avail_in == 0) { if (s->stream.avail_in == 0) {
s->z_eof = 1; s->z_eof = 1;
} else if (s->stream.avail_in == (uInt)EOF) { if (ferror(s->file)) {
s->stream.avail_in = 0; s->z_err = Z_ERRNO;
s->z_eof = 1; break;
s->z_err = Z_ERRNO; }
break;
} }
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
} }
s->z_err = inflate(&(s->stream), Z_NO_FLUSH); s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
if (s->z_err == Z_STREAM_END || if (s->z_err == Z_STREAM_END) {
s->z_err != Z_OK || s->z_eof) break; /* Check CRC and original size */
s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
start = s->stream.next_out;
if (getLong(s) != s->crc || getLong(s) != s->stream.total_out) {
s->z_err = Z_DATA_ERROR;
} else {
/* Check for concatenated .gz files: */
check_header(s);
if (s->z_err == Z_OK) {
inflateReset(&(s->stream));
s->crc = crc32(0L, Z_NULL, 0);
}
}
}
if (s->z_err != Z_OK || s->z_eof) break;
} }
len -= s->stream.avail_out; s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
s->crc = crc32(s->crc, buf, len);
return (int)len; return (int)(len - s->stream.avail_out);
} }
/* =========================================================================== /* ===========================================================================
@@ -292,7 +363,7 @@ int gzread (file, buf, len)
*/ */
int gzwrite (file, buf, len) int gzwrite (file, buf, len)
gzFile file; gzFile file;
voidp buf; const voidp buf;
unsigned len; unsigned len;
{ {
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
@@ -343,7 +414,7 @@ int gzflush (file, flush)
len = Z_BUFSIZE - s->stream.avail_out; len = Z_BUFSIZE - s->stream.avail_out;
if (len != 0) { if (len != 0) {
if (fwrite(s->outbuf, 1, len, s->file) != len) { if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
s->z_err = Z_ERRNO; s->z_err = Z_ERRNO;
return Z_ERRNO; return Z_ERRNO;
} }
@@ -379,18 +450,19 @@ local void putLong (file, x)
} }
/* =========================================================================== /* ===========================================================================
Reads a long in LSB order from the given buffer Reads a long in LSB order from the given gz_stream. Sets
*/ */
local uLong getLong (buf) local uLong getLong (s)
Bytef *buf; gz_stream *s;
{ {
uLong x = 0; uLong x = (uLong)get_byte(s);
Bytef *p = buf+4; int c;
do { x += ((uLong)get_byte(s))<<8;
x <<= 8; x += ((uLong)get_byte(s))<<16;
x |= *--p; c = get_byte(s);
} while (p != buf); if (c == EOF) s->z_err = Z_DATA_ERROR;
x += ((uLong)c)<<24;
return x; return x;
} }
@@ -401,7 +473,6 @@ local uLong getLong (buf)
int gzclose (file) int gzclose (file)
gzFile file; gzFile file;
{ {
uInt n;
int err; int err;
gz_stream *s = (gz_stream*)file; gz_stream *s = (gz_stream*)file;
@@ -414,25 +485,6 @@ int gzclose (file)
putLong (s->file, s->crc); putLong (s->file, s->crc);
putLong (s->file, s->stream.total_in); putLong (s->file, s->stream.total_in);
} else if (s->mode == 'r' && s->z_err == Z_STREAM_END) {
/* slide CRC and original size if they are at the end of inbuf */
if ((n = s->stream.avail_in) < 8 && !s->z_eof) {
Byte *p = s->inbuf;
Bytef *q = s->stream.next_in;
while (n--) { *p++ = *q++; };
n = s->stream.avail_in;
n += fread(p, 1, 8, s->file);
s->stream.next_in = s->inbuf;
}
/* check CRC and original size */
if (n < 8 ||
getLong(s->stream.next_in) != s->crc ||
getLong(s->stream.next_in + 4) != s->stream.total_out) {
s->z_err = Z_DATA_ERROR;
}
} }
return destroy(file); return destroy(file);
} }
@@ -444,7 +496,7 @@ int gzclose (file)
errnum is set to Z_ERRNO and the application may consult errno errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code. to get the exact error code.
*/ */
char* gzerror (file, errnum) const char* gzerror (file, errnum)
gzFile file; gzFile file;
int *errnum; int *errnum;
{ {
@@ -453,19 +505,19 @@ char* gzerror (file, errnum)
if (s == NULL) { if (s == NULL) {
*errnum = Z_STREAM_ERROR; *errnum = Z_STREAM_ERROR;
return z_errmsg[1-Z_STREAM_ERROR]; return (const char*)ERR_MSG(Z_STREAM_ERROR);
} }
*errnum = s->z_err; *errnum = s->z_err;
if (*errnum == Z_OK) return ""; if (*errnum == Z_OK) return (const 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*)ERR_MSG(s->z_err);
TRYFREE(s->msg); TRYFREE(s->msg);
s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
strcpy(s->msg, s->path); strcpy(s->msg, s->path);
strcat(s->msg, ": "); strcat(s->msg, ": ");
strcat(s->msg, m); strcat(s->msg, m);
return s->msg; return (const char*)s->msg;
} }

View File

@@ -1,5 +1,5 @@
/* infblock.c -- interpret and process block types to last block /* infblock.c -- interpret and process block types to last block
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -63,7 +63,7 @@ local uInt border[] = { /* Order of the bit length code lengths */
void inflate_blocks_reset(s, z, c) void inflate_blocks_reset(s, z, c)
inflate_blocks_statef *s; inflate_blocks_statef *s;
z_stream *z; z_streamp z;
uLongf *c; uLongf *c;
{ {
if (s->checkfn != Z_NULL) if (s->checkfn != Z_NULL)
@@ -81,13 +81,13 @@ uLongf *c;
s->bitb = 0; s->bitb = 0;
s->read = s->write = s->window; s->read = s->write = s->window;
if (s->checkfn != Z_NULL) if (s->checkfn != Z_NULL)
s->check = (*s->checkfn)(0L, Z_NULL, 0); z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
Trace((stderr, "inflate: blocks reset\n")); Trace((stderr, "inflate: blocks reset\n"));
} }
inflate_blocks_statef *inflate_blocks_new(z, c, w) inflate_blocks_statef *inflate_blocks_new(z, c, w)
z_stream *z; z_streamp z;
check_func c; check_func c;
uInt w; uInt w;
{ {
@@ -110,9 +110,12 @@ uInt w;
} }
#ifdef DEBUG
extern uInt inflate_hufts;
#endif
int inflate_blocks(s, z, r) int inflate_blocks(s, z, r)
inflate_blocks_statef *s; inflate_blocks_statef *s;
z_stream *z; z_streamp z;
int r; int r;
{ {
uInt t; /* temporary storage */ uInt t; /* temporary storage */
@@ -172,24 +175,24 @@ int r;
case 3: /* illegal */ case 3: /* illegal */
DUMPBITS(3) DUMPBITS(3)
s->mode = BAD; s->mode = BAD;
z->msg = "invalid block type"; z->msg = (char*)"invalid block type";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
break; break;
case LENS: case LENS:
NEEDBITS(32) NEEDBITS(32)
if (((~b) >> 16) != (b & 0xffff)) if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
{ {
s->mode = BAD; s->mode = BAD;
z->msg = "invalid stored block lengths"; z->msg = (char*)"invalid stored block lengths";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
s->sub.left = (uInt)b & 0xffff; s->sub.left = (uInt)b & 0xffff;
b = k = 0; /* dump bits */ b = k = 0; /* dump bits */
Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
s->mode = s->sub.left ? STORED : TYPE; s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
break; break;
case STORED: case STORED:
if (n == 0) if (n == 0)
@@ -215,7 +218,7 @@ int r;
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
{ {
s->mode = BAD; s->mode = BAD;
z->msg = "too many length or distance symbols"; z->msg = (char*)"too many length or distance symbols";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
@@ -285,7 +288,7 @@ int r;
(c == 16 && i < 1)) (c == 16 && i < 1))
{ {
s->mode = BAD; s->mode = BAD;
z->msg = "invalid bit length repeat"; z->msg = (char*)"invalid bit length repeat";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
} }
@@ -306,6 +309,9 @@ int r;
bl = 9; /* must be <= 9 for lookahead assumptions */ bl = 9; /* must be <= 9 for lookahead assumptions */
bd = 6; /* must be <= 9 for lookahead assumptions */ bd = 6; /* must be <= 9 for lookahead assumptions */
t = s->sub.trees.table; t = s->sub.trees.table;
#ifdef DEBUG
inflate_hufts = 0;
#endif
t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
s->sub.trees.blens, &bl, &bd, &tl, &td, z); s->sub.trees.blens, &bl, &bd, &tl, &td, z);
if (t != Z_OK) if (t != Z_OK)
@@ -315,7 +321,8 @@ int r;
r = t; r = t;
LEAVE LEAVE
} }
Tracev((stderr, "inflate: trees ok\n")); Tracev((stderr, "inflate: trees ok, %d * %d bytes used\n",
inflate_hufts, sizeof(inflate_huft)));
if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
{ {
inflate_trees_free(td, z); inflate_trees_free(td, z);
@@ -374,7 +381,7 @@ int r;
int inflate_blocks_free(s, z, c) int inflate_blocks_free(s, z, c)
inflate_blocks_statef *s; inflate_blocks_statef *s;
z_stream *z; z_streamp z;
uLongf *c; uLongf *c;
{ {
inflate_blocks_reset(s, z, c); inflate_blocks_reset(s, z, c);
@@ -383,3 +390,13 @@ uLongf *c;
Trace((stderr, "inflate: blocks freed\n")); Trace((stderr, "inflate: blocks freed\n"));
return Z_OK; return Z_OK;
} }
void inflate_set_dictionary(s, d, n)
inflate_blocks_statef *s;
const Bytef *d;
uInt n;
{
zmemcpy((charf *)s->window, d, n);
s->read = s->write = s->window + n;
}

View File

@@ -1,5 +1,5 @@
/* infblock.h -- header to use infblock.c /* infblock.h -- header to use infblock.c
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -12,21 +12,26 @@ struct inflate_blocks_state;
typedef struct inflate_blocks_state FAR inflate_blocks_statef; typedef struct inflate_blocks_state FAR inflate_blocks_statef;
extern inflate_blocks_statef * inflate_blocks_new OF(( extern inflate_blocks_statef * inflate_blocks_new OF((
z_stream *z, z_streamp z,
check_func c, /* check function */ check_func c, /* check function */
uInt w)); /* window size */ uInt w)); /* window size */
extern int inflate_blocks OF(( extern int inflate_blocks OF((
inflate_blocks_statef *, inflate_blocks_statef *,
z_stream *, z_streamp ,
int)); /* initial return code */ int)); /* initial return code */
extern void inflate_blocks_reset OF(( extern void inflate_blocks_reset OF((
inflate_blocks_statef *, inflate_blocks_statef *,
z_stream *, z_streamp ,
uLongf *)); /* check value on output */ uLongf *)); /* check value on output */
extern int inflate_blocks_free OF(( extern int inflate_blocks_free OF((
inflate_blocks_statef *, inflate_blocks_statef *,
z_stream *, z_streamp ,
uLongf *)); /* check value on output */ uLongf *)); /* check value on output */
extern void inflate_set_dictionary OF((
inflate_blocks_statef *s,
const Bytef *d, /* dictionary */
uInt n)); /* dictionary length */

View File

@@ -1,5 +1,5 @@
/* infcodes.c -- process literals and length/distance pairs /* infcodes.c -- process literals and length/distance pairs
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -58,8 +58,9 @@ struct inflate_codes_state {
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
uInt bl, bd; uInt bl, bd;
inflate_huft *tl, *td; inflate_huft *tl;
z_stream *z; inflate_huft *td; /* need separate declaration for Borland C++ */
z_streamp z;
{ {
inflate_codes_statef *c; inflate_codes_statef *c;
@@ -79,7 +80,7 @@ z_stream *z;
int inflate_codes(s, z, r) int inflate_codes(s, z, r)
inflate_blocks_statef *s; inflate_blocks_statef *s;
z_stream *z; z_streamp z;
int r; int r;
{ {
uInt j; /* temporary storage */ uInt j; /* temporary storage */
@@ -152,7 +153,7 @@ int r;
break; break;
} }
c->mode = BADCODE; /* invalid code */ c->mode = BADCODE; /* invalid code */
z->msg = "invalid literal/length code"; z->msg = (char*)"invalid literal/length code";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
case LENEXT: /* i: getting length extra (have base) */ case LENEXT: /* i: getting length extra (have base) */
@@ -184,7 +185,7 @@ int r;
break; break;
} }
c->mode = BADCODE; /* invalid code */ c->mode = BADCODE; /* invalid code */
z->msg = "invalid distance code"; z->msg = (char*)"invalid distance code";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
LEAVE LEAVE
case DISTEXT: /* i: getting distance extra */ case DISTEXT: /* i: getting distance extra */
@@ -202,7 +203,7 @@ int r;
#else #else
f = q - c->sub.copy.dist; f = q - c->sub.copy.dist;
if ((uInt)(q - s->window) < c->sub.copy.dist) if ((uInt)(q - s->window) < c->sub.copy.dist)
f = s->end - (c->sub.copy.dist - (q - s->window)); f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
#endif #endif
while (c->len) while (c->len)
{ {
@@ -239,7 +240,7 @@ int r;
void inflate_codes_free(c, z) void inflate_codes_free(c, z)
inflate_codes_statef *c; inflate_codes_statef *c;
z_stream *z; z_streamp z;
{ {
ZFREE(z, c); ZFREE(z, c);
Tracev((stderr, "inflate: codes free\n")); Tracev((stderr, "inflate: codes free\n"));

View File

@@ -1,5 +1,5 @@
/* infcodes.h -- header to use infcodes.c /* infcodes.h -- header to use infcodes.c
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -14,14 +14,14 @@ typedef struct inflate_codes_state FAR inflate_codes_statef;
extern inflate_codes_statef *inflate_codes_new OF(( extern inflate_codes_statef *inflate_codes_new OF((
uInt, uInt, uInt, uInt,
inflate_huft *, inflate_huft *, inflate_huft *, inflate_huft *,
z_stream *)); z_streamp ));
extern int inflate_codes OF(( extern int inflate_codes OF((
inflate_blocks_statef *, inflate_blocks_statef *,
z_stream *, z_streamp ,
int)); int));
extern void inflate_codes_free OF(( extern void inflate_codes_free OF((
inflate_codes_statef *, inflate_codes_statef *,
z_stream *)); z_streamp ));

View File

@@ -1,5 +1,5 @@
/* inffast.c -- process literals and length/distance pairs fast /* inffast.c -- process literals and length/distance pairs fast
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -29,9 +29,10 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */
int inflate_fast(bl, bd, tl, td, s, z) int inflate_fast(bl, bd, tl, td, s, z)
uInt bl, bd; uInt bl, bd;
inflate_huft *tl, *td; inflate_huft *tl;
inflate_huft *td; /* need separate declaration for Borland C++ */
inflate_blocks_statef *s; inflate_blocks_statef *s;
z_stream *z; z_streamp z;
{ {
inflate_huft *t; /* temporary pointer */ inflate_huft *t; /* temporary pointer */
uInt e; /* extra bits or operation */ uInt e; /* extra bits or operation */
@@ -102,7 +103,7 @@ z_stream *z;
} }
else /* else offset after destination */ else /* else offset after destination */
{ {
e = d - (q - s->window); /* bytes from offset to end */ e = d - (uInt)(q - s->window); /* bytes from offset to end */
r = s->end - e; /* pointer to offset */ r = s->end - e; /* pointer to offset */
if (c > e) /* if source crosses, */ if (c > e) /* if source crosses, */
{ {
@@ -122,7 +123,7 @@ z_stream *z;
e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
else else
{ {
z->msg = "invalid distance code"; z->msg = (char*)"invalid distance code";
UNGRAB UNGRAB
UPDATE UPDATE
return Z_DATA_ERROR; return Z_DATA_ERROR;
@@ -152,7 +153,7 @@ z_stream *z;
} }
else else
{ {
z->msg = "invalid literal/length code"; z->msg = (char*)"invalid literal/length code";
UNGRAB UNGRAB
UPDATE UPDATE
return Z_DATA_ERROR; return Z_DATA_ERROR;

View File

@@ -1,5 +1,5 @@
/* inffast.h -- header to use inffast.c /* inffast.h -- header to use inffast.c
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -14,4 +14,4 @@ extern int inflate_fast OF((
inflate_huft *, inflate_huft *,
inflate_huft *, inflate_huft *,
inflate_blocks_statef *, inflate_blocks_statef *,
z_stream *)); z_streamp ));

118
inflate.c
View File

@@ -1,5 +1,5 @@
/* inflate.c -- zlib interface to inflate modules /* inflate.c -- zlib interface to inflate modules
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -15,6 +15,11 @@ struct internal_state {
enum { enum {
METHOD, /* waiting for method byte */ METHOD, /* waiting for method byte */
FLAG, /* waiting for flag byte */ FLAG, /* waiting for flag byte */
DICT4, /* four dictionary check bytes to go */
DICT3, /* three dictionary check bytes to go */
DICT2, /* two dictionary check bytes to go */
DICT1, /* one dictionary check byte to go */
DICT0, /* waiting for inflateSetDictionary */
BLOCKS, /* decompressing blocks */ BLOCKS, /* decompressing blocks */
CHECK4, /* four check bytes to go */ CHECK4, /* four check bytes to go */
CHECK3, /* three check bytes to go */ CHECK3, /* three check bytes to go */
@@ -44,7 +49,7 @@ struct internal_state {
int inflateReset(z) int inflateReset(z)
z_stream *z; z_streamp z;
{ {
uLong c; uLong c;
@@ -60,7 +65,7 @@ z_stream *z;
int inflateEnd(z) int inflateEnd(z)
z_stream *z; z_streamp z;
{ {
uLong c; uLong c;
@@ -75,14 +80,25 @@ z_stream *z;
} }
int inflateInit2(z, w) int inflateInit2_(z, w, version, stream_size)
z_stream *z; z_streamp z;
int w; int w;
const char *version;
int stream_size;
{ {
if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
stream_size != sizeof(z_stream))
return Z_VERSION_ERROR;
/* initialize state */ /* initialize state */
if (z == Z_NULL) if (z == Z_NULL)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
if (z->zalloc == Z_NULL) z->zalloc = zcalloc; z->msg = Z_NULL;
if (z->zalloc == Z_NULL)
{
z->zalloc = zcalloc;
z->opaque = (voidpf)0;
}
if (z->zfree == Z_NULL) z->zfree = zcfree; if (z->zfree == Z_NULL) z->zfree = zcfree;
if ((z->state = (struct internal_state FAR *) if ((z->state = (struct internal_state FAR *)
ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
@@ -107,7 +123,7 @@ int w;
/* create inflate_blocks state */ /* create inflate_blocks state */
if ((z->state->blocks = if ((z->state->blocks =
inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
== Z_NULL) == Z_NULL)
{ {
inflateEnd(z); inflateEnd(z);
@@ -121,10 +137,12 @@ int w;
} }
int inflateInit(z) int inflateInit_(z, version, stream_size)
z_stream *z; z_streamp z;
const char *version;
int stream_size;
{ {
return inflateInit2(z, DEF_WBITS); return inflateInit2_(z, DEF_WBITS, version, stream_size);
} }
@@ -132,52 +150,74 @@ z_stream *z;
#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
int inflate(z, f) int inflate(z, f)
z_stream *z; z_streamp z;
int f; int f;
{ {
int r = f; /* to avoid warning about unused f */ int r;
uInt b; uInt b;
if (z == Z_NULL || z->next_in == Z_NULL) if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
r = Z_BUF_ERROR; r = Z_BUF_ERROR;
while (1) switch (z->state->mode) while (1) switch (z->state->mode)
{ {
case METHOD: case METHOD:
NEEDBYTE NEEDBYTE
if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "unknown compression method"; z->msg = (char*)"unknown compression method";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
if ((z->state->sub.method >> 4) + 8 > z->state->wbits) if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "invalid window size"; z->msg = (char*)"invalid window size";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
z->state->mode = FLAG; z->state->mode = FLAG;
case FLAG: case FLAG:
NEEDBYTE NEEDBYTE
if ((b = NEXTBYTE) & 0x20) b = NEXTBYTE;
{
z->state->mode = BAD;
z->msg = "invalid reserved bit";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
if (((z->state->sub.method << 8) + b) % 31) if (((z->state->sub.method << 8) + b) % 31)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "incorrect header check"; z->msg = (char*)"incorrect header check";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
Trace((stderr, "inflate: zlib header ok\n")); Trace((stderr, "inflate: zlib header ok\n"));
z->state->mode = BLOCKS; if (!(b & PRESET_DICT))
{
z->state->mode = BLOCKS;
break;
}
z->state->mode = DICT4;
case DICT4:
NEEDBYTE
z->state->sub.check.need = (uLong)NEXTBYTE << 24;
z->state->mode = DICT3;
case DICT3:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 16;
z->state->mode = DICT2;
case DICT2:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE << 8;
z->state->mode = DICT1;
case DICT1:
NEEDBYTE
z->state->sub.check.need += (uLong)NEXTBYTE;
z->adler = z->state->sub.check.need;
z->state->mode = DICT0;
return Z_NEED_DICT;
case DICT0:
z->state->mode = BAD;
z->msg = (char*)"need dictionary";
z->state->sub.marker = 0; /* can try inflateSync */
return Z_STREAM_ERROR;
case BLOCKS: case BLOCKS:
r = inflate_blocks(z->state->blocks, z, r); r = inflate_blocks(z->state->blocks, z, r);
if (r == Z_DATA_ERROR) if (r == Z_DATA_ERROR)
@@ -215,7 +255,7 @@ int f;
if (z->state->sub.check.was != z->state->sub.check.need) if (z->state->sub.check.was != z->state->sub.check.need)
{ {
z->state->mode = BAD; z->state->mode = BAD;
z->msg = "incorrect data check"; z->msg = (char*)"incorrect data check";
z->state->sub.marker = 5; /* can't try inflateSync */ z->state->sub.marker = 5; /* can't try inflateSync */
break; break;
} }
@@ -231,8 +271,32 @@ int f;
} }
int inflateSetDictionary(z, dictionary, dictLength)
z_streamp z;
const Bytef *dictionary;
uInt dictLength;
{
uInt length = dictLength;
if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
return Z_STREAM_ERROR;
if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
z->adler = 1L;
if (length >= ((uInt)1<<z->state->wbits))
{
length = (1<<z->state->wbits)-1;
dictionary += dictLength - length;
}
inflate_set_dictionary(z->state->blocks, dictionary, length);
z->state->mode = BLOCKS;
return Z_OK;
}
int inflateSync(z) int inflateSync(z)
z_stream *z; z_streamp z;
{ {
uInt n; /* number of bytes to look at */ uInt n; /* number of bytes to look at */
Bytef *p; /* pointer to bytes */ Bytef *p; /* pointer to bytes */

View File

@@ -1,11 +1,18 @@
/* inftrees.c -- generate Huffman trees for efficient decoding /* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
#include "zutil.h" #include "zutil.h"
#include "inftrees.h" #include "inftrees.h"
char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
/* simplify the use of the inflate_huft type with some defines */ /* simplify the use of the inflate_huft type with some defines */
@@ -23,30 +30,26 @@ local int huft_build OF((
uIntf *, /* list of extra bits for non-simple codes */ uIntf *, /* list of extra bits for non-simple codes */
inflate_huft * FAR*,/* result: starting table */ inflate_huft * FAR*,/* result: starting table */
uIntf *, /* maximum lookup bits (returns actual) */ uIntf *, /* maximum lookup bits (returns actual) */
z_stream *)); /* for zalloc function */ z_streamp )); /* for zalloc function */
local voidpf falloc OF(( local voidpf falloc OF((
voidpf, /* opaque pointer (not used) */ voidpf, /* opaque pointer (not used) */
uInt, /* number of items */ uInt, /* number of items */
uInt)); /* size of item */ uInt)); /* size of item */
local void ffree OF((
voidpf q, /* opaque pointer (not used) */
voidpf p)); /* what to free (not used) */
/* Tables for deflate from PKZIP's appnote.txt. */ /* Tables for deflate from PKZIP's appnote.txt. */
local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ local uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
/* actually lengths - 2; also see note #13 above about 258 */ /* actually lengths - 2; also see note #13 above about 258 */
local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ local uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ local uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577}; 8193, 12289, 16385, 24577};
local uInt cpdext[] = { /* Extra bits for distance codes */ local uInt cpdext[30] = { /* Extra bits for distance codes */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13}; 12, 12, 13, 13};
@@ -100,7 +103,7 @@ uIntf *d; /* list of base values for non-simple codes */
uIntf *e; /* list of extra bits for non-simple codes */ uIntf *e; /* list of extra bits for non-simple codes */
inflate_huft * FAR *t; /* result: starting table */ inflate_huft * FAR *t; /* result: starting table */
uIntf *m; /* maximum lookup bits, returns actual */ uIntf *m; /* maximum lookup bits, returns actual */
z_stream *zs; /* for zalloc function */ z_streamp zs; /* for zalloc function */
/* Given a list of code lengths and a maximum table size, make a set of /* Given a list of code lengths and a maximum table size, make a set of
tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
if the given code set is incomplete (the tables are still built in this if the given code set is incomplete (the tables are still built in this
@@ -212,7 +215,8 @@ z_stream *zs; /* for zalloc function */
w += l; /* previous table always l bits */ w += l; /* previous table always l bits */
/* compute minimum size table less than or equal to l bits */ /* compute minimum size table less than or equal to l bits */
z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ z = g - w;
z = z > (uInt)l ? l : z; /* table size upper limit */
if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
{ /* too few codes for k-w bit table */ { /* too few codes for k-w bit table */
f -= a + 1; /* deduct codes from patterns left */ f -= a + 1; /* deduct codes from patterns left */
@@ -265,7 +269,7 @@ z_stream *zs; /* for zalloc function */
} }
else else
{ {
r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
r.base = d[*p++ - s]; r.base = d[*p++ - s];
} }
@@ -298,17 +302,17 @@ int inflate_trees_bits(c, bb, tb, z)
uIntf *c; /* 19 code lengths */ uIntf *c; /* 19 code lengths */
uIntf *bb; /* bits tree desired/actual depth */ uIntf *bb; /* bits tree desired/actual depth */
inflate_huft * FAR *tb; /* bits tree result */ inflate_huft * FAR *tb; /* bits tree result */
z_stream *z; /* for zfree function */ z_streamp z; /* for zfree function */
{ {
int r; int r;
r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
if (r == Z_DATA_ERROR) if (r == Z_DATA_ERROR)
z->msg = "oversubscribed dynamic bit lengths tree"; z->msg = (char*)"oversubscribed dynamic bit lengths tree";
else if (r == Z_BUF_ERROR) else if (r == Z_BUF_ERROR)
{ {
inflate_trees_free(*tb, z); inflate_trees_free(*tb, z);
z->msg = "incomplete dynamic bit lengths tree"; z->msg = (char*)"incomplete dynamic bit lengths tree";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
} }
return r; return r;
@@ -323,7 +327,7 @@ uIntf *bl; /* literal desired/actual bit depth */
uIntf *bd; /* distance desired/actual bit depth */ uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */ inflate_huft * FAR *td; /* distance tree result */
z_stream *z; /* for zfree function */ z_streamp z; /* for zfree function */
{ {
int r; int r;
@@ -331,11 +335,11 @@ z_stream *z; /* for zfree function */
if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
{ {
if (r == Z_DATA_ERROR) if (r == Z_DATA_ERROR)
z->msg = "oversubscribed literal/length tree"; z->msg = (char*)"oversubscribed literal/length tree";
else if (r == Z_BUF_ERROR) else if (r == Z_BUF_ERROR)
{ {
inflate_trees_free(*tl, z); inflate_trees_free(*tl, z);
z->msg = "incomplete literal/length tree"; z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
} }
return r; return r;
@@ -345,14 +349,14 @@ z_stream *z; /* for zfree function */
if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
{ {
if (r == Z_DATA_ERROR) if (r == Z_DATA_ERROR)
z->msg = "oversubscribed literal/length tree"; z->msg = (char*)"oversubscribed literal/length tree";
else if (r == Z_BUF_ERROR) { else if (r == Z_BUF_ERROR) {
#ifdef PKZIP_BUG_WORKAROUND #ifdef PKZIP_BUG_WORKAROUND
r = Z_OK; r = Z_OK;
} }
#else #else
inflate_trees_free(*td, z); inflate_trees_free(*td, z);
z->msg = "incomplete literal/length tree"; z->msg = (char*)"incomplete literal/length tree";
r = Z_DATA_ERROR; r = Z_DATA_ERROR;
} }
inflate_trees_free(*tl, z); inflate_trees_free(*tl, z);
@@ -366,10 +370,8 @@ z_stream *z; /* for zfree function */
/* build fixed tables only once--keep them here */ /* build fixed tables only once--keep them here */
local int fixed_lock = 0;
local int fixed_built = 0; local int fixed_built = 0;
#define FIXEDH 530 /* number of hufts used by fixed tables */ #define FIXEDH 530 /* number of hufts used by fixed tables */
local uInt fixed_left = FIXEDH;
local inflate_huft fixed_mem[FIXEDH]; local inflate_huft fixed_mem[FIXEDH];
local uInt fixed_bl; local uInt fixed_bl;
local uInt fixed_bd; local uInt fixed_bd;
@@ -378,24 +380,14 @@ local inflate_huft *fixed_td;
local voidpf falloc(q, n, s) local voidpf falloc(q, n, s)
voidpf q; /* opaque pointer (not used) */ voidpf q; /* opaque pointer */
uInt n; /* number of items */ uInt n; /* number of items */
uInt s; /* size of item */ uInt s; /* size of item */
{ {
Assert(s == sizeof(inflate_huft) && n <= fixed_left, Assert(s == sizeof(inflate_huft) && n <= *(intf *)q,
"inflate_trees falloc overflow"); "inflate_trees falloc overflow");
if (q) s++; /* to make some compilers happy */ *(intf *)q -= n+s-s; /* s-s to avoid warning */
fixed_left -= n; return (voidpf)(fixed_mem + *(intf *)q);
return (voidpf)(fixed_mem + fixed_left);
}
local void ffree(q, p)
voidpf q;
voidpf p;
{
Assert(0, "inflate_trees ffree called!");
if (q) q = p; /* to make some compilers happy */
} }
@@ -405,19 +397,18 @@ uIntf *bd; /* distance desired/actual bit depth */
inflate_huft * FAR *tl; /* literal/length tree result */ inflate_huft * FAR *tl; /* literal/length tree result */
inflate_huft * FAR *td; /* distance tree result */ inflate_huft * FAR *td; /* distance tree result */
{ {
/* build fixed tables if not built already--lock out other instances */ /* build fixed tables if not already (multiple overlapped executions ok) */
while (++fixed_lock > 1)
fixed_lock--;
if (!fixed_built) if (!fixed_built)
{ {
int k; /* temporary variable */ int k; /* temporary variable */
unsigned c[288]; /* length list for huft_build */ unsigned c[288]; /* length list for huft_build */
z_stream z; /* for falloc function */ z_stream z; /* for falloc function */
int f = FIXEDH; /* number of hufts left in fixed_mem */
/* set up fake z_stream for memory routines */ /* set up fake z_stream for memory routines */
z.zalloc = falloc; z.zalloc = falloc;
z.zfree = ffree; z.zfree = Z_NULL;
z.opaque = Z_NULL; z.opaque = (voidpf)&f;
/* literal table */ /* literal table */
for (k = 0; k < 144; k++) for (k = 0; k < 144; k++)
@@ -438,9 +429,9 @@ inflate_huft * FAR *td; /* distance tree result */
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
/* done */ /* done */
Assert(f == 0, "invalid build of fixed tables");
fixed_built = 1; fixed_built = 1;
} }
fixed_lock--;
*bl = fixed_bl; *bl = fixed_bl;
*bd = fixed_bd; *bd = fixed_bd;
*tl = fixed_tl; *tl = fixed_tl;
@@ -451,15 +442,24 @@ inflate_huft * FAR *td; /* distance tree result */
int inflate_trees_free(t, z) int inflate_trees_free(t, z)
inflate_huft *t; /* table to free */ inflate_huft *t; /* table to free */
z_stream *z; /* for zfree function */ z_streamp z; /* for zfree function */
/* Free the malloc'ed tables built by huft_build(), which makes a linked /* Free the malloc'ed tables built by huft_build(), which makes a linked
list of the tables it made, with the links in a dummy first entry of list of the tables it made, with the links in a dummy first entry of
each table. */ each table. */
{ {
register inflate_huft *p, *q; register inflate_huft *p, *q, *r;
/* Reverse linked list */
p = Z_NULL;
q = t;
while (q != Z_NULL)
{
r = (q - 1)->next;
(q - 1)->next = p;
p = q;
q = r;
}
/* Go through linked list, freeing from the malloced (t[-1]) address. */ /* Go through linked list, freeing from the malloced (t[-1]) address. */
p = t;
while (p != Z_NULL) while (p != Z_NULL)
{ {
q = (--p)->next; q = (--p)->next;

View File

@@ -1,5 +1,5 @@
/* inftrees.h -- header to use inftrees.c /* inftrees.h -- header to use inftrees.c
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -35,7 +35,7 @@ extern int inflate_trees_bits OF((
uIntf *, /* 19 code lengths */ uIntf *, /* 19 code lengths */
uIntf *, /* bits tree desired/actual depth */ uIntf *, /* bits tree desired/actual depth */
inflate_huft * FAR *, /* bits tree result */ inflate_huft * FAR *, /* bits tree result */
z_stream *)); /* for zalloc, zfree functions */ z_streamp )); /* for zalloc, zfree functions */
extern int inflate_trees_dynamic OF(( extern int inflate_trees_dynamic OF((
uInt, /* number of literal/length codes */ uInt, /* number of literal/length codes */
@@ -45,7 +45,7 @@ extern int inflate_trees_dynamic OF((
uIntf *, /* distance desired/actual bit depth */ uIntf *, /* distance desired/actual bit depth */
inflate_huft * FAR *, /* literal/length tree result */ inflate_huft * FAR *, /* literal/length tree result */
inflate_huft * FAR *, /* distance tree result */ inflate_huft * FAR *, /* distance tree result */
z_stream *)); /* for zalloc, zfree functions */ z_streamp )); /* for zalloc, zfree functions */
extern int inflate_trees_fixed OF(( extern int inflate_trees_fixed OF((
uIntf *, /* literal desired/actual bit depth */ uIntf *, /* literal desired/actual bit depth */
@@ -55,5 +55,5 @@ extern int inflate_trees_fixed OF((
extern int inflate_trees_free OF(( extern int inflate_trees_free OF((
inflate_huft *, /* tables to free */ inflate_huft *, /* tables to free */
z_stream *)); /* for zfree function */ z_streamp )); /* for zfree function */

View File

@@ -1,5 +1,5 @@
/* inflate_util.c -- data and routines common to blocks and codes /* inflate_util.c -- data and routines common to blocks and codes
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -12,7 +12,7 @@
struct inflate_codes_state {int dummy;}; /* for buggy compilers */ struct inflate_codes_state {int dummy;}; /* for buggy compilers */
/* And'ing with mask[n] masks the lower n bits */ /* And'ing with mask[n] masks the lower n bits */
uInt inflate_mask[] = { uInt inflate_mask[17] = {
0x0000, 0x0000,
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
@@ -22,11 +22,12 @@ uInt inflate_mask[] = {
/* copy as much as possible from the sliding window to the output area */ /* copy as much as possible from the sliding window to the output area */
int inflate_flush(s, z, r) int inflate_flush(s, z, r)
inflate_blocks_statef *s; inflate_blocks_statef *s;
z_stream *z; z_streamp z;
int r; int r;
{ {
uInt n; uInt n;
Bytef *p, *q; Bytef *p;
Bytef *q;
/* local copies of source and destination pointers */ /* local copies of source and destination pointers */
p = z->next_out; p = z->next_out;
@@ -43,7 +44,7 @@ int r;
/* update check information */ /* update check information */
if (s->checkfn != Z_NULL) if (s->checkfn != Z_NULL)
s->check = (*s->checkfn)(s->check, q, n); z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy as far as end of window */ /* copy as far as end of window */
zmemcpy(p, q, n); zmemcpy(p, q, n);
@@ -69,7 +70,7 @@ int r;
/* update check information */ /* update check information */
if (s->checkfn != Z_NULL) if (s->checkfn != Z_NULL)
s->check = (*s->checkfn)(s->check, q, n); z->adler = s->check = (*s->checkfn)(s->check, q, n);
/* copy */ /* copy */
zmemcpy(p, q, n); zmemcpy(p, q, n);

View File

@@ -1,5 +1,5 @@
/* infutil.h -- types and macros common to blocks and codes /* infutil.h -- types and macros common to blocks and codes
* Copyright (C) 1995 Mark Adler * Copyright (C) 1995-1996 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -8,11 +8,10 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
/* inflate blocks semi-private state */ #ifndef _INFUTIL_H
struct inflate_blocks_state { #define _INFUTIL_H
/* mode */ typedef enum {
enum {
TYPE, /* get type bits (3, including end bit) */ TYPE, /* get type bits (3, including end bit) */
LENS, /* get lengths for stored */ LENS, /* get lengths for stored */
STORED, /* processing stored block */ STORED, /* processing stored block */
@@ -23,7 +22,13 @@ struct inflate_blocks_state {
DRY, /* output remaining window bytes */ DRY, /* output remaining window bytes */
DONE, /* finished last block, done */ DONE, /* finished last block, done */
BAD} /* got a data error--stuck here */ BAD} /* got a data error--stuck here */
mode; /* current inflate_block mode */ inflate_block_mode;
/* inflate blocks semi-private state */
struct inflate_blocks_state {
/* mode */
inflate_block_mode mode; /* current inflate_block mode */
/* mode dependent information */ /* mode dependent information */
union { union {
@@ -36,7 +41,8 @@ struct inflate_blocks_state {
inflate_huft *tb; /* bit length decoding tree */ inflate_huft *tb; /* bit length decoding tree */
} trees; /* if DTREE, decoding info for trees */ } trees; /* if DTREE, decoding info for trees */
struct { struct {
inflate_huft *tl, *td; /* trees to free */ inflate_huft *tl;
inflate_huft *td; /* trees to free */
inflate_codes_statef inflate_codes_statef
*codes; *codes;
} decode; /* if CODES, current state */ } decode; /* if CODES, current state */
@@ -70,22 +76,24 @@ struct inflate_blocks_state {
#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} #define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
#define DUMPBITS(j) {b>>=(j);k-=(j);} #define DUMPBITS(j) {b>>=(j);k-=(j);}
/* output bytes */ /* output bytes */
#define WAVAIL (q<s->read?s->read-q-1:s->end-q) #define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
#define LOADOUT {q=s->write;m=WAVAIL;} #define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} #define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} #define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} #define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
#define OUTBYTE(a) {*q++=(Byte)(a);m--;} #define OUTBYTE(a) {*q++=(Byte)(a);m--;}
/* load local pointers */ /* load local pointers */
#define LOAD {LOADIN LOADOUT} #define LOAD {LOADIN LOADOUT}
/* masks for lower bits */ /* masks for lower bits (size given to avoid silly warnings with Visual C++) */
extern uInt inflate_mask[]; extern uInt inflate_mask[17];
/* copy as much as possible from the sliding window to the output area */ /* copy as much as possible from the sliding window to the output area */
extern int inflate_flush OF(( extern int inflate_flush OF((
inflate_blocks_statef *, inflate_blocks_statef *,
z_stream *, z_streamp ,
int)); int));
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#endif

View File

@@ -1,5 +1,5 @@
/* minigzip.c -- simulate gzip using the zlib compression library /* minigzip.c -- simulate gzip using the zlib compression library
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -13,20 +13,19 @@
* or in pipe mode. * or in pipe mode.
*/ */
/* $Id: minigzip.c,v 1.5 1995/05/03 17:27:11 jloup Exp $ */ /* $Id: minigzip.c,v 1.10 1996/07/24 13:41:04 me Exp $ */
#include <stdio.h> #include <stdio.h>
#include "zlib.h" #include "zlib.h"
#ifndef __GO32__
extern void exit OF((int));
#endif
extern int unlink OF((const char *));
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h>
#else
extern void exit OF((int));
#endif #endif
#if defined(MSDOS) || defined(OS2) || defined(WIN32) #if defined(MSDOS) || defined(OS2) || defined(WIN32)
# include <fcntl.h> # include <fcntl.h>
# include <io.h> # include <io.h>
@@ -36,12 +35,22 @@ extern int unlink OF((const char *));
#endif #endif
#ifdef VMS #ifdef VMS
# define unlink delete
# define GZ_SUFFIX "-gz" # define GZ_SUFFIX "-gz"
#else #endif
#ifdef RISCOS
# define unlink remove
# define GZ_SUFFIX "-gz"
# define fileno(file) file->__file
#endif
#ifndef GZ_SUFFIX
# define GZ_SUFFIX ".gz" # define GZ_SUFFIX ".gz"
#endif #endif
#define SUFFIX_LEN sizeof(GZ_SUFFIX) #define SUFFIX_LEN sizeof(GZ_SUFFIX)
extern int unlink OF((const char *));
#define BUFLEN 4096 #define BUFLEN 4096
#define MAX_NAME_LEN 1024 #define MAX_NAME_LEN 1024
@@ -53,7 +62,7 @@ extern int unlink OF((const char *));
char *prog; char *prog;
void error OF((char *msg)); void error OF((const char *msg));
void gz_compress OF((FILE *in, gzFile out)); void gz_compress OF((FILE *in, gzFile out));
void gz_uncompress OF((gzFile in, FILE *out)); void gz_uncompress OF((gzFile in, FILE *out));
void file_compress OF((char *file)); void file_compress OF((char *file));
@@ -64,7 +73,7 @@ int main OF((int argc, char *argv[]));
* Display error message and exit * Display error message and exit
*/ */
void error(msg) void error(msg)
char *msg; const char *msg;
{ {
fprintf(stderr, "%s: %s\n", prog, msg); fprintf(stderr, "%s: %s\n", prog, msg);
exit(1); exit(1);
@@ -89,7 +98,7 @@ void gz_compress(in, out)
} }
if (len == 0) break; if (len == 0) break;
if (gzwrite(out, buf, len) != len) error(gzerror(out, &err)); if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
} }
fclose(in); fclose(in);
if (gzclose(out) != Z_OK) error("failed gzclose"); if (gzclose(out) != Z_OK) error("failed gzclose");
@@ -111,7 +120,9 @@ void gz_uncompress(in, out)
if (len < 0) error (gzerror(in, &err)); if (len < 0) error (gzerror(in, &err));
if (len == 0) break; if (len == 0) break;
if (fwrite(buf, 1, len, out) != (uInt)len) error("failed fwrite"); if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
error("failed fwrite");
}
} }
if (fclose(out)) error("failed fclose"); if (fclose(out)) error("failed fclose");

138
trees.c
View File

@@ -1,5 +1,5 @@
/* trees.c -- output deflated data using Huffman coding /* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995 Jean-loup Gailly * Copyright (C) 1995-1996 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -29,7 +29,7 @@
* Addison-Wesley, 1983. ISBN 0-201-06672-6. * Addison-Wesley, 1983. ISBN 0-201-06672-6.
*/ */
/* $Id: trees.c,v 1.5 1995/05/03 17:27:12 jloup Exp $ */ /* $Id: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */
#include "deflate.h" #include "deflate.h"
@@ -78,13 +78,12 @@ local uch bl_order[BL_CODES]
/* =========================================================================== /* ===========================================================================
* Local data. These are initialized only once. * Local data. These are initialized only once.
* To do: initialize at compile time to be completely reentrant. ???
*/ */
local ct_data static_ltree[L_CODES+2]; local ct_data static_ltree[L_CODES+2];
/* The static literal tree. Since the bit lengths are imposed, there is no /* The static literal tree. Since the bit lengths are imposed, there is no
* need for the L_CODES extra codes used during heap construction. However * need for the L_CODES extra codes used during heap construction. However
* The codes 286 and 287 are needed to build a canonical tree (see ct_init * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
* below). * below).
*/ */
@@ -129,7 +128,7 @@ local static_tree_desc static_bl_desc =
* Local (static) routines in this file. * Local (static) routines in this file.
*/ */
local void ct_static_init OF((void)); local void tr_static_init OF((void));
local void init_block OF((deflate_state *s)); local void init_block OF((deflate_state *s));
local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
@@ -155,7 +154,7 @@ local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
#else /* DEBUG */ #else /* DEBUG */
# define send_code(s, c, tree) \ # define send_code(s, c, tree) \
{ if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \ { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
send_bits(s, tree[c].Code, tree[c].Len); } send_bits(s, tree[c].Code, tree[c].Len); }
#endif #endif
@@ -187,7 +186,7 @@ local void send_bits(s, value, length)
int value; /* value to send */ int value; /* value to send */
int length; /* number of bits */ int length; /* number of bits */
{ {
Tracev((stderr," l %2d v %4x ", length, value)); Tracevv((stderr," l %2d v %4x ", length, value));
Assert(length > 0 && length <= 15, "invalid length"); Assert(length > 0 && length <= 15, "invalid length");
s->bits_sent += (ulg)length; s->bits_sent += (ulg)length;
@@ -227,11 +226,13 @@ local void send_bits(s, value, length)
/* the arguments must not have side effects */ /* the arguments must not have side effects */
/* =========================================================================== /* ===========================================================================
* Initialize the various 'constant' tables. * Initialize the various 'constant' tables. In a multi-threaded environment,
* To do: do this at compile time. * this function may be called by two threads concurrently, but this is
* harmless since both invocations do exactly the same thing.
*/ */
local void ct_static_init() local void tr_static_init()
{ {
static int static_init_done = 0;
int n; /* iterates over tree elements */ int n; /* iterates over tree elements */
int bits; /* bit counter */ int bits; /* bit counter */
int length; /* length value */ int length; /* length value */
@@ -240,6 +241,8 @@ local void ct_static_init()
ush bl_count[MAX_BITS+1]; ush bl_count[MAX_BITS+1];
/* number of codes at each bit length for an optimal tree */ /* number of codes at each bit length for an optimal tree */
if (static_init_done) return;
/* Initialize the mapping length (0..255) -> length code (0..28) */ /* Initialize the mapping length (0..255) -> length code (0..28) */
length = 0; length = 0;
for (code = 0; code < LENGTH_CODES-1; code++) { for (code = 0; code < LENGTH_CODES-1; code++) {
@@ -248,7 +251,7 @@ local void ct_static_init()
length_code[length++] = (uch)code; length_code[length++] = (uch)code;
} }
} }
Assert (length == 256, "ct_static_init: length != 256"); Assert (length == 256, "tr_static_init: length != 256");
/* Note that the length 255 (match length 258) can be represented /* Note that the length 255 (match length 258) can be represented
* in two different ways: code 284 + 5 bits or code 285, so we * in two different ways: code 284 + 5 bits or code 285, so we
* overwrite length_code[255] to use the best encoding: * overwrite length_code[255] to use the best encoding:
@@ -263,7 +266,7 @@ local void ct_static_init()
dist_code[dist++] = (uch)code; dist_code[dist++] = (uch)code;
} }
} }
Assert (dist == 256, "ct_static_init: dist != 256"); Assert (dist == 256, "tr_static_init: dist != 256");
dist >>= 7; /* from now on, all distances are divided by 128 */ dist >>= 7; /* from now on, all distances are divided by 128 */
for ( ; code < D_CODES; code++) { for ( ; code < D_CODES; code++) {
base_dist[code] = dist << 7; base_dist[code] = dist << 7;
@@ -271,7 +274,7 @@ local void ct_static_init()
dist_code[256 + dist++] = (uch)code; dist_code[256 + dist++] = (uch)code;
} }
} }
Assert (dist == 256, "ct_static_init: 256+dist != 512"); Assert (dist == 256, "tr_static_init: 256+dist != 512");
/* Construct the codes of the static literal tree */ /* Construct the codes of the static literal tree */
for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
@@ -289,19 +292,18 @@ local void ct_static_init()
/* The static distance tree is trivial: */ /* The static distance tree is trivial: */
for (n = 0; n < D_CODES; n++) { for (n = 0; n < D_CODES; n++) {
static_dtree[n].Len = 5; static_dtree[n].Len = 5;
static_dtree[n].Code = bi_reverse(n, 5); static_dtree[n].Code = bi_reverse((unsigned)n, 5);
} }
static_init_done = 1;
} }
/* =========================================================================== /* ===========================================================================
* Initialize the tree data structures for a new zlib stream. * Initialize the tree data structures for a new zlib stream.
*/ */
void ct_init(s) void _tr_init(s)
deflate_state *s; deflate_state *s;
{ {
if (static_dtree[0].Len == 0) { tr_static_init();
ct_static_init(); /* To do: at compile time */
}
s->compressed_len = 0L; s->compressed_len = 0L;
@@ -523,7 +525,7 @@ local void gen_codes (tree, max_code, bl_count)
/* Now reverse the bits */ /* Now reverse the bits */
tree[n].Code = bi_reverse(next_code[len]++, len); tree[n].Code = bi_reverse(next_code[len]++, len);
Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
} }
} }
@@ -783,14 +785,14 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
/* =========================================================================== /* ===========================================================================
* Send a stored block * Send a stored block
*/ */
void ct_stored_block(s, buf, stored_len, eof) void _tr_stored_block(s, buf, stored_len, eof)
deflate_state *s; deflate_state *s;
charf *buf; /* input block */ charf *buf; /* input block */
ulg stored_len; /* length of input block */ ulg stored_len; /* length of input block */
int eof; /* true if this is the last block for a file */ int eof; /* true if this is the last block for a file */
{ {
send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
s->compressed_len = (s->compressed_len + 3 + 7) & ~7L; s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
s->compressed_len += (stored_len + 4) << 3; s->compressed_len += (stored_len + 4) << 3;
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
@@ -799,12 +801,15 @@ void ct_stored_block(s, buf, stored_len, eof)
/* =========================================================================== /* ===========================================================================
* Send one empty static block to give enough lookahead for inflate. * Send one empty static block to give enough lookahead for inflate.
* This takes 10 bits, of which 7 may remain in the bit buffer. * This takes 10 bits, of which 7 may remain in the bit buffer.
* The current inflate code requires 9 bits of lookahead. If the EOB * The current inflate code requires 9 bits of lookahead. If the
* code for the previous block was coded on 5 bits or less, inflate * last two codes for the previous block (real code plus EOB) were coded
* may have only 5+3 bits of lookahead to decode this EOB. * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
* (There are no problems if the previous block is stored or fixed.) * the last real code. In this case we send two empty static blocks instead
* of one. (There are no problems if the previous block is stored or fixed.)
* To simplify the code, we assume the worst case of last real code encoded
* on one bit only.
*/ */
void ct_align(s) void _tr_align(s)
deflate_state *s; deflate_state *s;
{ {
send_bits(s, STATIC_TREES<<1, 3); send_bits(s, STATIC_TREES<<1, 3);
@@ -812,10 +817,11 @@ void ct_align(s)
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
bi_flush(s); bi_flush(s);
/* Of the 10 bits for the empty block, we have already sent /* Of the 10 bits for the empty block, we have already sent
* (10 - bi_valid) bits. The lookahead for the EOB of the previous * (10 - bi_valid) bits. The lookahead for the last real code (before
* block was thus its length plus what we have just sent. * the EOB of the previous block) was thus at least one plus the length
* of the EOB plus what we have just sent of the empty static block.
*/ */
if (s->last_eob_len + 10 - s->bi_valid < 9) { if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
send_bits(s, STATIC_TREES<<1, 3); send_bits(s, STATIC_TREES<<1, 3);
send_code(s, END_BLOCK, static_ltree); send_code(s, END_BLOCK, static_ltree);
s->compressed_len += 10L; s->compressed_len += 10L;
@@ -829,44 +835,52 @@ void ct_align(s)
* trees or store, and output the encoded block to the zip file. This function * trees or store, and output the encoded block to the zip file. This function
* returns the total compressed length for the file so far. * returns the total compressed length for the file so far.
*/ */
ulg ct_flush_block(s, buf, stored_len, eof) ulg _tr_flush_block(s, buf, stored_len, eof)
deflate_state *s; deflate_state *s;
charf *buf; /* input block, or NULL if too old */ charf *buf; /* input block, or NULL if too old */
ulg stored_len; /* length of input block */ ulg stored_len; /* length of input block */
int eof; /* true if this is the last block for a file */ int eof; /* true if this is the last block for a file */
{ {
ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
int max_blindex; /* index of last bit length code of non zero freq */ int max_blindex = 0; /* index of last bit length code of non zero freq */
/* Check if the file is ascii or binary */ /* Build the Huffman trees unless a stored block is forced */
if (s->data_type == UNKNOWN) set_data_type(s); if (s->level > 0) {
/* Construct the literal and distance trees */ /* Check if the file is ascii or binary */
build_tree(s, (tree_desc *)(&(s->l_desc))); if (s->data_type == Z_UNKNOWN) set_data_type(s);
Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
s->static_len));
build_tree(s, (tree_desc *)(&(s->d_desc))); /* Construct the literal and distance trees */
Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, build_tree(s, (tree_desc *)(&(s->l_desc)));
s->static_len)); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
/* At this point, opt_len and static_len are the total bit lengths of s->static_len));
* the compressed block data, excluding the tree representations.
*/
/* Build the bit length tree for the above two trees, and get the index build_tree(s, (tree_desc *)(&(s->d_desc)));
* in bl_order of the last bit length code to send. Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
*/ s->static_len));
max_blindex = build_bl_tree(s); /* At this point, opt_len and static_len are the total bit lengths of
* the compressed block data, excluding the tree representations.
*/
/* Determine the best encoding. Compute first the block length in bytes */ /* Build the bit length tree for the above two trees, and get the index
opt_lenb = (s->opt_len+3+7)>>3; * in bl_order of the last bit length code to send.
static_lenb = (s->static_len+3+7)>>3; */
max_blindex = build_bl_tree(s);
Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", /* Determine the best encoding. Compute first the block length in bytes*/
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, opt_lenb = (s->opt_len+3+7)>>3;
s->last_lit)); static_lenb = (s->static_len+3+7)>>3;
if (static_lenb <= opt_lenb) opt_lenb = static_lenb; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
s->last_lit));
if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
} else {
Assert(buf != (char*)0, "lost buf");
opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
}
/* If compression failed and this is the first and last block, /* If compression failed and this is the first and last block,
* and if the .zip file can be seeked (to rewrite the local header), * and if the .zip file can be seeked (to rewrite the local header),
@@ -874,7 +888,7 @@ ulg ct_flush_block(s, buf, stored_len, eof)
*/ */
#ifdef STORED_FILE_OK #ifdef STORED_FILE_OK
# ifdef FORCE_STORED_FILE # ifdef FORCE_STORED_FILE
if (eof && compressed_len == 0L) { /* force stored file */ if (eof && s->compressed_len == 0L) { /* force stored file */
# else # else
if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
# endif # endif
@@ -899,7 +913,7 @@ ulg ct_flush_block(s, buf, stored_len, eof)
* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
* transform a block into a stored block. * transform a block into a stored block.
*/ */
ct_stored_block(s, buf, stored_len, eof); _tr_stored_block(s, buf, stored_len, eof);
#ifdef FORCE_STATIC #ifdef FORCE_STATIC
} else if (static_lenb >= 0) { /* force static trees */ } else if (static_lenb >= 0) { /* force static trees */
@@ -933,10 +947,10 @@ ulg ct_flush_block(s, buf, stored_len, eof)
* Save the match info and tally the frequency counts. Return true if * Save the match info and tally the frequency counts. Return true if
* the current block must be flushed. * the current block must be flushed.
*/ */
int ct_tally (s, dist, lc) int _tr_tally (s, dist, lc)
deflate_state *s; deflate_state *s;
int dist; /* distance of matched string */ unsigned dist; /* distance of matched string */
int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
{ {
s->d_buf[s->last_lit] = (ush)dist; s->d_buf[s->last_lit] = (ush)dist;
s->l_buf[s->last_lit++] = (uch)lc; s->l_buf[s->last_lit++] = (uch)lc;
@@ -949,7 +963,7 @@ int ct_tally (s, dist, lc)
dist--; /* dist = match distance - 1 */ dist--; /* dist = match distance - 1 */
Assert((ush)dist < (ush)MAX_DIST(s) && Assert((ush)dist < (ush)MAX_DIST(s) &&
(ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
(ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
s->dyn_dtree[d_code(dist)].Freq++; s->dyn_dtree[d_code(dist)].Freq++;
@@ -959,7 +973,7 @@ int ct_tally (s, dist, lc)
if (s->level > 2 && (s->last_lit & 0xfff) == 0) { if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
/* Compute an upper bound for the compressed length */ /* Compute an upper bound for the compressed length */
ulg out_length = (ulg)s->last_lit*8L; ulg out_length = (ulg)s->last_lit*8L;
ulg in_length = (ulg)s->strstart - s->block_start; ulg in_length = (ulg)((long)s->strstart - s->block_start);
int dcode; int dcode;
for (dcode = 0; dcode < D_CODES; dcode++) { for (dcode = 0; dcode < D_CODES; dcode++) {
out_length += (ulg)s->dyn_dtree[dcode].Freq * out_length += (ulg)s->dyn_dtree[dcode].Freq *
@@ -1043,7 +1057,7 @@ local void set_data_type(s)
while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII); s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
} }
/* =========================================================================== /* ===========================================================================

View File

@@ -1,9 +1,9 @@
/* uncompr.c -- decompress a memory buffer /* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: uncompr.c,v 1.5 1995/05/03 17:27:12 jloup Exp $ */ /* $Id: uncompr.c,v 1.8 1996/01/30 21:59:26 me Exp $ */
#include "zlib.h" #include "zlib.h"
@@ -25,13 +25,13 @@
int uncompress (dest, destLen, source, sourceLen) int uncompress (dest, destLen, source, sourceLen)
Bytef *dest; Bytef *dest;
uLongf *destLen; uLongf *destLen;
Bytef *source; const Bytef *source;
uLong sourceLen; uLong sourceLen;
{ {
z_stream stream; z_stream stream;
int err; int err;
stream.next_in = source; stream.next_in = (Bytef*)source;
stream.avail_in = (uInt)sourceLen; stream.avail_in = (uInt)sourceLen;
/* Check for source > 64K on 16-bit machine: */ /* Check for source > 64K on 16-bit machine: */
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;

108
zconf.h
View File

@@ -1,30 +1,67 @@
/* zconf.h -- configuration of the zlib compression library /* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp $ */ /* $Id: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */
#ifndef _ZCONF_H #ifndef _ZCONF_H
#define _ZCONF_H #define _ZCONF_H
/* /*
The library does not install any signal handler. It is recommended to * If you *really* need a unique prefix for all types and library functions,
add at least a handler for SIGSEGV when decompressing; the library checks * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
the consistency of the input data whenever possible but may go nuts
for some forms of corrupted input.
*/ */
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateReset z_inflateReset
# define compress z_compress
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32
#endif
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
# ifndef __32BIT__
# define __32BIT__
# endif
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
/* /*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int). * than 64k bytes at a time (needed on systems with 16-bit int).
*/ */
#if defined(_GNUC__) && !defined(__32BIT__)
# define __32BIT__
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if defined(MSDOS) && !defined(__32BIT__) #if defined(MSDOS) && !defined(__32BIT__)
# define MAXSEG_64K # define MAXSEG_64K
#endif #endif
@@ -32,20 +69,22 @@
# define UNALIGNED_OK # define UNALIGNED_OK
#endif #endif
#ifndef STDC #if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) # define STDC
# define STDC #endif
# endif #if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
# define STDC
#endif #endif
#ifndef STDC #ifndef STDC
# ifndef const # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const # define const
# endif # endif
#endif #endif
#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ /* Some Mac compilers merge all .h files incorrectly: */
# include <unix.h> #if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
# define NO_DUMMY_DECL
#endif #endif
/* Maximum value for memLevel in deflateInit2 */ /* Maximum value for memLevel in deflateInit2 */
@@ -91,7 +130,9 @@
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty. * just define FAR to be empty.
*/ */
#if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ #if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER # ifdef _MSC_VER
# define FAR __far # define FAR __far
# else # else
@@ -99,7 +140,10 @@
# endif # endif
#endif #endif
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) #if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
# define FAR __far /* completely untested, just a best guess */ # ifndef __32BIT__
# define SMALL_MEDIUM
# define FAR __far
# endif
#endif #endif
#ifndef FAR #ifndef FAR
# define FAR # define FAR
@@ -109,10 +153,15 @@ typedef unsigned char Byte; /* 8 bits */
typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */ typedef unsigned long uLong; /* 32 bits or more */
typedef Byte FAR Bytef; #if defined(__BORLANDC__) && defined(SMALL_MEDIUM)
typedef char FAR charf; /* Borland C/C++ ignores FAR inside typedef */
typedef int FAR intf; # define Bytef Byte FAR
typedef uInt FAR uIntf; #else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf; typedef uLong FAR uLongf;
#ifdef STDC #ifdef STDC
@@ -123,4 +172,13 @@ typedef uLong FAR uLongf;
typedef Byte *voidp; typedef Byte *voidp;
#endif #endif
/* Compile with -DZLIB_DLL for Windows DLL support */
#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
# include <windows.h>
# define EXPORT WINAPI
#else
# define EXPORT
#endif
#endif /* _ZCONF_H */ #endif /* _ZCONF_H */

46
zlib.def Normal file
View File

@@ -0,0 +1,46 @@
LIBRARY "zlib"
DESCRIPTION '"""zlib data compression library"""'
EXETYPE NT
SUBSYSTEM WINDOWS
STUB 'WINSTUB.EXE'
VERSION 1.04
CODE EXECUTE READ
DATA READ WRITE
HEAPSIZE 1048576,4096
EXPORTS
zlibVersion
deflate
deflateEnd
inflate
inflateEnd
deflateSetDictionary
deflateCopy
deflateReset
deflateParams
inflateSetDictionary
inflateSync
inflateReset
compress
uncompress
gzopen
gzdopen
gzread
gzwrite
gzflush
gzclose
gzerror
adler32
crc32
deflateInit_
inflateInit_
deflateInit2_
inflateInit2_

348
zlib.h
View File

@@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library /* zlib.h -- interface of the 'zlib' general purpose compression library
version 0.95, Aug 16th, 1995. version 1.0.4, Jul 24th, 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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@@ -21,14 +21,23 @@
Jean-loup Gailly Mark Adler Jean-loup Gailly Mark Adler
gzip@prep.ai.mit.edu madler@alumni.caltech.edu gzip@prep.ai.mit.edu madler@alumni.caltech.edu
*/
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
*/
#ifndef _ZLIB_H #ifndef _ZLIB_H
#define _ZLIB_H #define _ZLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#include "zconf.h" #include "zconf.h"
#define ZLIB_VERSION "0.95" #define ZLIB_VERSION "1.0.4"
/* /*
The 'zlib' compression library provides in-memory compression and The 'zlib' compression library provides in-memory compression and
@@ -47,6 +56,11 @@
repeated calls of the compression function. In the latter case, the repeated calls of the compression function. In the latter case, the
application must provide more input and/or consume the output application must provide more input and/or consume the output
(providing more output space) before each call. (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)); typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
@@ -68,12 +82,15 @@ typedef struct z_stream_s {
alloc_func zalloc; /* used to allocate the internal state */ alloc_func zalloc; /* used to allocate the internal state */
free_func zfree; /* used to free the internal state */ free_func zfree; /* used to free the internal state */
voidp opaque; /* private data object passed to zalloc and zfree */ voidpf opaque; /* private data object passed to zalloc and zfree */
Byte data_type; /* best guess about the data type: ascii or binary */
int data_type; /* best guess about the data type: ascii or binary */
uLong adler; /* adler32 value of the uncompressed data */
uLong reserved; /* reserved for future use */
} z_stream; } z_stream;
typedef z_stream FAR *z_streamp;
/* /*
The application must update next_in and avail_in when avail_in has The application must update next_in and avail_in when avail_in has
dropped to zero. It must update next_out and avail_out when avail_out dropped to zero. It must update next_out and avail_out when avail_out
@@ -107,20 +124,25 @@ typedef struct z_stream_s {
#define Z_NO_FLUSH 0 #define Z_NO_FLUSH 0
#define Z_PARTIAL_FLUSH 1 #define Z_PARTIAL_FLUSH 1
#define Z_FULL_FLUSH 2 #define Z_SYNC_FLUSH 2
#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ #define Z_FULL_FLUSH 3
#define Z_FINISH 4 #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_OK 0
#define Z_STREAM_END 1 #define Z_STREAM_END 1
#define Z_NEED_DICT 2
#define Z_ERRNO (-1) #define Z_ERRNO (-1)
#define Z_STREAM_ERROR (-2) #define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR (-3) #define Z_DATA_ERROR (-3)
#define Z_MEM_ERROR (-4) #define Z_MEM_ERROR (-4)
#define Z_BUF_ERROR (-5) #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_SPEED 1
#define Z_BEST_COMPRESSION 9 #define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_COMPRESSION (-1) #define Z_DEFAULT_COMPRESSION (-1)
@@ -129,42 +151,54 @@ typedef struct z_stream_s {
#define Z_FILTERED 1 #define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2 #define Z_HUFFMAN_ONLY 2
#define Z_DEFAULT_STRATEGY 0 #define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */
#define Z_BINARY 0 #define Z_BINARY 0
#define Z_ASCII 1 #define Z_ASCII 1
#define Z_UNKNOWN 2 #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 */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
extern char *zlib_version; #define zlib_version zlibVersion()
/* The application can compare zlib_version and ZLIB_VERSION for consistency. /* for compatibility with versions < 1.0.2 */
If the first character differs, the library code actually used is
not compatible with the zlib.h header file used by the application.
*/
/* basic functions */ /* basic functions */
extern int deflateInit OF((z_stream *strm, int level)); extern const char * EXPORT zlibVersion OF((void));
/* The application can compare zlibVersion 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.
This check is automatically made by deflateInit and inflateInit.
*/
/* /*
extern int EXPORT deflateInit OF((z_streamp strm, int level));
Initializes the internal stream state for compression. The fields Initializes the internal stream state for compression. The fields
zalloc, zfree and opaque must be initialized before by the caller. zalloc, zfree and opaque must be initialized before by the caller.
If zalloc and zfree are set to Z_NULL, deflateInit updates them to If zalloc and zfree are set to Z_NULL, deflateInit updates them to
use default allocation functions. use default allocation functions.
The compression level must be Z_DEFAULT_COMPRESSION, or between 1 and 9: The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
1 gives best speed, 9 gives best compression. Z_DEFAULT_COMPRESSION requests 1 gives best speed, 9 gives best compression, 0 gives no compression at
a default compromise between speed and compression (currently equivalent all (the input data is simply copied a block at a time).
to level 6). 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 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 msg is set to null if there is no error message. deflateInit does not
perform any compression: this will be done by deflate(). perform any compression: this will be done by deflate().
*/ */
extern int deflate OF((z_stream *strm, int flush)); extern int EXPORT deflate OF((z_streamp strm, int flush));
/* /*
Performs one or both of the following actions: Performs one or both of the following actions:
@@ -184,13 +218,20 @@ extern int deflate OF((z_stream *strm, int flush));
more output, and updating avail_in or avail_out accordingly; avail_out more output, and updating avail_in or avail_out accordingly; avail_out
should never be zero before the call. The application can consume the should never be zero before the call. The application can consume the
compressed output when it wants, for example when the output buffer is full compressed output when it wants, for example when the output buffer is full
(avail_out == 0), or after each call of deflate(). (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
and with zero avail_out, it must be called again after making room in the
output buffer because there might be more output pending.
If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
block is terminated and flushed to the output buffer so that the 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 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. variant on method 8, the current block will be flushed but not terminated.
If flush is set to Z_FULL_FLUSH, the compression block is terminated, a 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 special marker is output and the compression dictionary is discarded; this
is useful to allow the decompressor to synchronize if one compressed block is useful to allow the decompressor to synchronize if one compressed block
has been damaged (see inflateSync below). Flushing degrades compression and has been damaged (see inflateSync below). Flushing degrades compression and
@@ -200,8 +241,8 @@ extern int deflate OF((z_stream *strm, int flush));
parameter and more output space (updated avail_out), until the flush is parameter and more output space (updated avail_out), until the flush is
complete (deflate returns with non-zero avail_out). complete (deflate returns with non-zero avail_out).
If the parameter flush is set to Z_FINISH, all pending input is processed, If the parameter flush is set to Z_FINISH, pending input is processed,
all pending output is flushed and deflate returns with Z_STREAM_END if there pending output is flushed and deflate returns with Z_STREAM_END if there
was enough output space; if deflate returns with Z_OK, this function must be was enough output space; if deflate returns with Z_OK, this function must be
called again with Z_FINISH and more output space (updated avail_out) but no called again with Z_FINISH and more output space (updated avail_out) but no
more input data, until it returns with Z_STREAM_END or an error. After more input data, until it returns with Z_STREAM_END or an error. After
@@ -226,33 +267,37 @@ extern int deflate OF((z_stream *strm, int flush));
*/ */
extern int deflateEnd OF((z_stream *strm)); extern int EXPORT deflateEnd OF((z_streamp strm));
/* /*
All dynamically allocated data structures for this stream are freed. All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any This function discards any unprocessed input and does not flush any
pending output. pending output.
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
stream state was inconsistent. In the error case, msg may be set stream state was inconsistent, Z_DATA_ERROR if the stream was freed
but then points to a static string (which must not be deallocated). 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 EXPORT inflateInit OF((z_streamp strm));
Initializes the internal stream state for decompression. The fields Initializes the internal stream state for decompression. The fields
zalloc and zfree must be initialized before by the caller. If zalloc and zalloc, zfree and opaque must be initialized before by the caller. If
zfree are set to Z_NULL, inflateInit updates them to use default allocation zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
functions. allocation functions.
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not 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. enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
inflateInit does not perform any decompression: this will be done by with the version assumed by the caller. msg is set to null if there is no
inflate(). error message. inflateInit does not perform any decompression: this will be
done by inflate().
*/ */
extern int inflate OF((z_stream *strm, int flush)); extern int EXPORT inflate OF((z_streamp strm, int flush));
/* /*
Performs one or both of the following actions: Performs one or both of the following actions:
@@ -262,15 +307,18 @@ extern int inflate OF((z_stream *strm, int flush));
will resume at this point for the next call of inflate(). will resume at this point for the next call of inflate().
- Provide more output starting at next_out and update next_out and avail_out - Provide more output starting at next_out and update next_out and avail_out
accordingly. inflate() always provides as much output as possible accordingly. inflate() provides as much output as possible, until there
(until there is no more input data or no more space in the output buffer). is no more input data or no more space in the output buffer (see below
about the flush parameter).
Before the call of inflate(), the application should ensure that at least Before the call of inflate(), the application should ensure that at least
one of the actions is possible, by providing more input and/or consuming one of the actions is possible, by providing more input and/or consuming
more output, and updating the next_* and avail_* values accordingly. more output, and updating the next_* and avail_* values accordingly.
The application can consume the uncompressed output when it wants, for The application can consume the uncompressed output when it wants, for
example when the output buffer is full (avail_out == 0), or after each example when the output buffer is full (avail_out == 0), or after each
call of inflate(). call of inflate(). If inflate returns Z_OK and with zero avail_out, it
must be called again after making room in the output buffer because there
might be more output pending.
If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much
output as possible to the output buffer. The flushing behavior of inflate is output as possible to the output buffer. The flushing behavior of inflate is
@@ -292,16 +340,19 @@ extern int inflate OF((z_stream *strm, int flush));
inflate() returns Z_OK if some progress has been made (more input 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 processed or more output produced), Z_STREAM_END if the end of the
compressed data has been reached and all uncompressed output has been 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 produced, Z_NEED_DICT if a preset dictionary is needed at this point (see
the stream structure was inconsistent (for example if next_in or next_out inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted,
was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no Z_STREAM_ERROR if the stream structure was inconsistent (for example if
progress is possible or if there was not enough room in the output buffer next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then Z_BUF_ERROR if no progress is possible or if there was not enough room in
call inflateSync to look for a good compression block. 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.
*/ */
extern int inflateEnd OF((z_stream *strm)); extern int EXPORT inflateEnd OF((z_streamp strm));
/* /*
All dynamically allocated data structures for this stream are freed. All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any This function discards any unprocessed input and does not flush any
@@ -312,24 +363,26 @@ extern int inflateEnd OF((z_stream *strm));
static string (which must not be deallocated). static string (which must not be deallocated).
*/ */
/* advanced functions */ /* Advanced functions */
/* /*
The following functions are needed only in some special applications. 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 extern int EXPORT deflateInit2 OF((z_streamp strm,
fields next_in, zalloc and zfree must be initialized before by the caller. int level,
int method,
int windowBits,
int memLevel,
int strategy));
The method parameter is the compression method. It must be 8 in this This is another version of deflateInit with more compression options. The
version of the library. (Method 9 will allow a 64K history buffer and 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.) partial block flushes.)
The windowBits parameter is the base two logarithm of the window size The windowBits parameter is the base two logarithm of the window size
@@ -338,20 +391,22 @@ extern int deflateInit2 OF((z_stream *strm,
values of this parameter result in better compression at the expense of values of this parameter result in better compression at the expense of
memory usage. The default value is 15 if deflateInit is used instead. memory usage. The default value is 15 if deflateInit is used instead.
The memLevel parameter specifies how much memory should be allocated The memLevel parameter specifies how much memory should be allocated
for the internal compression state. memLevel=1 uses minimum memory but for the internal compression state. memLevel=1 uses minimum memory but
is slow and reduces compression ratio; memLevel=9 uses maximum memory is slow and reduces compression ratio; memLevel=9 uses maximum memory
for optimal speed. The default value is 8. See zconf.h for total memory for optimal speed. The default value is 8. See zconf.h for total memory
usage as a function of windowBits and memLevel. usage as a function of windowBits and memLevel.
The strategy parameter is used to tune the compression algorithm. Use The strategy parameter is used to tune the compression algorithm. Use the
the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
encoding only (no string match). Filtered data consists mostly of small string match). Filtered data consists mostly of small values with a
values with a somewhat random distribution. In this case, the somewhat random distribution. In this case, the compression algorithm is
compression algorithm is tuned to compress them better. The strategy tuned to compress them better. The effect of Z_FILTERED is to force more
parameter only affects the compression ratio but not the correctness of Huffman coding and less string matching; it is somewhat intermediate
the compressed output even if it is not set appropriately. 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 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 some history information; the buffer must either hold the entire input
@@ -373,8 +428,37 @@ extern int deflateInit2 OF((z_stream *strm,
deflate(). deflate().
*/ */
extern int deflateCopy OF((z_stream *dest, extern int EXPORT deflateSetDictionary OF((z_streamp strm,
z_stream *source)); 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 EXPORT deflateCopy OF((z_streamp dest,
z_streamp source));
/* /*
Sets the destination stream as a complete copy of the source stream. If Sets the destination stream as a complete copy of the source stream. If
the source stream is using an application-supplied history buffer, a new the source stream is using an application-supplied history buffer, a new
@@ -383,20 +467,20 @@ extern int deflateCopy OF((z_stream *dest,
application to provide the correct values of next_out and avail_out for the application to provide the correct values of next_out and avail_out for the
next call of deflate. 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 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 data with a filter. The streams that will be discarded should then be freed
by calling deflateEnd. Note that deflateCopy duplicates the internal by calling deflateEnd. Note that deflateCopy duplicates the internal
compression state which can be quite large, so this strategy is slow and compression state which can be quite large, so this strategy is slow and
can consume lots of memory. can consume lots of memory.
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
(such as zalloc being NULL). msg is left unchanged in both source and (such as zalloc being NULL). msg is left unchanged in both source and
destination. destination.
*/ */
extern int deflateReset OF((z_stream *strm)); extern int EXPORT deflateReset OF((z_streamp strm));
/* /*
This function is equivalent to deflateEnd followed by deflateInit, This function is equivalent to deflateEnd followed by deflateInit,
but does not free and reallocate all the internal compression state. but does not free and reallocate all the internal compression state.
@@ -407,11 +491,31 @@ extern int deflateReset OF((z_stream *strm));
stream state was inconsistent (such as zalloc or state being NULL). stream state was inconsistent (such as zalloc or state being NULL).
*/ */
extern int inflateInit2 OF((z_stream *strm, extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
int windowBits));
/* /*
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().
Before the call of deflateParams, the stream state must be set as for
a call of deflate(), since the currently available input may have to
be compressed and flushed. In particular, strm->avail_out must be non-zero.
deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
if strm->avail_out was zero.
*/
/*
extern int EXPORT inflateInit2 OF((z_streamp strm,
int windowBits));
This is another version of inflateInit with more compression options. The 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 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 size (the size of the history buffer). It should be in the range 8..15 for
@@ -440,7 +544,26 @@ extern int inflateInit2 OF((z_stream *strm,
inflate(). inflate().
*/ */
extern int inflateSync OF((z_stream *strm)); extern int EXPORT inflateSetDictionary OF((z_streamp 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 EXPORT inflateSync OF((z_streamp strm));
/* /*
Skips invalid compressed data until the special marker (see deflate() Skips invalid compressed data until the special marker (see deflate()
above) can be found, or until all available input is skipped. No output above) can be found, or until all available input is skipped. No output
@@ -455,7 +578,7 @@ extern int inflateSync OF((z_stream *strm));
until success or end of the input data. until success or end of the input data.
*/ */
extern int inflateReset OF((z_stream *strm)); extern int EXPORT inflateReset OF((z_streamp strm));
/* /*
This function is equivalent to inflateEnd followed by inflateInit, This function is equivalent to inflateEnd followed by inflateInit,
but does not free and reallocate all the internal decompression state. but does not free and reallocate all the internal decompression state.
@@ -476,8 +599,8 @@ extern int inflateReset OF((z_stream *strm));
utility functions can easily be modified if you need special options. utility functions can easily be modified if you need special options.
*/ */
extern int compress OF((Bytef *dest, uLongf *destLen, extern int EXPORT 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 Compresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total the byte length of the source buffer. Upon entry, destLen is the total
@@ -491,8 +614,8 @@ extern int compress OF((Bytef *dest, uLongf *destLen,
buffer. buffer.
*/ */
extern int uncompress OF((Bytef *dest, uLongf *destLen, extern int EXPORT 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 Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total the byte length of the source buffer. Upon entry, destLen is the total
@@ -512,7 +635,7 @@ extern int uncompress OF((Bytef *dest, uLongf *destLen,
typedef voidp gzFile; typedef voidp gzFile;
extern gzFile gzopen OF((char *path, char *mode)); extern gzFile EXPORT gzopen OF((const char *path, const char *mode));
/* /*
Opens a gzip (.gz) file for reading or writing. The mode parameter Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb") but can also include a compression level is as in fopen ("rb" or "wb") but can also include a compression level
@@ -524,16 +647,20 @@ extern gzFile gzopen OF((char *path, char *mode));
zlib error is Z_MEM_ERROR). zlib error is Z_MEM_ERROR).
*/ */
extern gzFile gzdopen OF((int fd, char *mode)); extern gzFile EXPORT gzdopen OF((int fd, const char *mode));
/* /*
gzdopen() associates a gzFile with the file descriptor fd. File 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
The mode parameter is as in fopen ("rb" or "wb"). fileno (in the file has been previously opened with fopen).
The mode parameter is as in gzopen.
The next call of gzclose on the returned gzFile will also close the
file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
gzdopen returns NULL if there was insufficient memory to allocate gzdopen returns NULL if there was insufficient memory to allocate
the (de)compression state. the (de)compression state.
*/ */
extern int gzread OF((gzFile file, voidp buf, unsigned len)); extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/* /*
Reads the given number of uncompressed bytes from the compressed file. Reads the given number of uncompressed bytes from the compressed file.
If the input file was not in gzip format, gzread copies the given number If the input file was not in gzip format, gzread copies the given number
@@ -541,14 +668,14 @@ extern int gzread OF((gzFile file, voidp buf, unsigned len));
gzread returns the number of uncompressed bytes actually read (0 for gzread returns the number of uncompressed bytes actually read (0 for
end of file, -1 for error). */ end of file, -1 for error). */
extern int gzwrite OF((gzFile file, voidp buf, unsigned len)); extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len));
/* /*
Writes the given number of uncompressed bytes into the compressed file. Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of uncompressed bytes actually written gzwrite returns the number of uncompressed bytes actually written
(0 in case of error). (0 in case of error).
*/ */
extern int gzflush OF((gzFile file, int flush)); extern int EXPORT gzflush OF((gzFile file, int flush));
/* /*
Flushes all pending output into the compressed file. The parameter Flushes all pending output into the compressed file. The parameter
flush is as in the deflate() function. The return value is the zlib flush is as in the deflate() function. The return value is the zlib
@@ -558,14 +685,14 @@ extern int gzflush OF((gzFile file, int flush));
degrade compression. degrade compression.
*/ */
extern int gzclose OF((gzFile file)); extern int EXPORT gzclose OF((gzFile file));
/* /*
Flushes all pending output if necessary, closes the compressed file Flushes all pending output if necessary, closes the compressed file
and deallocates all the (de)compression state. The return value is the zlib and deallocates all the (de)compression state. The return value is the zlib
error number (see function gzerror below). error number (see function gzerror below).
*/ */
extern char* gzerror OF((gzFile file, int *errnum)); extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
/* /*
Returns the error message for the last error which occurred on the Returns the error message for the last error which occurred on the
given compressed file. errnum is set to zlib error number. If an given compressed file. errnum is set to zlib error number. If an
@@ -582,7 +709,7 @@ extern char* gzerror OF((gzFile file, int *errnum));
compression library. compression library.
*/ */
extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len)); extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/* /*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and Update a running Adler-32 checksum with the bytes buf[0..len-1] and
@@ -599,7 +726,7 @@ extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
if (adler != original_adler) error(); if (adler != original_adler) error();
*/ */
extern uLong crc32 OF((uLong crc, Bytef *buf, uInt len)); extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/* /*
Update a running crc with the bytes buf[0..len-1] and return the updated 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 crc. If buf is NULL, this function returns the required initial value
@@ -615,8 +742,39 @@ extern uLong crc32 OF((uLong crc, Bytef *buf, uInt len));
if (crc != original_crc) error(); if (crc != original_crc) error();
*/ */
#ifndef _Z_UTIL_H
/* various hacks, don't look :) */
/* deflateInit and inflateInit are macros to allow checking the zlib version
* and the compiler's view of z_stream:
*/
extern int EXPORT deflateInit_ OF((z_streamp strm, int level,
const char *version, int stream_size));
extern int EXPORT inflateInit_ OF((z_streamp strm,
const char *version, int stream_size));
extern int EXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int windowBits, int memLevel, int strategy,
const char *version, int stream_size));
extern int EXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size));
#define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit(strm) \
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
(strategy), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;}; /* hack for buggy compilers */ struct internal_state {int dummy;}; /* hack for buggy compilers */
#endif #endif
uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
#ifdef __cplusplus
}
#endif
#endif /* _ZLIB_H */ #endif /* _ZLIB_H */

32
zlib.rc Normal file
View File

@@ -0,0 +1,32 @@
#include <windows.h>
#define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1,0,4,0
PRODUCTVERSION 1,0,4,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0 // not used
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
//language ID = U.S. English, char set = Windows, Multilingual
BEGIN
VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", "1.0.4\0"
VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlib.lib\0"
VALUE "ProductName", "ZLib.DLL\0"
VALUE "Comments", "DLL support by Alessandro Iacopetti\0"
VALUE "LegalCopyright", "(C) 1995-1996 Jean-loup Gailly & Mark Adler\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1252
END
END

70
zutil.c
View File

@@ -1,9 +1,9 @@
/* zutil.c -- target dependent utility functions for the compression library /* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
/* $Id: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp $ */ /* $Id: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */
#include <stdio.h> #include <stdio.h>
@@ -11,29 +11,36 @@
struct internal_state {int dummy;}; /* for buggy compilers */ struct internal_state {int dummy;}; /* for buggy compilers */
#ifndef __GO32__ #ifndef STDC
extern void exit OF((int)); extern void exit OF((int));
#endif #endif
char *zlib_version = ZLIB_VERSION; const char *z_errmsg[10] = {
"need dictionary", /* Z_NEED_DICT 2 */
char *z_errmsg[] = { "stream end", /* Z_STREAM_END 1 */
"stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */
"", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */
"file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */
"stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */
"data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */
"insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */
"buffer error", /* Z_BUF_ERROR (-5) */ "incompatible version",/* Z_VERSION_ERROR (-6) */
""}; ""};
const char *zlibVersion()
{
return ZLIB_VERSION;
}
#ifdef DEBUG
void z_error (m) void z_error (m)
char *m; char *m;
{ {
fprintf(stderr, "%s\n", m); fprintf(stderr, "%s\n", m);
exit(1); exit(1);
} }
#endif
#ifndef HAVE_MEMCPY #ifndef HAVE_MEMCPY
@@ -48,6 +55,19 @@ void zmemcpy(dest, source, len)
} while (--len != 0); } while (--len != 0);
} }
int zmemcmp(s1, s2, len)
Bytef* s1;
Bytef* s2;
uInt len;
{
uInt j;
for (j = 0; j < len; j++) {
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
}
return 0;
}
void zmemzero(dest, len) void zmemzero(dest, len)
Bytef* dest; Bytef* dest;
uInt len; uInt len;
@@ -59,9 +79,10 @@ void zmemzero(dest, len)
} }
#endif #endif
#if defined( __TURBOC__) && !defined(__SMALL__) && !defined(__MEDIUM__) #ifdef __TURBOC__
/* Small and medium model are for now limited to near allocation with #if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
* reduced MAX_WBITS and MAX_MEM_LEVEL /* Small and medium model in Turbo C are for now limited to near allocation
* with reduced MAX_WBITS and MAX_MEM_LEVEL
*/ */
# define MY_ZCALLOC # define MY_ZCALLOC
@@ -94,7 +115,10 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
voidpf buf = opaque; /* just to make some compilers happy */ voidpf buf = opaque; /* just to make some compilers happy */
ulg bsize = (ulg)items*size; ulg bsize = (ulg)items*size;
if (bsize < 65536L) { /* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
if (bsize < 65520L) {
buf = farmalloc(bsize); buf = farmalloc(bsize);
if (*(ush*)&buf != 0) return buf; if (*(ush*)&buf != 0) return buf;
} else { } else {
@@ -129,12 +153,14 @@ void zcfree (voidpf opaque, voidpf ptr)
return; return;
} }
ptr = opaque; /* just to make some compilers happy */ ptr = opaque; /* just to make some compilers happy */
z_error("zcfree: ptr not found"); Assert(0, "zcfree: ptr not found");
} }
#endif
#endif /* __TURBOC__ */ #endif /* __TURBOC__ */
#if defined(M_I86SM)||defined(M_I86MM)||defined(M_I86CM)||defined(M_I86LM)
/* Microsoft C */ #if defined(M_I86) && !defined(__32BIT__)
/* Microsoft C in 16-bit mode */
# define MY_ZCALLOC # define MY_ZCALLOC
@@ -160,7 +186,7 @@ void zcfree (voidpf opaque, voidpf ptr)
#ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef __GO32__ #ifndef STDC
extern voidp calloc OF((uInt items, uInt size)); extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr)); extern void free OF((voidpf ptr));
#endif #endif
@@ -170,6 +196,7 @@ voidpf zcalloc (opaque, items, size)
unsigned items; unsigned items;
unsigned size; unsigned size;
{ {
if (opaque) items += size - size; /* make compiler happy */
return (voidpf)calloc(items, size); return (voidpf)calloc(items, size);
} }
@@ -178,6 +205,7 @@ void zcfree (opaque, ptr)
voidpf ptr; voidpf ptr;
{ {
free(ptr); free(ptr);
if (opaque) return; /* make compiler happy */
} }
#endif /* MY_ZCALLOC */ #endif /* MY_ZCALLOC */

35
zutil.h
View File

@@ -1,5 +1,5 @@
/* zutil.h -- internal interface and configuration of the compression library /* zutil.h -- internal interface and configuration of the compression library
* Copyright (C) 1995 Jean-loup Gailly. * Copyright (C) 1995-1996 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@@ -8,14 +8,14 @@
subject to change. Applications should only use zlib.h. subject to change. Applications should only use zlib.h.
*/ */
/* $Id: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp $ */ /* $Id: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */
#ifndef _Z_UTIL_H #ifndef _Z_UTIL_H
#define _Z_UTIL_H #define _Z_UTIL_H
#include "zlib.h" #include "zlib.h"
#if defined(MSDOS) || defined(VMS) #if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS)
# include <stddef.h> # include <stddef.h>
# include <errno.h> # include <errno.h>
#else #else
@@ -23,6 +23,7 @@
#endif #endif
#ifdef STDC #ifdef STDC
# include <string.h> # include <string.h>
# include <stdlib.h>
#endif #endif
#ifndef local #ifndef local
@@ -36,15 +37,17 @@ typedef unsigned short ush;
typedef ush FAR ushf; typedef ush FAR ushf;
typedef unsigned long ulg; typedef unsigned long ulg;
extern char *z_errmsg[]; /* indexed by 1-zlib_error */ extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
/* (size given to avoid silly warnings with Visual C++) */
#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
#define ERR_RETURN(strm,err) \
return (strm->msg = (char*)ERR_MSG(err), (err))
/* To be used only when the state is known to be valid */ /* To be used only when the state is known to be valid */
/* common constants */ /* common constants */
#define DEFLATED 8
#ifndef DEF_WBITS #ifndef DEF_WBITS
# define DEF_WBITS MAX_WBITS # define DEF_WBITS MAX_WBITS
#endif #endif
@@ -66,6 +69,8 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
#define MAX_MATCH 258 #define MAX_MATCH 258
/* The minimum and maximum match lengths */ /* The minimum and maximum match lengths */
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
/* target dependencies */ /* target dependencies */
#ifdef MSDOS #ifdef MSDOS
@@ -81,7 +86,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
# define OS_CODE 0x06 # define OS_CODE 0x06
#endif #endif
#ifdef WIN32 /* Windows NT */ #ifdef WIN32 /* Window 95 & Windows NT */
# define OS_CODE 0x0b # define OS_CODE 0x0b
#endif #endif
@@ -109,6 +114,10 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
#ifdef TOPS20 #ifdef TOPS20
# define OS_CODE 0x0a # define OS_CODE 0x0a
#endif
#if defined(_BEOS_) || defined(RISCOS)
# define fdopen(fd,mode) NULL /* No fdopen() */
#endif #endif
/* Common defaults */ /* Common defaults */
@@ -143,15 +152,18 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
# define HAVE_MEMCPY # define HAVE_MEMCPY
#endif #endif
#ifdef HAVE_MEMCPY #ifdef HAVE_MEMCPY
# if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # ifdef SMALL_MEDIUM /* MSDOS small or medium model */
# define zmemcpy _fmemcpy # define zmemcpy _fmemcpy
# define zmemcmp _fmemcmp
# define zmemzero(dest, len) _fmemset(dest, 0, len) # define zmemzero(dest, len) _fmemset(dest, 0, len)
# else # else
# define zmemcpy memcpy # define zmemcpy memcpy
# define zmemcmp memcmp
# define zmemzero(dest, len) memset(dest, 0, len) # define zmemzero(dest, len) memset(dest, 0, len)
# endif # endif
#else #else
extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len)); extern void zmemcpy OF((Bytef* dest, Bytef* source, uInt len));
extern int zmemcmp OF((Bytef* s1, Bytef* s2, uInt len));
extern void zmemzero OF((Bytef* dest, uInt len)); extern void zmemzero OF((Bytef* dest, uInt len));
#endif #endif
@@ -161,6 +173,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
# ifndef verbose # ifndef verbose
# define verbose 0 # define verbose 0
# endif # endif
extern void z_error OF((char *m));
# define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Assert(cond,msg) {if(!(cond)) z_error(msg);}
# define Trace(x) fprintf x # define Trace(x) fprintf x
# define Tracev(x) {if (verbose) fprintf x ;} # define Tracev(x) {if (verbose) fprintf x ;}
@@ -177,9 +190,7 @@ extern char *z_errmsg[]; /* indexed by 1-zlib_error */
#endif #endif
typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len));
extern void z_error OF((char *m));
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
void zcfree OF((voidpf opaque, voidpf ptr)); void zcfree OF((voidpf opaque, voidpf ptr));