summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2011-09-09 23:26:40 -0700
committerMark Adler <madler@alumni.caltech.edu>2011-09-09 23:26:40 -0700
commitf6194ef39af5864f792412460c354cc339dde7d1 (patch)
tree5ea1e6849128e9b2194c66ee3d82afa36b4ac07c
parent639be997883d9016baaf46017a2802b2ce1698bd (diff)
downloadzlib-1.2.3.4.tar.gz
zlib-1.2.3.4.tar.bz2
zlib-1.2.3.4.zip
zlib 1.2.3.4v1.2.3.4
-rw-r--r--ChangeLog63
-rw-r--r--INDEX1
-rw-r--r--Makefile112
-rw-r--r--Makefile.in112
-rw-r--r--README4
-rw-r--r--adler32.c38
-rw-r--r--as400/zlib.inc6
-rwxr-xr-xconfigure140
-rw-r--r--contrib/README.contrib4
-rw-r--r--contrib/amd64/amd64-match.S357
-rw-r--r--contrib/infback9/infback9.c13
-rw-r--r--contrib/infback9/inftree9.c21
-rw-r--r--contrib/infback9/inftree9.h24
-rw-r--r--contrib/nintendods/Makefile126
-rw-r--r--contrib/nintendods/README5
-rwxr-xr-xcontrib/puff/puffbin0 -> 17344 bytes
-rw-r--r--contrib/puff/puff.c193
-rw-r--r--contrib/puff/puff.h4
-rw-r--r--contrib/vstudio/vc7/zlib.rc6
-rw-r--r--crc32.c32
-rw-r--r--deflate.c75
-rw-r--r--deflate.h13
-rw-r--r--doc/algorithm.txt2
-rw-r--r--examples/README.examples21
-rw-r--r--examples/enough.c569
-rw-r--r--examples/gzlog.c1303
-rw-r--r--examples/gzlog.h93
-rw-r--r--examples/pigz.c452
-rw-r--r--gzio.c94
-rw-r--r--infback.c13
-rw-r--r--inffast.c5
-rw-r--r--inflate.c136
-rw-r--r--inflate.h26
-rw-r--r--inftrees.c23
-rw-r--r--inftrees.h23
-rw-r--r--make_vms.com3
-rw-r--r--qnx/package.qpg10
-rw-r--r--trees.c10
-rw-r--r--win32/zlib.def16
-rw-r--r--zconf.h6
-rw-r--r--zlib.34
-rw-r--r--zlib.h169
-rw-r--r--zlib.map9
-rwxr-xr-xzlib2ansi152
-rw-r--r--zutil.h6
45 files changed, 3642 insertions, 852 deletions
diff --git a/ChangeLog b/ChangeLog
index 1bc7105..497b757 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,67 @@
1 1
2 ChangeLog file for zlib 2 ChangeLog file for zlib
3 3
4Changes in 1.2.3.4 (21 Dec 2009)
5- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
6- Update comments in configure and Makefile.in for default --shared
7- Fix test -z's in configure [Marquess]
8- Build examplesh and minigzipsh when not testing
9- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
10- Import LDFLAGS from the environment in configure
11- Fix configure to populate SFLAGS with discovered CFLAGS options
12- Adapt make_vms.com to the new Makefile.in [Zinser]
13- Add zlib2ansi script for C++ compilation [Marquess]
14- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
15- Add AMD64 assembler code for longest match to contrib [Teterin]
16- Include options from $SFLAGS when doing $LDSHARED
17- Simplify 64-bit file support by introducing z_off64_t type
18- Make shared object files in objs directory to work around old Sun cc
19- Use only three-part version number for Darwin shared compiles
20- Add rc option to ar in Makefile.in for when ./configure not run
21- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
22- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
23- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
24- Rename Makefile.in targets allstatic to static and allshared to shared
25- Fix static and shared Makefile.in targets to be independent
26- Correct error return bug in gz_open() by setting state [Brown]
27- Put spaces before ;;'s in configure for better sh compatibility
28- Added pigz.c (parallel implementation of gzip) to examples/
29- Correct constant in crc32.c to UL [Leventhal]
30- Reject negative lengths in crc32_combine()
31- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
32- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
33- Correct typo in doc/algorithm.txt [Janik]
34- Fix bug in adler32_combine() [Zhu]
35- Catch missing-end-of-block-code error in all inflates and in puff
36 Assures that random input to inflate eventually results in an error
37- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
38- Update ENOUGH and its usage to reflect discovered bounds
39- Fix gzerror() error report on empty input file [Brown]
40- Add ush casts in trees.c to avoid pedantic runtime errors
41- Fix typo in zlib.h uncompress() description [Reiss]
42- Correct inflate() comments with regard to automatic header detection
43- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
44- Put new version of gzlog (2.0) in examples with interruption recovery
45- Add puff compile option to permit invalid distance-too-far streams
46- Add puff TEST command options, ability to read piped input
47- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
48 _LARGEFILE64_SOURCE not defined
49- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
50- Fix deflateSetDictionary() to use all 32K for output consistency
51- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
52- Clear bytes after deflate lookahead to avoid use of uninitialized data
53- Change a limit in inftrees.c to be more transparent to Coverity Prevent
54- Update win32/zlib.def with exported symbols from zlib.h
55- Correct spelling error in zlib.h [Willem]
56- Allow Z_BLOCK for deflate() to force a new block
57- Allow negative bits in inflatePrime() to delete existing bit buffer
58- Add Z_TREES flush option to inflate() to return at end of trees
59- Add inflateMark() to return current state information for random access
60- Added Makefile for NintendoDS to contrib [Costa]
61- Add -w in configure compile tests to avoid spurious warnings [Beucler]
62- Fix typos in zlib.h comments for deflateSetDictionary()
63- Fix EOF detection in transparent gzread() [Maier]
64
4Changes in 1.2.3.3 (2 October 2006) 65Changes in 1.2.3.3 (2 October 2006)
5- Make --shared the default for configure, add a --static option 66- Make --shared the default for configure, add a --static option
6- Add compile option to permit invalid distance-too-far streams 67- Add compile option to permit invalid distance-too-far streams
@@ -10,7 +71,7 @@ Changes in 1.2.3.3 (2 October 2006)
10- Use ftello() and fseeko() if available instead of ftell() and fseek() 71- Use ftello() and fseeko() if available instead of ftell() and fseek()
11- Provide two versions of all functions that use the z_off_t type for 72- Provide two versions of all functions that use the z_off_t type for
12 binary compatibility -- a normal version and a 64-bit offset version, 73 binary compatibility -- a normal version and a 64-bit offset version,
13 per the Large File Support Extension when _LARGEFILE64_SUPPORT is 74 per the Large File Support Extension when _LARGEFILE64_SOURCE is
14 defined; use the 64-bit versions by default when _FILE_OFFSET_BITS 75 defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
15 is defined to be 64 76 is defined to be 64
16- Add a --uname= option to configure to perhaps help with cross-compiling 77- Add a --uname= option to configure to perhaps help with cross-compiling
diff --git a/INDEX b/INDEX
index 722d4ec..2c7a512 100644
--- a/INDEX
+++ b/INDEX
@@ -10,6 +10,7 @@ treebuild.xml see http://treebuild.metux.de/
10zlib.3 Man page for zlib 10zlib.3 Man page for zlib
11zlib.map Linux symbol information 11zlib.map Linux symbol information
12zlib.pc.in Template for pkg-config descriptor 12zlib.pc.in Template for pkg-config descriptor
13zlib2ansi perl script to convert source files for C++ compilation
13 14
14amiga/ makefiles for Amiga SAS C 15amiga/ makefiles for Amiga SAS C
15as400/ makefiles for IBM AS/400 16as400/ makefiles for IBM AS/400
diff --git a/Makefile b/Makefile
index 2fa2e25..6ad7a5c 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,8 @@
4 4
5# To compile and test, type: 5# To compile and test, type:
6# ./configure; make test 6# ./configure; make test
7# The call of configure is optional if you don't have special requirements 7# Normally configure builds both a static and a shared library.
8# If you wish to build zlib as a shared library, use: ./configure -s 8# If you want to build just a static library, use: ./configure --static
9 9
10# To use the asm code, type: 10# To use the asm code, type:
11# cp contrib/asm?86/match.S ./match.S 11# cp contrib/asm?86/match.S ./match.S
@@ -26,16 +26,17 @@ CFLAGS=-O
26 26
27SFLAGS=-O 27SFLAGS=-O
28 28
29LDFLAGS=libz.a 29LDFLAGS=-L. libz.a
30LDSHARED=$(CC) 30LDSHARED=$(CC)
31CPP=$(CC) -E 31CPP=$(CC) -E
32 32
33LIBS=libz.a 33STATICLIB=libz.a
34SHAREDLIB=libz.so 34SHAREDLIB=libz.so
35SHAREDLIBV=libz.so.1.2.3.3 35SHAREDLIBV=libz.so.1.2.3.4
36SHAREDLIBM=libz.so.1 36SHAREDLIBM=libz.so.1
37LIBS=$(STATICLIB) $(SHAREDLIB)
37 38
38AR=ar 39AR=ar rc
39RANLIB=ranlib 40RANLIB=ranlib
40TAR=tar 41TAR=tar
41SHELL=/bin/sh 42SHELL=/bin/sh
@@ -52,22 +53,30 @@ pkgconfigdir = ${libdir}/pkgconfig
52OBJC = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ 53OBJC = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
53 zutil.o inflate.o infback.o inftrees.o inffast.o 54 zutil.o inflate.o infback.o inftrees.o inffast.o
54 55
56PIC_OBJC = adler32.lo compress.lo crc32.lo gzio.lo uncompr.lo deflate.lo trees.lo \
57 zutil.lo inflate.lo infback.lo inftrees.lo inffast.lo
58
59# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
55OBJA = 60OBJA =
56# to use the asm code: make OBJA=match.o 61PIC_OBJA =
57 62
58OBJS = $(OBJC) $(OBJA) 63OBJS = $(OBJC) $(OBJA)
59 64
60PIC_OBJS = $(OBJS:%.o=%.lo) 65PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
66
67all: static shared
61 68
62TEST_OBJS = example.o minigzip.o 69static: example$(EXE) minigzip$(EXE)
63 70
64allstatic: example$(EXE) minigzip$(EXE) 71shared: examplesh$(EXE) minigzipsh$(EXE)
65 72
66allshared: examplesh$(EXE) minigzipsh$(EXE) 73all64: example64$(EXE) minigzip64$(EXE)
74
75check: test
67 76
68all: allstatic allshared 77test: all teststatic testshared
69 78
70teststatic: allstatic 79teststatic: static
71 @echo hello world | ./minigzip | ./minigzip -d || \ 80 @echo hello world | ./minigzip | ./minigzip -d || \
72 echo ' *** minigzip test FAILED ***' ; \ 81 echo ' *** minigzip test FAILED ***' ; \
73 if ./example; then \ 82 if ./example; then \
@@ -76,8 +85,9 @@ teststatic: allstatic
76 echo ' *** zlib test FAILED ***'; \ 85 echo ' *** zlib test FAILED ***'; \
77 fi 86 fi
78 87
79testshared: allshared 88testshared: shared
80 @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ 89 @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
90 LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
81 DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ 91 DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
82 SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ 92 SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
83 echo hello world | ./minigzipsh | ./minigzipsh -d || \ 93 echo hello world | ./minigzipsh | ./minigzipsh -d || \
@@ -88,9 +98,14 @@ testshared: allshared
88 echo ' *** zlib shared test FAILED ***'; \ 98 echo ' *** zlib shared test FAILED ***'; \
89 fi 99 fi
90 100
91test: teststatic testshared 101test64: all64
92 102 @echo hello world | ./minigzip64 | ./minigzip64 -d || \
93check: test 103 echo ' *** minigzip 64-bit test FAILED ***' ; \
104 if ./example64; then \
105 echo ' *** zlib 64-bit test OK ***'; \
106 else \
107 echo ' *** zlib 64-bit test FAILED ***'; \
108 fi
94 109
95libz.a: $(OBJS) 110libz.a: $(OBJS)
96 $(AR) $@ $(OBJS) 111 $(AR) $@ $(OBJS)
@@ -108,26 +123,43 @@ match.lo: match.S
108 mv _match.o match.lo 123 mv _match.o match.lo
109 rm -f _match.s 124 rm -f _match.s
110 125
111%.lo: %.c 126example64.o: example.c zlib.h zconf.h zlibdefs.h
112 $(CC) $(SFLAGS) -DPIC -c $< -o $@ 127 $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ $<
128
129minigzip64.o: minigzip.c zlib.h zconf.h zlibdefs.h
130 $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ $<
131
132.SUFFIXES: .lo
133
134.c.lo:
135 -@if [ ! -d objs ]; then mkdir objs; fi
136 $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $<
137 -@mv objs/$*.o $@
113 138
114$(SHAREDLIBV): $(PIC_OBJS) 139$(SHAREDLIBV): $(PIC_OBJS)
115 $(LDSHARED) -o $@ $(PIC_OBJS) -lc 140 $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) -lc
116 rm -f $(SHAREDLIB) $(SHAREDLIBM) 141 rm -f $(SHAREDLIB) $(SHAREDLIBM)
117 ln -s $@ $(SHAREDLIB) 142 ln -s $@ $(SHAREDLIB)
118 ln -s $@ $(SHAREDLIBM) 143 ln -s $@ $(SHAREDLIBM)
144 -@rmdir objs
119 145
120example$(EXE): example.o $(LIBS) 146example$(EXE): example.o $(STATICLIB)
121 $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) 147 $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
122 148
123minigzip$(EXE): minigzip.o $(LIBS) 149minigzip$(EXE): minigzip.o $(STATICLIB)
124 $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) 150 $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
125 151
126examplesh$(EXE): example.o $(LIBS) 152examplesh$(EXE): example.o $(SHAREDLIBV)
127 $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIB) 153 $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
154
155minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
156 $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
157
158example64$(EXE): example64.o $(STATICLIB)
159 $(CC) $(CFLAGS) -o $@ example64.o $(LDFLAGS)
128 160
129minigzipsh$(EXE): minigzip.o $(LIBS) 161minigzip64$(EXE): minigzip64.o $(STATICLIB)
130 $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIB) 162 $(CC) $(CFLAGS) -o $@ minigzip64.o $(LDFLAGS)
131 163
132install-libs: $(LIBS) 164install-libs: $(LIBS)
133 -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi 165 -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
@@ -168,8 +200,10 @@ mostlyclean: clean
168clean: 200clean:
169 rm -f *.o *.lo *~ \ 201 rm -f *.o *.lo *~ \
170 example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ 202 example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
203 example64$(EXE) minigzip64$(EXE) \
171 libz.* foo.gz so_locations \ 204 libz.* foo.gz so_locations \
172 _match.s maketree contrib/infback9/*.o 205 _match.s maketree contrib/infback9/*.o
206 rm -rf objs
173 207
174maintainer-clean: distclean 208maintainer-clean: distclean
175distclean: clean 209distclean: clean
@@ -186,30 +220,20 @@ depend:
186 220
187# DO NOT DELETE THIS LINE -- make depend depends on it. 221# DO NOT DELETE THIS LINE -- make depend depends on it.
188 222
189adler32.o: zlib.h zconf.h zlibdefs.h 223adler32.o gzio.o zutil.o: zutil.h zlib.h zconf.h zlibdefs.h
190compress.o: zlib.h zconf.h zlibdefs.h 224compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h zlibdefs.h
191crc32.o: crc32.h zlib.h zconf.h zlibdefs.h 225crc32.o: zutil.h zlib.h zconf.h zlibdefs.h crc32.h
192deflate.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h 226deflate.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h
193example.o: zlib.h zconf.h zlibdefs.h 227infback.o inflate.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
194gzio.o: zutil.h zlib.h zconf.h zlibdefs.h
195inffast.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h 228inffast.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h
196inflate.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
197infback.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
198inftrees.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h 229inftrees.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h
199minigzip.o: zlib.h zconf.h zlibdefs.h
200trees.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h 230trees.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h
201uncompr.o: zlib.h zconf.h zlibdefs.h
202zutil.o: zutil.h zlib.h zconf.h zlibdefs.h
203 231
204adler32.lo: zlib.h zconf.h zlibdefs.h 232adler32.lo gzio.lo zutil.lo: zutil.h zlib.h zconf.h zlibdefs.h
205compress.lo: zlib.h zconf.h zlibdefs.h 233compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h zlibdefs.h
206crc32.lo: crc32.h zlib.h zconf.h zlibdefs.h 234crc32.lo: zutil.h zlib.h zconf.h zlibdefs.h crc32.h
207deflate.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h 235deflate.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h
208gzio.lo: zutil.h zlib.h zconf.h zlibdefs.h 236infback.lo inflate.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
209inffast.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h 237inffast.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h
210inflate.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
211infback.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
212inftrees.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h 238inftrees.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h
213trees.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h 239trees.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h
214uncompr.lo: zlib.h zconf.h zlibdefs.h
215zutil.lo: zutil.h zlib.h zconf.h zlibdefs.h
diff --git a/Makefile.in b/Makefile.in
index 2fa2e25..6ad7a5c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -4,8 +4,8 @@
4 4
5# To compile and test, type: 5# To compile and test, type:
6# ./configure; make test 6# ./configure; make test
7# The call of configure is optional if you don't have special requirements 7# Normally configure builds both a static and a shared library.
8# If you wish to build zlib as a shared library, use: ./configure -s 8# If you want to build just a static library, use: ./configure --static
9 9
10# To use the asm code, type: 10# To use the asm code, type:
11# cp contrib/asm?86/match.S ./match.S 11# cp contrib/asm?86/match.S ./match.S
@@ -26,16 +26,17 @@ CFLAGS=-O
26 26
27SFLAGS=-O 27SFLAGS=-O
28 28
29LDFLAGS=libz.a 29LDFLAGS=-L. libz.a
30LDSHARED=$(CC) 30LDSHARED=$(CC)
31CPP=$(CC) -E 31CPP=$(CC) -E
32 32
33LIBS=libz.a 33STATICLIB=libz.a
34SHAREDLIB=libz.so 34SHAREDLIB=libz.so
35SHAREDLIBV=libz.so.1.2.3.3 35SHAREDLIBV=libz.so.1.2.3.4
36SHAREDLIBM=libz.so.1 36SHAREDLIBM=libz.so.1
37LIBS=$(STATICLIB) $(SHAREDLIB)
37 38
38AR=ar 39AR=ar rc
39RANLIB=ranlib 40RANLIB=ranlib
40TAR=tar 41TAR=tar
41SHELL=/bin/sh 42SHELL=/bin/sh
@@ -52,22 +53,30 @@ pkgconfigdir = ${libdir}/pkgconfig
52OBJC = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ 53OBJC = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
53 zutil.o inflate.o infback.o inftrees.o inffast.o 54 zutil.o inflate.o infback.o inftrees.o inffast.o
54 55
56PIC_OBJC = adler32.lo compress.lo crc32.lo gzio.lo uncompr.lo deflate.lo trees.lo \
57 zutil.lo inflate.lo infback.lo inftrees.lo inffast.lo
58
59# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
55OBJA = 60OBJA =
56# to use the asm code: make OBJA=match.o 61PIC_OBJA =
57 62
58OBJS = $(OBJC) $(OBJA) 63OBJS = $(OBJC) $(OBJA)
59 64
60PIC_OBJS = $(OBJS:%.o=%.lo) 65PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
66
67all: static shared
61 68
62TEST_OBJS = example.o minigzip.o 69static: example$(EXE) minigzip$(EXE)
63 70
64allstatic: example$(EXE) minigzip$(EXE) 71shared: examplesh$(EXE) minigzipsh$(EXE)
65 72
66allshared: examplesh$(EXE) minigzipsh$(EXE) 73all64: example64$(EXE) minigzip64$(EXE)
74
75check: test
67 76
68all: allstatic allshared 77test: all teststatic testshared
69 78
70teststatic: allstatic 79teststatic: static
71 @echo hello world | ./minigzip | ./minigzip -d || \ 80 @echo hello world | ./minigzip | ./minigzip -d || \
72 echo ' *** minigzip test FAILED ***' ; \ 81 echo ' *** minigzip test FAILED ***' ; \
73 if ./example; then \ 82 if ./example; then \
@@ -76,8 +85,9 @@ teststatic: allstatic
76 echo ' *** zlib test FAILED ***'; \ 85 echo ' *** zlib test FAILED ***'; \
77 fi 86 fi
78 87
79testshared: allshared 88testshared: shared
80 @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ 89 @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
90 LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
81 DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ 91 DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
82 SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ 92 SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
83 echo hello world | ./minigzipsh | ./minigzipsh -d || \ 93 echo hello world | ./minigzipsh | ./minigzipsh -d || \
@@ -88,9 +98,14 @@ testshared: allshared
88 echo ' *** zlib shared test FAILED ***'; \ 98 echo ' *** zlib shared test FAILED ***'; \
89 fi 99 fi
90 100
91test: teststatic testshared 101test64: all64
92 102 @echo hello world | ./minigzip64 | ./minigzip64 -d || \
93check: test 103 echo ' *** minigzip 64-bit test FAILED ***' ; \
104 if ./example64; then \
105 echo ' *** zlib 64-bit test OK ***'; \
106 else \
107 echo ' *** zlib 64-bit test FAILED ***'; \
108 fi
94 109
95libz.a: $(OBJS) 110libz.a: $(OBJS)
96 $(AR) $@ $(OBJS) 111 $(AR) $@ $(OBJS)
@@ -108,26 +123,43 @@ match.lo: match.S
108 mv _match.o match.lo 123 mv _match.o match.lo
109 rm -f _match.s 124 rm -f _match.s
110 125
111%.lo: %.c 126example64.o: example.c zlib.h zconf.h zlibdefs.h
112 $(CC) $(SFLAGS) -DPIC -c $< -o $@ 127 $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ $<
128
129minigzip64.o: minigzip.c zlib.h zconf.h zlibdefs.h
130 $(CC) $(CFLAGS) -D_FILE_OFFSET_BITS=64 -c -o $@ $<
131
132.SUFFIXES: .lo
133
134.c.lo:
135 -@if [ ! -d objs ]; then mkdir objs; fi
136 $(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $<
137 -@mv objs/$*.o $@
113 138
114$(SHAREDLIBV): $(PIC_OBJS) 139$(SHAREDLIBV): $(PIC_OBJS)
115 $(LDSHARED) -o $@ $(PIC_OBJS) -lc 140 $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) -lc
116 rm -f $(SHAREDLIB) $(SHAREDLIBM) 141 rm -f $(SHAREDLIB) $(SHAREDLIBM)
117 ln -s $@ $(SHAREDLIB) 142 ln -s $@ $(SHAREDLIB)
118 ln -s $@ $(SHAREDLIBM) 143 ln -s $@ $(SHAREDLIBM)
144 -@rmdir objs
119 145
120example$(EXE): example.o $(LIBS) 146example$(EXE): example.o $(STATICLIB)
121 $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) 147 $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
122 148
123minigzip$(EXE): minigzip.o $(LIBS) 149minigzip$(EXE): minigzip.o $(STATICLIB)
124 $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) 150 $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
125 151
126examplesh$(EXE): example.o $(LIBS) 152examplesh$(EXE): example.o $(SHAREDLIBV)
127 $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIB) 153 $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
154
155minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
156 $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
157
158example64$(EXE): example64.o $(STATICLIB)
159 $(CC) $(CFLAGS) -o $@ example64.o $(LDFLAGS)
128 160
129minigzipsh$(EXE): minigzip.o $(LIBS) 161minigzip64$(EXE): minigzip64.o $(STATICLIB)
130 $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIB) 162 $(CC) $(CFLAGS) -o $@ minigzip64.o $(LDFLAGS)
131 163
132install-libs: $(LIBS) 164install-libs: $(LIBS)
133 -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi 165 -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
@@ -168,8 +200,10 @@ mostlyclean: clean
168clean: 200clean:
169 rm -f *.o *.lo *~ \ 201 rm -f *.o *.lo *~ \
170 example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ 202 example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
203 example64$(EXE) minigzip64$(EXE) \
171 libz.* foo.gz so_locations \ 204 libz.* foo.gz so_locations \
172 _match.s maketree contrib/infback9/*.o 205 _match.s maketree contrib/infback9/*.o
206 rm -rf objs
173 207
174maintainer-clean: distclean 208maintainer-clean: distclean
175distclean: clean 209distclean: clean
@@ -186,30 +220,20 @@ depend:
186 220
187# DO NOT DELETE THIS LINE -- make depend depends on it. 221# DO NOT DELETE THIS LINE -- make depend depends on it.
188 222
189adler32.o: zlib.h zconf.h zlibdefs.h 223adler32.o gzio.o zutil.o: zutil.h zlib.h zconf.h zlibdefs.h
190compress.o: zlib.h zconf.h zlibdefs.h 224compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h zlibdefs.h
191crc32.o: crc32.h zlib.h zconf.h zlibdefs.h 225crc32.o: zutil.h zlib.h zconf.h zlibdefs.h crc32.h
192deflate.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h 226deflate.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h
193example.o: zlib.h zconf.h zlibdefs.h 227infback.o inflate.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
194gzio.o: zutil.h zlib.h zconf.h zlibdefs.h
195inffast.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h 228inffast.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h
196inflate.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
197infback.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
198inftrees.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h 229inftrees.o: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h
199minigzip.o: zlib.h zconf.h zlibdefs.h
200trees.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h 230trees.o: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h
201uncompr.o: zlib.h zconf.h zlibdefs.h
202zutil.o: zutil.h zlib.h zconf.h zlibdefs.h
203 231
204adler32.lo: zlib.h zconf.h zlibdefs.h 232adler32.lo gzio.lo zutil.lo: zutil.h zlib.h zconf.h zlibdefs.h
205compress.lo: zlib.h zconf.h zlibdefs.h 233compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h zlibdefs.h
206crc32.lo: crc32.h zlib.h zconf.h zlibdefs.h 234crc32.lo: zutil.h zlib.h zconf.h zlibdefs.h crc32.h
207deflate.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h 235deflate.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h
208gzio.lo: zutil.h zlib.h zconf.h zlibdefs.h 236infback.lo inflate.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
209inffast.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h 237inffast.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h
210inflate.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
211infback.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h inflate.h inffast.h inffixed.h
212inftrees.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h 238inftrees.lo: zutil.h zlib.h zconf.h zlibdefs.h inftrees.h
213trees.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h 239trees.lo: deflate.h zutil.h zlib.h zconf.h zlibdefs.h trees.h
214uncompr.lo: zlib.h zconf.h zlibdefs.h
215zutil.lo: zutil.h zlib.h zconf.h zlibdefs.h
diff --git a/README b/README
index 75cae36..b1446be 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
1ZLIB DATA COMPRESSION LIBRARY 1ZLIB DATA COMPRESSION LIBRARY
2 2
3zlib 1.2.3.3 is a general purpose data compression library. All the code is 3zlib 1.2.3.4 is a general purpose data compression library. All the code is
4thread safe. The data format used by the zlib library is described by RFCs 4thread safe. The data format used by the zlib library is described by RFCs
5(Request for Comments) 1950 to 1952 in the files 5(Request for Comments) 1950 to 1952 in the files
6http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) 6http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -33,7 +33,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
33issue of Dr. Dobb's Journal; a copy of the article is available in 33issue of Dr. Dobb's Journal; a copy of the article is available in
34http://dogma.net/markn/articles/zlibtool/zlibtool.htm 34http://dogma.net/markn/articles/zlibtool/zlibtool.htm
35 35
36The changes made in version 1.2.3.3 are documented in the file ChangeLog. 36The changes made in version 1.2.3.4 are documented in the file ChangeLog.
37 37
38Unsupported third party contributions are provided in directory "contrib". 38Unsupported third party contributions are provided in directory "contrib".
39 39
diff --git a/adler32.c b/adler32.c
index 8bf7dc4..65ad6a5 100644
--- a/adler32.c
+++ b/adler32.c
@@ -1,21 +1,15 @@
1/* adler32.c -- compute the Adler-32 checksum of a data stream 1/* adler32.c -- compute the Adler-32 checksum of a data stream
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2007 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
6/* @(#) $Id$ */ 6/* @(#) $Id$ */
7 7
8#define ZLIB_INTERNAL 8#include "zutil.h"
9#include "zlib.h"
10 9
11#define local static 10#define local static
12 11
13#ifdef _LARGEFILE64_SOURCE 12local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
14 local uLong adler32_combine_(uLong adler1, uLong adler2, off64_t len2);
15#else
16 local uLong adler32_combine_(uLong adler1, uLong adler2, z_off_t len2);
17#endif
18
19 13
20#define BASE 65521UL /* largest prime smaller than 65536 */ 14#define BASE 65521UL /* largest prime smaller than 65536 */
21#define NMAX 5552 15#define NMAX 5552
@@ -137,11 +131,7 @@ uLong ZEXPORT adler32(adler, buf, len)
137local uLong adler32_combine_(adler1, adler2, len2) 131local uLong adler32_combine_(adler1, adler2, len2)
138 uLong adler1; 132 uLong adler1;
139 uLong adler2; 133 uLong adler2;
140#ifdef _LARGEFILE64_SOURCE 134 z_off64_t len2;
141 off64_t len2;
142#else
143 z_off_t len2;
144#endif
145{ 135{
146 unsigned long sum1; 136 unsigned long sum1;
147 unsigned long sum2; 137 unsigned long sum2;
@@ -154,10 +144,10 @@ local uLong adler32_combine_(adler1, adler2, len2)
154 MOD(sum2); 144 MOD(sum2);
155 sum1 += (adler2 & 0xffff) + BASE - 1; 145 sum1 += (adler2 & 0xffff) + BASE - 1;
156 sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 146 sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
157 if (sum1 > BASE) sum1 -= BASE; 147 if (sum1 >= BASE) sum1 -= BASE;
158 if (sum1 > BASE) sum1 -= BASE; 148 if (sum1 >= BASE) sum1 -= BASE;
159 if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); 149 if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
160 if (sum2 > BASE) sum2 -= BASE; 150 if (sum2 >= BASE) sum2 -= BASE;
161 return sum1 | (sum2 << 16); 151 return sum1 | (sum2 << 16);
162} 152}
163 153
@@ -170,20 +160,10 @@ uLong ZEXPORT adler32_combine(adler1, adler2, len2)
170 return adler32_combine_(adler1, adler2, len2); 160 return adler32_combine_(adler1, adler2, len2);
171} 161}
172 162
173#ifdef _LARGEFILE64_SOURCE
174uLong ZEXPORT adler32_combine64(adler1, adler2, len2) 163uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
175 uLong adler1; 164 uLong adler1;
176 uLong adler2; 165 uLong adler2;
177 off64_t len2; 166 z_off64_t len2;
178{ 167{
179 return adler32_combine_(adler1, adler2, len2); 168 return adler32_combine_(adler1, adler2, len2);
180} 169}
181#else
182uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
183 uLong adler1;
184 uLong adler2;
185 z_off_t len2;
186{
187 return adler32_combine_(adler1, adler2, len2);
188}
189#endif
diff --git a/as400/zlib.inc b/as400/zlib.inc
index 4436477..9ef0b14 100644
--- a/as400/zlib.inc
+++ b/as400/zlib.inc
@@ -1,7 +1,7 @@
1 * ZLIB.INC - Interface to the general purpose compression library 1 * ZLIB.INC - Interface to the general purpose compression library
2 * 2 *
3 * ILE RPG400 version by Patrick Monnerat, DATASPHERE. 3 * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
4 * Version 1.2.3.3 4 * Version 1.2.3.4
5 * 5 *
6 * 6 *
7 * WARNING: 7 * WARNING:
@@ -22,8 +22,8 @@
22 * 22 *
23 * Versioning information. 23 * Versioning information.
24 * 24 *
25 D ZLIB_VERSION C '1.2.3.3' 25 D ZLIB_VERSION C '1.2.3.4'
26 D ZLIB_VERNUM C X'1233' 26 D ZLIB_VERNUM C X'1234'
27 * 27 *
28 * Other equates. 28 * Other equates.
29 * 29 *
diff --git a/configure b/configure
index cc97872..b87dddc 100755
--- a/configure
+++ b/configure
@@ -1,26 +1,22 @@
1#!/bin/sh 1#!/bin/sh
2# configure script for zlib. This script is needed only if 2# configure script for zlib.
3# you wish to build a shared library and your system supports them,
4# of if you need special compiler, flags or install directory.
5# Otherwise, you can just use directly "make test; make install"
6# 3#
7# To create a shared library, use "configure --shared"; by default a static 4# Normally configure builds both a static and a shared library.
8# library is created. If the primitive shared library support provided here 5# If you want to build just a static library, use: ./configure --static
9# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
10# 6#
11# To impose specific compiler or flags or install directory, use for example: 7# To impose specific compiler or flags or install directory, use for example:
12# prefix=$HOME CC=cc CFLAGS="-O4" ./configure 8# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
13# or for csh/tcsh users: 9# or for csh/tcsh users:
14# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) 10# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
15# LDSHARED is the command to be used to create a shared library
16 11
17# Incorrect settings of CC or CFLAGS may prevent creating a shared library. 12# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
18# If you have problems, try without defining CC and CFLAGS before reporting 13# If you have problems, try without defining CC and CFLAGS before reporting
19# an error. 14# an error.
20 15
21LIBS=libz.a 16STATICLIB=libz.a
22LDFLAGS="-L. ${LIBS}" 17LDFLAGS="${LDFLAGS} -L. ${STATICLIB}"
23VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` 18VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
19VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
24VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` 20VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
25VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` 21VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
26AR=${AR-"ar"} 22AR=${AR-"ar"}
@@ -45,22 +41,22 @@ case "$1" in
45 echo 'usage:' 41 echo 'usage:'
46 echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' 42 echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]'
47 echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR] [--zprefix]' 43 echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR] [--zprefix]'
48 exit 0;; 44 exit 0 ;;
49 -p*=* | --prefix=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; 45 -p*=* | --prefix=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift ;;
50 -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; 46 -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift ;;
51 -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; 47 -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift ;;
52 -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; 48 -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift ;;
53 -u*=* | --uname=*) uname=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; 49 -u*=* | --uname=*) uname=`echo $1 | sed 's/[-a-z_]*=//'`;shift ;;
54 -p* | --prefix) prefix="$2"; shift; shift;; 50 -p* | --prefix) prefix="$2"; shift; shift ;;
55 -e* | --eprefix) exec_prefix="$2"; shift; shift;; 51 -e* | --eprefix) exec_prefix="$2"; shift; shift ;;
56 -l* | --libdir) libdir="$2"; shift; shift;; 52 -l* | --libdir) libdir="$2"; shift; shift ;;
57 -i* | --includedir) includedir="$2"; shift; shift;; 53 -i* | --includedir) includedir="$2"; shift; shift ;;
58 -s* | --shared | --enable-shared) shared=1; shift;; 54 -s* | --shared | --enable-shared) shared=1; shift ;;
59 -t | --static) shared=0; shift;; 55 -t | --static) shared=0; shift ;;
60 -z* | --zprefix) zprefix=1; shift;; 56 -z* | --zprefix) zprefix=1; shift ;;
61 --sysconfdir=*) echo "ignored option: --sysconfdir"; shift;; 57 --sysconfdir=*) echo "ignored option: --sysconfdir"; shift ;;
62 --localstatedir=*) echo "ignored option: --localstatedir"; shift;; 58 --localstatedir=*) echo "ignored option: --localstatedir"; shift ;;
63 *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;; 59 *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1 ;;
64 esac 60 esac
65done 61done
66 62
@@ -75,44 +71,44 @@ cc=${CC-gcc}
75cflags=${CFLAGS-"-O3"} 71cflags=${CFLAGS-"-O3"}
76# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure 72# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
77case "$cc" in 73case "$cc" in
78 *gcc*) gcc=1;; 74 *gcc*) gcc=1 ;;
79esac 75esac
80 76
81if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then 77if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
82 CC="$cc" 78 CC="$cc"
83 SFLAGS="${CFLAGS-"-O3"} -fPIC" 79 SFLAGS="${CFLAGS-"-O3"} -fPIC"
84 CFLAGS="${CFLAGS-"-O3"}" 80 CFLAGS="${CFLAGS-"-O3"}"
85 if test -z $uname; then 81 if test -z "$uname"; then
86 uname=`(uname -s || echo unknown) 2>/dev/null` 82 uname=`(uname -s || echo unknown) 2>/dev/null`
87 fi 83 fi
88 case "$uname" in 84 case "$uname" in
89 Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"};; 85 Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;;
90 CYGWIN* | Cygwin* | cygwin* | OS/2* ) 86 CYGWIN* | Cygwin* | cygwin* | OS/2* )
91 EXE='.exe';; 87 EXE='.exe' ;;
92 QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 88 QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
93 # (alain.bonnefoy@icbt.com) 89 # (alain.bonnefoy@icbt.com)
94 LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};; 90 LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
95 HP-UX*) 91 HP-UX*)
96 LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} 92 LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
97 case `(uname -m || echo unknown) 2>/dev/null` in 93 case `(uname -m || echo unknown) 2>/dev/null` in
98 ia64) 94 ia64)
99 shared_ext='.so' 95 shared_ext='.so'
100 SHAREDLIB='libz.so';; 96 SHAREDLIB='libz.so' ;;
101 *) 97 *)
102 shared_ext='.sl' 98 shared_ext='.sl'
103 SHAREDLIB='libz.sl';; 99 SHAREDLIB='libz.sl' ;;
104 esac;; 100 esac ;;
105 Darwin*) shared_ext='.dylib' 101 Darwin*) shared_ext='.dylib'
106 SHAREDLIB=libz$shared_ext 102 SHAREDLIB=libz$shared_ext
107 SHAREDLIBV=libz.$VER$shared_ext 103 SHAREDLIBV=libz.$VER$shared_ext
108 SHAREDLIBM=libz.$VER1$shared_ext 104 SHAREDLIBM=libz.$VER1$shared_ext
109 LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};; 105 LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} ;;
110 *) LDSHARED=${LDSHARED-"$cc -shared"};; 106 *) LDSHARED=${LDSHARED-"$cc -shared"} ;;
111 esac 107 esac
112else 108else
113 # find system name and corresponding cc options 109 # find system name and corresponding cc options
114 CC=${CC-cc} 110 CC=${CC-cc}
115 if test -z $uname; then 111 if test -z "$uname"; then
116 uname=`(uname -sr || echo unknown) 2>/dev/null` 112 uname=`(uname -sr || echo unknown) 2>/dev/null`
117 fi 113 fi
118 case "$uname" in 114 case "$uname" in
@@ -123,63 +119,64 @@ else
123 case `(uname -m || echo unknown) 2>/dev/null` in 119 case `(uname -m || echo unknown) 2>/dev/null` in
124 ia64) 120 ia64)
125 shared_ext='.so' 121 shared_ext='.so'
126 SHAREDLIB='libz.so';; 122 SHAREDLIB='libz.so' ;;
127 *) 123 *)
128 shared_ext='.sl' 124 shared_ext='.sl'
129 SHAREDLIB='libz.sl';; 125 SHAREDLIB='libz.sl' ;;
130 esac;; 126 esac ;;
131 IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} 127 IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
132 CFLAGS=${CFLAGS-"-ansi -O2"} 128 CFLAGS=${CFLAGS-"-ansi -O2"}
133 LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"};; 129 LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
134 OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} 130 OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
135 CFLAGS=${CFLAGS-"-O -std1"} 131 CFLAGS=${CFLAGS-"-O -std1"}
136 LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; 132 LDFLAGS="${LDFLAGS} -Wl,-rpath,."
133 LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;;
137 OSF1*) SFLAGS=${CFLAGS-"-O -std1"} 134 OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
138 CFLAGS=${CFLAGS-"-O -std1"} 135 CFLAGS=${CFLAGS-"-O -std1"}
139 LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"};; 136 LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
140 QNX*) SFLAGS=${CFLAGS-"-4 -O"} 137 QNX*) SFLAGS=${CFLAGS-"-4 -O"}
141 CFLAGS=${CFLAGS-"-4 -O"} 138 CFLAGS=${CFLAGS-"-4 -O"}
142 LDSHARED=${LDSHARED-"cc"} 139 LDSHARED=${LDSHARED-"cc"}
143 RANLIB=${RANLIB-"true"} 140 RANLIB=${RANLIB-"true"}
144 AR_RC="cc -A";; 141 AR_RC="cc -A" ;;
145 SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} 142 SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
146 CFLAGS=${CFLAGS-"-O3"} 143 CFLAGS=${CFLAGS-"-O3"}
147 LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; 144 LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
148 SunOS\ 5*) LDSHARED=${LDSHARED-"cc -G"} 145 SunOS\ 5*) LDSHARED=${LDSHARED-"cc -G"}
149 case `(uname -m || echo unknown) 2>/dev/null` in 146 case `(uname -m || echo unknown) 2>/dev/null` in
150 i86*) 147 i86*)
151 SFLAGS=${CFLAGS-"-xpentium -fast -KPIC -R."} 148 SFLAGS=${CFLAGS-"-xpentium -fast -KPIC -R."}
152 CFLAGS=${CFLAGS-"-xpentium -fast"};; 149 CFLAGS=${CFLAGS-"-xpentium -fast"} ;;
153 *) 150 *)
154 SFLAGS=${CFLAGS-"-fast -xcg92 -KPIC -R."} 151 SFLAGS=${CFLAGS-"-fast -xcg92 -KPIC -R."}
155 CFLAGS=${CFLAGS-"-fast -xcg92"};; 152 CFLAGS=${CFLAGS-"-fast -xcg92"} ;;
156 esac;; 153 esac ;;
157 SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} 154 SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
158 CFLAGS=${CFLAGS-"-O2"} 155 CFLAGS=${CFLAGS-"-O2"}
159 LDSHARED=${LDSHARED-"ld"};; 156 LDSHARED=${LDSHARED-"ld"} ;;
160 SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} 157 SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
161 CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"} 158 CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"}
162 LDSHARED=${LDSHARED-"cc -xarch=v9b"};; 159 LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;;
163 UNIX_System_V\ 4.2.0) 160 UNIX_System_V\ 4.2.0)
164 SFLAGS=${CFLAGS-"-KPIC -O"} 161 SFLAGS=${CFLAGS-"-KPIC -O"}
165 CFLAGS=${CFLAGS-"-O"} 162 CFLAGS=${CFLAGS-"-O"}
166 LDSHARED=${LDSHARED-"cc -G"};; 163 LDSHARED=${LDSHARED-"cc -G"} ;;
167 UNIX_SV\ 4.2MP) 164 UNIX_SV\ 4.2MP)
168 SFLAGS=${CFLAGS-"-Kconform_pic -O"} 165 SFLAGS=${CFLAGS-"-Kconform_pic -O"}
169 CFLAGS=${CFLAGS-"-O"} 166 CFLAGS=${CFLAGS-"-O"}
170 LDSHARED=${LDSHARED-"cc -G"};; 167 LDSHARED=${LDSHARED-"cc -G"} ;;
171 OpenUNIX\ 5) 168 OpenUNIX\ 5)
172 SFLAGS=${CFLAGS-"-KPIC -O"} 169 SFLAGS=${CFLAGS-"-KPIC -O"}
173 CFLAGS=${CFLAGS-"-O"} 170 CFLAGS=${CFLAGS-"-O"}
174 LDSHARED=${LDSHARED-"cc -G"};; 171 LDSHARED=${LDSHARED-"cc -G"} ;;
175 AIX*) # Courtesy of dbakker@arrayasolutions.com 172 AIX*) # Courtesy of dbakker@arrayasolutions.com
176 SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} 173 SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
177 CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} 174 CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
178 LDSHARED=${LDSHARED-"xlc -G"};; 175 LDSHARED=${LDSHARED-"xlc -G"} ;;
179 # send working options for other systems to support@gzip.org 176 # send working options for other systems to support@gzip.org
180 *) SFLAGS=${CFLAGS-"-O"} 177 *) SFLAGS=${CFLAGS-"-O"}
181 CFLAGS=${CFLAGS-"-O"} 178 CFLAGS=${CFLAGS-"-O"}
182 LDSHARED=${LDSHARED-"cc -shared"};; 179 LDSHARED=${LDSHARED-"cc -shared"} ;;
183 esac 180 esac
184fi 181fi
185 182
@@ -190,16 +187,15 @@ SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
190if test $shared -eq 1; then 187if test $shared -eq 1; then
191 echo Checking for shared library support... 188 echo Checking for shared library support...
192 # we must test in two steps (cc then ld), required at least on SunOS 4.x 189 # we must test in two steps (cc then ld), required at least on SunOS 4.x
193 if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && 190 if test "`($CC -w -c $SFLAGS $test.c) 2>&1`" = "" &&
194 test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then 191 test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
195 LIBS="$LIBS $SHAREDLIBV"
196 echo Building shared library $SHAREDLIBV with $CC. 192 echo Building shared library $SHAREDLIBV with $CC.
197 elif test -z "$old_cc" -a -z "$old_cflags"; then 193 elif test -z "$old_cc" -a -z "$old_cflags"; then
198 echo No shared library support. 194 echo No shared library support.
199 shared=0; 195 shared=0;
200 else 196 else
201 echo Tested $CC -c $SFLAGS $test.c 197 echo Tested $CC -w -c $SFLAGS $test.c
202 $CC -c $SFLAGS $test.c 198 $CC -w -c $SFLAGS $test.c
203 echo Tested $LDSHARED -o $test$shared_ext $test.o 199 echo Tested $LDSHARED -o $test$shared_ext $test.o
204 $LDSHARED -o $test$shared_ext $test.o 200 $LDSHARED -o $test$shared_ext $test.o
205 echo 'No shared library support; try without defining CC and CFLAGS' 201 echo 'No shared library support; try without defining CC and CFLAGS'
@@ -208,12 +204,12 @@ if test $shared -eq 1; then
208fi 204fi
209if test $shared -eq 0; then 205if test $shared -eq 0; then
210 LDSHARED="$CC" 206 LDSHARED="$CC"
211 ALL="allstatic" 207 ALL="static"
212 TEST="teststatic" 208 TEST="all teststatic"
213 echo Building static library $LIBS version $VER with $CC. 209 echo Building static library $STATICLIB version $VER with $CC.
214else 210else
215 ALL="allstatic allshared" 211 ALL="static shared"
216 TEST="teststatic testshared" 212 TEST="all teststatic testshared"
217fi 213fi
218 214
219cat > zlibdefs.h << EOF 215cat > zlibdefs.h << EOF
@@ -231,6 +227,8 @@ EOF
231if test "`($CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c) 2>&1`" = ""; then 227if test "`($CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c) 2>&1`" = ""; then
232 CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" 228 CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
233 SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" 229 SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
230 ALL="${ALL} all64"
231 TEST="${TEST} test64"
234 echo "Checking for off64_t... Yes." 232 echo "Checking for off64_t... Yes."
235 echo "Checking for fseeko... Yes." 233 echo "Checking for fseeko... Yes."
236else 234else
@@ -345,6 +343,7 @@ EOF
345 echo "Checking for return value of vsnprintf()... Yes." 343 echo "Checking for return value of vsnprintf()... Yes."
346 else 344 else
347 CFLAGS="$CFLAGS -DHAS_vsnprintf_void" 345 CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
346 SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
348 echo "Checking for return value of vsnprintf()... No." 347 echo "Checking for return value of vsnprintf()... No."
349 echo " WARNING: apparently vsnprintf() does not return a value. zlib" 348 echo " WARNING: apparently vsnprintf() does not return a value. zlib"
350 echo " can build but will be open to possible string-format security" 349 echo " can build but will be open to possible string-format security"
@@ -352,6 +351,7 @@ EOF
352 fi 351 fi
353 else 352 else
354 CFLAGS="$CFLAGS -DNO_vsnprintf" 353 CFLAGS="$CFLAGS -DNO_vsnprintf"
354 SFLAGS="$SFLAGS -DNO_vsnprintf"
355 echo "Checking for vsnprintf() in stdio.h... No." 355 echo "Checking for vsnprintf() in stdio.h... No."
356 echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" 356 echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
357 echo " can build but will be open to possible buffer-overflow security" 357 echo " can build but will be open to possible buffer-overflow security"
@@ -383,6 +383,7 @@ EOF
383 echo "Checking for return value of vsprintf()... Yes." 383 echo "Checking for return value of vsprintf()... Yes."
384 else 384 else
385 CFLAGS="$CFLAGS -DHAS_vsprintf_void" 385 CFLAGS="$CFLAGS -DHAS_vsprintf_void"
386 SFLAGS="$SFLAGS -DHAS_vsprintf_void"
386 echo "Checking for return value of vsprintf()... No." 387 echo "Checking for return value of vsprintf()... No."
387 echo " WARNING: apparently vsprintf() does not return a value. zlib" 388 echo " WARNING: apparently vsprintf() does not return a value. zlib"
388 echo " can build but will be open to possible string-format security" 389 echo " can build but will be open to possible string-format security"
@@ -432,6 +433,7 @@ EOF
432 echo "Checking for return value of snprintf()... Yes." 433 echo "Checking for return value of snprintf()... Yes."
433 else 434 else
434 CFLAGS="$CFLAGS -DHAS_snprintf_void" 435 CFLAGS="$CFLAGS -DHAS_snprintf_void"
436 SFLAGS="$SFLAGS -DHAS_snprintf_void"
435 echo "Checking for return value of snprintf()... No." 437 echo "Checking for return value of snprintf()... No."
436 echo " WARNING: apparently snprintf() does not return a value. zlib" 438 echo " WARNING: apparently snprintf() does not return a value. zlib"
437 echo " can build but will be open to possible string-format security" 439 echo " can build but will be open to possible string-format security"
@@ -439,6 +441,7 @@ EOF
439 fi 441 fi
440 else 442 else
441 CFLAGS="$CFLAGS -DNO_snprintf" 443 CFLAGS="$CFLAGS -DNO_snprintf"
444 SFLAGS="$SFLAGS -DNO_snprintf"
442 echo "Checking for snprintf() in stdio.h... No." 445 echo "Checking for snprintf() in stdio.h... No."
443 echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" 446 echo " WARNING: snprintf() not found, falling back to sprintf(). zlib"
444 echo " can build but will be open to possible buffer-overflow security" 447 echo " can build but will be open to possible buffer-overflow security"
@@ -464,6 +467,7 @@ EOF
464 echo "Checking for return value of sprintf()... Yes." 467 echo "Checking for return value of sprintf()... Yes."
465 else 468 else
466 CFLAGS="$CFLAGS -DHAS_sprintf_void" 469 CFLAGS="$CFLAGS -DHAS_sprintf_void"
470 SFLAGS="$SFLAGS -DHAS_sprintf_void"
467 echo "Checking for return value of sprintf()... No." 471 echo "Checking for return value of sprintf()... No."
468 echo " WARNING: apparently sprintf() does not return a value. zlib" 472 echo " WARNING: apparently sprintf() does not return a value. zlib"
469 echo " can build but will be open to possible string-format security" 473 echo " can build but will be open to possible string-format security"
@@ -481,6 +485,7 @@ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
481else 485else
482 echo "Checking for errno.h... No." 486 echo "Checking for errno.h... No."
483 CFLAGS="$CFLAGS -DNO_ERRNO_H" 487 CFLAGS="$CFLAGS -DNO_ERRNO_H"
488 SFLAGS="$SFLAGS -DNO_ERRNO_H"
484fi 489fi
485 490
486cat > $test.c <<EOF 491cat > $test.c <<EOF
@@ -493,6 +498,7 @@ caddr_t hello() {
493EOF 498EOF
494if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then 499if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
495 CFLAGS="$CFLAGS -DUSE_MMAP" 500 CFLAGS="$CFLAGS -DUSE_MMAP"
501 SFLAGS="$SFLAGS -DUSE_MMAP"
496 echo Checking for mmap support... Yes. 502 echo Checking for mmap support... Yes.
497else 503else
498 echo Checking for mmap support... No. 504 echo Checking for mmap support... No.
@@ -506,7 +512,7 @@ case $CFLAGS in
506 echo Checking for underline in external names... No. 512 echo Checking for underline in external names... No.
507 else 513 else
508 echo Checking for underline in external names... Yes. 514 echo Checking for underline in external names... Yes.
509 fi;; 515 fi ;;
510esac 516esac
511 517
512rm -f $test.[co] $test $test$shared_ext 518rm -f $test.[co] $test $test$shared_ext
@@ -519,7 +525,7 @@ sed < Makefile.in "
519/^LDFLAGS *=/s#=.*#=$LDFLAGS# 525/^LDFLAGS *=/s#=.*#=$LDFLAGS#
520/^LDSHARED *=/s#=.*#=$LDSHARED# 526/^LDSHARED *=/s#=.*#=$LDSHARED#
521/^CPP *=/s#=.*#=$CPP# 527/^CPP *=/s#=.*#=$CPP#
522/^LIBS *=/s#=.*#=$LIBS# 528/^STATICLIB *=/s#=.*#=$STATICLIB#
523/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# 529/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
524/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# 530/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
525/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# 531/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
@@ -540,7 +546,7 @@ sed < zlib.pc.in "
540/^CFLAGS *=/s#=.*#=$CFLAGS# 546/^CFLAGS *=/s#=.*#=$CFLAGS#
541/^CPP *=/s#=.*#=$CPP# 547/^CPP *=/s#=.*#=$CPP#
542/^LDSHARED *=/s#=.*#=$LDSHARED# 548/^LDSHARED *=/s#=.*#=$LDSHARED#
543/^LIBS *=/s#=.*#=$LIBS# 549/^STATICLIB *=/s#=.*#=$STATICLIB#
544/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# 550/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
545/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# 551/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
546/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# 552/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
diff --git a/contrib/README.contrib b/contrib/README.contrib
index 20afc62..f9c1665 100644
--- a/contrib/README.contrib
+++ b/contrib/README.contrib
@@ -8,6 +8,10 @@ ada/ by Dmitriy Anisimkov <anisimkov@yahoo.com>
8 Support for Ada 8 Support for Ada
9 See http://zlib-ada.sourceforge.net/ 9 See http://zlib-ada.sourceforge.net/
10 10
11amd64/ by Mikhail Teterin <mi@ALDAN.algebra.com>
12 asm code for AMD64
13 See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
14
11asm586/ 15asm586/
12asm686/ by Brian Raiter <breadbox@muppetlabs.com> 16asm686/ by Brian Raiter <breadbox@muppetlabs.com>
13 asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax 17 asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
diff --git a/contrib/amd64/amd64-match.S b/contrib/amd64/amd64-match.S
new file mode 100644
index 0000000..b3bf1ac
--- /dev/null
+++ b/contrib/amd64/amd64-match.S
@@ -0,0 +1,357 @@
1/*
2 * match.S -- optimized version of longest_match()
3 * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998
4 *
5 * This is free software; you can redistribute it and/or modify it
6 * under the terms of the BSD License. Use by owners of Che Guevarra
7 * parafernalia is prohibited, where possible, and highly discouraged
8 * elsewhere.
9 */
10
11#ifndef NO_UNDERLINE
12# define match_init _match_init
13# define longest_match _longest_match
14#endif
15
16#define scanend ebx
17#define scanendw bx
18#define chainlenwmask edx /* high word: current chain len low word: s->wmask */
19#define curmatch rsi
20#define curmatchd esi
21#define windowbestlen r8
22#define scanalign r9
23#define scanalignd r9d
24#define window r10
25#define bestlen r11
26#define bestlend r11d
27#define scanstart r12d
28#define scanstartw r12w
29#define scan r13
30#define nicematch r14d
31#define limit r15
32#define limitd r15d
33#define prev rcx
34
35/*
36 * The 258 is a "magic number, not a parameter -- changing it
37 * breaks the hell loose
38 */
39#define MAX_MATCH (258)
40#define MIN_MATCH (3)
41#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
42#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
43
44/* stack frame offsets */
45#define LocalVarsSize (112)
46#define _chainlenwmask ( 8-LocalVarsSize)(%rsp)
47#define _windowbestlen (16-LocalVarsSize)(%rsp)
48#define save_r14 (24-LocalVarsSize)(%rsp)
49#define save_rsi (32-LocalVarsSize)(%rsp)
50#define save_rbx (40-LocalVarsSize)(%rsp)
51#define save_r12 (56-LocalVarsSize)(%rsp)
52#define save_r13 (64-LocalVarsSize)(%rsp)
53#define save_r15 (80-LocalVarsSize)(%rsp)
54
55/*
56 * On AMD64 the first argument of a function (in our case -- the pointer to
57 * deflate_state structure) is passed in %rdi, hence our offsets below are
58 * all off of that.
59 */
60#ifndef STRUCT_OFFSET
61# define STRUCT_OFFSET (0)
62#endif
63#define dsWSize ( 56 + STRUCT_OFFSET)(%rdi)
64#define dsWMask ( 64 + STRUCT_OFFSET)(%rdi)
65#define dsWindow ( 72 + STRUCT_OFFSET)(%rdi)
66#define dsPrev ( 88 + STRUCT_OFFSET)(%rdi)
67#define dsMatchLen (136 + STRUCT_OFFSET)(%rdi)
68#define dsPrevMatch (140 + STRUCT_OFFSET)(%rdi)
69#define dsStrStart (148 + STRUCT_OFFSET)(%rdi)
70#define dsMatchStart (152 + STRUCT_OFFSET)(%rdi)
71#define dsLookahead (156 + STRUCT_OFFSET)(%rdi)
72#define dsPrevLen (160 + STRUCT_OFFSET)(%rdi)
73#define dsMaxChainLen (164 + STRUCT_OFFSET)(%rdi)
74#define dsGoodMatch (180 + STRUCT_OFFSET)(%rdi)
75#define dsNiceMatch (184 + STRUCT_OFFSET)(%rdi)
76
77.globl match_init, longest_match
78
79.text
80
81/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
82
83longest_match:
84/*
85 * Retrieve the function arguments. %curmatch will hold cur_match
86 * throughout the entire function (passed via rsi on amd64).
87 * rdi will hold the pointer to the deflate_state (first arg on amd64)
88 */
89 mov %rsi, save_rsi
90 mov %rbx, save_rbx
91 mov %r12, save_r12
92 mov %r13, save_r13
93 mov %r14, save_r14
94 mov %r15, save_r15
95
96/* uInt wmask = s->w_mask; */
97/* unsigned chain_length = s->max_chain_length; */
98/* if (s->prev_length >= s->good_match) { */
99/* chain_length >>= 2; */
100/* } */
101
102 movl dsPrevLen, %eax
103 movl dsGoodMatch, %ebx
104 cmpl %ebx, %eax
105 movl dsWMask, %eax
106 movl dsMaxChainLen, %chainlenwmask
107 jl LastMatchGood
108 shrl $2, %chainlenwmask
109LastMatchGood:
110
111/* chainlen is decremented once beforehand so that the function can */
112/* use the sign flag instead of the zero flag for the exit test. */
113/* It is then shifted into the high word, to make room for the wmask */
114/* value, which it will always accompany. */
115
116 decl %chainlenwmask
117 shll $16, %chainlenwmask
118 orl %eax, %chainlenwmask
119
120/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
121
122 movl dsNiceMatch, %eax
123 movl dsLookahead, %ebx
124 cmpl %eax, %ebx
125 jl LookaheadLess
126 movl %eax, %ebx
127LookaheadLess: movl %ebx, %nicematch
128
129/* register Bytef *scan = s->window + s->strstart; */
130
131 mov dsWindow, %window
132 movl dsStrStart, %limitd
133 lea (%limit, %window), %scan
134
135/* Determine how many bytes the scan ptr is off from being */
136/* dword-aligned. */
137
138 mov %scan, %scanalign
139 negl %scanalignd
140 andl $3, %scanalignd
141
142/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
143/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
144
145 movl dsWSize, %eax
146 subl $MIN_LOOKAHEAD, %eax
147 xorl %ecx, %ecx
148 subl %eax, %limitd
149 cmovng %ecx, %limitd
150
151/* int best_len = s->prev_length; */
152
153 movl dsPrevLen, %bestlend
154
155/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory. */
156
157 lea (%window, %bestlen), %windowbestlen
158 mov %windowbestlen, _windowbestlen
159
160/* register ush scan_start = *(ushf*)scan; */
161/* register ush scan_end = *(ushf*)(scan+best_len-1); */
162/* Posf *prev = s->prev; */
163
164 movzwl (%scan), %scanstart
165 movzwl -1(%scan, %bestlen), %scanend
166 mov dsPrev, %prev
167
168/* Jump into the main loop. */
169
170 movl %chainlenwmask, _chainlenwmask
171 jmp LoopEntry
172
173.balign 16
174
175/* do {
176 * match = s->window + cur_match;
177 * if (*(ushf*)(match+best_len-1) != scan_end ||
178 * *(ushf*)match != scan_start) continue;
179 * [...]
180 * } while ((cur_match = prev[cur_match & wmask]) > limit
181 * && --chain_length != 0);
182 *
183 * Here is the inner loop of the function. The function will spend the
184 * majority of its time in this loop, and majority of that time will
185 * be spent in the first ten instructions.
186 */
187LookupLoop:
188 andl %chainlenwmask, %curmatchd
189 movzwl (%prev, %curmatch, 2), %curmatchd
190 cmpl %limitd, %curmatchd
191 jbe LeaveNow
192 subl $0x00010000, %chainlenwmask
193 js LeaveNow
194LoopEntry: cmpw -1(%windowbestlen, %curmatch), %scanendw
195 jne LookupLoop
196 cmpw %scanstartw, (%window, %curmatch)
197 jne LookupLoop
198
199/* Store the current value of chainlen. */
200 movl %chainlenwmask, _chainlenwmask
201
202/* %scan is the string under scrutiny, and %prev to the string we */
203/* are hoping to match it up with. In actuality, %esi and %edi are */
204/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
205/* initialized to -(MAX_MATCH_8 - scanalign). */
206
207 mov $(-MAX_MATCH_8), %rdx
208 lea (%curmatch, %window), %windowbestlen
209 lea MAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen
210 lea MAX_MATCH_8(%scan, %scanalign), %prev
211
212/* the prefetching below makes very little difference... */
213 prefetcht1 (%windowbestlen, %rdx)
214 prefetcht1 (%prev, %rdx)
215
216/*
217 * Test the strings for equality, 8 bytes at a time. At the end,
218 * adjust %rdx so that it is offset to the exact byte that mismatched.
219 *
220 * It should be confessed that this loop usually does not represent
221 * much of the total running time. Replacing it with a more
222 * straightforward "rep cmpsb" would not drastically degrade
223 * performance -- unrolling it, for example, makes no difference.
224 */
225#undef USE_SSE /* works, but is 6-7% slower, than non-SSE... */
226LoopCmps:
227#ifdef USE_SSE
228 /* Preload the SSE registers */
229 movdqu (%windowbestlen, %rdx), %xmm1
230 movdqu (%prev, %rdx), %xmm2
231 pcmpeqb %xmm2, %xmm1
232 movdqu 16(%windowbestlen, %rdx), %xmm3
233 movdqu 16(%prev, %rdx), %xmm4
234 pcmpeqb %xmm4, %xmm3
235 movdqu 32(%windowbestlen, %rdx), %xmm5
236 movdqu 32(%prev, %rdx), %xmm6
237 pcmpeqb %xmm6, %xmm5
238 movdqu 48(%windowbestlen, %rdx), %xmm7
239 movdqu 48(%prev, %rdx), %xmm8
240 pcmpeqb %xmm8, %xmm7
241
242 /* Check the comparisions' results */
243 pmovmskb %xmm1, %rax
244 notw %ax
245 bsfw %ax, %ax
246 jnz LeaveLoopCmps
247 add $16, %rdx
248 pmovmskb %xmm3, %rax
249 notw %ax
250 bsfw %ax, %ax
251 jnz LeaveLoopCmps
252 add $16, %rdx
253 pmovmskb %xmm5, %rax
254 notw %ax
255 bsfw %ax, %ax
256 jnz LeaveLoopCmps
257 add $16, %rdx
258 pmovmskb %xmm7, %rax
259 notw %ax
260 bsfw %ax, %ax
261 jnz LeaveLoopCmps
262 add $16, %rdx
263 jmp LoopCmps
264LeaveLoopCmps: add %rax, %rdx
265#else
266 mov (%windowbestlen, %rdx), %rax
267 xor (%prev, %rdx), %rax
268 jnz LeaveLoopCmps
269 add $8, %rdx
270 jnz LoopCmps
271 jmp LenMaximum
272# if 0
273/*
274 * This three-liner is tantalizingly simple, but bsf is a slow instruction,
275 * and the complicated alternative down below is quite a bit faster. Sad...
276 */
277LeaveLoopCmps: bsf %rax, %rax /* find the first non-zero bit */
278 shrl $3, %eax /* divide by 8 to get the byte */
279 add %rax, %rdx
280# else
281LeaveLoopCmps: testl $0xFFFFFFFF, %eax /* Check the first 4 bytes */
282 jnz Check16
283 add $4, %rdx
284 shr $32, %rax
285Check16: testw $0xFFFF, %ax
286 jnz LenLower
287 add $2, %rdx
288 shrl $16, %eax
289LenLower: subb $1, %al
290 adc $0, %rdx
291# endif
292#endif
293
294/* Calculate the length of the match. If it is longer than MAX_MATCH, */
295/* then automatically accept it as the best possible match and leave. */
296
297 lea (%prev, %rdx), %rax
298 sub %scan, %rax
299 cmpl $MAX_MATCH, %eax
300 jge LenMaximum
301
302/* If the length of the match is not longer than the best match we */
303/* have so far, then forget it and return to the lookup loop. */
304
305 cmpl %bestlend, %eax
306 jg LongerMatch
307 mov _windowbestlen, %windowbestlen
308 mov dsPrev, %prev
309 movl _chainlenwmask, %edx
310 jmp LookupLoop
311
312/* s->match_start = cur_match; */
313/* best_len = len; */
314/* if (len >= nice_match) break; */
315/* scan_end = *(ushf*)(scan+best_len-1); */
316
317LongerMatch:
318 movl %eax, %bestlend
319 movl %curmatchd, dsMatchStart
320 cmpl %nicematch, %eax
321 jge LeaveNow
322
323 lea (%window, %bestlen), %windowbestlen
324 mov %windowbestlen, _windowbestlen
325
326 movzwl -1(%scan, %rax), %scanend
327 mov dsPrev, %prev
328 movl _chainlenwmask, %chainlenwmask
329 jmp LookupLoop
330
331/* Accept the current string, with the maximum possible length. */
332
333LenMaximum:
334 movl $MAX_MATCH, %bestlend
335 movl %curmatchd, dsMatchStart
336
337/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
338/* return s->lookahead; */
339
340LeaveNow:
341 movl dsLookahead, %eax
342 cmpl %eax, %bestlend
343 cmovngl %bestlend, %eax
344LookaheadRet:
345
346/* Restore the registers and return from whence we came. */
347
348 mov save_rsi, %rsi
349 mov save_rbx, %rbx
350 mov save_r12, %r12
351 mov save_r13, %r13
352 mov save_r14, %r14
353 mov save_r15, %r15
354
355 ret
356
357match_init: ret
diff --git a/contrib/infback9/infback9.c b/contrib/infback9/infback9.c
index c5547ae..7bbe90c 100644
--- a/contrib/infback9/infback9.c
+++ b/contrib/infback9/infback9.c
@@ -1,5 +1,5 @@
1/* infback9.c -- inflate deflate64 data using a call-back interface 1/* infback9.c -- inflate deflate64 data using a call-back interface
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2008 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -433,7 +433,16 @@ void FAR *out_desc;
433 /* handle error breaks in while */ 433 /* handle error breaks in while */
434 if (mode == BAD) break; 434 if (mode == BAD) break;
435 435
436 /* build code tables */ 436 /* check for end-of-block code (better have one) */
437 if (state->lens[256] == 0) {
438 strm->msg = (char *)"invalid code -- missing end-of-block";
439 mode = BAD;
440 break;
441 }
442
443 /* build code tables -- note: do not change the lenbits or distbits
444 values here (9 and 6) without reading the comments in inftree9.h
445 concerning the ENOUGH constants, which depend on those values */
437 state->next = state->codes; 446 state->next = state->codes;
438 lencode = (code const FAR *)(state->next); 447 lencode = (code const FAR *)(state->next);
439 lenbits = 9; 448 lenbits = 9;
diff --git a/contrib/infback9/inftree9.c b/contrib/infback9/inftree9.c
index c24302b..18353cb 100644
--- a/contrib/infback9/inftree9.c
+++ b/contrib/infback9/inftree9.c
@@ -1,5 +1,5 @@
1/* inftree9.c -- generate Huffman trees for efficient decoding 1/* inftree9.c -- generate Huffman trees for efficient decoding
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2008 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -9,7 +9,7 @@
9#define MAXBITS 15 9#define MAXBITS 15
10 10
11const char inflate9_copyright[] = 11const char inflate9_copyright[] =
12 " inflate9 1.2.3.3 Copyright 1995-2006 Mark Adler "; 12 " inflate9 1.2.3.4 Copyright 1995-2008 Mark Adler ";
13/* 13/*
14 If you use the zlib library in a product, an acknowledgment is welcome 14 If you use the zlib library in a product, an acknowledgment is welcome
15 in the documentation of your product. If for some reason you cannot 15 in the documentation of your product. If for some reason you cannot
@@ -64,7 +64,7 @@ unsigned short FAR *work;
64 static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 64 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
65 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 65 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
66 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, 66 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
67 133, 133, 133, 133, 144, 201, 203}; 67 133, 133, 133, 133, 144, 72, 200};
68 static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ 68 static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
69 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 69 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
70 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 70 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
@@ -160,11 +160,10 @@ unsigned short FAR *work;
160 entered in the tables. 160 entered in the tables.
161 161
162 used keeps track of how many table entries have been allocated from the 162 used keeps track of how many table entries have been allocated from the
163 provided *table space. It is checked when a LENS table is being made 163 provided *table space. It is checked for LENS and DIST tables against
164 against the space in *table, ENOUGH, minus the maximum space needed by 164 the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
165 the worst case distance code, MAXD. This should never happen, but the 165 the initial root table size constants. See the comments in inftree9.h
166 sufficiency of ENOUGH has not been proven exhaustively, hence the check. 166 for more information.
167 This assumes that when type == LENS, bits == 9.
168 167
169 sym increments through all symbols, and the loop terminates when 168 sym increments through all symbols, and the loop terminates when
170 all codes of length max, i.e. all codes, have been processed. This 169 all codes of length max, i.e. all codes, have been processed. This
@@ -203,7 +202,8 @@ unsigned short FAR *work;
203 mask = used - 1; /* mask for comparing low */ 202 mask = used - 1; /* mask for comparing low */
204 203
205 /* check available table space */ 204 /* check available table space */
206 if (type == LENS && used >= ENOUGH - MAXD) 205 if ((type == LENS && used >= ENOUGH_LENS) ||
206 (type == DISTS && used >= ENOUGH_DISTS))
207 return 1; 207 return 1;
208 208
209 /* process all codes and make table entries */ 209 /* process all codes and make table entries */
@@ -270,7 +270,8 @@ unsigned short FAR *work;
270 270
271 /* check for enough space */ 271 /* check for enough space */
272 used += 1U << curr; 272 used += 1U << curr;
273 if (type == LENS && used >= ENOUGH - MAXD) 273 if ((type == LENS && used >= ENOUGH_LENS) ||
274 (type == DISTS && used >= ENOUGH_DISTS))
274 return 1; 275 return 1;
275 276
276 /* point entry in root table to sub-table */ 277 /* point entry in root table to sub-table */
diff --git a/contrib/infback9/inftree9.h b/contrib/infback9/inftree9.h
index a268084..5ab21f0 100644
--- a/contrib/infback9/inftree9.h
+++ b/contrib/infback9/inftree9.h
@@ -1,5 +1,5 @@
1/* inftree9.h -- header to use inftree9.c 1/* inftree9.h -- header to use inftree9.c
2 * Copyright (C) 1995-2003 Mark Adler 2 * Copyright (C) 1995-2008 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -35,15 +35,21 @@ typedef struct {
35 01000000 - invalid code 35 01000000 - invalid code
36 */ 36 */
37 37
38/* Maximum size of dynamic tree. The maximum found in a long but non- 38/* Maximum size of the dynamic table. The maximum number of code structures is
39 exhaustive search was 1444 code structures (852 for length/literals 39 1446, which is the sum of 852 for literal/length codes and 594 for distance
40 and 592 for distances, the latter actually the result of an 40 codes. These values were found by exhaustive searches using the program
41 exhaustive search). The true maximum is not known, but the value 41 examples/enough.c found in the zlib distribtution. The arguments to that
42 below is more than safe. */ 42 program are the number of symbols, the initial root table size, and the
43#define ENOUGH 2048 43 maximum bit length of a code. "enough 286 9 15" for literal/length codes
44#define MAXD 592 44 returns returns 852, and "enough 32 6 15" for distance codes returns 594.
45 The initial root table size (9 or 6) is found in the fifth argument of the
46 inflate_table() calls in infback9.c. If the root table size is changed,
47 then these maximum sizes would be need to be recalculated and updated. */
48#define ENOUGH_LENS 852
49#define ENOUGH_DISTS 594
50#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
45 51
46/* Type of code to build for inftable() */ 52/* Type of code to build for inflate_table9() */
47typedef enum { 53typedef enum {
48 CODES, 54 CODES,
49 LENS, 55 LENS,
diff --git a/contrib/nintendods/Makefile b/contrib/nintendods/Makefile
new file mode 100644
index 0000000..21337d0
--- /dev/null
+++ b/contrib/nintendods/Makefile
@@ -0,0 +1,126 @@
1#---------------------------------------------------------------------------------
2.SUFFIXES:
3#---------------------------------------------------------------------------------
4
5ifeq ($(strip $(DEVKITARM)),)
6$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
7endif
8
9include $(DEVKITARM)/ds_rules
10
11#---------------------------------------------------------------------------------
12# TARGET is the name of the output
13# BUILD is the directory where object files & intermediate files will be placed
14# SOURCES is a list of directories containing source code
15# DATA is a list of directories containing data files
16# INCLUDES is a list of directories containing header files
17#---------------------------------------------------------------------------------
18TARGET := $(shell basename $(CURDIR))
19BUILD := build
20SOURCES := ../../
21DATA := data
22INCLUDES := include
23
24#---------------------------------------------------------------------------------
25# options for code generation
26#---------------------------------------------------------------------------------
27ARCH := -mthumb -mthumb-interwork
28
29CFLAGS := -Wall -O2\
30 -march=armv5te -mtune=arm946e-s \
31 -fomit-frame-pointer -ffast-math \
32 $(ARCH)
33
34CFLAGS += $(INCLUDE) -DARM9
35CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
36
37ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s
38LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
39
40#---------------------------------------------------------------------------------
41# list of directories containing libraries, this must be the top level containing
42# include and lib
43#---------------------------------------------------------------------------------
44LIBDIRS := $(LIBNDS)
45
46#---------------------------------------------------------------------------------
47# no real need to edit anything past this point unless you need to add additional
48# rules for different file extensions
49#---------------------------------------------------------------------------------
50ifneq ($(BUILD),$(notdir $(CURDIR)))
51#---------------------------------------------------------------------------------
52
53export OUTPUT := $(CURDIR)/lib/libz.a
54
55export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
56 $(foreach dir,$(DATA),$(CURDIR)/$(dir))
57
58export DEPSDIR := $(CURDIR)/$(BUILD)
59
60CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
61CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
62SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
63BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
64
65#---------------------------------------------------------------------------------
66# use CXX for linking C++ projects, CC for standard C
67#---------------------------------------------------------------------------------
68ifeq ($(strip $(CPPFILES)),)
69#---------------------------------------------------------------------------------
70 export LD := $(CC)
71#---------------------------------------------------------------------------------
72else
73#---------------------------------------------------------------------------------
74 export LD := $(CXX)
75#---------------------------------------------------------------------------------
76endif
77#---------------------------------------------------------------------------------
78
79export OFILES := $(addsuffix .o,$(BINFILES)) \
80 $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
81
82export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
83 $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
84 -I$(CURDIR)/$(BUILD)
85
86.PHONY: $(BUILD) clean all
87
88#---------------------------------------------------------------------------------
89all: $(BUILD)
90 @[ -d $@ ] || mkdir -p include
91 @cp ../../*.h include
92
93lib:
94 @[ -d $@ ] || mkdir -p $@
95
96$(BUILD): lib
97 @[ -d $@ ] || mkdir -p $@
98 @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
99
100#---------------------------------------------------------------------------------
101clean:
102 @echo clean ...
103 @rm -fr $(BUILD) lib
104
105#---------------------------------------------------------------------------------
106else
107
108DEPENDS := $(OFILES:.o=.d)
109
110#---------------------------------------------------------------------------------
111# main targets
112#---------------------------------------------------------------------------------
113$(OUTPUT) : $(OFILES)
114
115#---------------------------------------------------------------------------------
116%.bin.o : %.bin
117#---------------------------------------------------------------------------------
118 @echo $(notdir $<)
119 @$(bin2o)
120
121
122-include $(DEPENDS)
123
124#---------------------------------------------------------------------------------------
125endif
126#---------------------------------------------------------------------------------------
diff --git a/contrib/nintendods/README b/contrib/nintendods/README
new file mode 100644
index 0000000..ba7a37d
--- /dev/null
+++ b/contrib/nintendods/README
@@ -0,0 +1,5 @@
1This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template.
2
3Eduardo Costa <eduardo.m.costa@gmail.com>
4January 3, 2009
5
diff --git a/contrib/puff/puff b/contrib/puff/puff
new file mode 100755
index 0000000..bedac26
--- /dev/null
+++ b/contrib/puff/puff
Binary files differ
diff --git a/contrib/puff/puff.c b/contrib/puff/puff.c
index ce0cc40..df5b79f 100644
--- a/contrib/puff/puff.c
+++ b/contrib/puff/puff.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * puff.c 2 * puff.c
3 * Copyright (C) 2002-2004 Mark Adler 3 * Copyright (C) 2002-2008 Mark Adler
4 * For conditions of distribution and use, see copyright notice in puff.h 4 * For conditions of distribution and use, see copyright notice in puff.h
5 * version 1.8, 9 Jan 2004 5 * version 2.0, 25 Jul 2008
6 * 6 *
7 * puff.c is a simple inflate written to be an unambiguous way to specify the 7 * puff.c is a simple inflate written to be an unambiguous way to specify the
8 * deflate format. It is not written for speed but rather simplicity. As a 8 * deflate format. It is not written for speed but rather simplicity. As a
@@ -61,6 +61,12 @@
61 * 1.7 3 Mar 2003 - Added test code for distribution 61 * 1.7 3 Mar 2003 - Added test code for distribution
62 * - Added zlib-like license 62 * - Added zlib-like license
63 * 1.8 9 Jan 2004 - Added some comments on no distance codes case 63 * 1.8 9 Jan 2004 - Added some comments on no distance codes case
64 * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland]
65 * - Catch missing end-of-block symbol error
66 * 2.0 25 Jul 2008 - Add #define to permit distance too far back
67 * - Add option in TEST code for puff to write the data
68 * - Add option in TEST code to skip input bytes
69 * - Allow TEST code to read from piped stdin
64 */ 70 */
65 71
66#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ 72#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
@@ -194,7 +200,7 @@ struct huffman {
194 * Decode a code from the stream s using huffman table h. Return the symbol or 200 * Decode a code from the stream s using huffman table h. Return the symbol or
195 * a negative value if there is an error. If all of the lengths are zero, i.e. 201 * a negative value if there is an error. If all of the lengths are zero, i.e.
196 * an empty code, or if the code is incomplete and an invalid code is received, 202 * an empty code, or if the code is incomplete and an invalid code is received,
197 * then -9 is returned after reading MAXBITS bits. 203 * then -10 is returned after reading MAXBITS bits.
198 * 204 *
199 * Format notes: 205 * Format notes:
200 * 206 *
@@ -226,14 +232,14 @@ local int decode(struct state *s, struct huffman *h)
226 for (len = 1; len <= MAXBITS; len++) { 232 for (len = 1; len <= MAXBITS; len++) {
227 code |= bits(s, 1); /* get next bit */ 233 code |= bits(s, 1); /* get next bit */
228 count = h->count[len]; 234 count = h->count[len];
229 if (code < first + count) /* if length len, return symbol */ 235 if (code - count < first) /* if length len, return symbol */
230 return h->symbol[index + (code - first)]; 236 return h->symbol[index + (code - first)];
231 index += count; /* else update for next length */ 237 index += count; /* else update for next length */
232 first += count; 238 first += count;
233 first <<= 1; 239 first <<= 1;
234 code <<= 1; 240 code <<= 1;
235 } 241 }
236 return -9; /* ran out of codes */ 242 return -10; /* ran out of codes */
237} 243}
238 244
239/* 245/*
@@ -263,7 +269,7 @@ local int decode(struct state *s, struct huffman *h)
263 code |= bitbuf & 1; 269 code |= bitbuf & 1;
264 bitbuf >>= 1; 270 bitbuf >>= 1;
265 count = *next++; 271 count = *next++;
266 if (code < first + count) { /* if length len, return symbol */ 272 if (code - count < first) { /* if length len, return symbol */
267 s->bitbuf = bitbuf; 273 s->bitbuf = bitbuf;
268 s->bitcnt = (s->bitcnt - len) & 7; 274 s->bitcnt = (s->bitcnt - len) & 7;
269 return h->symbol[index + (code - first)]; 275 return h->symbol[index + (code - first)];
@@ -280,7 +286,7 @@ local int decode(struct state *s, struct huffman *h)
280 bitbuf = s->in[s->incnt++]; 286 bitbuf = s->in[s->incnt++];
281 if (left > 8) left = 8; 287 if (left > 8) left = 8;
282 } 288 }
283 return -9; /* ran out of codes */ 289 return -10; /* ran out of codes */
284} 290}
285#endif /* SLOW */ 291#endif /* SLOW */
286 292
@@ -448,21 +454,27 @@ local int codes(struct state *s,
448 else if (symbol > 256) { /* length */ 454 else if (symbol > 256) { /* length */
449 /* get and compute length */ 455 /* get and compute length */
450 symbol -= 257; 456 symbol -= 257;
451 if (symbol >= 29) return -9; /* invalid fixed code */ 457 if (symbol >= 29) return -10; /* invalid fixed code */
452 len = lens[symbol] + bits(s, lext[symbol]); 458 len = lens[symbol] + bits(s, lext[symbol]);
453 459
454 /* get and check distance */ 460 /* get and check distance */
455 symbol = decode(s, distcode); 461 symbol = decode(s, distcode);
456 if (symbol < 0) return symbol; /* invalid symbol */ 462 if (symbol < 0) return symbol; /* invalid symbol */
457 dist = dists[symbol] + bits(s, dext[symbol]); 463 dist = dists[symbol] + bits(s, dext[symbol]);
464#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
458 if (dist > s->outcnt) 465 if (dist > s->outcnt)
459 return -10; /* distance too far back */ 466 return -11; /* distance too far back */
467#endif
460 468
461 /* copy length bytes from distance bytes back */ 469 /* copy length bytes from distance bytes back */
462 if (s->out != NIL) { 470 if (s->out != NIL) {
463 if (s->outcnt + len > s->outlen) return 1; 471 if (s->outcnt + len > s->outlen) return 1;
464 while (len--) { 472 while (len--) {
465 s->out[s->outcnt] = s->out[s->outcnt - dist]; 473 s->out[s->outcnt] =
474#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
475 dist > s->outcnt ? 0 :
476#endif
477 s->out[s->outcnt - dist];
466 s->outcnt++; 478 s->outcnt++;
467 } 479 }
468 } 480 }
@@ -680,6 +692,10 @@ local int dynamic(struct state *s)
680 } 692 }
681 } 693 }
682 694
695 /* check for end-of-block code -- there better be one! */
696 if (lengths[256] == 0)
697 return -9;
698
683 /* build huffman table for literal/length codes */ 699 /* build huffman table for literal/length codes */
684 err = construct(&lencode, lengths, nlen); 700 err = construct(&lencode, lengths, nlen);
685 if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1)) 701 if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
@@ -724,8 +740,9 @@ local int dynamic(struct state *s)
724 * -6: dynamic block code description: repeat more than specified lengths 740 * -6: dynamic block code description: repeat more than specified lengths
725 * -7: dynamic block code description: invalid literal/length code lengths 741 * -7: dynamic block code description: invalid literal/length code lengths
726 * -8: dynamic block code description: invalid distance code lengths 742 * -8: dynamic block code description: invalid distance code lengths
727 * -9: invalid literal/length or distance code in fixed or dynamic block 743 * -9: dynamic block code description: missing end-of-block code
728 * -10: distance is too far back in fixed or dynamic block 744 * -10: invalid literal/length or distance code in fixed or dynamic block
745 * -11: distance is too far back in fixed or dynamic block
729 * 746 *
730 * Format notes: 747 * Format notes:
731 * 748 *
@@ -783,54 +800,142 @@ int puff(unsigned char *dest, /* pointer to destination pointer */
783} 800}
784 801
785#ifdef TEST 802#ifdef TEST
786/* Example of how to use puff() */ 803/* Examples of how to use puff().
804
805 Usage: puff [-w] [-nnn] file
806 ... | puff [-w] [-nnn]
807
808 where file is the input file with deflate data, nnn is the number of bytes
809 of input to skip before inflating (e.g. to skip a zlib or gzip header), and
810 -w is used to write the decompressed data to stdout */
811
787#include <stdio.h> 812#include <stdio.h>
788#include <stdlib.h> 813#include <stdlib.h>
789#include <sys/types.h>
790#include <sys/stat.h>
791 814
792local unsigned char *yank(char *name, unsigned long *len) 815/* Return size times approximately the cube root of 2, keeping the result as 1,
816 3, or 5 times a power of 2 -- the result is always > size, until the result
817 is the maximum value of an unsigned long, where it remains. This is useful
818 to keep reallocations less than ~33% over the actual data. */
819local size_t bythirds(size_t size)
793{ 820{
794 unsigned long size; 821 int n;
795 unsigned char *buf; 822 size_t m;
823
824 m = size;
825 for (n = 0; m; n++)
826 m >>= 1;
827 if (n < 3)
828 return size + 1;
829 n -= 3;
830 m = size >> n;
831 m += m == 6 ? 2 : 1;
832 m <<= n;
833 return m > size ? m : (size_t)(-1);
834}
835
836/* Read the input file *name, or stdin if name is NULL, into allocated memory.
837 Reallocate to larger buffers until the entire file is read in. Return a
838 pointer to the allocated data, or NULL if there was a memory allocation
839 failure. *len is the number of bytes of data read from the input file (even
840 if load() returns NULL). If the input file was empty or could not be opened
841 or read, *len is zero. */
842local void *load(char *name, size_t *len)
843{
844 size_t size;
845 void *buf, *swap;
796 FILE *in; 846 FILE *in;
797 struct stat s;
798 847
799 *len = 0; 848 *len = 0;
800 if (stat(name, &s)) return NULL; 849 buf = malloc(size = 4096);
801 if ((s.st_mode & S_IFMT) != S_IFREG) return NULL; 850 if (buf == NULL)
802 size = (unsigned long)(s.st_size); 851 return NULL;
803 if (size == 0 || (off_t)size != s.st_size) return NULL; 852 in = name == NULL ? stdin : fopen(name, "rb");
804 in = fopen(name, "r"); 853 if (in != NULL) {
805 if (in == NULL) return NULL; 854 for (;;) {
806 buf = malloc(size); 855 *len += fread((char *)buf + *len, 1, size - *len, in);
807 if (buf != NULL && fread(buf, 1, size, in) != size) { 856 if (*len < size) break;
808 free(buf); 857 size = bythirds(size);
809 buf = NULL; 858 if (size == *len || (swap = realloc(buf, size)) == NULL) {
859 free(buf);
860 buf = NULL;
861 break;
862 }
863 buf = swap;
864 }
865 fclose(in);
810 } 866 }
811 fclose(in);
812 *len = size;
813 return buf; 867 return buf;
814} 868}
815 869
816int main(int argc, char **argv) 870int main(int argc, char **argv)
817{ 871{
818 int ret; 872 int ret, skip = 0, put = 0;
819 unsigned char *source; 873 char *arg, *name = NULL;
820 unsigned long len, sourcelen, destlen; 874 unsigned char *source = NULL, *dest;
821 875 size_t len = 0;
822 if (argc < 2) return 2; 876 unsigned long sourcelen, destlen;
823 source = yank(argv[1], &len); 877
824 if (source == NULL) return 2; 878 /* process arguments */
825 sourcelen = len; 879 while (arg = *++argv, --argc)
826 ret = puff(NIL, &destlen, source, &sourcelen); 880 if (arg[0] == '-') {
881 if (arg[1] == 'w' && arg[2] == 0)
882 put = 1;
883 else if (arg[1] >= '0' && arg[1] <= '9')
884 skip = atoi(arg + 1);
885 else {
886 fprintf(stderr, "invalid option %s\n", arg);
887 return 3;
888 }
889 }
890 else if (name != NULL) {
891 fprintf(stderr, "only one file name allowed\n");
892 return 3;
893 }
894 else
895 name = arg;
896 source = load(name, &len);
897 if (source == NULL) {
898 fprintf(stderr, "memory allocation failure\n");
899 return 4;
900 }
901 if (len == 0) {
902 fprintf(stderr, "could not read %s, or it was empty\n",
903 name == NULL ? "<stdin>" : name);
904 free(source);
905 return 3;
906 }
907 if (skip >= len) {
908 fprintf(stderr, "skip request of %d leaves no input\n", skip);
909 free(source);
910 return 3;
911 }
912
913 /* test inflate data with offset skip */
914 len -= skip;
915 sourcelen = (unsigned long)len;
916 ret = puff(NIL, &destlen, source + skip, &sourcelen);
827 if (ret) 917 if (ret)
828 printf("puff() failed with return code %d\n", ret); 918 fprintf(stderr, "puff() failed with return code %d\n", ret);
829 else { 919 else {
830 printf("puff() succeeded uncompressing %lu bytes\n", destlen); 920 fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
831 if (sourcelen < len) printf("%lu compressed bytes unused\n", 921 if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
832 len - sourcelen); 922 len - sourcelen);
833 } 923 }
924
925 /* if requested, inflate again and write decompressd data to stdout */
926 if (put) {
927 dest = malloc(destlen);
928 if (dest == NULL) {
929 fprintf(stderr, "memory allocation failure\n");
930 free(source);
931 return 4;
932 }
933 puff(dest, &destlen, source + skip, &sourcelen);
934 fwrite(dest, 1, destlen, stdout);
935 free(dest);
936 }
937
938 /* clean up */
834 free(source); 939 free(source);
835 return ret; 940 return ret;
836} 941}
diff --git a/contrib/puff/puff.h b/contrib/puff/puff.h
index ef61252..8d7f5f8 100644
--- a/contrib/puff/puff.h
+++ b/contrib/puff/puff.h
@@ -1,6 +1,6 @@
1/* puff.h 1/* puff.h
2 Copyright (C) 2002, 2003 Mark Adler, all rights reserved 2 Copyright (C) 2002-2008 Mark Adler, all rights reserved
3 version 1.7, 3 Mar 2002 3 version 1.9, 10 Jan 2008
4 4
5 This software is provided 'as-is', without any express or implied 5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the author be held liable for any damages 6 warranty. In no event will the author be held liable for any damages
diff --git a/contrib/vstudio/vc7/zlib.rc b/contrib/vstudio/vc7/zlib.rc
index 39eca7e..98ca20b 100644
--- a/contrib/vstudio/vc7/zlib.rc
+++ b/contrib/vstudio/vc7/zlib.rc
@@ -2,8 +2,8 @@
2 2
3#define IDR_VERSION1 1 3#define IDR_VERSION1 1
4IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE 4IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
5 FILEVERSION 1,2,3,3 5 FILEVERSION 1,2,3,4
6 PRODUCTVERSION 1,2,3,3 6 PRODUCTVERSION 1,2,3,4
7 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 7 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
8 FILEFLAGS 0 8 FILEFLAGS 0
9 FILEOS VOS_DOS_WINDOWS32 9 FILEOS VOS_DOS_WINDOWS32
@@ -17,7 +17,7 @@ BEGIN
17 17
18 BEGIN 18 BEGIN
19 VALUE "FileDescription", "zlib data compression library\0" 19 VALUE "FileDescription", "zlib data compression library\0"
20 VALUE "FileVersion", "1.2.3.3\0" 20 VALUE "FileVersion", "1.2.3.4\0"
21 VALUE "InternalName", "zlib\0" 21 VALUE "InternalName", "zlib\0"
22 VALUE "OriginalFilename", "zlib.dll\0" 22 VALUE "OriginalFilename", "zlib.dll\0"
23 VALUE "ProductName", "ZLib.DLL\0" 23 VALUE "ProductName", "ZLib.DLL\0"
diff --git a/crc32.c b/crc32.c
index b34a510..1acc7ed 100644
--- a/crc32.c
+++ b/crc32.c
@@ -53,7 +53,7 @@
53 53
54/* Definitions for doing the crc four data bytes at a time. */ 54/* Definitions for doing the crc four data bytes at a time. */
55#ifdef BYFOUR 55#ifdef BYFOUR
56# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ 56# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
57 (((w)&0xff00)<<8)+(((w)&0xff)<<24)) 57 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
58 local unsigned long crc32_little OF((unsigned long, 58 local unsigned long crc32_little OF((unsigned long,
59 const unsigned char FAR *, unsigned)); 59 const unsigned char FAR *, unsigned));
@@ -68,11 +68,7 @@
68local unsigned long gf2_matrix_times OF((unsigned long *mat, 68local unsigned long gf2_matrix_times OF((unsigned long *mat,
69 unsigned long vec)); 69 unsigned long vec));
70local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); 70local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
71#ifdef _LARGEFILE64_SOURCE 71local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
72 local uLong crc32_combine_(uLong crc1, uLong crc2, off64_t len2);
73#else
74 local uLong crc32_combine_(uLong crc1, uLong crc2, z_off_t len2);
75#endif
76 72
77 73
78#ifdef DYNAMIC_CRC_TABLE 74#ifdef DYNAMIC_CRC_TABLE
@@ -376,23 +372,19 @@ local void gf2_matrix_square(square, mat)
376local uLong crc32_combine_(crc1, crc2, len2) 372local uLong crc32_combine_(crc1, crc2, len2)
377 uLong crc1; 373 uLong crc1;
378 uLong crc2; 374 uLong crc2;
379#ifdef _LARGEFILE64_SOURCE 375 z_off64_t len2;
380 off64_t len2;
381#else
382 z_off_t len2;
383#endif
384{ 376{
385 int n; 377 int n;
386 unsigned long row; 378 unsigned long row;
387 unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ 379 unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
388 unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ 380 unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
389 381
390 /* degenerate case */ 382 /* degenerate case (also disallow negative lengths) */
391 if (len2 == 0) 383 if (len2 <= 0)
392 return crc1; 384 return crc1;
393 385
394 /* put operator for one zero bit in odd */ 386 /* put operator for one zero bit in odd */
395 odd[0] = 0xedb88320L; /* CRC-32 polynomial */ 387 odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
396 row = 1; 388 row = 1;
397 for (n = 1; n < GF2_DIM; n++) { 389 for (n = 1; n < GF2_DIM; n++) {
398 odd[n] = row; 390 odd[n] = row;
@@ -441,20 +433,10 @@ uLong ZEXPORT crc32_combine(crc1, crc2, len2)
441 return crc32_combine_(crc1, crc2, len2); 433 return crc32_combine_(crc1, crc2, len2);
442} 434}
443 435
444#ifdef _LARGEFILE64_SOURCE
445uLong ZEXPORT crc32_combine64(crc1, crc2, len2) 436uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
446 uLong crc1; 437 uLong crc1;
447 uLong crc2; 438 uLong crc2;
448 off64_t len2; 439 z_off64_t len2;
449{
450 return crc32_combine_(crc1, crc2, len2);
451}
452#else
453uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
454 uLong crc1;
455 uLong crc2;
456 z_off_t len2;
457{ 440{
458 return crc32_combine_(crc1, crc2, len2); 441 return crc32_combine_(crc1, crc2, len2);
459} 442}
460#endif
diff --git a/deflate.c b/deflate.c
index fc41b80..db01adf 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1,5 +1,5 @@
1/* deflate.c -- compress data using the deflation algorithm 1/* deflate.c -- compress data using the deflation algorithm
2 * Copyright (C) 1995-2006 Jean-loup Gailly. 2 * Copyright (C) 1995-2009 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -52,7 +52,7 @@
52#include "deflate.h" 52#include "deflate.h"
53 53
54const char deflate_copyright[] = 54const char deflate_copyright[] =
55 " deflate 1.2.3.3 Copyright 1995-2006 Jean-loup Gailly "; 55 " deflate 1.2.3.4 Copyright 1995-2009 Jean-loup Gailly ";
56/* 56/*
57 If you use the zlib library in a product, an acknowledgment is welcome 57 If you use the zlib library in a product, an acknowledgment is welcome
58 in the documentation of your product. If for some reason you cannot 58 in the documentation of your product. If for some reason you cannot
@@ -110,11 +110,6 @@ local void check_match OF((deflate_state *s, IPos start, IPos match,
110#endif 110#endif
111/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ 111/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
112 112
113#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
114/* Minimum amount of lookahead, except at the end of the input file.
115 * See deflate.c for comments about the MIN_MATCH+1.
116 */
117
118/* Values for max_lazy_match, good_match and max_chain_length, depending on 113/* Values for max_lazy_match, good_match and max_chain_length, depending on
119 * the desired pack level (0..9). The values given below have been tuned to 114 * the desired pack level (0..9). The values given below have been tuned to
120 * exclude worst case performance for pathological files. Better values may be 115 * exclude worst case performance for pathological files. Better values may be
@@ -288,6 +283,8 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
288 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); 283 s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
289 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); 284 s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
290 285
286 s->high_water = 0; /* nothing written to s->window yet */
287
291 s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ 288 s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
292 289
293 overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); 290 overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
@@ -332,8 +329,8 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
332 strm->adler = adler32(strm->adler, dictionary, dictLength); 329 strm->adler = adler32(strm->adler, dictionary, dictLength);
333 330
334 if (length < MIN_MATCH) return Z_OK; 331 if (length < MIN_MATCH) return Z_OK;
335 if (length > MAX_DIST(s)) { 332 if (length > s->w_size) {
336 length = MAX_DIST(s); 333 length = s->w_size;
337 dictionary += dictLength - length; /* use the tail of the dictionary */ 334 dictionary += dictLength - length; /* use the tail of the dictionary */
338 } 335 }
339 zmemcpy(s->window, dictionary, length); 336 zmemcpy(s->window, dictionary, length);
@@ -513,16 +510,16 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
513 break; 510 break;
514 case 2: /* gzip wrapper */ 511 case 2: /* gzip wrapper */
515 wraplen = 18; 512 wraplen = 18;
516 if (s->gzhead != NULL) { /* user-supplied gzip header */ 513 if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
517 if (s->gzhead->extra != NULL) 514 if (s->gzhead->extra != Z_NULL)
518 wraplen += 2 + s->gzhead->extra_len; 515 wraplen += 2 + s->gzhead->extra_len;
519 str = s->gzhead->name; 516 str = s->gzhead->name;
520 if (str != NULL) 517 if (str != Z_NULL)
521 do { 518 do {
522 wraplen++; 519 wraplen++;
523 } while (*str++); 520 } while (*str++);
524 str = s->gzhead->comment; 521 str = s->gzhead->comment;
525 if (str != NULL) 522 if (str != Z_NULL)
526 do { 523 do {
527 wraplen++; 524 wraplen++;
528 } while (*str++); 525 } while (*str++);
@@ -589,7 +586,7 @@ int ZEXPORT deflate (strm, flush)
589 deflate_state *s; 586 deflate_state *s;
590 587
591 if (strm == Z_NULL || strm->state == Z_NULL || 588 if (strm == Z_NULL || strm->state == Z_NULL ||
592 flush > Z_FINISH || flush < 0) { 589 flush > Z_BLOCK || flush < 0) {
593 return Z_STREAM_ERROR; 590 return Z_STREAM_ERROR;
594 } 591 }
595 s = strm->state; 592 s = strm->state;
@@ -613,7 +610,7 @@ int ZEXPORT deflate (strm, flush)
613 put_byte(s, 31); 610 put_byte(s, 31);
614 put_byte(s, 139); 611 put_byte(s, 139);
615 put_byte(s, 8); 612 put_byte(s, 8);
616 if (s->gzhead == NULL) { 613 if (s->gzhead == Z_NULL) {
617 put_byte(s, 0); 614 put_byte(s, 0);
618 put_byte(s, 0); 615 put_byte(s, 0);
619 put_byte(s, 0); 616 put_byte(s, 0);
@@ -640,7 +637,7 @@ int ZEXPORT deflate (strm, flush)
640 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 637 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
641 4 : 0)); 638 4 : 0));
642 put_byte(s, s->gzhead->os & 0xff); 639 put_byte(s, s->gzhead->os & 0xff);
643 if (s->gzhead->extra != NULL) { 640 if (s->gzhead->extra != Z_NULL) {
644 put_byte(s, s->gzhead->extra_len & 0xff); 641 put_byte(s, s->gzhead->extra_len & 0xff);
645 put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); 642 put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
646 } 643 }
@@ -682,7 +679,7 @@ int ZEXPORT deflate (strm, flush)
682 } 679 }
683#ifdef GZIP 680#ifdef GZIP
684 if (s->status == EXTRA_STATE) { 681 if (s->status == EXTRA_STATE) {
685 if (s->gzhead->extra != NULL) { 682 if (s->gzhead->extra != Z_NULL) {
686 uInt beg = s->pending; /* start of bytes to update crc */ 683 uInt beg = s->pending; /* start of bytes to update crc */
687 684
688 while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { 685 while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
@@ -710,7 +707,7 @@ int ZEXPORT deflate (strm, flush)
710 s->status = NAME_STATE; 707 s->status = NAME_STATE;
711 } 708 }
712 if (s->status == NAME_STATE) { 709 if (s->status == NAME_STATE) {
713 if (s->gzhead->name != NULL) { 710 if (s->gzhead->name != Z_NULL) {
714 uInt beg = s->pending; /* start of bytes to update crc */ 711 uInt beg = s->pending; /* start of bytes to update crc */
715 int val; 712 int val;
716 713
@@ -741,7 +738,7 @@ int ZEXPORT deflate (strm, flush)
741 s->status = COMMENT_STATE; 738 s->status = COMMENT_STATE;
742 } 739 }
743 if (s->status == COMMENT_STATE) { 740 if (s->status == COMMENT_STATE) {
744 if (s->gzhead->comment != NULL) { 741 if (s->gzhead->comment != Z_NULL) {
745 uInt beg = s->pending; /* start of bytes to update crc */ 742 uInt beg = s->pending; /* start of bytes to update crc */
746 int val; 743 int val;
747 744
@@ -840,13 +837,17 @@ int ZEXPORT deflate (strm, flush)
840 if (bstate == block_done) { 837 if (bstate == block_done) {
841 if (flush == Z_PARTIAL_FLUSH) { 838 if (flush == Z_PARTIAL_FLUSH) {
842 _tr_align(s); 839 _tr_align(s);
843 } else { /* FULL_FLUSH or SYNC_FLUSH */ 840 } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
844 _tr_stored_block(s, (char*)0, 0L, 0); 841 _tr_stored_block(s, (char*)0, 0L, 0);
845 /* For a full flush, this empty block will be recognized 842 /* For a full flush, this empty block will be recognized
846 * as a special marker by inflate_sync(). 843 * as a special marker by inflate_sync().
847 */ 844 */
848 if (flush == Z_FULL_FLUSH) { 845 if (flush == Z_FULL_FLUSH) {
849 CLEAR_HASH(s); /* forget history */ 846 CLEAR_HASH(s); /* forget history */
847 if (s->lookahead == 0) {
848 s->strstart = 0;
849 s->block_start = 0L;
850 }
850 } 851 }
851 } 852 }
852 flush_pending(strm); 853 flush_pending(strm);
@@ -1387,6 +1388,40 @@ local void fill_window(s)
1387 */ 1388 */
1388 1389
1389 } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); 1390 } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
1391
1392 /* If the WIN_INIT bytes after the end of the current data have never been
1393 * written, then zero those bytes in order to avoid memory check reports of
1394 * the use of uninitialized (or uninitialised as Julian writes) bytes by
1395 * the longest match routines. Update the high water mark for the next
1396 * time through here. WIN_INIT is set to MAX_MATCH since the longest match
1397 * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
1398 */
1399 if (s->high_water < s->window_size) {
1400 ulg curr = s->strstart + (ulg)(s->lookahead);
1401 ulg init;
1402
1403 if (s->high_water < curr) {
1404 /* Previous high water mark below current data -- zero WIN_INIT
1405 * bytes or up to end of window, whichever is less.
1406 */
1407 init = s->window_size - curr;
1408 if (init > WIN_INIT)
1409 init = WIN_INIT;
1410 zmemzero(s->window + curr, (unsigned)init);
1411 s->high_water = curr + init;
1412 }
1413 else if (s->high_water < (ulg)curr + WIN_INIT) {
1414 /* High water mark at or above current data, but below current data
1415 * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
1416 * to end of window, whichever is less.
1417 */
1418 init = (ulg)curr + WIN_INIT - s->high_water;
1419 if (init > s->window_size - s->high_water)
1420 init = s->window_size - s->high_water;
1421 zmemzero(s->window + s->high_water, (unsigned)init);
1422 s->high_water += init;
1423 }
1424 }
1390} 1425}
1391 1426
1392/* =========================================================================== 1427/* ===========================================================================
diff --git a/deflate.h b/deflate.h
index 90077d8..f1df04c 100644
--- a/deflate.h
+++ b/deflate.h
@@ -1,5 +1,5 @@
1/* deflate.h -- internal compression state 1/* deflate.h -- internal compression state
2 * Copyright (C) 1995-2005 Jean-loup Gailly 2 * Copyright (C) 1995-2009 Jean-loup Gailly
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -260,6 +260,13 @@ typedef struct internal_state {
260 * are always zero. 260 * are always zero.
261 */ 261 */
262 262
263 ulg high_water;
264 /* High water mark offset in window for initialized bytes -- bytes above
265 * this are set to zero in order to avoid memory check warnings when
266 * longest match routines access bytes past the input. This is then
267 * updated to the new high water mark.
268 */
269
263} FAR deflate_state; 270} FAR deflate_state;
264 271
265/* Output a byte on the stream. 272/* Output a byte on the stream.
@@ -278,6 +285,10 @@ typedef struct internal_state {
278 * distances are limited to MAX_DIST instead of WSIZE. 285 * distances are limited to MAX_DIST instead of WSIZE.
279 */ 286 */
280 287
288#define WIN_INIT MAX_MATCH
289/* Number of bytes after end of data in window to initialize in order to avoid
290 memory checker errors from longest match routines */
291
281 /* in trees.c */ 292 /* in trees.c */
282void _tr_init OF((deflate_state *s)); 293void _tr_init OF((deflate_state *s));
283int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); 294int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
diff --git a/doc/algorithm.txt b/doc/algorithm.txt
index b022dde..34960bd 100644
--- a/doc/algorithm.txt
+++ b/doc/algorithm.txt
@@ -121,7 +121,7 @@ At least for deflate's output that generates new trees every several 10's of
121kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code 121kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
122would take too long if you're only decoding several thousand symbols. At the 122would take too long if you're only decoding several thousand symbols. At the
123other extreme, you could make a new table for every bit in the code. In fact, 123other extreme, you could make a new table for every bit in the code. In fact,
124that's essentially a Huffman tree. But then you spend two much time 124that's essentially a Huffman tree. But then you spend too much time
125traversing the tree while decoding, even for short symbols. 125traversing the tree while decoding, even for short symbols.
126 126
127So the number of bits for the first lookup table is a trade of the time to 127So the number of bits for the first lookup table is a trade of the time to
diff --git a/examples/README.examples b/examples/README.examples
index 5632d7a..146919c 100644
--- a/examples/README.examples
+++ b/examples/README.examples
@@ -1,4 +1,10 @@
1This directory contains examples of the use of zlib. 1This directory contains examples of the use of zlib and other relevant
2programs and documentation.
3
4enough.c
5 calculation and justification of ENOUGH parameter in inftrees.h
6 - calculates the maximum table space used in inflate tree
7 construction over all possible Huffman codes
2 8
3fitblk.c 9fitblk.c
4 compress just enough input to nearly fill a requested output size 10 compress just enough input to nearly fill a requested output size
@@ -23,9 +29,16 @@ gzjoin.c
23 29
24gzlog.c 30gzlog.c
25gzlog.h 31gzlog.h
26 efficiently maintain a message log file in gzip format 32 efficiently and robustly maintain a message log file in gzip format
27 - illustrates use of raw deflate and Z_SYNC_FLUSH 33 - illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(),
28 - illustrates use of gzip header extra field 34 and deflateSetDictionary()
35 - illustrates use of a gzip header extra field
36
37pigz.c
38 parallel implementation of gzip compression
39 - uses pthreads to speed up compression on multiple core machines
40 - illustrates the use of deflateSetDictionary() with raw deflate
41 - illustrates the use of crc32_combine()
29 42
30zlib_how.html 43zlib_how.html
31 painfully comprehensive description of zpipe.c (see below) 44 painfully comprehensive description of zpipe.c (see below)
diff --git a/examples/enough.c b/examples/enough.c
new file mode 100644
index 0000000..b570707
--- /dev/null
+++ b/examples/enough.c
@@ -0,0 +1,569 @@
1/* enough.c -- determine the maximum size of inflate's Huffman code tables over
2 * all possible valid and complete Huffman codes, subject to a length limit.
3 * Copyright (C) 2007, 2008 Mark Adler
4 * Version 1.3 17 February 2008 Mark Adler
5 */
6
7/* Version history:
8 1.0 3 Jan 2007 First version (derived from codecount.c version 1.4)
9 1.1 4 Jan 2007 Use faster incremental table usage computation
10 Prune examine() search on previously visited states
11 1.2 5 Jan 2007 Comments clean up
12 As inflate does, decrease root for short codes
13 Refuse cases where inflate would increase root
14 1.3 17 Feb 2008 Add argument for initial root table size
15 Fix bug for initial root table size == max - 1
16 Use a macro to compute the history index
17 */
18
19/*
20 Examine all possible Huffman codes for a given number of symbols and a
21 maximum code length in bits to determine the maximum table size for zilb's
22 inflate. Only complete Huffman codes are counted.
23
24 Two codes are considered distinct if the vectors of the number of codes per
25 length are not identical. So permutations of the symbol assignments result
26 in the same code for the counting, as do permutations of the assignments of
27 the bit values to the codes (i.e. only canonical codes are counted).
28
29 We build a code from shorter to longer lengths, determining how many symbols
30 are coded at each length. At each step, we have how many symbols remain to
31 be coded, what the last code length used was, and how many bit patterns of
32 that length remain unused. Then we add one to the code length and double the
33 number of unused patterns to graduate to the next code length. We then
34 assign all portions of the remaining symbols to that code length that
35 preserve the properties of a correct and eventually complete code. Those
36 properties are: we cannot use more bit patterns than are available; and when
37 all the symbols are used, there are exactly zero possible bit patterns
38 remaining.
39
40 The inflate Huffman decoding algorithm uses two-level lookup tables for
41 speed. There is a single first-level table to decode codes up to root bits
42 in length (root == 9 in the current inflate implementation). The table
43 has 1 << root entries and is indexed by the next root bits of input. Codes
44 shorter than root bits have replicated table entries, so that the correct
45 entry is pointed to regardless of the bits that follow the short code. If
46 the code is longer than root bits, then the table entry points to a second-
47 level table. The size of that table is determined by the longest code with
48 that root-bit prefix. If that longest code has length len, then the table
49 has size 1 << (len - root), to index the remaining bits in that set of
50 codes. Each subsequent root-bit prefix then has its own sub-table. The
51 total number of table entries required by the code is calculated
52 incrementally as the number of codes at each bit length is populated. When
53 all of the codes are shorter than root bits, then root is reduced to the
54 longest code length, resulting in a single, smaller, one-level table.
55
56 The inflate algorithm also provides for small values of root (relative to
57 the log2 of the number of symbols), where the shortest code has more bits
58 than root. In that case, root is increased to the length of the shortest
59 code. This program, by design, does not handle that case, so it is verified
60 that the number of symbols is less than 2^(root + 1).
61
62 In order to speed up the examination (by about ten orders of magnitude for
63 the default arguments), the intermediate states in the build-up of a code
64 are remembered and previously visited branches are pruned. The memory
65 required for this will increase rapidly with the total number of symbols and
66 the maximum code length in bits. However this is a very small price to pay
67 for the vast speedup.
68
69 First, all of the possible Huffman codes are counted, and reachable
70 intermediate states are noted by a non-zero count in a saved-results array.
71 Second, the intermediate states that lead to (root + 1) bit or longer codes
72 are used to look at all sub-codes from those junctures for their inflate
73 memory usage. (The amount of memory used is not affected by the number of
74 codes of root bits or less in length.) Third, the visited states in the
75 construction of those sub-codes and the associated calculation of the table
76 size is recalled in order to avoid recalculating from the same juncture.
77 Beginning the code examination at (root + 1) bit codes, which is enabled by
78 identifying the reachable nodes, accounts for about six of the orders of
79 magnitude of improvement for the default arguments. About another four
80 orders of magnitude come from not revisiting previous states. Out of
81 approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes
82 need to be examined to cover all of the possible table memory usage cases
83 for the default arguments of 286 symbols limited to 15-bit codes.
84
85 Note that an unsigned long long type is used for counting. It is quite easy
86 to exceed the capacity of an eight-byte integer with a large number of
87 symbols and a large maximum code length, so multiple-precision arithmetic
88 would need to replace the unsigned long long arithmetic in that case. This
89 program will abort if an overflow occurs. The big_t type identifies where
90 the counting takes place.
91
92 An unsigned long long type is also used for calculating the number of
93 possible codes remaining at the maximum length. This limits the maximum
94 code length to the number of bits in a long long minus the number of bits
95 needed to represent the symbols in a flat code. The code_t type identifies
96 where the bit pattern counting takes place.
97 */
98
99#include <stdio.h>
100#include <stdlib.h>
101#include <string.h>
102#include <assert.h>
103
104#define local static
105
106/* special data types */
107typedef unsigned long long big_t; /* type for code counting */
108typedef unsigned long long code_t; /* type for bit pattern counting */
109struct tab { /* type for been here check */
110 size_t len; /* length of bit vector in char's */
111 char *vec; /* allocated bit vector */
112};
113
114/* The array for saving results, num[], is indexed with this triplet:
115
116 syms: number of symbols remaining to code
117 left: number of available bit patterns at length len
118 len: number of bits in the codes currently being assigned
119
120 Those indices are constrained thusly when saving results:
121
122 syms: 3..totsym (totsym == total symbols to code)
123 left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)
124 len: 1..max - 1 (max == maximum code length in bits)
125
126 syms == 2 is not saved since that immediately leads to a single code. left
127 must be even, since it represents the number of available bit patterns at
128 the current length, which is double the number at the previous length.
129 left ends at syms-1 since left == syms immediately results in a single code.
130 (left > sym is not allowed since that would result in an incomplete code.)
131 len is less than max, since the code completes immediately when len == max.
132
133 The offset into the array is calculated for the three indices with the
134 first one (syms) being outermost, and the last one (len) being innermost.
135 We build the array with length max-1 lists for the len index, with syms-3
136 of those for each symbol. There are totsym-2 of those, with each one
137 varying in length as a function of sym. See the calculation of index in
138 count() for the index, and the calculation of size in main() for the size
139 of the array.
140
141 For the deflate example of 286 symbols limited to 15-bit codes, the array
142 has 284,284 entries, taking up 2.17 MB for an 8-byte big_t. More than
143 half of the space allocated for saved results is actually used -- not all
144 possible triplets are reached in the generation of valid Huffman codes.
145 */
146
147/* The array for tracking visited states, done[], is itself indexed identically
148 to the num[] array as described above for the (syms, left, len) triplet.
149 Each element in the array is further indexed by the (mem, rem) doublet,
150 where mem is the amount of inflate table space used so far, and rem is the
151 remaining unused entries in the current inflate sub-table. Each indexed
152 element is simply one bit indicating whether the state has been visited or
153 not. Since the ranges for mem and rem are not known a priori, each bit
154 vector is of a variable size, and grows as needed to accommodate the visited
155 states. mem and rem are used to calculate a single index in a triangular
156 array. Since the range of mem is expected in the default case to be about
157 ten times larger than the range of rem, the array is skewed to reduce the
158 memory usage, with eight times the range for mem than for rem. See the
159 calculations for offset and bit in beenhere() for the details.
160
161 For the deflate example of 286 symbols limited to 15-bit codes, the bit
162 vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[]
163 array itself.
164 */
165
166/* Globals to avoid propagating constants or constant pointers recursively */
167local int max; /* maximum allowed bit length for the codes */
168local int root; /* size of base code table in bits */
169local int large; /* largest code table so far */
170local size_t size; /* number of elements in num and done */
171local int *code; /* number of symbols assigned to each bit length */
172local big_t *num; /* saved results array for code counting */
173local struct tab *done; /* states already evaluated array */
174
175/* Index function for num[] and done[] */
176#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1)
177
178/* Free allocated space. Uses globals code, num, and done. */
179local void cleanup(void)
180{
181 size_t n;
182
183 if (done != NULL) {
184 for (n = 0; n < size; n++)
185 if (done[n].len)
186 free(done[n].vec);
187 free(done);
188 }
189 if (num != NULL)
190 free(num);
191 if (code != NULL)
192 free(code);
193}
194
195/* Return the number of possible Huffman codes using bit patterns of lengths
196 len through max inclusive, coding syms symbols, with left bit patterns of
197 length len unused -- return -1 if there is an overflow in the counting.
198 Keep a record of previous results in num to prevent repeating the same
199 calculation. Uses the globals max and num. */
200local big_t count(int syms, int len, int left)
201{
202 big_t sum; /* number of possible codes from this juncture */
203 big_t got; /* value returned from count() */
204 int least; /* least number of syms to use at this juncture */
205 int most; /* most number of syms to use at this juncture */
206 int use; /* number of bit patterns to use in next call */
207 size_t index; /* index of this case in *num */
208
209 /* see if only one possible code */
210 if (syms == left)
211 return 1;
212
213 /* note and verify the expected state */
214 assert(syms > left && left > 0 && len < max);
215
216 /* see if we've done this one already */
217 index = INDEX(syms, left, len);
218 got = num[index];
219 if (got)
220 return got; /* we have -- return the saved result */
221
222 /* we need to use at least this many bit patterns so that the code won't be
223 incomplete at the next length (more bit patterns than symbols) */
224 least = (left << 1) - syms;
225 if (least < 0)
226 least = 0;
227
228 /* we can use at most this many bit patterns, lest there not be enough
229 available for the remaining symbols at the maximum length (if there were
230 no limit to the code length, this would become: most = left - 1) */
231 most = (((code_t)left << (max - len)) - syms) /
232 (((code_t)1 << (max - len)) - 1);
233
234 /* count all possible codes from this juncture and add them up */
235 sum = 0;
236 for (use = least; use <= most; use++) {
237 got = count(syms - use, len + 1, (left - use) << 1);
238 sum += got;
239 if (got == -1 || sum < got) /* overflow */
240 return -1;
241 }
242
243 /* verify that all recursive calls are productive */
244 assert(sum != 0);
245
246 /* save the result and return it */
247 num[index] = sum;
248 return sum;
249}
250
251/* Return true if we've been here before, set to true if not. Set a bit in a
252 bit vector to indicate visiting this state. Each (syms,len,left) state
253 has a variable size bit vector indexed by (mem,rem). The bit vector is
254 lengthened if needed to allow setting the (mem,rem) bit. */
255local int beenhere(int syms, int len, int left, int mem, int rem)
256{
257 size_t index; /* index for this state's bit vector */
258 size_t offset; /* offset in this state's bit vector */
259 int bit; /* mask for this state's bit */
260 size_t length; /* length of the bit vector in bytes */
261 char *vector; /* new or enlarged bit vector */
262
263 /* point to vector for (syms,left,len), bit in vector for (mem,rem) */
264 index = INDEX(syms, left, len);
265 mem -= 1 << root;
266 offset = (mem >> 3) + rem;
267 offset = ((offset * (offset + 1)) >> 1) + rem;
268 bit = 1 << (mem & 7);
269
270 /* see if we've been here */
271 length = done[index].len;
272 if (offset < length && (done[index].vec[offset] & bit) != 0)
273 return 1; /* done this! */
274
275 /* we haven't been here before -- set the bit to show we have now */
276
277 /* see if we need to lengthen the vector in order to set the bit */
278 if (length <= offset) {
279 /* if we have one already, enlarge it, zero out the appended space */
280 if (length) {
281 do {
282 length <<= 1;
283 } while (length <= offset);
284 vector = realloc(done[index].vec, length);
285 if (vector != NULL)
286 memset(vector + done[index].len, 0, length - done[index].len);
287 }
288
289 /* otherwise we need to make a new vector and zero it out */
290 else {
291 length = 1 << (len - root);
292 while (length <= offset)
293 length <<= 1;
294 vector = calloc(length, sizeof(char));
295 }
296
297 /* in either case, bail if we can't get the memory */
298 if (vector == NULL) {
299 fputs("abort: unable to allocate enough memory\n", stderr);
300 cleanup();
301 exit(1);
302 }
303
304 /* install the new vector */
305 done[index].len = length;
306 done[index].vec = vector;
307 }
308
309 /* set the bit */
310 done[index].vec[offset] |= bit;
311 return 0;
312}
313
314/* Examine all possible codes from the given node (syms, len, left). Compute
315 the amount of memory required to build inflate's decoding tables, where the
316 number of code structures used so far is mem, and the number remaining in
317 the current sub-table is rem. Uses the globals max, code, root, large, and
318 done. */
319local void examine(int syms, int len, int left, int mem, int rem)
320{
321 int least; /* least number of syms to use at this juncture */
322 int most; /* most number of syms to use at this juncture */
323 int use; /* number of bit patterns to use in next call */
324
325 /* see if we have a complete code */
326 if (syms == left) {
327 /* set the last code entry */
328 code[len] = left;
329
330 /* complete computation of memory used by this code */
331 while (rem < left) {
332 left -= rem;
333 rem = 1 << (len - root);
334 mem += rem;
335 }
336 assert(rem == left);
337
338 /* if this is a new maximum, show the entries used and the sub-code */
339 if (mem > large) {
340 large = mem;
341 printf("max %d: ", mem);
342 for (use = root + 1; use <= max; use++)
343 if (code[use])
344 printf("%d[%d] ", code[use], use);
345 putchar('\n');
346 fflush(stdout);
347 }
348
349 /* remove entries as we drop back down in the recursion */
350 code[len] = 0;
351 return;
352 }
353
354 /* prune the tree if we can */
355 if (beenhere(syms, len, left, mem, rem))
356 return;
357
358 /* we need to use at least this many bit patterns so that the code won't be
359 incomplete at the next length (more bit patterns than symbols) */
360 least = (left << 1) - syms;
361 if (least < 0)
362 least = 0;
363
364 /* we can use at most this many bit patterns, lest there not be enough
365 available for the remaining symbols at the maximum length (if there were
366 no limit to the code length, this would become: most = left - 1) */
367 most = (((code_t)left << (max - len)) - syms) /
368 (((code_t)1 << (max - len)) - 1);
369
370 /* occupy least table spaces, creating new sub-tables as needed */
371 use = least;
372 while (rem < use) {
373 use -= rem;
374 rem = 1 << (len - root);
375 mem += rem;
376 }
377 rem -= use;
378
379 /* examine codes from here, updating table space as we go */
380 for (use = least; use <= most; use++) {
381 code[len] = use;
382 examine(syms - use, len + 1, (left - use) << 1,
383 mem + (rem ? 1 << (len - root) : 0), rem << 1);
384 if (rem == 0) {
385 rem = 1 << (len - root);
386 mem += rem;
387 }
388 rem--;
389 }
390
391 /* remove entries as we drop back down in the recursion */
392 code[len] = 0;
393}
394
395/* Look at all sub-codes starting with root + 1 bits. Look at only the valid
396 intermediate code states (syms, left, len). For each completed code,
397 calculate the amount of memory required by inflate to build the decoding
398 tables. Find the maximum amount of memory required and show the code that
399 requires that maximum. Uses the globals max, root, and num. */
400local void enough(int syms)
401{
402 int n; /* number of remaing symbols for this node */
403 int left; /* number of unused bit patterns at this length */
404 size_t index; /* index of this case in *num */
405
406 /* clear code */
407 for (n = 0; n <= max; n++)
408 code[n] = 0;
409
410 /* look at all (root + 1) bit and longer codes */
411 large = 1 << root; /* base table */
412 if (root < max) /* otherwise, there's only a base table */
413 for (n = 3; n <= syms; n++)
414 for (left = 2; left < n; left += 2)
415 {
416 /* look at all reachable (root + 1) bit nodes, and the
417 resulting codes (complete at root + 2 or more) */
418 index = INDEX(n, left, root + 1);
419 if (root + 1 < max && num[index]) /* reachable node */
420 examine(n, root + 1, left, 1 << root, 0);
421
422 /* also look at root bit codes with completions at root + 1
423 bits (not saved in num, since complete), just in case */
424 if (num[index - 1] && n <= left << 1)
425 examine((n - left) << 1, root + 1, (n - left) << 1,
426 1 << root, 0);
427 }
428
429 /* done */
430 printf("done: maximum of %d table entries\n", large);
431}
432
433/*
434 Examine and show the total number of possible Huffman codes for a given
435 maximum number of symbols, initial root table size, and maximum code length
436 in bits -- those are the command arguments in that order. The default
437 values are 286, 9, and 15 respectively, for the deflate literal/length code.
438 The possible codes are counted for each number of coded symbols from two to
439 the maximum. The counts for each of those and the total number of codes are
440 shown. The maximum number of inflate table entires is then calculated
441 across all possible codes. Each new maximum number of table entries and the
442 associated sub-code (starting at root + 1 == 10 bits) is shown.
443
444 To count and examine Huffman codes that are not length-limited, provide a
445 maximum length equal to the number of symbols minus one.
446
447 For the deflate literal/length code, use "enough". For the deflate distance
448 code, use "enough 30 6".
449
450 This uses the %llu printf format to print big_t numbers, which assumes that
451 big_t is an unsigned long long. If the big_t type is changed (for example
452 to a multiple precision type), the method of printing will also need to be
453 updated.
454 */
455int main(int argc, char **argv)
456{
457 int syms; /* total number of symbols to code */
458 int n; /* number of symbols to code for this run */
459 big_t got; /* return value of count() */
460 big_t sum; /* accumulated number of codes over n */
461
462 /* set up globals for cleanup() */
463 code = NULL;
464 num = NULL;
465 done = NULL;
466
467 /* get arguments -- default to the deflate literal/length code */
468 syms = 286;
469 root = 9;
470 max = 15;
471 if (argc > 1) {
472 syms = atoi(argv[1]);
473 if (argc > 2) {
474 root = atoi(argv[2]);
475 if (argc > 3)
476 max = atoi(argv[3]);
477 }
478 }
479 if (argc > 4 || syms < 2 || root < 1 || max < 1) {
480 fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
481 stderr);
482 return 1;
483 }
484
485 /* if not restricting the code length, the longest is syms - 1 */
486 if (max > syms - 1)
487 max = syms - 1;
488
489 /* determine the number of bits in a code_t */
490 n = 0;
491 while (((code_t)1 << n) != 0)
492 n++;
493
494 /* make sure that the calculation of most will not overflow */
495 if (max > n || syms - 2 >= (((code_t)0 - 1) >> (max - 1))) {
496 fputs("abort: code length too long for internal types\n", stderr);
497 return 1;
498 }
499
500 /* reject impossible code requests */
501 if (syms - 1 > ((code_t)1 << max) - 1) {
502 fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
503 syms, max);
504 return 1;
505 }
506
507 /* allocate code vector */
508 code = calloc(max + 1, sizeof(int));
509 if (code == NULL) {
510 fputs("abort: unable to allocate enough memory\n", stderr);
511 return 1;
512 }
513
514 /* determine size of saved results array, checking for overflows,
515 allocate and clear the array (set all to zero with calloc()) */
516 if (syms == 2) /* iff max == 1 */
517 num = NULL; /* won't be saving any results */
518 else {
519 size = syms >> 1;
520 if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) ||
521 (size *= n, size > ((size_t)0 - 1) / (n = max - 1)) ||
522 (size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) ||
523 (num = calloc(size, sizeof(big_t))) == NULL) {
524 fputs("abort: unable to allocate enough memory\n", stderr);
525 cleanup();
526 return 1;
527 }
528 }
529
530 /* count possible codes for all numbers of symbols, add up counts */
531 sum = 0;
532 for (n = 2; n <= syms; n++) {
533 got = count(n, 1, 2);
534 sum += got;
535 if (got == -1 || sum < got) { /* overflow */
536 fputs("abort: can't count that high!\n", stderr);
537 cleanup();
538 return 1;
539 }
540 printf("%llu %d-codes\n", got, n);
541 }
542 printf("%llu total codes for 2 to %d symbols", sum, syms);
543 if (max < syms - 1)
544 printf(" (%d-bit length limit)\n", max);
545 else
546 puts(" (no length limit)");
547
548 /* allocate and clear done array for beenhere() */
549 if (syms == 2)
550 done = NULL;
551 else if (size > ((size_t)0 - 1) / sizeof(struct tab) ||
552 (done = calloc(size, sizeof(struct tab))) == NULL) {
553 fputs("abort: unable to allocate enough memory\n", stderr);
554 cleanup();
555 return 1;
556 }
557
558 /* find and show maximum inflate table usage */
559 if (root > max) /* reduce root to max length */
560 root = max;
561 if (syms < ((code_t)1 << (root + 1)))
562 enough(syms);
563 else
564 puts("cannot handle minimum code lengths > root");
565
566 /* done */
567 cleanup();
568 return 0;
569}
diff --git a/examples/gzlog.c b/examples/gzlog.c
index b6acdef..4daf1c2 100644
--- a/examples/gzlog.c
+++ b/examples/gzlog.c
@@ -1,413 +1,1058 @@
1/* 1/*
2 * gzlog.c 2 * gzlog.c
3 * Copyright (C) 2004 Mark Adler 3 * Copyright (C) 2004, 2008 Mark Adler, all rights reserved
4 * For conditions of distribution and use, see copyright notice in gzlog.h 4 * For conditions of distribution and use, see copyright notice in gzlog.h
5 * version 1.0, 26 Nov 2004 5 * version 2.0, 25 Apr 2008
6 *
7 */ 6 */
8 7
9#include <string.h> /* memcmp() */ 8/*
10#include <stdlib.h> /* malloc(), free(), NULL */ 9 gzlog provides a mechanism for frequently appending short strings to a gzip
11#include <sys/types.h> /* size_t, off_t */ 10 file that is efficient both in execution time and compression ratio. The
12#include <unistd.h> /* read(), close(), sleep(), ftruncate(), */ 11 strategy is to write the short strings in an uncompressed form to the end of
13 /* lseek() */ 12 the gzip file, only compressing when the amount of uncompressed data has
14#include <fcntl.h> /* open() */ 13 reached a given threshold.
15#include <sys/file.h> /* flock() */ 14
16#include "zlib.h" /* deflateInit2(), deflate(), deflateEnd() */ 15 gzlog also provides protection against interruptions in the process due to
16 system crashes. The status of the operation is recorded in an extra field
17 in the gzip file, and is only updated once the gzip file is brought to a
18 valid state. The last data to be appended or compressed is saved in an
19 auxiliary file, so that if the operation is interrupted, it can be completed
20 the next time an append operation is attempted.
21
22 gzlog maintains another auxiliary file with the last 32K of data from the
23 compressed portion, which is preloaded for the compression of the subsequent
24 data. This minimizes the impact to the compression ratio of appending.
25 */
26
27/*
28 Operations Concept:
29
30 Files (log name "foo"):
31 foo.gz -- gzip file with the complete log
32 foo.add -- last message to append or last data to compress
33 foo.dict -- dictionary of the last 32K of data for next compression
34 foo.temp -- temporary dictionary file for compression after this one
35 foo.lock -- lock file for reading and writing the other files
36 foo.repairs -- log file for log file recovery operations (not compressed)
37
38 gzip file structure:
39 - fixed-length (no file name) header with extra field (see below)
40 - compressed data ending initially with empty stored block
41 - uncompressed data filling out originally empty stored block and
42 subsequent stored blocks as needed (16K max each)
43 - gzip trailer
44 - no junk at end (no other gzip streams)
45
46 When appending data, the information in the first three items above plus the
47 foo.add file are sufficient to recover an interrupted append operation. The
48 extra field has the necessary information to restore the start of the last
49 stored block and determine where to append the data in the foo.add file, as
50 well as the crc and length of the gzip data before the append operation.
51
52 The foo.add file is created before the gzip file is marked for append, and
53 deleted after the gzip file is marked as complete. So if the append
54 operation is interrupted, the data to add will still be there. If due to
55 some external force, the foo.add file gets deleted between when the append
56 operation was interrupted and when recovery is attempted, the gzip file will
57 still be restored, but without the appended data.
58
59 When compressing data, the information in the first two items above plus the
60 foo.add file are sufficient to recover an interrupted compress operation.
61 The extra field has the necessary information to find the end of the
62 compressed data, and contains both the crc and length of just the compressed
63 data and of the complete set of data including the contents of the foo.add
64 file.
65
66 Again, the foo.add file is maintained during the compress operation in case
67 of an interruption. If in the unlikely event the foo.add file with the data
68 to be compressed is missing due to some external force, a gzip file with
69 just the previous compressed data will be reconstructed. In this case, all
70 of the data that was to be compressed is lost (approximately one megabyte).
71 This will not occur if all that happened was an interruption of the compress
72 operation.
73
74 The third state that is marked is the replacement of the old dictionary with
75 the new dictionary after a compress operation. Once compression is
76 complete, the gzip file is marked as being in the replace state. This
77 completes the gzip file, so an interrupt after being so marked does not
78 result in recompression. Then the dictionary file is replaced, and the gzip
79 file is marked as completed. This state prevents the possibility of
80 restarting compression with the wrong dictionary file.
81
82 All three operations are wrapped by a lock/unlock procedure. In order to
83 gain exclusive access to the log files, first a foo.lock file must be
84 exclusively created. When all operations are complete, the lock is
85 released by deleting the foo.lock file. If when attempting to create the
86 lock file, it already exists and the modify time of the lock file is more
87 than five minutes old (set by the PATIENCE define below), then the old
88 lock file is considered stale and deleted, and the exclusive creation of
89 the lock file is retried. To assure that there are no false assessments
90 of the staleness of the lock file, the operations periodically touch the
91 lock file to update the modified date.
92
93 Following is the definition of the extra field with all of the information
94 required to enable the above append and compress operations and their
95 recovery if interrupted. Multi-byte values are stored little endian
96 (consistent with the gzip format). File pointers are eight bytes long.
97 The crc's and lengths for the gzip trailer are four bytes long. (Note that
98 the length at the end of a gzip file is used for error checking only, and
99 for large files is actually the length modulo 2^32.) The stored block
100 length is two bytes long. The gzip extra field two-byte identification is
101 "ap" for append. It is assumed that writing the extra field to the file is
102 an "atomic" operation. That is, either all of the extra field is written
103 to the file, or none of it is, if the operation is interrupted right at the
104 point of updating the extra field. This is a reasonable assumption, since
105 the extra field is within the first 52 bytes of the file, which is smaller
106 than any expected block size for a mass storage device (usually 512 bytes or
107 larger).
108
109 Extra field (35 bytes):
110 - Pointer to first stored block length -- this points to the two-byte length
111 of the first stored block, which is followed by the two-byte, one's
112 complement of that length. The stored block length is preceded by the
113 three-bit header of the stored block, which is the actual start of the
114 stored block in the deflate format. See the bit offset field below.
115 - Pointer to the last stored block length. This is the same as above, but
116 for the last stored block of the uncompressed data in the gzip file.
117 Initially this is the same as the first stored block length pointer.
118 When the stored block gets to 16K (see the MAX_STORE define), then a new
119 stored block as added, at which point the last stored block length pointer
120 is different from the first stored block length pointer. When they are
121 different, the first bit of the last stored block header is eight bits, or
122 one byte back from the block length.
123 - Compressed data crc and length. This is the crc and length of the data
124 that is in the compressed portion of the deflate stream. These are used
125 only in the event that the foo.add file containing the data to compress is
126 lost after a compress operation is interrupted.
127 - Total data crc and length. This is the crc and length of all of the data
128 stored in the gzip file, compressed and uncompressed. It is used to
129 reconstruct the gzip trailer when compressing, as well as when recovering
130 interrupted operations.
131 - Final stored block length. This is used to quickly find where to append,
132 and allows the restoration of the original final stored block state when
133 an append operation is interrupted.
134 - First stored block start as the number of bits back from the final stored
135 block first length byte. This value is in the range of 3..10, and is
136 stored as the low three bits of the final byte of the extra field after
137 subtracting three (0..7). This allows the last-block bit of the stored
138 block header to be updated when a new stored block is added, for the case
139 when the first stored block and the last stored block are the same. (When
140 they are different, the numbers of bits back is known to be eight.) This
141 also allows for new compressed data to be appended to the old compressed
142 data in the compress operation, overwriting the previous first stored
143 block, or for the compressed data to be terminated and a valid gzip file
144 reconstructed on the off chance that a compression operation was
145 interrupted and the data to compress in the foo.add file was deleted.
146 - The operation in process. This is the next two bits in the last byte (the
147 bits under the mask 0x18). The are interpreted as 0: nothing in process,
148 1: append in process, 2: compress in process, 3: replace in process.
149 - The top three bits of the last byte in the extra field are reserved and
150 are currently set to zero.
151
152 Main procedure:
153 - Exclusively create the foo.lock file using the O_CREAT and O_EXCL modes of
154 the system open() call. If the modify time of an existing lock file is
155 more than PATIENCE seconds old, then the lock file is deleted and the
156 exclusive create is retried.
157 - Load the extra field from the foo.gz file, and see if an operation was in
158 progress but not completed. If so, apply the recovery procedure below.
159 - Perform the append procedure with the provided data.
160 - If the uncompressed data in the foo.gz file is 1MB or more, apply the
161 compress procedure.
162 - Delete the foo.lock file.
163
164 Append procedure:
165 - Put what to append in the foo.add file so that the operation can be
166 restarted if this procedure is interrupted.
167 - Mark the foo.gz extra field with the append operation in progress.
168 + Restore the original last-block bit and stored block length of the last
169 stored block from the information in the extra field, in case a previous
170 append operation was interrupted.
171 - Append the provided data to the last stored block, creating new stored
172 blocks as needed and updating the stored blocks last-block bits and
173 lengths.
174 - Update the crc and length with the new data, and write the gzip trailer.
175 - Write over the extra field (with a single write operation) with the new
176 pointers, lengths, and crc's, and mark the gzip file as not in process.
177 Though there is still a foo.add file, it will be ignored since nothing
178 is in process. If a foo.add file is leftover from a previously
179 completed operation, it is truncated when writing new data to it.
180 - Delete the foo.add file.
181
182 Compress and replace procedures:
183 - Read all of the uncompressed data in the stored blocks in foo.gz and write
184 it to foo.add. Also write foo.temp with the last 32K of that data to
185 provide a dictionary for the next invocation of this procedure.
186 - Rewrite the extra field marking foo.gz with a compression in process.
187 * If there is no data provided to compress (due to a missing foo.add file
188 when recovering), reconstruct and truncate the foo.gz file to contain
189 only the previous compressed data and proceed to the step after the next
190 one. Otherwise ...
191 - Compress the data with the dictionary in foo.dict, and write to the
192 foo.gz file starting at the bit immediately following the last previously
193 compressed block. If there is no foo.dict, proceed anyway with the
194 compression at slightly reduced efficiency. (For the foo.dict file to be
195 missing requires some external failure beyond simply the interruption of
196 a compress operation.) During this process, the foo.lock file is
197 periodically touched to assure that that file is not considered stale by
198 another process before we're done. The deflation is terminated with a
199 non-last empty static block (10 bits long), that is then located and
200 written over by a last-bit-set empty stored block.
201 - Append the crc and length of the data in the gzip file (previously
202 calculated during the append operations).
203 - Write over the extra field with the updated stored block offsets, bits
204 back, crc's, and lengths, and mark foo.gz as in process for a replacement
205 of the dictionary.
206 @ Delete the foo.add file.
207 - Replace foo.dict with foo.temp.
208 - Write over the extra field, marking foo.gz as complete.
209
210 Recovery procedure:
211 - If not a replace recovery, read in the foo.add file, and provide that data
212 to the appropriate recovery below. If there is no foo.add file, provide
213 a zero data length to the recovery. In that case, the append recovery
214 restores the foo.gz to the previous compressed + uncompressed data state.
215 For the the compress recovery, a missing foo.add file results in foo.gz
216 being restored to the previous compressed-only data state.
217 - Append recovery:
218 - Pick up append at + step above
219 - Compress recovery:
220 - Pick up compress at * step above
221 - Replace recovery:
222 - Pick up compress at @ step above
223 - Log the repair with a date stamp in foo.repairs
224 */
225
226#include <sys/types.h>
227#include <stdio.h> /* rename, fopen, fprintf, fclose */
228#include <stdlib.h> /* malloc, free */
229#include <string.h> /* strlen, strrchr, strcpy, strncpy, strcmp */
230#include <fcntl.h> /* open */
231#include <unistd.h> /* lseek, read, write, close, unlink, sleep, */
232 /* ftruncate, fsync */
233#include <errno.h> /* errno */
234#include <time.h> /* time, ctime */
235#include <sys/stat.h> /* stat */
236#include <sys/time.h> /* utimes */
237#include "zlib.h" /* crc32 */
238
239#include "gzlog.h" /* header for external access */
17 240
18#include "gzlog.h" /* interface */
19#define local static 241#define local static
242typedef unsigned int uint;
243typedef unsigned long ulong;
244
245/* Macro for debugging to deterministically force recovery operations */
246#ifdef DEBUG
247 #include <setjmp.h> /* longjmp */
248 jmp_buf gzlog_jump; /* where to go back to */
249 int gzlog_bail = 0; /* which point to bail at (1..8) */
250 int gzlog_count = -1; /* number of times through to wait */
251# define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \
252 longjmp(gzlog_jump, gzlog_bail); } while (0)
253#else
254# define BAIL(n)
255#endif
256
257/* how old the lock file can be in seconds before considering it stale */
258#define PATIENCE 300
259
260/* maximum stored block size in Kbytes -- must be in 1..63 */
261#define MAX_STORE 16
20 262
21/* log object structure */ 263/* number of stored Kbytes to trigger compression (must be >= 32 to allow
22typedef struct { 264 dictionary construction, and <= 204 * MAX_STORE, in order for >> 10 to
23 int id; /* object identifier */ 265 discard the stored block headers contribution of five bytes each) */
24 int fd; /* log file descriptor */ 266#define TRIGGER 1024
25 off_t extra; /* offset of extra "ap" subfield */ 267
26 off_t mark_off; /* offset of marked data */ 268/* size of a deflate dictionary (this cannot be changed) */
27 off_t last_off; /* offset of last block */ 269#define DICT 32768U
28 unsigned long crc; /* uncompressed crc */ 270
29 unsigned long len; /* uncompressed length (modulo 2^32) */ 271/* values for the operation (2 bits) */
30 unsigned stored; /* length of current stored block */ 272#define NO_OP 0
31} gz_log; 273#define APPEND_OP 1
32 274#define COMPRESS_OP 2
33#define GZLOGID 19334 /* gz_log object identifier */ 275#define REPLACE_OP 3
34 276
35#define LOCK_RETRY 1 /* retry lock once a second */ 277/* macros to extract little-endian integers from an unsigned byte buffer */
36#define LOCK_PATIENCE 1200 /* try about twenty minutes before forcing */ 278#define PULL2(p) ((p)[0]+((uint)((p)[1])<<8))
37 279#define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16))
38/* acquire a lock on a file */ 280#define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32))
39local int lock(int fd) 281
282/* macros to store integers into a byte buffer in little-endian order */
283#define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0)
284#define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0)
285#define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0)
286
287/* internal structure for log information */
288#define LOGID "\106\035\172" /* should be three non-zero characters */
289struct log {
290 char id[4]; /* contains LOGID to detect inadvertent overwrites */
291 int fd; /* file descriptor for .gz file, opened read/write */
292 char *path; /* allocated path, e.g. "/var/log/foo" or "foo" */
293 char *end; /* end of path, for appending suffices such as ".gz" */
294 off_t first; /* offset of first stored block first length byte */
295 int back; /* location of first block id in bits back from first */
296 uint stored; /* bytes currently in last stored block */
297 off_t last; /* offset of last stored block first length byte */
298 ulong ccrc; /* crc of compressed data */
299 ulong clen; /* length (modulo 2^32) of compressed data */
300 ulong tcrc; /* crc of total data */
301 ulong tlen; /* length (modulo 2^32) of total data */
302 time_t lock; /* last modify time of our lock file */
303};
304
305/* gzip header for gzlog */
306local unsigned char log_gzhead[] = {
307 0x1f, 0x8b, /* magic gzip id */
308 8, /* compression method is deflate */
309 4, /* there is an extra field (no file name) */
310 0, 0, 0, 0, /* no modification time provided */
311 0, 0xff, /* no extra flags, no OS specified */
312 39, 0, 'a', 'p', 35, 0 /* extra field with "ap" subfield */
313 /* 35 is EXTRA, 39 is EXTRA + 4 */
314};
315
316#define HEAD sizeof(log_gzhead) /* should be 16 */
317
318/* initial gzip extra field content (52 == HEAD + EXTRA + 1) */
319local unsigned char log_gzext[] = {
320 52, 0, 0, 0, 0, 0, 0, 0, /* offset of first stored block length */
321 52, 0, 0, 0, 0, 0, 0, 0, /* offset of last stored block length */
322 0, 0, 0, 0, 0, 0, 0, 0, /* compressed data crc and length */
323 0, 0, 0, 0, 0, 0, 0, 0, /* total data crc and length */
324 0, 0, /* final stored block data length */
325 5 /* op is NO_OP, last bit 8 bits back */
326};
327
328#define EXTRA sizeof(log_gzext) /* should be 35 */
329
330/* initial gzip data and trailer */
331local unsigned char log_gzbody[] = {
332 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */
333 0, 0, 0, 0, /* crc */
334 0, 0, 0, 0 /* uncompressed length */
335};
336
337#define BODY sizeof(log_gzbody)
338
339/* Exclusively create foo.lock in order to negotiate exclusive access to the
340 foo.* files. If the modify time of an existing lock file is greater than
341 PATIENCE seconds in the past, then consider the lock file to have been
342 abandoned, delete it, and try the exclusive create again. Save the lock
343 file modify time for verification of ownership. Return 0 on success, or -1
344 on failure, usually due to an access restriction or invalid path. Note that
345 if stat() or unlink() fails, it may be due to another process noticing the
346 abandoned lock file a smidge sooner and deleting it, so those are not
347 flagged as an error. */
348local int log_lock(struct log *log)
40{ 349{
41 int patience; 350 int fd;
351 struct stat st;
42 352
43 /* try to lock every LOCK_RETRY seconds for LOCK_PATIENCE seconds */ 353 strcpy(log->end, ".lock");
44 patience = LOCK_PATIENCE; 354 while ((fd = open(log->path, O_CREAT | O_EXCL, 0644)) < 0) {
45 do { 355 if (errno != EEXIST)
46 if (flock(fd, LOCK_EX + LOCK_NB) == 0) 356 return -1;
47 return 0; 357 if (stat(log->path, &st) == 0 && time(NULL) - st.st_mtime > PATIENCE) {
48 (void)sleep(LOCK_RETRY); 358 unlink(log->path);
49 patience -= LOCK_RETRY; 359 continue;
50 } while (patience > 0); 360 }
361 sleep(2); /* relinquish the CPU for two seconds while waiting */
362 }
363 close(fd);
364 if (stat(log->path, &st) == 0)
365 log->lock = st.st_mtime;
366 return 0;
367}
51 368
52 /* we've run out of patience -- give up */ 369/* Update the modify time of the lock file to now, in order to prevent another
53 return -1; 370 task from thinking that the lock is stale. Save the lock file modify time
371 for verification of ownership. */
372local void log_touch(struct log *log)
373{
374 struct stat st;
375
376 strcpy(log->end, ".lock");
377 utimes(log->path, NULL);
378 if (stat(log->path, &st) == 0)
379 log->lock = st.st_mtime;
54} 380}
55 381
56/* release lock */ 382/* Check the log file modify time against what is expected. Return true if
57local void unlock(int fd) 383 this is not our lock. If it is our lock, touch it to keep it. */
384local int log_check(struct log *log)
58{ 385{
59 (void)flock(fd, LOCK_UN); 386 struct stat st;
387
388 strcpy(log->end, ".lock");
389 if (stat(log->path, &st) || st.st_mtime != log->lock)
390 return 1;
391 log_touch(log);
392 return 0;
60} 393}
61 394
62/* release a log object */ 395/* Unlock a previously acquired lock, but only if it's ours. */
63local void log_clean(gz_log *log) 396local void log_unlock(struct log *log)
64{ 397{
65 unlock(log->fd); 398 if (log_check(log))
66 (void)close(log->fd); 399 return;
67 free(log); 400 strcpy(log->end, ".lock");
401 unlink(log->path);
402 log->lock = 0;
68} 403}
69 404
70/* read an unsigned long from a byte buffer little-endian */ 405/* Check the gzip header and read in the extra field, filling in the values in
71local unsigned long make_ulg(unsigned char *buf) 406 the log structure. Return op on success or -1 if the gzip header was not as
407 expected. op is the current operation in progress last written to the extra
408 field. This assumes that the gzip file has already been opened, with the
409 file descriptor log->fd. */
410local int log_head(struct log *log)
72{ 411{
73 int n; 412 int op;
74 unsigned long val; 413 unsigned char buf[HEAD + EXTRA];
75 414
76 val = (unsigned long)(*buf++); 415 if (lseek(log->fd, 0, SEEK_SET) < 0 ||
77 for (n = 8; n < 32; n += 8) 416 read(log->fd, buf, HEAD + EXTRA) != HEAD + EXTRA ||
78 val += (unsigned long)(*buf++) << n; 417 memcmp(buf, log_gzhead, HEAD)) {
79 return val; 418 return -1;
419 }
420 log->first = PULL8(buf + HEAD);
421 log->last = PULL8(buf + HEAD + 8);
422 log->ccrc = PULL4(buf + HEAD + 16);
423 log->clen = PULL4(buf + HEAD + 20);
424 log->tcrc = PULL4(buf + HEAD + 24);
425 log->tlen = PULL4(buf + HEAD + 28);
426 log->stored = PULL2(buf + HEAD + 32);
427 log->back = 3 + (buf[HEAD + 34] & 7);
428 op = (buf[HEAD + 34] >> 3) & 3;
429 return op;
80} 430}
81 431
82/* read an off_t from a byte buffer little-endian */ 432/* Write over the extra field contents, marking the operation as op. Use fsync
83local off_t make_off(unsigned char *buf) 433 to assure that the device is written to, and in the requested order. This
434 operation, and only this operation, is assumed to be atomic in order to
435 assure that the log is recoverable in the event of an interruption at any
436 point in the process. Return -1 if the write to foo.gz failed. */
437local int log_mark(struct log *log, int op)
84{ 438{
85 int n; 439 int ret;
86 off_t val; 440 unsigned char ext[EXTRA];
87 441
88 val = (off_t)(*buf++); 442 PUT8(ext, log->first);
89 for (n = 8; n < 64; n += 8) 443 PUT8(ext + 8, log->last);
90 val += (off_t)(*buf++) << n; 444 PUT4(ext + 16, log->ccrc);
91 return val; 445 PUT4(ext + 20, log->clen);
446 PUT4(ext + 24, log->tcrc);
447 PUT4(ext + 28, log->tlen);
448 PUT2(ext + 32, log->stored);
449 ext[34] = log->back - 3 + (op << 3);
450 fsync(log->fd);
451 ret = lseek(log->fd, HEAD, SEEK_SET) < 0 ||
452 write(log->fd, ext, EXTRA) != EXTRA ? -1 : 0;
453 fsync(log->fd);
454 return ret;
92} 455}
93 456
94/* write an unsigned long little-endian to byte buffer */ 457/* Rewrite the last block header bits and subsequent zero bits to get to a byte
95local void dice_ulg(unsigned long val, unsigned char *buf) 458 boundary, setting the last block bit if last is true, and then write the
459 remainder of the stored block header (length and one's complement). Leave
460 the file pointer after the end of the last stored block data. Return -1 if
461 there is a read or write failure on the foo.gz file */
462local int log_last(struct log *log, int last)
96{ 463{
97 int n; 464 int back, len, mask;
465 unsigned char buf[6];
466
467 /* determine the locations of the bytes and bits to modify */
468 back = log->last == log->first ? log->back : 8;
469 len = back > 8 ? 2 : 1; /* bytes back from log->last */
470 mask = 0x80 >> ((back - 1) & 7); /* mask for block last-bit */
471
472 /* get the byte to modify (one or two back) into buf[0] -- don't need to
473 read the byte if the last-bit is eight bits back, since in that case
474 the entire byte will be modified */
475 buf[0] = 0;
476 if (back != 8 && (lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
477 read(log->fd, buf, 1) != 1))
478 return -1;
479
480 /* change the last-bit of the last stored block as requested -- note
481 that all bits above the last-bit are set to zero, per the type bits
482 of a stored block being 00 and per the convention that the bits to
483 bring the stream to a byte boundary are also zeros */
484 buf[1] = 0;
485 buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0);
98 486
99 for (n = 0; n < 4; n++) { 487 /* write the modified stored block header and lengths, move the file
100 *buf++ = val & 0xff; 488 pointer to after the last stored block data */
101 val >>= 8; 489 PUT2(buf + 2, log->stored);
490 PUT2(buf + 4, log->stored ^ 0xffff);
491 return lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
492 write(log->fd, buf + 2 - len, len + 4) != len + 4 ||
493 lseek(log->fd, log->stored, SEEK_CUR) < 0 ? -1 : 0;
494}
495
496/* Append len bytes from data to the locked and open log file. len may be zero
497 if recovering and no .add file was found. In that case, the previous state
498 of the foo.gz file is restored. The data is appended uncompressed in
499 deflate stored blocks. Return -1 if there was an error reading or writing
500 the foo.gz file. */
501local int log_append(struct log *log, unsigned char *data, size_t len)
502{
503 uint put;
504 off_t end;
505 unsigned char buf[8];
506
507 /* set the last block last-bit and length, in case recovering an
508 interrupted append, then position the file pointer to append to the
509 block */
510 if (log_last(log, 1))
511 return -1;
512
513 /* append, adding stored blocks and updating the offset of the last stored
514 block as needed, and update the total crc and length */
515 while (len) {
516 /* append as much as we can to the last block */
517 put = (MAX_STORE << 10) - log->stored;
518 if (put > len)
519 put = (uint)len;
520 if (put) {
521 if (write(log->fd, data, put) != put)
522 return -1;
523 BAIL(1);
524 log->tcrc = crc32(log->tcrc, data, put);
525 log->tlen += put;
526 log->stored += put;
527 data += put;
528 len -= put;
529 }
530
531 /* if we need to, add a new empty stored block */
532 if (len) {
533 /* mark current block as not last */
534 if (log_last(log, 0))
535 return -1;
536
537 /* point to new, empty stored block */
538 log->last += 4 + log->stored + 1;
539 log->stored = 0;
540 }
541
542 /* mark last block as last, update its length */
543 if (log_last(log, 1))
544 return -1;
545 BAIL(2);
102 } 546 }
547
548 /* write the new crc and length trailer, and truncate just in case (could
549 be recovering from partial append with a missing foo.add file) */
550 PUT4(buf, log->tcrc);
551 PUT4(buf + 4, log->tlen);
552 if (write(log->fd, buf, 8) != 8 ||
553 (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
554 return -1;
555
556 /* write the extra field, marking the log file as done, delete .add file */
557 if (log_mark(log, NO_OP))
558 return -1;
559 strcpy(log->end, ".add");
560 unlink(log->path); /* ignore error, since may not exist */
561 return 0;
103} 562}
104 563
105/* write an off_t little-endian to byte buffer */ 564/* Replace the foo.dict file with the foo.temp file. Also delete the foo.add
106local void dice_off(off_t val, unsigned char *buf) 565 file, since the compress operation may have been interrupted before that was
566 done. Returns 1 if memory could not be allocated, or -1 if reading or
567 writing foo.gz fails, or if the rename fails for some reason other than
568 foo.temp not existing. foo.temp not existing is a permitted error, since
569 the replace operation may have been interrupted after the rename is done,
570 but before foo.gz is marked as complete. */
571local int log_replace(struct log *log)
107{ 572{
108 int n; 573 int ret;
574 char *dest;
575
576 /* delete foo.add file */
577 strcpy(log->end, ".add");
578 unlink(log->path); /* ignore error, since may not exist */
579 BAIL(3);
580
581 /* rename foo.name to foo.dict, replacing foo.dict if it exists */
582 strcpy(log->end, ".dict");
583 dest = malloc(strlen(log->path) + 1);
584 if (dest == NULL)
585 return -2;
586 strcpy(dest, log->path);
587 strcpy(log->end, ".temp");
588 ret = rename(log->path, dest);
589 free(dest);
590 if (ret && errno != ENOENT)
591 return -1;
592 BAIL(4);
109 593
110 for (n = 0; n < 8; n++) { 594 /* mark the foo.gz file as done */
111 *buf++ = val & 0xff; 595 return log_mark(log, NO_OP);
112 val >>= 8; 596}
597
598/* Compress the len bytes at data and append the compressed data to the
599 foo.gz deflate data immediately after the previous compressed data. This
600 overwrites the previous uncompressed data, which was stored in foo.add
601 and is the data provided in data[0..len-1]. If this operation is
602 interrupted, it picks up at the start of this routine, with the foo.add
603 file read in again. If there is no data to compress (len == 0), then we
604 simply terminate the foo.gz file after the previously compressed data,
605 appending a final empty stored block and the gzip trailer. Return -1 if
606 reading or writing the log.gz file failed, or -2 if there was a memory
607 allocation failure. */
608local int log_compress(struct log *log, unsigned char *data, size_t len)
609{
610 int fd;
611 uint got, max;
612 ssize_t dict;
613 off_t end;
614 z_stream strm;
615 unsigned char buf[DICT];
616
617 /* compress and append compressed data */
618 if (len) {
619 /* set up for deflate, allocating memory */
620 strm.zalloc = Z_NULL;
621 strm.zfree = Z_NULL;
622 strm.opaque = Z_NULL;
623 if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8,
624 Z_DEFAULT_STRATEGY) != Z_OK)
625 return -2;
626
627 /* read in dictionary (last 32K of data that was compressed) */
628 strcpy(log->end, ".dict");
629 fd = open(log->path, O_RDONLY, 0);
630 if (fd >= 0) {
631 dict = read(fd, buf, DICT);
632 close(fd);
633 if (dict < 0) {
634 deflateEnd(&strm);
635 return -1;
636 }
637 if (dict)
638 deflateSetDictionary(&strm, buf, (uint)dict);
639 }
640 log_touch(log);
641
642 /* prime deflate with last bits of previous block, position write
643 pointer to write those bits and overwrite what follows */
644 if (lseek(log->fd, log->first - (log->back > 8 ? 2 : 1),
645 SEEK_SET) < 0 ||
646 read(log->fd, buf, 1) != 1 || lseek(log->fd, -1, SEEK_CUR) < 0) {
647 deflateEnd(&strm);
648 return -1;
649 }
650 deflatePrime(&strm, (8 - log->back) & 7, *buf);
651
652 /* compress, finishing with a partial non-last empty static block */
653 strm.next_in = data;
654 max = (((uint)0 - 1) >> 1) + 1; /* in case int smaller than size_t */
655 do {
656 strm.avail_in = len > max ? max : (uint)len;
657 len -= strm.avail_in;
658 do {
659 strm.avail_out = DICT;
660 strm.next_out = buf;
661 deflate(&strm, len ? Z_NO_FLUSH : Z_PARTIAL_FLUSH);
662 got = DICT - strm.avail_out;
663 if (got && write(log->fd, buf, got) != got) {
664 deflateEnd(&strm);
665 return -1;
666 }
667 log_touch(log);
668 } while (strm.avail_out == 0);
669 } while (len);
670 deflateEnd(&strm);
671 BAIL(5);
672
673 /* find start of empty static block -- scanning backwards the first one
674 bit is the second bit of the block, if the last byte is zero, then
675 we know the byte before that has a one in the top bit, since an
676 empty static block is ten bits long */
677 if ((log->first = lseek(log->fd, -1, SEEK_CUR)) < 0 ||
678 read(log->fd, buf, 1) != 1)
679 return -1;
680 log->first++;
681 if (*buf) {
682 log->back = 1;
683 while ((*buf & ((uint)1 << (8 - log->back++))) == 0)
684 ; /* guaranteed to terminate, since *buf != 0 */
685 }
686 else
687 log->back = 10;
688
689 /* update compressed crc and length */
690 log->ccrc = log->tcrc;
691 log->clen = log->tlen;
692 }
693 else {
694 /* no data to compress -- fix up existing gzip stream */
695 log->tcrc = log->ccrc;
696 log->tlen = log->clen;
113 } 697 }
698
699 /* complete and truncate gzip stream */
700 log->last = log->first;
701 log->stored = 0;
702 PUT4(buf, log->tcrc);
703 PUT4(buf + 4, log->tlen);
704 if (log_last(log, 1) || write(log->fd, buf, 8) != 8 ||
705 (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
706 return -1;
707 BAIL(6);
708
709 /* mark as being in the replace operation */
710 if (log_mark(log, REPLACE_OP))
711 return -1;
712
713 /* execute the replace operation and mark the file as done */
714 return log_replace(log);
114} 715}
115 716
116/* initial, empty gzip file for appending */ 717/* log a repair record to the .repairs file */
117local char empty_gz[] = { 718local void log_log(struct log *log, int op, char *record)
118 0x1f, 0x8b, /* magic gzip id */ 719{
119 8, /* compression method is deflate */ 720 time_t now;
120 4, /* there is an extra field */ 721 FILE *rec;
121 0, 0, 0, 0, /* no modification time provided */
122 0, 0xff, /* no extra flags, no OS */
123 20, 0, 'a', 'p', 16, 0, /* extra field with "ap" subfield */
124 32, 0, 0, 0, 0, 0, 0, 0, /* offset of uncompressed data */
125 32, 0, 0, 0, 0, 0, 0, 0, /* offset of last block */
126 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */
127 0, 0, 0, 0, /* crc */
128 0, 0, 0, 0 /* uncompressed length */
129};
130 722
131/* initialize a log object with locking */ 723 now = time(NULL);
132void *gzlog_open(char *path) 724 strcpy(log->end, ".repairs");
725 rec = fopen(log->path, "a");
726 if (rec == NULL)
727 return;
728 fprintf(rec, "%.24s %s recovery: %s\n", ctime(&now), op == APPEND_OP ?
729 "append" : (op == COMPRESS_OP ? "compress" : "replace"), record);
730 fclose(rec);
731 return;
732}
733
734/* Recover the interrupted operation op. First read foo.add for recovering an
735 append or compress operation. Return -1 if there was an error reading or
736 writing foo.gz or reading an existing foo.add, or -2 if there was a memory
737 allocation failure. */
738local int log_recover(struct log *log, int op)
133{ 739{
134 unsigned xlen; 740 int fd, ret = 0;
135 unsigned char temp[20]; 741 unsigned char *data = NULL;
136 unsigned sub_len; 742 size_t len = 0;
137 int good; 743 struct stat st;
138 gz_log *log;
139
140 /* allocate log structure */
141 log = malloc(sizeof(gz_log));
142 if (log == NULL)
143 return NULL;
144 log->id = GZLOGID;
145 744
146 /* open file, creating it if necessary, and locking it */ 745 /* log recovery */
147 log->fd = open(path, O_RDWR | O_CREAT, 0600); 746 log_log(log, op, "start");
148 if (log->fd < 0) { 747
149 free(log); 748 /* load foo.add file if expected and present */
150 return NULL; 749 if (op == APPEND_OP || op == COMPRESS_OP) {
750 strcpy(log->end, ".add");
751 if (stat(log->path, &st) == 0 && st.st_size) {
752 len = (size_t)(st.st_size);
753 if (len != st.st_size || (data = malloc(st.st_size)) == NULL) {
754 log_log(log, op, "allocation failure");
755 return -2;
756 }
757 if ((fd = open(log->path, O_RDONLY, 0)) < 0) {
758 log_log(log, op, ".add file read failure");
759 return -1;
760 }
761 ret = read(fd, data, len) != len;
762 close(fd);
763 if (ret) {
764 log_log(log, op, ".add file read failure");
765 return -1;
766 }
767 log_log(log, op, "loaded .add file");
768 }
769 else
770 log_log(log, op, "missing .add file!");
771 }
772
773 /* recover the interrupted operation */
774 switch (op) {
775 case APPEND_OP:
776 ret = log_append(log, data, len);
777 break;
778 case COMPRESS_OP:
779 ret = log_compress(log, data, len);
780 break;
781 case REPLACE_OP:
782 ret = log_replace(log);
151 } 783 }
152 if (lock(log->fd)) { 784
785 /* log status */
786 log_log(log, op, ret ? "failure" : "complete");
787
788 /* clean up */
789 if (data != NULL)
790 free(data);
791 return ret;
792}
793
794/* Close the foo.gz file (if open) and release the lock. */
795local void log_close(struct log *log)
796{
797 if (log->fd >= 0)
153 close(log->fd); 798 close(log->fd);
154 free(log); 799 log->fd = -1;
155 return NULL; 800 log_unlock(log);
801}
802
803/* Open foo.gz, verify the header, and load the extra field contents, after
804 first creating the foo.lock file to gain exclusive access to the foo.*
805 files. If foo.gz does not exist or is empty, then write the initial header,
806 extra, and body content of an empty foo.gz log file. If there is an error
807 creating the lock file due to access restrictions, or an error reading or
808 writing the foo.gz file, or if the foo.gz file is not a proper log file for
809 this object (e.g. not a gzip file or does not contain the expected extra
810 field), then return true. If there is an error, the lock is released.
811 Otherwise, the lock is left in place. */
812local int log_open(struct log *log)
813{
814 int op;
815
816 /* release open file resource if left over -- can occur if lock lost
817 between gzlog_open() and gzlog_write() */
818 if (log->fd >= 0)
819 close(log->fd);
820 log->fd = -1;
821
822 /* negotiate exclusive access */
823 if (log_lock(log) < 0)
824 return -1;
825
826 /* open the log file, foo.gz */
827 strcpy(log->end, ".gz");
828 log->fd = open(log->path, O_RDWR | O_CREAT, 0644);
829 if (log->fd < 0) {
830 log_close(log);
831 return -1;
156 } 832 }
157 833
158 /* if file is empty, write new gzip stream */ 834 /* if new, initialize foo.gz with an empty log, delete old dictionary */
159 if (lseek(log->fd, 0, SEEK_END) == 0) { 835 if (lseek(log->fd, 0, SEEK_END) == 0) {
160 if (write(log->fd, empty_gz, sizeof(empty_gz)) != sizeof(empty_gz)) { 836 if (write(log->fd, log_gzhead, HEAD) != HEAD ||
161 log_clean(log); 837 write(log->fd, log_gzext, EXTRA) != EXTRA ||
162 return NULL; 838 write(log->fd, log_gzbody, BODY) != BODY) {
839 log_close(log);
840 return -1;
163 } 841 }
842 strcpy(log->end, ".dict");
843 unlink(log->path);
164 } 844 }
165 845
166 /* check gzip header */ 846 /* verify log file and load extra field information */
167 (void)lseek(log->fd, 0, SEEK_SET); 847 if ((op = log_head(log)) < 0) {
168 if (read(log->fd, temp, 12) != 12 || temp[0] != 0x1f || 848 log_close(log);
169 temp[1] != 0x8b || temp[2] != 8 || (temp[3] & 4) == 0) { 849 return -1;
170 log_clean(log);
171 return NULL;
172 } 850 }
173 851
174 /* process extra field to find "ap" sub-field */ 852 /* check for interrupted process and if so, recover */
175 xlen = temp[10] + (temp[11] << 8); 853 if (op != NO_OP && log_recover(log, op)) {
176 good = 0; 854 log_close(log);
177 while (xlen) { 855 return -1;
178 if (xlen < 4 || read(log->fd, temp, 4) != 4)
179 break;
180 sub_len = temp[2];
181 sub_len += temp[3] << 8;
182 xlen -= 4;
183 if (memcmp(temp, "ap", 2) == 0 && sub_len == 16) {
184 good = 1;
185 break;
186 }
187 if (xlen < sub_len)
188 break;
189 (void)lseek(log->fd, sub_len, SEEK_CUR);
190 xlen -= sub_len;
191 } 856 }
192 if (!good) { 857
193 log_clean(log); 858 /* touch the lock file to prevent another process from grabbing it */
859 log_touch(log);
860 return 0;
861}
862
863/* See gzlog.h for the description of the external methods below */
864gzlog *gzlog_open(char *path)
865{
866 size_t n;
867 struct log *log;
868
869 /* check arguments */
870 if (path == NULL || *path == 0)
194 return NULL; 871 return NULL;
195 }
196 872
197 /* read in "ap" sub-field */ 873 /* allocate and initialize log structure */
198 log->extra = lseek(log->fd, 0, SEEK_CUR); 874 log = malloc(sizeof(struct log));
199 if (read(log->fd, temp, 16) != 16) { 875 if (log == NULL)
200 log_clean(log); 876 return NULL;
877 strcpy(log->id, LOGID);
878 log->fd = -1;
879
880 /* save path and end of path for name construction */
881 n = strlen(path);
882 log->path = malloc(n + 9); /* allow for ".repairs" */
883 if (log->path == NULL) {
884 free(log);
201 return NULL; 885 return NULL;
202 } 886 }
203 log->mark_off = make_off(temp); 887 strcpy(log->path, path);
204 log->last_off = make_off(temp + 8); 888 log->end = log->path + n;
205 889
206 /* get crc, length of gzip file */ 890 /* gain exclusive access and verify log file -- may perform a
207 (void)lseek(log->fd, log->last_off, SEEK_SET); 891 recovery operation if needed */
208 if (read(log->fd, temp, 13) != 13 || 892 if (log_open(log)) {
209 memcmp(temp, "\001\000\000\377\377", 5) != 0) { 893 free(log->path);
210 log_clean(log); 894 free(log);
211 return NULL; 895 return NULL;
212 } 896 }
213 log->crc = make_ulg(temp + 5);
214 log->len = make_ulg(temp + 9);
215 897
216 /* set up to write over empty last block */ 898 /* return pointer to log structure */
217 (void)lseek(log->fd, log->last_off + 5, SEEK_SET); 899 return log;
218 log->stored = 0;
219 return (void *)log;
220} 900}
221 901
222/* maximum amount to put in a stored block before starting a new one */ 902/* gzlog_compress() return values:
223#define MAX_BLOCK 16384 903 0: all good
224 904 -1: file i/o error (usually access issue)
225/* write a block to a log object */ 905 -2: memory allocation failure
226int gzlog_write(void *obj, char *data, size_t len) 906 -3: invalid log pointer argument */
907int gzlog_compress(gzlog *logd)
227{ 908{
228 size_t some; 909 int fd, ret;
229 unsigned char temp[5]; 910 uint block;
230 gz_log *log; 911 size_t len, next;
912 unsigned char *data, buf[5];
913 struct log *log = logd;
231 914
232 /* check object */ 915 /* check arguments */
233 log = (gz_log *)obj; 916 if (log == NULL || strcmp(log->id, LOGID) || len < 0)
234 if (log == NULL || log->id != GZLOGID) 917 return -3;
235 return 1;
236 918
237 /* write stored blocks until all of the input is written */ 919 /* see if we lost the lock -- if so get it again and reload the extra
238 do { 920 field information (it probably changed), recover last operation if
239 some = MAX_BLOCK - log->stored; 921 necessary */
240 if (some > len) 922 if (log_check(log) && log_open(log))
241 some = len; 923 return -1;
242 if (write(log->fd, data, some) != some)
243 return 1;
244 log->crc = crc32(log->crc, (unsigned char *)data, some);
245 log->len += some;
246 len -= some;
247 data += some;
248 log->stored += some;
249
250 /* if the stored block is full, end it and start another */
251 if (log->stored == MAX_BLOCK) {
252 (void)lseek(log->fd, log->last_off, SEEK_SET);
253 temp[0] = 0;
254 dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
255 temp + 1);
256 if (write(log->fd, temp, 5) != 5)
257 return 1;
258 log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
259 (void)lseek(log->fd, 5, SEEK_CUR);
260 log->stored = 0;
261 }
262 } while (len);
263 return 0;
264}
265 924
266/* recompress the remaining stored deflate data in place */ 925 /* create space for uncompressed data */
267local int recomp(gz_log *log) 926 len = ((size_t)(log->last - log->first) & ~(((size_t)1 << 10) - 1)) +
268{ 927 log->stored;
269 z_stream strm; 928 if ((data = malloc(len)) == NULL)
270 size_t len, max; 929 return -2;
271 unsigned char *in;
272 unsigned char *out;
273 unsigned char temp[16];
274
275 /* allocate space and read it all in (it's around 1 MB) */
276 len = log->last_off - log->mark_off;
277 max = len + (len >> 12) + (len >> 14) + 11;
278 out = malloc(max);
279 if (out == NULL)
280 return 1;
281 in = malloc(len);
282 if (in == NULL) {
283 free(out);
284 return 1;
285 }
286 (void)lseek(log->fd, log->mark_off, SEEK_SET);
287 if (read(log->fd, in, len) != len) {
288 free(in);
289 free(out);
290 return 1;
291 }
292 930
293 /* recompress in memory, decoding stored data as we go */ 931 /* do statement here is just a cheap trick for error handling */
294 /* note: this assumes that unsigned is four bytes or more */ 932 do {
295 /* consider not making that assumption */ 933 /* read in the uncompressed data */
296 strm.zalloc = Z_NULL; 934 if (lseek(log->fd, log->first - 1, SEEK_SET) < 0)
297 strm.zfree = Z_NULL;
298 strm.opaque = Z_NULL;
299 if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 8,
300 Z_DEFAULT_STRATEGY) != Z_OK) {
301 free(in);
302 free(out);
303 return 1;
304 }
305 strm.next_in = in;
306 strm.avail_out = max;
307 strm.next_out = out;
308 while (len >= 5) {
309 if (strm.next_in[0] != 0)
310 break; 935 break;
311 strm.avail_in = strm.next_in[1] + (strm.next_in[2] << 8); 936 next = 0;
312 strm.next_in += 5; 937 while (next < len) {
313 len -= 5; 938 if (read(log->fd, buf, 5) != 5)
314 if (strm.avail_in != 0) {
315 if (len < strm.avail_in)
316 break; 939 break;
317 len -= strm.avail_in; 940 block = PULL2(buf + 1);
318 (void)deflate(&strm, Z_NO_FLUSH); 941 if (next + block > len ||
319 if (strm.avail_in != 0 || strm.avail_out == 0) 942 read(log->fd, (char *)data + next, block) != block)
320 break; 943 break;
944 next += block;
321 } 945 }
322 } 946 if (lseek(log->fd, 0, SEEK_CUR) != log->last + 4 + log->stored)
323 (void)deflate(&strm, Z_SYNC_FLUSH); 947 break;
324 (void)deflateEnd(&strm); 948 log_touch(log);
325 free(in);
326 if (len != 0 || strm.avail_out == 0) {
327 free(out);
328 return 1;
329 }
330 949
331 /* overwrite stored data with compressed data */ 950 /* write the uncompressed data to the .add file */
332 (void)lseek(log->fd, log->mark_off, SEEK_SET); 951 strcpy(log->end, ".add");
333 len = max - strm.avail_out; 952 fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
334 if (write(log->fd, out, len) != len) { 953 if (fd < 0)
335 free(out); 954 break;
336 return 1; 955 ret = write(fd, data, len) != len;
337 } 956 if (ret | close(fd))
338 free(out); 957 break;
339 958 log_touch(log);
340 /* write last empty block, crc, and length */
341 log->mark_off = log->last_off = lseek(log->fd, 0, SEEK_CUR);
342 temp[0] = 1;
343 dice_ulg(0xffffL << 16, temp + 1);
344 dice_ulg(log->crc, temp + 5);
345 dice_ulg(log->len, temp + 9);
346 if (write(log->fd, temp, 13) != 13)
347 return 1;
348 959
349 /* truncate file to discard remaining stored data and old trailer */ 960 /* write the dictionary for the next compress to the .temp file */
350 ftruncate(log->fd, lseek(log->fd, 0, SEEK_CUR)); 961 strcpy(log->end, ".temp");
962 fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
963 if (fd < 0)
964 break;
965 next = DICT > len ? len : DICT;
966 ret = write(fd, (char *)data + len - next, next) != next;
967 if (ret | close(fd))
968 break;
969 log_touch(log);
351 970
352 /* update extra field to point to new last empty block */ 971 /* roll back to compressed data, mark the compress in progress */
353 (void)lseek(log->fd, log->extra, SEEK_SET); 972 log->last = log->first;
354 dice_off(log->mark_off, temp); 973 log->stored = 0;
355 dice_off(log->last_off, temp + 8); 974 if (log_mark(log, COMPRESS_OP))
356 if (write(log->fd, temp, 16) != 16) 975 break;
357 return 1; 976 BAIL(7);
358 return 0; 977
359} 978 /* compress and append the data (clears mark) */
979 ret = log_compress(log, data, len);
980 free(data);
981 return ret;
982 } while (0);
360 983
361/* maximum accumulation of stored blocks before compressing */ 984 /* broke out of do above on i/o error */
362#define MAX_STORED 1048576 985 free(data);
986 return -1;
987}
363 988
364/* close log object */ 989/* gzlog_write() return values:
365int gzlog_close(void *obj) 990 0: all good
991 -1: file i/o error (usually access issue)
992 -2: memory allocation failure
993 -3: invalid log pointer argument */
994int gzlog_write(gzlog *logd, void *data, size_t len)
366{ 995{
367 unsigned char temp[8]; 996 int fd, ret;
368 gz_log *log; 997 struct log *log = logd;
369 998
370 /* check object */ 999 /* check arguments */
371 log = (gz_log *)obj; 1000 if (log == NULL || strcmp(log->id, LOGID) || len < 0)
372 if (log == NULL || log->id != GZLOGID) 1001 return -3;
373 return 1; 1002 if (data == NULL || len == 0)
1003 return 0;
374 1004
375 /* go to start of most recent block being written */ 1005 /* see if we lost the lock -- if so get it again and reload the extra
376 (void)lseek(log->fd, log->last_off, SEEK_SET); 1006 field information (it probably changed), recover last operation if
377 1007 necessary */
378 /* if some stuff was put there, update block */ 1008 if (log_check(log) && log_open(log))
379 if (log->stored) { 1009 return -1;
380 temp[0] = 0;
381 dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16),
382 temp + 1);
383 if (write(log->fd, temp, 5) != 5)
384 return 1;
385 log->last_off = lseek(log->fd, log->stored, SEEK_CUR);
386 }
387 1010
388 /* write last block (empty) */ 1011 /* create and write .add file */
389 if (write(log->fd, "\001\000\000\377\377", 5) != 5) 1012 strcpy(log->end, ".add");
390 return 1; 1013 fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1014 if (fd < 0)
1015 return -1;
1016 ret = write(fd, data, len) != len;
1017 if (ret | close(fd))
1018 return -1;
1019 log_touch(log);
391 1020
392 /* write updated crc and uncompressed length */ 1021 /* mark log file with append in progress */
393 dice_ulg(log->crc, temp); 1022 if (log_mark(log, APPEND_OP))
394 dice_ulg(log->len, temp + 4); 1023 return -1;
395 if (write(log->fd, temp, 8) != 8) 1024 BAIL(8);
396 return 1;
397 1025
398 /* put offset of that last block in gzip extra block */ 1026 /* append data (clears mark) */
399 (void)lseek(log->fd, log->extra + 8, SEEK_SET); 1027 if (log_append(log, data, len))
400 dice_off(log->last_off, temp); 1028 return -1;
401 if (write(log->fd, temp, 8) != 8)
402 return 1;
403 1029
404 /* if more than 1 MB stored, then time to compress it */ 1030 /* check to see if it's time to compress -- if not, then done */
405 if (log->last_off - log->mark_off > MAX_STORED) { 1031 if (((log->last - log->first) >> 10) + (log->stored >> 10) < TRIGGER)
406 if (recomp(log)) 1032 return 0;
407 return 1; 1033
408 } 1034 /* time to compress */
1035 return gzlog_compress(log);
1036}
1037
1038/* gzlog_close() return values:
1039 0: ok
1040 -3: invalid log pointer argument */
1041int gzlog_close(gzlog *logd)
1042{
1043 struct log *log = logd;
409 1044
410 /* unlock and close file */ 1045 /* check arguments */
411 log_clean(log); 1046 if (log == NULL || strcmp(log->id, LOGID))
1047 return -3;
1048
1049 /* close the log file and release the lock */
1050 log_close(log);
1051
1052 /* free structure and return */
1053 if (log->path != NULL)
1054 free(log->path);
1055 strcpy(log->id, "bad");
1056 free(log);
412 return 0; 1057 return 0;
413} 1058}
diff --git a/examples/gzlog.h b/examples/gzlog.h
index a800bd5..c461426 100644
--- a/examples/gzlog.h
+++ b/examples/gzlog.h
@@ -1,6 +1,6 @@
1/* gzlog.h 1/* gzlog.h
2 Copyright (C) 2004 Mark Adler, all rights reserved 2 Copyright (C) 2004, 2008 Mark Adler, all rights reserved
3 version 1.0, 26 Nov 2004 3 version 2.0, 25 Apr 2008
4 4
5 This software is provided 'as-is', without any express or implied 5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the author be held liable for any damages 6 warranty. In no event will the author be held liable for any damages
@@ -21,38 +21,69 @@
21 Mark Adler madler@alumni.caltech.edu 21 Mark Adler madler@alumni.caltech.edu
22 */ 22 */
23 23
24/* Version History:
25 1.0 26 Nov 2004 First version
26 2.0 25 Apr 2008 Complete redesign for recovery of interrupted operations
27 Interface changed slightly in that now path is a prefix
28 Compression now occurs as needed during gzlog_write()
29 gzlog_write() now always leaves the log file as valid gzip
30 */
31
24/* 32/*
25 The gzlog object allows writing short messages to a gzipped log file, 33 The gzlog object allows writing short messages to a gzipped log file,
26 opening the log file locked for small bursts, and then closing it. The log 34 opening the log file locked for small bursts, and then closing it. The log
27 object works by appending stored data to the gzip file until 1 MB has been 35 object works by appending stored (uncompressed) data to the gzip file until
28 accumulated. At that time, the stored data is compressed, and replaces the 36 1 MB has been accumulated. At that time, the stored data is compressed, and
29 uncompressed data in the file. The log file is truncated to its new size at 37 replaces the uncompressed data in the file. The log file is truncated to
30 that time. After closing, the log file is always valid gzip file that can 38 its new size at that time. After each write operation, the log file is a
31 decompressed to recover what was written. 39 valid gzip file that can decompressed to recover what was written.
32 40
33 A gzip header "extra" field contains two file offsets for appending. The 41 The gzlog operations can be interupted at any point due to an application or
34 first points to just after the last compressed data. The second points to 42 system crash, and the log file will be recovered the next time the log is
35 the last stored block in the deflate stream, which is empty. All of the 43 opened with gzlog_open().
36 data between those pointers is uncompressed.
37 */ 44 */
38 45
46#ifndef GZLOG_H
47#define GZLOG_H
48
49/* gzlog object type */
50typedef void gzlog;
51
39/* Open a gzlog object, creating the log file if it does not exist. Return 52/* Open a gzlog object, creating the log file if it does not exist. Return
40 NULL on error. Note that gzlog_open() could take a long time to return if 53 NULL on error. Note that gzlog_open() could take a while to complete if it
41 there is difficulty in locking the file. */ 54 has to wait to verify that a lock is stale (possibly for five minutes), or
42void *gzlog_open(char *path); 55 if there is significant contention with other instantiations of this object
43 56 when locking the resource. path is the prefix of the file names created by
44/* Write to a gzlog object. Return non-zero on error. This function will 57 this object. If path is "foo", then the log file will be "foo.gz", and
45 simply write data to the file uncompressed. Compression of the data 58 other auxiliary files will be created and destroyed during the process:
46 will not occur until gzlog_close() is called. It is expected that 59 "foo.dict" for a compression dictionary, "foo.temp" for a temporary (next)
47 gzlog_write() is used for a short message, and then gzlog_close() is 60 dictionary, "foo.add" for data being added or compressed, "foo.lock" for the
48 called. If a large amount of data is to be written, then the application 61 lock file, and "foo.repairs" to log recovery operations performed due to
49 should write no more than 1 MB at a time with gzlog_write() before 62 interrupted gzlog operations. A gzlog_open() followed by a gzlog_close()
50 calling gzlog_close() and then gzlog_open() again. */ 63 will recover a previously interrupted operation, if any. */
51int gzlog_write(void *log, char *data, size_t len); 64gzlog *gzlog_open(char *path);
52 65
53/* Close a gzlog object. Return non-zero on error. The log file is locked 66/* Write to a gzlog object. Return zero on success, -1 if there is a file i/o
54 until this function is called. This function will compress stored data 67 error on any of the gzlog files (this should not happen if gzlog_open()
55 at the end of the gzip file if at least 1 MB has been accumulated. Note 68 succeeded, unless the device has run out of space or leftover auxiliary
56 that the file will not be a valid gzip file until this function completes. 69 files have permissions or ownership that prevent their use), -2 if there is
57 */ 70 a memory allocation failure, or -3 if the log argument is invalid (e.g. if
58int gzlog_close(void *log); 71 it was not created by gzlog_open()). This function will write data to the
72 file uncompressed, until 1 MB has been accumulated, at which time that data
73 will be compressed. The log file will be a valid gzip file upon successful
74 return. */
75int gzlog_write(gzlog *log, void *data, size_t len);
76
77/* Force compression of any uncompressed data in the log. This should be used
78 sparingly, if at all. The main application would be when a log file will
79 not be appended to again. If this is used to compress frequently while
80 appending, it will both significantly increase the execution time and
81 reduce the compression ratio. The return codes are the same as for
82 gzlog_write(). */
83int gzlog_compress(gzlog *log);
84
85/* Close a gzlog object. Return zero on success, -3 if the log argument is
86 invalid. The log object is freed, and so cannot be referenced again. */
87int gzlog_close(gzlog *log);
88
89#endif
diff --git a/examples/pigz.c b/examples/pigz.c
new file mode 100644
index 0000000..42794d0
--- /dev/null
+++ b/examples/pigz.c
@@ -0,0 +1,452 @@
1/* pigz.c -- parallel implementation of gzip
2 * Copyright (C) 2007 Mark Adler
3 * Version 1.1 28 January 2007 Mark Adler
4 */
5
6/* Version history:
7 1.0 17 Jan 2007 First version
8 1.1 28 Jan 2007 Avoid void * arithmetic (some compilers don't get that)
9 Add note about requiring zlib 1.2.3
10 Allow compression level 0 (no compression)
11 Completely rewrite parallelism -- add a write thread
12 Use deflateSetDictionary() to make use of history
13 Tune argument defaults to best performance on four cores
14 */
15
16/*
17 pigz compresses from stdin to stdout using threads to make use of multiple
18 processors and cores. The input is broken up into 128 KB chunks, and each
19 is compressed separately. The CRC for each chunk is also calculated
20 separately. The compressed chunks are written in order to the output,
21 and the overall CRC is calculated from the CRC's of the chunks.
22
23 The compressed data format generated is the gzip format using the deflate
24 compression method. First a gzip header is written, followed by raw deflate
25 partial streams. They are partial, in that they do not have a terminating
26 block. At the end, the deflate stream is terminated with a final empty
27 static block, and lastly a gzip trailer is written with the CRC and the
28 number of input bytes.
29
30 Each raw deflate partial stream is terminated by an empty stored block
31 (using the Z_SYNC_FLUSH option of zlib), in order to end that partial
32 bit stream at a byte boundary. That allows the partial streams to be
33 concantenated simply as sequences of bytes. This adds a very small four
34 or five byte overhead to the output for each input chunk.
35
36 zlib's crc32_combine() routine allows the calcuation of the CRC of the
37 entire input using the independent CRC's of the chunks. pigz requires zlib
38 version 1.2.3 or later, since that is the first version that provides the
39 crc32_combine() function.
40
41 pigz uses the POSIX pthread library for thread control and communication.
42 */
43
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <pthread.h>
48#include <sys/types.h>
49#include <sys/uio.h>
50#include <unistd.h>
51#include "zlib.h"
52
53#define local static
54
55/* exit with error */
56local void bail(char *msg)
57{
58 fprintf(stderr, "pigz abort: %s\n", msg);
59 exit(1);
60}
61
62/* read up to len bytes into buf, repeating read() calls as needed */
63local size_t readn(int desc, unsigned char *buf, size_t len)
64{
65 ssize_t ret;
66 size_t got;
67
68 got = 0;
69 while (len) {
70 ret = read(desc, buf, len);
71 if (ret < 0)
72 bail("read error");
73 if (ret == 0)
74 break;
75 buf += ret;
76 len -= ret;
77 got += ret;
78 }
79 return got;
80}
81
82/* write len bytes, repeating write() calls as needed */
83local void writen(int desc, unsigned char *buf, size_t len)
84{
85 ssize_t ret;
86
87 while (len) {
88 ret = write(desc, buf, len);
89 if (ret < 1)
90 bail("write error");
91 buf += ret;
92 len -= ret;
93 }
94}
95
96/* a flag variable for communication between two threads */
97struct flag {
98 int value; /* value of flag */
99 pthread_mutex_t lock; /* lock for checking and changing flag */
100 pthread_cond_t cond; /* condition for signaling on flag change */
101};
102
103/* initialize a flag for use, starting with value val */
104local void flag_init(struct flag *me, int val)
105{
106 me->value = val;
107 pthread_mutex_init(&(me->lock), NULL);
108 pthread_cond_init(&(me->cond), NULL);
109}
110
111/* set the flag to val, signal another process that may be waiting for it */
112local void flag_set(struct flag *me, int val)
113{
114 pthread_mutex_lock(&(me->lock));
115 me->value = val;
116 pthread_cond_signal(&(me->cond));
117 pthread_mutex_unlock(&(me->lock));
118}
119
120/* if it isn't already, wait for some other thread to set the flag to val */
121local void flag_wait(struct flag *me, int val)
122{
123 pthread_mutex_lock(&(me->lock));
124 while (me->value != val)
125 pthread_cond_wait(&(me->cond), &(me->lock));
126 pthread_mutex_unlock(&(me->lock));
127}
128
129/* if flag is equal to val, wait for some other thread to change it */
130local void flag_wait_not(struct flag *me, int val)
131{
132 pthread_mutex_lock(&(me->lock));
133 while (me->value == val)
134 pthread_cond_wait(&(me->cond), &(me->lock));
135 pthread_mutex_unlock(&(me->lock));
136}
137
138/* clean up the flag when done with it */
139local void flag_done(struct flag *me)
140{
141 pthread_cond_destroy(&(me->cond));
142 pthread_mutex_destroy(&(me->lock));
143}
144
145/* a unit of work to feed to compress_thread() -- it is assumed that the out
146 buffer is large enough to hold the maximum size len bytes could deflate to,
147 plus five bytes for the final sync marker */
148struct work {
149 size_t len; /* length of input */
150 unsigned long crc; /* crc of input */
151 unsigned char *buf; /* input */
152 unsigned char *out; /* space for output (guaranteed big enough) */
153 z_stream strm; /* pre-initialized z_stream */
154 struct flag busy; /* busy flag indicating work unit in use */
155 pthread_t comp; /* this compression thread */
156};
157
158/* busy flag values */
159#define IDLE 0 /* compress and writing done -- can start compress */
160#define COMP 1 /* compress -- input and output buffers in use */
161#define WRITE 2 /* compress done, writing output -- can read input */
162
163/* read-only globals (set by main/read thread before others started) */
164local int ind; /* input file descriptor */
165local int outd; /* output file descriptor */
166local int level; /* compression level */
167local int procs; /* number of compression threads (>= 2) */
168local size_t size; /* uncompressed input size per thread (>= 32K) */
169local struct work *jobs; /* work units: jobs[0..procs-1] */
170
171/* next and previous jobs[] indices */
172#define NEXT(n) ((n) == procs - 1 ? 0 : (n) + 1)
173#define PREV(n) ((n) == 0 ? procs - 1 : (n) - 1)
174
175/* sliding dictionary size for deflate */
176#define DICT 32768U
177
178/* largest power of 2 that fits in an unsigned int -- used to limit requests
179 to zlib functions that use unsigned int lengths */
180#define MAX ((((unsigned)-1) >> 1) + 1)
181
182/* compress thread: compress the input in the provided work unit and compute
183 its crc -- assume that the amount of space at job->out is guaranteed to be
184 enough for the compressed output, as determined by the maximum expansion
185 of deflate compression -- use the input in the previous work unit (if there
186 is one) to set the deflate dictionary for better compression */
187local void *compress_thread(void *arg)
188{
189 size_t len; /* input length for this work unit */
190 unsigned long crc; /* crc of input data */
191 struct work *prev; /* previous work unit */
192 struct work *job = arg; /* work unit for this thread */
193 z_stream *strm = &(job->strm); /* zlib stream for this work unit */
194
195 /* reset state for a new compressed stream */
196 (void)deflateReset(strm);
197
198 /* initialize input, output, and crc */
199 strm->next_in = job->buf;
200 strm->next_out = job->out;
201 len = job->len;
202 crc = crc32(0L, Z_NULL, 0);
203
204 /* set dictionary if this isn't the first work unit, and if we will be
205 compressing something (the read thread assures that the dictionary
206 data in the previous work unit is still there) */
207 prev = jobs + PREV(job - jobs);
208 if (prev->buf != NULL && len != 0)
209 deflateSetDictionary(strm, prev->buf + (size - DICT), DICT);
210
211 /* run MAX-sized amounts of input through deflate and crc32 -- this loop
212 is needed for those cases where the integer type is smaller than the
213 size_t type, or when len is close to the limit of the size_t type */
214 while (len > MAX) {
215 strm->avail_in = MAX;
216 strm->avail_out = (unsigned)-1;
217 crc = crc32(crc, strm->next_in, strm->avail_in);
218 (void)deflate(strm, Z_NO_FLUSH);
219 len -= MAX;
220 }
221
222 /* run last piece through deflate and crc32, follow with a sync marker */
223 if (len) {
224 strm->avail_in = len;
225 strm->avail_out = (unsigned)-1;
226 crc = crc32(crc, strm->next_in, strm->avail_in);
227 (void)deflate(strm, Z_SYNC_FLUSH);
228 }
229
230 /* don't need to Z_FINISH, since we'd delete the last two bytes anyway */
231
232 /* return result */
233 job->crc = crc;
234 return NULL;
235}
236
237/* put a 4-byte integer into a byte array in LSB order */
238#define PUT4(a,b) (*(a)=(b),(a)[1]=(b)>>8,(a)[2]=(b)>>16,(a)[3]=(b)>>24)
239
240/* write thread: wait for compression threads to complete, write output in
241 order, also write gzip header and trailer around the compressed data */
242local void *write_thread(void *arg)
243{
244 int n; /* compress thread index */
245 size_t len; /* length of input processed */
246 unsigned long tot; /* total uncompressed size (overflow ok) */
247 unsigned long crc; /* CRC-32 of uncompressed data */
248 unsigned char wrap[10]; /* gzip header or trailer */
249
250 /* write simple gzip header */
251 memcpy(wrap, "\037\213\10\0\0\0\0\0\0\3", 10);
252 wrap[8] = level == 9 ? 2 : (level == 1 ? 4 : 0);
253 writen(outd, wrap, 10);
254
255 /* process output of compress threads until end of input */
256 tot = 0;
257 crc = crc32(0L, Z_NULL, 0);
258 n = 0;
259 do {
260 /* wait for compress thread to start, then wait to complete */
261 flag_wait(&(jobs[n].busy), COMP);
262 pthread_join(jobs[n].comp, NULL);
263
264 /* now that compress is done, allow read thread to use input buffer */
265 flag_set(&(jobs[n].busy), WRITE);
266
267 /* write compressed data and update length and crc */
268 writen(outd, jobs[n].out, jobs[n].strm.next_out - jobs[n].out);
269 len = jobs[n].len;
270 tot += len;
271 crc = crc32_combine(crc, jobs[n].crc, len);
272
273 /* release this work unit and go to the next work unit */
274 flag_set(&(jobs[n].busy), IDLE);
275 n = NEXT(n);
276
277 /* an input buffer less than size in length indicates end of input */
278 } while (len == size);
279
280 /* write final static block and gzip trailer (crc and len mod 2^32) */
281 wrap[0] = 3; wrap[1] = 0;
282 PUT4(wrap + 2, crc);
283 PUT4(wrap + 6, tot);
284 writen(outd, wrap, 10);
285 return NULL;
286}
287
288/* one-time initialization of a work unit -- this is where we set the deflate
289 compression level and request raw deflate, and also where we set the size
290 of the output buffer to guarantee enough space for a worst-case deflate
291 ending with a Z_SYNC_FLUSH */
292local void job_init(struct work *job)
293{
294 int ret; /* deflateInit2() return value */
295
296 job->buf = malloc(size);
297 job->out = malloc(size + (size >> 11) + 10);
298 job->strm.zfree = Z_NULL;
299 job->strm.zalloc = Z_NULL;
300 job->strm.opaque = Z_NULL;
301 ret = deflateInit2(&(job->strm), level, Z_DEFLATED, -15, 8,
302 Z_DEFAULT_STRATEGY);
303 if (job->buf == NULL || job->out == NULL || ret != Z_OK)
304 bail("not enough memory");
305}
306
307/* compress ind to outd in the gzip format, using multiple threads for the
308 compression and crc calculation and another thread for writing the output --
309 the read thread is the main thread */
310local void read_thread(void)
311{
312 int n; /* general index */
313 size_t got; /* amount read */
314 pthread_attr_t attr; /* thread attributes (left at defaults) */
315 pthread_t write; /* write thread */
316
317 /* set defaults (not all pthread implementations default to joinable) */
318 pthread_attr_init(&attr);
319 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
320
321 /* allocate and set up work list (individual work units will be initialized
322 as needed, in case the input is short), assure that allocation size
323 arithmetic does not overflow */
324 if (size + (size >> 11) + 10 < (size >> 11) + 10 ||
325 (ssize_t)(size + (size >> 11) + 10) < 0 ||
326 ((size_t)0 - 1) / procs <= sizeof(struct work) ||
327 (jobs = malloc(procs * sizeof(struct work))) == NULL)
328 bail("not enough memory");
329 for (n = 0; n < procs; n++) {
330 jobs[n].buf = NULL;
331 flag_init(&(jobs[n].busy), IDLE);
332 }
333
334 /* start write thread */
335 pthread_create(&write, &attr, write_thread, NULL);
336
337 /* read from input and start compress threads (write thread will pick up
338 the output of the compress threads) */
339 n = 0;
340 do {
341 /* initialize this work unit if it's the first time it's used */
342 if (jobs[n].buf == NULL)
343 job_init(jobs + n);
344
345 /* read input data, but wait for last compress on this work unit to be
346 done, and wait for the dictionary to be used by the last compress on
347 the next work unit */
348 flag_wait_not(&(jobs[n].busy), COMP);
349 flag_wait_not(&(jobs[NEXT(n)].busy), COMP);
350 got = readn(ind, jobs[n].buf, size);
351
352 /* start compress thread, but wait for write to be done first */
353 flag_wait(&(jobs[n].busy), IDLE);
354 jobs[n].len = got;
355 pthread_create(&(jobs[n].comp), &attr, compress_thread, jobs + n);
356
357 /* mark work unit so write thread knows compress was started */
358 flag_set(&(jobs[n].busy), COMP);
359
360 /* go to the next work unit */
361 n = NEXT(n);
362
363 /* do until end of input, indicated by a read less than size */
364 } while (got == size);
365
366 /* wait for the write thread to complete -- the write thread will join with
367 all of the compress threads, so this waits for all of the threads to
368 complete */
369 pthread_join(write, NULL);
370
371 /* free up all requested resources and return */
372 for (n = procs - 1; n >= 0; n--) {
373 flag_done(&(jobs[n].busy));
374 (void)deflateEnd(&(jobs[n].strm));
375 free(jobs[n].out);
376 free(jobs[n].buf);
377 }
378 free(jobs);
379 pthread_attr_destroy(&attr);
380}
381
382/* Process arguments for level, size, and procs, compress from stdin to
383 stdout in the gzip format. Note that procs must be at least two in
384 order to provide a dictionary in one work unit for the other work
385 unit, and that size must be at least 32K to store a full dictionary. */
386int main(int argc, char **argv)
387{
388 int n; /* general index */
389 int get; /* command line parameters to get */
390 char *arg; /* command line argument */
391
392 /* set defaults -- 32 processes and 128K buffers was found to provide
393 good utilization of four cores (about 97%) and balanced the overall
394 execution time impact of more threads against more dictionary
395 processing for a fixed amount of memory -- the memory usage for these
396 settings and full use of all work units (at least 4 MB of input) is
397 16.2 MB
398 */
399 level = Z_DEFAULT_COMPRESSION;
400 procs = 32;
401 size = 131072UL;
402
403 /* process command-line arguments */
404 get = 0;
405 for (n = 1; n < argc; n++) {
406 arg = argv[n];
407 if (*arg == '-') {
408 while (*++arg)
409 if (*arg >= '0' && *arg <= '9') /* compression level */
410 level = *arg - '0';
411 else if (*arg == 'b') /* chunk size in K */
412 get |= 1;
413 else if (*arg == 'p') /* number of processes */
414 get |= 2;
415 else if (*arg == 'h') { /* help */
416 fputs("usage: pigz [-0..9] [-b blocksizeinK]", stderr);
417 fputs(" [-p processes] < foo > foo.gz\n", stderr);
418 return 0;
419 }
420 else
421 bail("invalid option");
422 }
423 else if (get & 1) {
424 if (get & 2)
425 bail("you need to separate the -b and -p options");
426 size = (size_t)(atol(arg)) << 10; /* chunk size */
427 if (size < DICT)
428 bail("invalid option");
429 get = 0;
430 }
431 else if (get & 2) {
432 procs = atoi(arg); /* processes */
433 if (procs < 2)
434 bail("invalid option");
435 get = 0;
436 }
437 else
438 bail("invalid option (you need to pipe input and output)");
439 }
440 if (get)
441 bail("missing option argument");
442
443 /* do parallel compression from stdin to stdout (the read thread starts up
444 the write thread and the compression threads, and they all join before
445 the read thread returns) */
446 ind = 0;
447 outd = 1;
448 read_thread();
449
450 /* done */
451 return 0;
452}
diff --git a/gzio.c b/gzio.c
index df34620..cf55486 100644
--- a/gzio.c
+++ b/gzio.c
@@ -1,5 +1,5 @@
1/* gzio.c -- IO on .gz files 1/* gzio.c -- IO on .gz files
2 * Copyright (C) 1995-2006 Jean-loup Gailly. 2 * Copyright (C) 1995-2009 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 * 4 *
5 * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. 5 * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
@@ -71,43 +71,32 @@ static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
71 71
72typedef struct gz_stream { 72typedef struct gz_stream {
73 z_stream stream; 73 z_stream stream;
74 int z_err; /* error code for last stream operation */ 74 int z_err; /* error code for last stream operation */
75 int z_eof; /* set if end of input file */ 75 int z_eof; /* set if end of input file */
76 FILE *file; /* .gz file */ 76 FILE *file; /* .gz file */
77 Byte *inbuf; /* input buffer */ 77 Byte *inbuf; /* input buffer */
78 Byte *outbuf; /* output buffer */ 78 Byte *outbuf; /* output buffer */
79 uLong crc; /* crc32 of uncompressed data */ 79 uLong crc; /* crc32 of uncompressed data */
80 char *msg; /* error message */ 80 char *msg; /* error message */
81 char *path; /* path name for debugging only */ 81 char *path; /* path name for debugging only */
82 int transparent; /* 1 if input file is not a .gz file */ 82 int transparent; /* 1 if input file is not a .gz file */
83 char mode; /* 'w' or 'r' */ 83 char mode; /* 'w' or 'r' */
84#ifdef _LARGEFILE64_SOURCE 84 z_off64_t start; /* start of compressed data in file */
85 off64_t start; /* start of compressed data in file (header skipped) */ 85 z_off64_t in; /* bytes into deflate or inflate */
86 off64_t in; /* bytes into deflate or inflate */ 86 z_off64_t out; /* bytes out of deflate or inflate */
87 off64_t out; /* bytes out of deflate or inflate */ 87 int back; /* one character push-back */
88#else 88 int last; /* true if push-back is last character */
89 z_off_t start; /* start of compressed data in file (header skipped) */
90 z_off_t in; /* bytes into deflate or inflate */
91 z_off_t out; /* bytes out of deflate or inflate */
92#endif
93 int back; /* one character push-back */
94 int last; /* true if push-back is last character */
95} gz_stream; 89} gz_stream;
96 90
97 91
98local gzFile gz_open OF((const char *path, const char *mode, int fd, 92local gzFile gz_open OF((const char *, const char *, int, int));
99 int use64)); 93local z_off64_t gz_seek OF((gzFile, z_off64_t, int, int));
100#ifdef _LARGEFILE64_SOURCE 94local int do_flush OF((gzFile, int));
101local off64_t gz_seek OF((gzFile file, off64_t offset, int whence, int use64)); 95local int get_byte OF((gz_stream *));
102#else 96local void check_header OF((gz_stream *));
103local z_off_t gz_seek OF((gzFile file, z_off_t offset, int whence, int use64)); 97local int destroy OF((gz_stream *));
104#endif 98local void putLong OF((FILE *, uLong));
105local int do_flush OF((gzFile file, int flush)); 99local uLong getLong OF((gz_stream *));
106local int get_byte OF((gz_stream *s));
107local void check_header OF((gz_stream *s));
108local int destroy OF((gz_stream *s));
109local void putLong OF((FILE *file, uLong x));
110local uLong getLong OF((gz_stream *s));
111 100
112/* =========================================================================== 101/* ===========================================================================
113 Opens a gzip (.gz) file for reading or writing. The mode parameter 102 Opens a gzip (.gz) file for reading or writing. The mode parameter
@@ -143,6 +132,7 @@ local gzFile gz_open (path, mode, fd, use64)
143 s->stream.next_in = s->inbuf = Z_NULL; 132 s->stream.next_in = s->inbuf = Z_NULL;
144 s->stream.next_out = s->outbuf = Z_NULL; 133 s->stream.next_out = s->outbuf = Z_NULL;
145 s->stream.avail_in = s->stream.avail_out = 0; 134 s->stream.avail_in = s->stream.avail_out = 0;
135 s->stream.state = Z_NULL;
146 s->file = NULL; 136 s->file = NULL;
147 s->z_err = Z_OK; 137 s->z_err = Z_OK;
148 s->z_eof = 0; 138 s->z_eof = 0;
@@ -442,7 +432,7 @@ int ZEXPORT gzread (file, buf, len)
442 if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; 432 if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
443 433
444 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; 434 if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
445 if (s->z_err == Z_STREAM_END) return 0; /* EOF */ 435 if (s->z_err == Z_STREAM_END || s->z_eof) return 0; /* EOF */
446 436
447 next_out = (Byte*)buf; 437 next_out = (Byte*)buf;
448 s->stream.next_out = (Bytef*)buf; 438 s->stream.next_out = (Bytef*)buf;
@@ -482,7 +472,7 @@ int ZEXPORT gzread (file, buf, len)
482 len -= s->stream.avail_out; 472 len -= s->stream.avail_out;
483 s->in += len; 473 s->in += len;
484 s->out += len; 474 s->out += len;
485 if (len == 0) s->z_eof = 1; 475 if (feof(s->file)) s->z_eof = 1;
486 return (int)len; 476 return (int)len;
487 } 477 }
488 if (s->stream.avail_in == 0 && !s->z_eof) { 478 if (s->stream.avail_in == 0 && !s->z_eof) {
@@ -803,15 +793,9 @@ int ZEXPORT gzflush (file, flush)
803 SEEK_END is not implemented, returns error. 793 SEEK_END is not implemented, returns error.
804 In this version of the library, gzseek can be extremely slow. 794 In this version of the library, gzseek can be extremely slow.
805*/ 795*/
806#ifdef _LARGEFILE64_SOURCE 796local z_off64_t gz_seek (file, offset, whence, use64)
807local off64_t gz_seek (file, offset, whence, use64)
808 gzFile file;
809 off64_t offset;
810#else
811local z_off_t gz_seek (file, offset, whence, use64)
812 gzFile file; 797 gzFile file;
813 z_off_t offset; 798 z_off64_t offset;
814#endif
815 int whence; 799 int whence;
816 int use64; 800 int use64;
817{ 801{
@@ -914,23 +898,17 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
914 return (z_off_t)gz_seek(file, offset, whence, 0); 898 return (z_off_t)gz_seek(file, offset, whence, 0);
915} 899}
916 900
917#ifdef _LARGEFILE64_SOURCE 901z_off64_t ZEXPORT gzseek64 (file, offset, whence)
918off64_t ZEXPORT gzseek64 (file, offset, whence)
919 gzFile file; 902 gzFile file;
920 off64_t offset; 903 z_off64_t offset;
921 int whence; 904 int whence;
922{ 905{
906#ifdef _LARGEFILE64_SOURCE
923 return gz_seek(file, offset, whence, 1); 907 return gz_seek(file, offset, whence, 1);
924}
925#else 908#else
926z_off_t ZEXPORT gzseek64 (file, offset, whence)
927 gzFile file;
928 z_off_t offset;
929 int whence;
930{
931 return gz_seek(file, offset, whence, 0); 909 return gz_seek(file, offset, whence, 0);
932}
933#endif 910#endif
911}
934 912
935/* =========================================================================== 913/* ===========================================================================
936 Rewinds input file. 914 Rewinds input file.
@@ -968,11 +946,7 @@ z_off_t ZEXPORT gztell (file)
968/* =========================================================================== 946/* ===========================================================================
969 64-bit version 947 64-bit version
970*/ 948*/
971#ifdef _LARGEFILE64_SOURCE 949z_off64_t ZEXPORT gztell64 (file)
972off64_t ZEXPORT gztell64 (file)
973#else
974z_off_t ZEXPORT gztell64 (file)
975#endif
976 gzFile file; 950 gzFile file;
977{ 951{
978 return gzseek64(file, 0L, SEEK_CUR); 952 return gzseek64(file, 0L, SEEK_CUR);
diff --git a/infback.c b/infback.c
index be0b3dc..e279d8f 100644
--- a/infback.c
+++ b/infback.c
@@ -1,5 +1,5 @@
1/* infback.c -- inflate using a call-back interface 1/* infback.c -- inflate using a call-back interface
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2008 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -438,7 +438,16 @@ void FAR *out_desc;
438 /* handle error breaks in while */ 438 /* handle error breaks in while */
439 if (state->mode == BAD) break; 439 if (state->mode == BAD) break;
440 440
441 /* build code tables */ 441 /* check for end-of-block code (better have one) */
442 if (state->lens[256] == 0) {
443 strm->msg = (char *)"invalid code -- missing end-of-block";
444 state->mode = BAD;
445 break;
446 }
447
448 /* build code tables -- note: do not change the lenbits or distbits
449 values here (9 and 6) without reading the comments in inftrees.h
450 concerning the ENOUGH constants, which depend on those values */
442 state->next = state->codes; 451 state->next = state->codes;
443 state->lencode = (code const FAR *)(state->next); 452 state->lencode = (code const FAR *)(state->next);
444 state->lenbits = 9; 453 state->lenbits = 9;
diff --git a/inffast.c b/inffast.c
index 0b919bb..97f9a84 100644
--- a/inffast.c
+++ b/inffast.c
@@ -1,5 +1,5 @@
1/* inffast.c -- fast decoding 1/* inffast.c -- fast decoding
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2008 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -188,7 +188,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
188 op = dist - op; /* distance back in window */ 188 op = dist - op; /* distance back in window */
189 if (op > whave) { 189 if (op > whave) {
190 if (state->sane) { 190 if (state->sane) {
191 strm->msg = (char *)"invalid distance too far back"; 191 strm->msg =
192 (char *)"invalid distance too far back";
192 state->mode = BAD; 193 state->mode = BAD;
193 break; 194 break;
194 } 195 }
diff --git a/inflate.c b/inflate.c
index d3c718c..d069bbe 100644
--- a/inflate.c
+++ b/inflate.c
@@ -1,5 +1,5 @@
1/* inflate.c -- zlib decompression 1/* inflate.c -- zlib decompression
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2009 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -122,24 +122,47 @@ z_streamp strm;
122 state->bits = 0; 122 state->bits = 0;
123 state->lencode = state->distcode = state->next = state->codes; 123 state->lencode = state->distcode = state->next = state->codes;
124 state->sane = 1; 124 state->sane = 1;
125 state->back = -1;
125 Tracev((stderr, "inflate: reset\n")); 126 Tracev((stderr, "inflate: reset\n"));
126 return Z_OK; 127 return Z_OK;
127} 128}
128 129
129int ZEXPORT inflatePrime(strm, bits, value) 130int ZEXPORT inflateReset2(strm, windowBits)
130z_streamp strm; 131z_streamp strm;
131int bits; 132int windowBits;
132int value;
133{ 133{
134 int wrap;
134 struct inflate_state FAR *state; 135 struct inflate_state FAR *state;
135 136
137 /* get the state */
136 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 138 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
137 state = (struct inflate_state FAR *)strm->state; 139 state = (struct inflate_state FAR *)strm->state;
138 if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; 140
139 value &= (1L << bits) - 1; 141 /* extract wrap request from windowBits parameter */
140 state->hold += value << state->bits; 142 if (windowBits < 0) {
141 state->bits += bits; 143 wrap = 0;
142 return Z_OK; 144 windowBits = -windowBits;
145 }
146 else {
147 wrap = (windowBits >> 4) + 1;
148#ifdef GUNZIP
149 if (windowBits < 48)
150 windowBits &= 15;
151#endif
152 }
153
154 /* set number of window bits, free window if different */
155 if (windowBits < 8 || windowBits > 15)
156 return Z_STREAM_ERROR;
157 if (state->wbits != windowBits && state->window != Z_NULL) {
158 ZFREE(strm, state->window);
159 state->window = Z_NULL;
160 }
161
162 /* update state and reset the rest of it */
163 state->wrap = wrap;
164 state->wbits = (unsigned)windowBits;
165 return inflateReset(strm);
143} 166}
144 167
145int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) 168int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
@@ -148,6 +171,7 @@ int windowBits;
148const char *version; 171const char *version;
149int stream_size; 172int stream_size;
150{ 173{
174 int ret;
151 struct inflate_state FAR *state; 175 struct inflate_state FAR *state;
152 176
153 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 177 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
@@ -165,24 +189,13 @@ int stream_size;
165 if (state == Z_NULL) return Z_MEM_ERROR; 189 if (state == Z_NULL) return Z_MEM_ERROR;
166 Tracev((stderr, "inflate: allocated\n")); 190 Tracev((stderr, "inflate: allocated\n"));
167 strm->state = (struct internal_state FAR *)state; 191 strm->state = (struct internal_state FAR *)state;
168 if (windowBits < 0) { 192 state->window = Z_NULL;
169 state->wrap = 0; 193 ret = inflateReset2(strm, windowBits);
170 windowBits = -windowBits; 194 if (ret != Z_OK) {
171 }
172 else {
173 state->wrap = (windowBits >> 4) + 1;
174#ifdef GUNZIP
175 if (windowBits < 48) windowBits &= 15;
176#endif
177 }
178 if (windowBits < 8 || windowBits > 15) {
179 ZFREE(strm, state); 195 ZFREE(strm, state);
180 strm->state = Z_NULL; 196 strm->state = Z_NULL;
181 return Z_STREAM_ERROR;
182 } 197 }
183 state->wbits = (unsigned)windowBits; 198 return ret;
184 state->window = Z_NULL;
185 return inflateReset(strm);
186} 199}
187 200
188int ZEXPORT inflateInit_(strm, version, stream_size) 201int ZEXPORT inflateInit_(strm, version, stream_size)
@@ -193,6 +206,27 @@ int stream_size;
193 return inflateInit2_(strm, DEF_WBITS, version, stream_size); 206 return inflateInit2_(strm, DEF_WBITS, version, stream_size);
194} 207}
195 208
209int ZEXPORT inflatePrime(strm, bits, value)
210z_streamp strm;
211int bits;
212int value;
213{
214 struct inflate_state FAR *state;
215
216 if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
217 state = (struct inflate_state FAR *)strm->state;
218 if (bits < 0) {
219 state->hold = 0;
220 state->bits = 0;
221 return Z_OK;
222 }
223 if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
224 value &= (1L << bits) - 1;
225 state->hold += value << state->bits;
226 state->bits += bits;
227 return Z_OK;
228}
229
196/* 230/*
197 Return state with length and distance decoding tables and index sizes set to 231 Return state with length and distance decoding tables and index sizes set to
198 fixed code decoding. Normally this returns fixed tables from inffixed.h. 232 fixed code decoding. Normally this returns fixed tables from inffixed.h.
@@ -772,7 +806,7 @@ int flush;
772 strm->adler = state->check = adler32(0L, Z_NULL, 0); 806 strm->adler = state->check = adler32(0L, Z_NULL, 0);
773 state->mode = TYPE; 807 state->mode = TYPE;
774 case TYPE: 808 case TYPE:
775 if (flush == Z_BLOCK) goto inf_leave; 809 if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
776 case TYPEDO: 810 case TYPEDO:
777 if (state->last) { 811 if (state->last) {
778 BYTEBITS(); 812 BYTEBITS();
@@ -792,7 +826,11 @@ int flush;
792 fixedtables(state); 826 fixedtables(state);
793 Tracev((stderr, "inflate: fixed codes block%s\n", 827 Tracev((stderr, "inflate: fixed codes block%s\n",
794 state->last ? " (last)" : "")); 828 state->last ? " (last)" : ""));
795 state->mode = LEN; /* decode codes */ 829 state->mode = LEN_; /* decode codes */
830 if (flush == Z_TREES) {
831 DROPBITS(2);
832 goto inf_leave;
833 }
796 break; 834 break;
797 case 2: /* dynamic block */ 835 case 2: /* dynamic block */
798 Tracev((stderr, "inflate: dynamic codes block%s\n", 836 Tracev((stderr, "inflate: dynamic codes block%s\n",
@@ -817,6 +855,9 @@ int flush;
817 Tracev((stderr, "inflate: stored length %u\n", 855 Tracev((stderr, "inflate: stored length %u\n",
818 state->length)); 856 state->length));
819 INITBITS(); 857 INITBITS();
858 state->mode = COPY_;
859 if (flush == Z_TREES) goto inf_leave;
860 case COPY_:
820 state->mode = COPY; 861 state->mode = COPY;
821 case COPY: 862 case COPY:
822 copy = state->length; 863 copy = state->length;
@@ -926,7 +967,16 @@ int flush;
926 /* handle error breaks in while */ 967 /* handle error breaks in while */
927 if (state->mode == BAD) break; 968 if (state->mode == BAD) break;
928 969
929 /* build code tables */ 970 /* check for end-of-block code (better have one) */
971 if (state->lens[256] == 0) {
972 strm->msg = (char *)"invalid code -- missing end-of-block";
973 state->mode = BAD;
974 break;
975 }
976
977 /* build code tables -- note: do not change the lenbits or distbits
978 values here (9 and 6) without reading the comments in inftrees.h
979 concerning the ENOUGH constants, which depend on those values */
930 state->next = state->codes; 980 state->next = state->codes;
931 state->lencode = (code const FAR *)(state->next); 981 state->lencode = (code const FAR *)(state->next);
932 state->lenbits = 9; 982 state->lenbits = 9;
@@ -947,14 +997,20 @@ int flush;
947 break; 997 break;
948 } 998 }
949 Tracev((stderr, "inflate: codes ok\n")); 999 Tracev((stderr, "inflate: codes ok\n"));
1000 state->mode = LEN_;
1001 if (flush == Z_TREES) goto inf_leave;
1002 case LEN_:
950 state->mode = LEN; 1003 state->mode = LEN;
951 case LEN: 1004 case LEN:
952 if (have >= 6 && left >= 258) { 1005 if (have >= 6 && left >= 258) {
953 RESTORE(); 1006 RESTORE();
954 inflate_fast(strm, out); 1007 inflate_fast(strm, out);
955 LOAD(); 1008 LOAD();
1009 if (state->mode == TYPE)
1010 state->back = -1;
956 break; 1011 break;
957 } 1012 }
1013 state->back = 0;
958 for (;;) { 1014 for (;;) {
959 here = state->lencode[BITS(state->lenbits)]; 1015 here = state->lencode[BITS(state->lenbits)];
960 if ((unsigned)(here.bits) <= bits) break; 1016 if ((unsigned)(here.bits) <= bits) break;
@@ -969,8 +1025,10 @@ int flush;
969 PULLBYTE(); 1025 PULLBYTE();
970 } 1026 }
971 DROPBITS(last.bits); 1027 DROPBITS(last.bits);
1028 state->back += last.bits;
972 } 1029 }
973 DROPBITS(here.bits); 1030 DROPBITS(here.bits);
1031 state->back += here.bits;
974 state->length = (unsigned)here.val; 1032 state->length = (unsigned)here.val;
975 if ((int)(here.op) == 0) { 1033 if ((int)(here.op) == 0) {
976 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 1034 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
@@ -981,6 +1039,7 @@ int flush;
981 } 1039 }
982 if (here.op & 32) { 1040 if (here.op & 32) {
983 Tracevv((stderr, "inflate: end of block\n")); 1041 Tracevv((stderr, "inflate: end of block\n"));
1042 state->back = -1;
984 state->mode = TYPE; 1043 state->mode = TYPE;
985 break; 1044 break;
986 } 1045 }
@@ -996,8 +1055,10 @@ int flush;
996 NEEDBITS(state->extra); 1055 NEEDBITS(state->extra);
997 state->length += BITS(state->extra); 1056 state->length += BITS(state->extra);
998 DROPBITS(state->extra); 1057 DROPBITS(state->extra);
1058 state->back += state->extra;
999 } 1059 }
1000 Tracevv((stderr, "inflate: length %u\n", state->length)); 1060 Tracevv((stderr, "inflate: length %u\n", state->length));
1061 state->was = state->length;
1001 state->mode = DIST; 1062 state->mode = DIST;
1002 case DIST: 1063 case DIST:
1003 for (;;) { 1064 for (;;) {
@@ -1014,8 +1075,10 @@ int flush;
1014 PULLBYTE(); 1075 PULLBYTE();
1015 } 1076 }
1016 DROPBITS(last.bits); 1077 DROPBITS(last.bits);
1078 state->back += last.bits;
1017 } 1079 }
1018 DROPBITS(here.bits); 1080 DROPBITS(here.bits);
1081 state->back += here.bits;
1019 if (here.op & 64) { 1082 if (here.op & 64) {
1020 strm->msg = (char *)"invalid distance code"; 1083 strm->msg = (char *)"invalid distance code";
1021 state->mode = BAD; 1084 state->mode = BAD;
@@ -1029,6 +1092,7 @@ int flush;
1029 NEEDBITS(state->extra); 1092 NEEDBITS(state->extra);
1030 state->offset += BITS(state->extra); 1093 state->offset += BITS(state->extra);
1031 DROPBITS(state->extra); 1094 DROPBITS(state->extra);
1095 state->back += state->extra;
1032 } 1096 }
1033#ifdef INFLATE_STRICT 1097#ifdef INFLATE_STRICT
1034 if (state->offset > state->dmax) { 1098 if (state->offset > state->dmax) {
@@ -1066,6 +1130,9 @@ int flush;
1066 } 1130 }
1067 if (copy > state->write) { 1131 if (copy > state->write) {
1068 copy -= state->write; 1132 copy -= state->write;
1133 /* %% problem here if copy > state->wsize -- avoid? */
1134 /* %% or can (state->window + state->wsize) - copy */
1135 /* %% but really should detect and reject this case */
1069 from = state->window + (state->wsize - copy); 1136 from = state->window + (state->wsize - copy);
1070 } 1137 }
1071 else 1138 else
@@ -1162,7 +1229,8 @@ int flush;
1162 strm->adler = state->check = 1229 strm->adler = state->check =
1163 UPDATE(state->check, strm->next_out - out, out); 1230 UPDATE(state->check, strm->next_out - out, out);
1164 strm->data_type = state->bits + (state->last ? 64 : 0) + 1231 strm->data_type = state->bits + (state->last ? 64 : 0) +
1165 (state->mode == TYPE ? 128 : 0); 1232 (state->mode == TYPE ? 128 : 0) +
1233 (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
1166 if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 1234 if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
1167 ret = Z_BUF_ERROR; 1235 ret = Z_BUF_ERROR;
1168 return ret; 1236 return ret;
@@ -1399,3 +1467,15 @@ int subvert;
1399 return Z_DATA_ERROR; 1467 return Z_DATA_ERROR;
1400#endif 1468#endif
1401} 1469}
1470
1471long ZEXPORT inflateMark(strm)
1472z_streamp strm;
1473{
1474 struct inflate_state FAR *state;
1475
1476 if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
1477 state = (struct inflate_state FAR *)strm->state;
1478 return ((long)(state->back) << 16) +
1479 (state->mode == COPY ? state->length :
1480 (state->mode == MATCH ? state->was - state->length : 0));
1481}
diff --git a/inflate.h b/inflate.h
index d54a868..ba03e7c 100644
--- a/inflate.h
+++ b/inflate.h
@@ -1,5 +1,5 @@
1/* inflate.h -- internal inflate state definition 1/* inflate.h -- internal inflate state definition
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2009 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -32,11 +32,13 @@ typedef enum {
32 TYPE, /* i: waiting for type bits, including last-flag bit */ 32 TYPE, /* i: waiting for type bits, including last-flag bit */
33 TYPEDO, /* i: same, but skip check to exit inflate on new block */ 33 TYPEDO, /* i: same, but skip check to exit inflate on new block */
34 STORED, /* i: waiting for stored size (length and complement) */ 34 STORED, /* i: waiting for stored size (length and complement) */
35 COPY_, /* i/o: same as COPY below, but only first time in */
35 COPY, /* i/o: waiting for input or output to copy stored block */ 36 COPY, /* i/o: waiting for input or output to copy stored block */
36 TABLE, /* i: waiting for dynamic block table lengths */ 37 TABLE, /* i: waiting for dynamic block table lengths */
37 LENLENS, /* i: waiting for code length code lengths */ 38 LENLENS, /* i: waiting for code length code lengths */
38 CODELENS, /* i: waiting for length/lit and distance code lengths */ 39 CODELENS, /* i: waiting for length/lit and distance code lengths */
39 LEN, /* i: waiting for length/lit code */ 40 LEN_, /* i: same as LEN below, but only first time in */
41 LEN, /* i: waiting for length/lit/eob code */
40 LENEXT, /* i: waiting for length extra bits */ 42 LENEXT, /* i: waiting for length extra bits */
41 DIST, /* i: waiting for distance code */ 43 DIST, /* i: waiting for distance code */
42 DISTEXT, /* i: waiting for distance extra bits */ 44 DISTEXT, /* i: waiting for distance extra bits */
@@ -53,19 +55,21 @@ typedef enum {
53/* 55/*
54 State transitions between above modes - 56 State transitions between above modes -
55 57
56 (most modes can go to the BAD or MEM mode -- not shown for clarity) 58 (most modes can go to BAD or MEM on error -- not shown for clarity)
57 59
58 Process header: 60 Process header:
59 HEAD -> (gzip) or (zlib) 61 HEAD -> (gzip) or (zlib) or (raw)
60 (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME 62 (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
61 NAME -> COMMENT -> HCRC -> TYPE 63 HCRC -> TYPE
62 (zlib) -> DICTID or TYPE 64 (zlib) -> DICTID or TYPE
63 DICTID -> DICT -> TYPE 65 DICTID -> DICT -> TYPE
66 (raw) -> TYPEDO
64 Read deflate blocks: 67 Read deflate blocks:
65 TYPE -> STORED or TABLE or LEN or CHECK 68 TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
66 STORED -> COPY -> TYPE 69 STORED -> COPY_ -> COPY -> TYPE
67 TABLE -> LENLENS -> CODELENS -> LEN 70 TABLE -> LENLENS -> CODELENS -> LEN_
68 Read deflate codes: 71 LEN_ -> LEN
72 Read deflate codes in fixed or dynamic block:
69 LEN -> LENEXT or LIT or TYPE 73 LEN -> LENEXT or LIT or TYPE
70 LENEXT -> DIST -> DISTEXT -> MATCH -> LEN 74 LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
71 LIT -> LEN 75 LIT -> LEN
@@ -113,4 +117,6 @@ struct inflate_state {
113 unsigned short work[288]; /* work area for code table building */ 117 unsigned short work[288]; /* work area for code table building */
114 code codes[ENOUGH]; /* space for code tables */ 118 code codes[ENOUGH]; /* space for code tables */
115 int sane; /* if false, allow invalid distance too far */ 119 int sane; /* if false, allow invalid distance too far */
120 int back; /* bits back of last unprocessed length/lit */
121 unsigned was; /* initial length of match */
116}; 122};
diff --git a/inftrees.c b/inftrees.c
index fb8d843..2b12d70 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -1,5 +1,5 @@
1/* inftrees.c -- generate Huffman trees for efficient decoding 1/* inftrees.c -- generate Huffman trees for efficient decoding
2 * Copyright (C) 1995-2006 Mark Adler 2 * Copyright (C) 1995-2009 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -9,7 +9,7 @@
9#define MAXBITS 15 9#define MAXBITS 15
10 10
11const char inflate_copyright[] = 11const char inflate_copyright[] =
12 " inflate 1.2.3.3 Copyright 1995-2006 Mark Adler "; 12 " inflate 1.2.3.4 Copyright 1995-2008 Mark Adler ";
13/* 13/*
14 If you use the zlib library in a product, an acknowledgment is welcome 14 If you use the zlib library in a product, an acknowledgment is welcome
15 in the documentation of your product. If for some reason you cannot 15 in the documentation of your product. If for some reason you cannot
@@ -62,7 +62,7 @@ unsigned short FAR *work;
62 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 62 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
63 static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 63 static const unsigned short lext[31] = { /* Length codes 257..285 extra */
64 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 64 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
65 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 203}; 65 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 200};
66 static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 66 static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
67 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 67 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
68 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 68 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
@@ -123,7 +123,7 @@ unsigned short FAR *work;
123 *bits = 1; 123 *bits = 1;
124 return 0; /* no symbols, but wait for decoding to report error */ 124 return 0; /* no symbols, but wait for decoding to report error */
125 } 125 }
126 for (min = 1; min <= MAXBITS; min++) 126 for (min = 1; min < max; min++)
127 if (count[min] != 0) break; 127 if (count[min] != 0) break;
128 if (root < min) root = min; 128 if (root < min) root = min;
129 129
@@ -166,11 +166,10 @@ unsigned short FAR *work;
166 entered in the tables. 166 entered in the tables.
167 167
168 used keeps track of how many table entries have been allocated from the 168 used keeps track of how many table entries have been allocated from the
169 provided *table space. It is checked when a LENS table is being made 169 provided *table space. It is checked for LENS and DIST tables against
170 against the space in *table, ENOUGH, minus the maximum space needed by 170 the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
171 the worst case distance code, MAXD. This should never happen, but the 171 the initial root table size constants. See the comments in inftrees.h
172 sufficiency of ENOUGH has not been proven exhaustively, hence the check. 172 for more information.
173 This assumes that when type == LENS, bits == 9.
174 173
175 sym increments through all symbols, and the loop terminates when 174 sym increments through all symbols, and the loop terminates when
176 all codes of length max, i.e. all codes, have been processed. This 175 all codes of length max, i.e. all codes, have been processed. This
@@ -209,7 +208,8 @@ unsigned short FAR *work;
209 mask = used - 1; /* mask for comparing low */ 208 mask = used - 1; /* mask for comparing low */
210 209
211 /* check available table space */ 210 /* check available table space */
212 if (type == LENS && used >= ENOUGH - MAXD) 211 if ((type == LENS && used >= ENOUGH_LENS) ||
212 (type == DISTS && used >= ENOUGH_DISTS))
213 return 1; 213 return 1;
214 214
215 /* process all codes and make table entries */ 215 /* process all codes and make table entries */
@@ -277,7 +277,8 @@ unsigned short FAR *work;
277 277
278 /* check for enough space */ 278 /* check for enough space */
279 used += 1U << curr; 279 used += 1U << curr;
280 if (type == LENS && used >= ENOUGH - MAXD) 280 if ((type == LENS && used >= ENOUGH_LENS) ||
281 (type == DISTS && used >= ENOUGH_DISTS))
281 return 1; 282 return 1;
282 283
283 /* point entry in root table to sub-table */ 284 /* point entry in root table to sub-table */
diff --git a/inftrees.h b/inftrees.h
index b1104c8..67461da 100644
--- a/inftrees.h
+++ b/inftrees.h
@@ -35,15 +35,22 @@ typedef struct {
35 01000000 - invalid code 35 01000000 - invalid code
36 */ 36 */
37 37
38/* Maximum size of dynamic tree. The maximum found in a long but non- 38/* Maximum size of the dynamic table. The maximum number of code structures is
39 exhaustive search was 1444 code structures (852 for length/literals 39 1444, which is the sum of 852 for literal/length codes and 592 for distance
40 and 592 for distances, the latter actually the result of an 40 codes. These values were found by exhaustive searches using the program
41 exhaustive search). The true maximum is not known, but the value 41 examples/enough.c found in the zlib distribtution. The arguments to that
42 below is more than safe. */ 42 program are the number of symbols, the initial root table size, and the
43#define ENOUGH 2048 43 maximum bit length of a code. "enough 286 9 15" for literal/length codes
44#define MAXD 592 44 returns returns 852, and "enough 30 6 15" for distance codes returns 592.
45 The initial root table size (9 or 6) is found in the fifth argument of the
46 inflate_table() calls in inflate.c and infback.c. If the root table size is
47 changed, then these maximum sizes would be need to be recalculated and
48 updated. */
49#define ENOUGH_LENS 852
50#define ENOUGH_DISTS 592
51#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
45 52
46/* Type of code to build for inftable() */ 53/* Type of code to build for inflate_table() */
47typedef enum { 54typedef enum {
48 CODES, 55 CODES,
49 LENS, 56 LENS,
diff --git a/make_vms.com b/make_vms.com
index c8fa6a5..87c480a 100644
--- a/make_vms.com
+++ b/make_vms.com
@@ -10,6 +10,7 @@ $!
10$!------------------------------------------------------------------------------ 10$!------------------------------------------------------------------------------
11$! Version history 11$! Version history
12$! 0.01 20060120 First version to receive a number 12$! 0.01 20060120 First version to receive a number
13$! 0.02 20061008 Adapt to new Makefile.in
13$! 14$!
14$ on error then goto err_exit 15$ on error then goto err_exit
15$! 16$!
@@ -353,7 +354,7 @@ $!
353$CREA_OLIST: 354$CREA_OLIST:
354$ open/read min makefile.in 355$ open/read min makefile.in
355$ open/write mod modules.opt 356$ open/write mod modules.opt
356$ src_check = "OBJS =" 357$ src_check = "OBJC ="
357$MRLOOP: 358$MRLOOP:
358$ read/end=mrdone min rec 359$ read/end=mrdone min rec
359$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop 360$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop
diff --git a/qnx/package.qpg b/qnx/package.qpg
index be5d5c1..c37e91b 100644
--- a/qnx/package.qpg
+++ b/qnx/package.qpg
@@ -25,10 +25,10 @@
25 <QPG:Files> 25 <QPG:Files>
26 <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/> 26 <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
27 <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/> 27 <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
28 <QPG:Add file="../libz.so.1.2.3.3" install="/opt/lib/" user="root:bin" permission="644"/> 28 <QPG:Add file="../libz.so.1.2.3.4" install="/opt/lib/" user="root:bin" permission="644"/>
29 <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.3.3"/> 29 <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.3.4"/>
30 <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.3.3"/> 30 <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.3.4"/>
31 <QPG:Add file="../libz.so.1.2.3.3" install="/opt/lib/" component="slib"/> 31 <QPG:Add file="../libz.so.1.2.3.4" install="/opt/lib/" component="slib"/>
32 </QPG:Files> 32 </QPG:Files>
33 33
34 <QPG:PackageFilter> 34 <QPG:PackageFilter>
@@ -63,7 +63,7 @@
63 </QPM:ProductDescription> 63 </QPM:ProductDescription>
64 64
65 <QPM:ReleaseDescription> 65 <QPM:ReleaseDescription>
66 <QPM:ReleaseVersion>1.2.3.3</QPM:ReleaseVersion> 66 <QPM:ReleaseVersion>1.2.3.4</QPM:ReleaseVersion>
67 <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency> 67 <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
68 <QPM:ReleaseStability>Stable</QPM:ReleaseStability> 68 <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
69 <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor> 69 <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
diff --git a/trees.c b/trees.c
index 94f28bb..aa599a5 100644
--- a/trees.c
+++ b/trees.c
@@ -1,5 +1,5 @@
1/* trees.c -- output deflated data using Huffman coding 1/* trees.c -- output deflated data using Huffman coding
2 * Copyright (C) 1995-2006 Jean-loup Gailly 2 * Copyright (C) 1995-2009 Jean-loup Gailly
3 * detect_data_type() function provided freely by Cosmin Truta, 2006 3 * detect_data_type() function provided freely by Cosmin Truta, 2006
4 * For conditions of distribution and use, see copyright notice in zlib.h 4 * For conditions of distribution and use, see copyright notice in zlib.h
5 */ 5 */
@@ -204,12 +204,12 @@ local void send_bits(s, value, length)
204 * unused bits in value. 204 * unused bits in value.
205 */ 205 */
206 if (s->bi_valid > (int)Buf_size - length) { 206 if (s->bi_valid > (int)Buf_size - length) {
207 s->bi_buf |= (value << s->bi_valid); 207 s->bi_buf |= (ush)value << s->bi_valid;
208 put_short(s, s->bi_buf); 208 put_short(s, s->bi_buf);
209 s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); 209 s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
210 s->bi_valid += length - Buf_size; 210 s->bi_valid += length - Buf_size;
211 } else { 211 } else {
212 s->bi_buf |= value << s->bi_valid; 212 s->bi_buf |= (ush)value << s->bi_valid;
213 s->bi_valid += length; 213 s->bi_valid += length;
214 } 214 }
215} 215}
@@ -219,12 +219,12 @@ local void send_bits(s, value, length)
219{ int len = length;\ 219{ int len = length;\
220 if (s->bi_valid > (int)Buf_size - len) {\ 220 if (s->bi_valid > (int)Buf_size - len) {\
221 int val = value;\ 221 int val = value;\
222 s->bi_buf |= (val << s->bi_valid);\ 222 s->bi_buf |= (ush)val << s->bi_valid;\
223 put_short(s, s->bi_buf);\ 223 put_short(s, s->bi_buf);\
224 s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ 224 s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
225 s->bi_valid += len - Buf_size;\ 225 s->bi_valid += len - Buf_size;\
226 } else {\ 226 } else {\
227 s->bi_buf |= (value) << s->bi_valid;\ 227 s->bi_buf |= (ush)(value) << s->bi_valid;\
228 s->bi_valid += len;\ 228 s->bi_valid += len;\
229 }\ 229 }\
230} 230}
diff --git a/win32/zlib.def b/win32/zlib.def
index dbea9c5..c148ecb 100644
--- a/win32/zlib.def
+++ b/win32/zlib.def
@@ -13,12 +13,18 @@ EXPORTS
13 deflateCopy 13 deflateCopy
14 deflateReset 14 deflateReset
15 deflateParams 15 deflateParams
16 deflateTune
16 deflateBound 17 deflateBound
17 deflatePrime 18 deflatePrime
19 deflateSetHeader
18 inflateSetDictionary 20 inflateSetDictionary
19 inflateSync 21 inflateSync
20 inflateCopy 22 inflateCopy
21 inflateReset 23 inflateReset
24 inflateReset2
25 inflatePrime
26 inflateMark
27 inflateGetHeader
22 inflateBack 28 inflateBack
23 inflateBackEnd 29 inflateBackEnd
24 zlibCompileFlags 30 zlibCompileFlags
@@ -49,8 +55,8 @@ EXPORTS
49 gzclearerr 55 gzclearerr
50; checksum functions 56; checksum functions
51 adler32 57 adler32
52 adler32_combine
53 crc32 58 crc32
59 adler32_combine
54 crc32_combine 60 crc32_combine
55; various hacks, don't look :) 61; various hacks, don't look :)
56 deflateInit_ 62 deflateInit_
@@ -58,6 +64,12 @@ EXPORTS
58 inflateInit_ 64 inflateInit_
59 inflateInit2_ 65 inflateInit2_
60 inflateBackInit_ 66 inflateBackInit_
67 gzopen64
68 gzseek64
69 gztell64
70 adler32_combine64
71 crc32_combine64
72 zError
61 inflateSyncPoint 73 inflateSyncPoint
62 get_crc_table 74 get_crc_table
63 zError 75 inflateUndermine
diff --git a/zconf.h b/zconf.h
index 0a9f5a4..e8d9553 100644
--- a/zconf.h
+++ b/zconf.h
@@ -1,5 +1,5 @@
1/* zconf.h -- configuration of the zlib compression library 1/* zconf.h -- configuration of the zlib compression library
2 * Copyright (C) 1995-2006 Jean-loup Gailly. 2 * Copyright (C) 1995-2007 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h 3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */ 4 */
5 5
@@ -353,6 +353,10 @@ typedef uLong FAR uLongf;
353 353
354#include "zlibdefs.h" /* created by configure */ 354#include "zlibdefs.h" /* created by configure */
355 355
356#ifdef _LARGEFILE64_SOURCE
357# include <sys/types.h>
358#endif
359
356#ifndef SEEK_SET 360#ifndef SEEK_SET
357# define SEEK_SET 0 /* Seek from beginning of file. */ 361# define SEEK_SET 0 /* Seek from beginning of file. */
358# define SEEK_CUR 1 /* Seek from current position. */ 362# define SEEK_CUR 1 /* Seek from current position. */
diff --git a/zlib.3 b/zlib.3
index b83f234..71c166c 100644
--- a/zlib.3
+++ b/zlib.3
@@ -1,4 +1,4 @@
1.TH ZLIB 3 "2 October 2006" 1.TH ZLIB 3 "21 December 2009"
2.SH NAME 2.SH NAME
3zlib \- compression/decompression library 3zlib \- compression/decompression library
4.SH SYNOPSIS 4.SH SYNOPSIS
@@ -133,7 +133,7 @@ before asking for help.
133Send questions and/or comments to zlib@gzip.org, 133Send questions and/or comments to zlib@gzip.org,
134or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). 134or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
135.SH AUTHORS 135.SH AUTHORS
136Version 1.2.3.3 136Version 1.2.3.4
137Copyright (C) 1995-2006 Jean-loup Gailly (jloup@gzip.org) 137Copyright (C) 1995-2006 Jean-loup Gailly (jloup@gzip.org)
138and Mark Adler (madler@alumni.caltech.edu). 138and Mark Adler (madler@alumni.caltech.edu).
139.LP 139.LP
diff --git a/zlib.h b/zlib.h
index bb164c0..4d13ca1 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1,7 +1,7 @@
1/* zlib.h -- interface of the 'zlib' general purpose compression library 1/* zlib.h -- interface of the 'zlib' general purpose compression library
2 version 1.2.3.3, October 2nd, 2006 2 version 1.2.3.4, December 21st, 2009
3 3
4 Copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler 4 Copyright (C) 1995-2009 Jean-loup Gailly and Mark Adler
5 5
6 This software is provided 'as-is', without any express or implied 6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages 7 warranty. In no event will the authors be held liable for any damages
@@ -37,8 +37,8 @@
37extern "C" { 37extern "C" {
38#endif 38#endif
39 39
40#define ZLIB_VERSION "1.2.3.3" 40#define ZLIB_VERSION "1.2.3.4"
41#define ZLIB_VERNUM 0x1233 41#define ZLIB_VERNUM 0x1234
42#define ZLIB_VER_MAJOR 1 42#define ZLIB_VER_MAJOR 1
43#define ZLIB_VER_MINOR 2 43#define ZLIB_VER_MINOR 2
44#define ZLIB_VER_REVISION 3 44#define ZLIB_VER_REVISION 3
@@ -163,11 +163,12 @@ typedef gz_header FAR *gz_headerp;
163 /* constants */ 163 /* constants */
164 164
165#define Z_NO_FLUSH 0 165#define Z_NO_FLUSH 0
166#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ 166#define Z_PARTIAL_FLUSH 1
167#define Z_SYNC_FLUSH 2 167#define Z_SYNC_FLUSH 2
168#define Z_FULL_FLUSH 3 168#define Z_FULL_FLUSH 3
169#define Z_FINISH 4 169#define Z_FINISH 4
170#define Z_BLOCK 5 170#define Z_BLOCK 5
171#define Z_TREES 6
171/* Allowed flush values; see deflate() and inflate() below for details */ 172/* Allowed flush values; see deflate() and inflate() below for details */
172 173
173#define Z_OK 0 174#define Z_OK 0
@@ -273,7 +274,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
273 output buffer because there might be more output pending. 274 output buffer because there might be more output pending.
274 275
275 Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to 276 Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
276 decide how much data to accumualte before producing output, in order to 277 decide how much data to accumulate before producing output, in order to
277 maximize compression. 278 maximize compression.
278 279
279 If the parameter flush is set to Z_SYNC_FLUSH, all pending output is 280 If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
@@ -281,7 +282,26 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
281 that the decompressor can get all input data available so far. (In particular 282 that the decompressor can get all input data available so far. (In particular
282 avail_in is zero after the call if enough output space has been provided 283 avail_in is zero after the call if enough output space has been provided
283 before the call.) Flushing may degrade compression for some compression 284 before the call.) Flushing may degrade compression for some compression
284 algorithms and so it should be used only when necessary. 285 algorithms and so it should be used only when necessary. This completes the
286 current deflate block and follows it with an empty stored block that is three
287 bits plus filler bits to the next byte, followed by four bytes (00 00 ff ff).
288
289 If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
290 output buffer, but the output is not aligned to a byte boundary. All of the
291 input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
292 This completes the current deflate block and follows it with an empty fixed
293 codes block that is 10 bits long. This assures that enough bytes are output
294 in order for the decompressor to finish the block before the empty fixed code
295 block.
296
297 If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
298 for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
299 seven bits of the current block are held to be written as the next byte after
300 the next deflate block is completed. In this case, the decompressor may not
301 be provided enough bits at this point in order to complete decompression of
302 the data provided so far to the compressor. It may need to wait for the next
303 block to be emitted. This is for advanced applications that need to control
304 the emission of deflate blocks.
285 305
286 If flush is set to Z_FULL_FLUSH, all output is flushed as with 306 If flush is set to Z_FULL_FLUSH, all output is flushed as with
287 Z_SYNC_FLUSH, and the compression state is reset so that decompression can 307 Z_SYNC_FLUSH, and the compression state is reset so that decompression can
@@ -321,7 +341,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
321 processed or more output produced), Z_STREAM_END if all input has been 341 processed or more output produced), Z_STREAM_END if all input has been
322 consumed and all output has been produced (only when flush is set to 342 consumed and all output has been produced (only when flush is set to
323 Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example 343 Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
324 if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible 344 if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
325 (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not 345 (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
326 fatal, and deflate() can be called again with more input and more output 346 fatal, and deflate() can be called again with more input and more output
327 space to continue compressing. 347 space to continue compressing.
@@ -396,8 +416,8 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
396 must be called again after making room in the output buffer because there 416 must be called again after making room in the output buffer because there
397 might be more output pending. 417 might be more output pending.
398 418
399 The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, 419 The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
400 Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much 420 Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
401 output as possible to the output buffer. Z_BLOCK requests that inflate() stop 421 output as possible to the output buffer. Z_BLOCK requests that inflate() stop
402 if and when it gets to the next deflate block boundary. When decoding the 422 if and when it gets to the next deflate block boundary. When decoding the
403 zlib or gzip format, this will cause inflate() to return immediately after 423 zlib or gzip format, this will cause inflate() to return immediately after
@@ -415,7 +435,16 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
415 uncompressed data from that block has been written to strm->next_out. The 435 uncompressed data from that block has been written to strm->next_out. The
416 number of unused bits may in general be greater than seven, except when 436 number of unused bits may in general be greater than seven, except when
417 bit 7 of data_type is set, in which case the number of unused bits will be 437 bit 7 of data_type is set, in which case the number of unused bits will be
418 less than eight. 438 less than eight. data_type is set as noted here every time inflate()
439 returns for all flush options, and so can be used to determine the amount
440 of currently consumed input in bits.
441
442 The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
443 end of each deflate block header is reached, before any actual data in that
444 block is decoded. This allows the caller to determine the length of the
445 deflate block header for later use in random access within a deflate block.
446 256 is added to the value of strm->data_type when inflate() returns
447 immediately after reaching the end of the deflate block header.
419 448
420 inflate() should normally be called until it returns Z_STREAM_END or an 449 inflate() should normally be called until it returns Z_STREAM_END or an
421 error. However if all decompression is to be performed in a single step 450 error. However if all decompression is to be performed in a single step
@@ -432,7 +461,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
432 possible to the output buffer, and always uses the faster approach on the 461 possible to the output buffer, and always uses the faster approach on the
433 first call. So the only effect of the flush parameter in this implementation 462 first call. So the only effect of the flush parameter in this implementation
434 is on the return value of inflate(), as noted below, or when it returns early 463 is on the return value of inflate(), as noted below, or when it returns early
435 because Z_BLOCK is used. 464 because Z_BLOCK or Z_TREES is used.
436 465
437 If a preset dictionary is needed after this call (see inflateSetDictionary 466 If a preset dictionary is needed after this call (see inflateSetDictionary
438 below), inflate sets strm->adler to the adler32 checksum of the dictionary 467 below), inflate sets strm->adler to the adler32 checksum of the dictionary
@@ -443,12 +472,12 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
443 checksum is equal to that saved by the compressor and returns Z_STREAM_END 472 checksum is equal to that saved by the compressor and returns Z_STREAM_END
444 only if the checksum is correct. 473 only if the checksum is correct.
445 474
446 inflate() will decompress and check either zlib-wrapped or gzip-wrapped 475 inflate() can decompress and check either zlib-wrapped or gzip-wrapped
447 deflate data. The header type is detected automatically. Any information 476 deflate data. The header type is detected automatically, if requested when
448 contained in the gzip header is not retained, so applications that need that 477 initializing with inflateInit2(). Any information contained in the gzip
449 information should instead use raw inflate, see inflateInit2() below, or 478 header is not retained, so applications that need that information should
450 inflateBack() and perform their own processing of the gzip header and 479 instead use raw inflate, see inflateInit2() below, or inflateBack() and
451 trailer. 480 perform their own processing of the gzip header and trailer.
452 481
453 inflate() returns Z_OK if some progress has been made (more input processed 482 inflate() returns Z_OK if some progress has been made (more input processed
454 or more output produced), Z_STREAM_END if the end of the compressed data has 483 or more output produced), Z_STREAM_END if the end of the compressed data has
@@ -456,7 +485,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
456 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was 485 preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
457 corrupted (input stream not conforming to the zlib format or incorrect check 486 corrupted (input stream not conforming to the zlib format or incorrect check
458 value), Z_STREAM_ERROR if the stream structure was inconsistent (for example 487 value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
459 if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, 488 next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
460 Z_BUF_ERROR if no progress is possible or if there was not enough room in the 489 Z_BUF_ERROR if no progress is possible or if there was not enough room in the
461 output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and 490 output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
462 inflate() can be called again with more input and more output space to 491 inflate() can be called again with more input and more output space to
@@ -529,12 +558,12 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
529 random distribution. In this case, the compression algorithm is tuned to 558 random distribution. In this case, the compression algorithm is tuned to
530 compress them better. The effect of Z_FILTERED is to force more Huffman 559 compress them better. The effect of Z_FILTERED is to force more Huffman
531 coding and less string matching; it is somewhat intermediate between 560 coding and less string matching; it is somewhat intermediate between
532 Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as 561 Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
533 Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy 562 fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
534 parameter only affects the compression ratio but not the correctness of the 563 strategy parameter only affects the compression ratio but not the
535 compressed output even if it is not set appropriately. Z_FIXED prevents the 564 correctness of the compressed output even if it is not set appropriately.
536 use of dynamic Huffman codes, allowing for a simpler decoder for special 565 Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
537 applications. 566 decoder for special applications.
538 567
539 deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 568 deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
540 memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid 569 memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
@@ -561,11 +590,11 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
561 590
562 Depending on the size of the compression data structures selected by 591 Depending on the size of the compression data structures selected by
563 deflateInit or deflateInit2, a part of the dictionary may in effect be 592 deflateInit or deflateInit2, a part of the dictionary may in effect be
564 discarded, for example if the dictionary is larger than the window size in 593 discarded, for example if the dictionary is larger than the window size
565 deflate or deflate2. Thus the strings most likely to be useful should be 594 provided in deflateInit or deflateInit2. Thus the strings most likely to be
566 put at the end of the dictionary, not at the front. In addition, the 595 useful should be put at the end of the dictionary, not at the front. In
567 current implementation of deflate will use at most the window size minus 596 addition, the current implementation of deflate will use at most the window
568 262 bytes of the provided dictionary. 597 size minus 262 bytes of the provided dictionary.
569 598
570 Upon return of this function, strm->adler is set to the adler32 value 599 Upon return of this function, strm->adler is set to the adler32 value
571 of the dictionary; the decompressor may later use this value to determine 600 of the dictionary; the decompressor may later use this value to determine
@@ -575,7 +604,7 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
575 adler32 value is not computed and strm->adler is not set. 604 adler32 value is not computed and strm->adler is not set.
576 605
577 deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a 606 deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
578 parameter is invalid (such as NULL dictionary) or the stream state is 607 parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
579 inconsistent (for example if deflate has already been called for this stream 608 inconsistent (for example if deflate has already been called for this stream
580 or if the compression method is bsort). deflateSetDictionary does not 609 or if the compression method is bsort). deflateSetDictionary does not
581 perform any compression: this will be done by deflate(). 610 perform any compression: this will be done by deflate().
@@ -595,7 +624,7 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
595 624
596 deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not 625 deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
597 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent 626 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
598 (such as zalloc being NULL). msg is left unchanged in both source and 627 (such as zalloc being Z_NULL). msg is left unchanged in both source and
599 destination. 628 destination.
600*/ 629*/
601 630
@@ -607,7 +636,7 @@ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
607 that may have been set by deflateInit2. 636 that may have been set by deflateInit2.
608 637
609 deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source 638 deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
610 stream state was inconsistent (such as zalloc or state being NULL). 639 stream state was inconsistent (such as zalloc or state being Z_NULL).
611*/ 640*/
612 641
613ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, 642ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
@@ -760,7 +789,7 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
760 dictionary that was used for compression is provided. 789 dictionary that was used for compression is provided.
761 790
762 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a 791 inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
763 parameter is invalid (such as NULL dictionary) or the stream state is 792 parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
764 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the 793 inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
765 expected one (incorrect adler32 value). inflateSetDictionary does not 794 expected one (incorrect adler32 value). inflateSetDictionary does not
766 perform any decompression: this will be done by subsequent calls of 795 perform any decompression: this will be done by subsequent calls of
@@ -794,7 +823,7 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
794 823
795 inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not 824 inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
796 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent 825 enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
797 (such as zalloc being NULL). msg is left unchanged in both source and 826 (such as zalloc being Z_NULL). msg is left unchanged in both source and
798 destination. 827 destination.
799*/ 828*/
800 829
@@ -805,7 +834,19 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
805 The stream will keep attributes that may have been set by inflateInit2. 834 The stream will keep attributes that may have been set by inflateInit2.
806 835
807 inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source 836 inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
808 stream state was inconsistent (such as zalloc or state being NULL). 837 stream state was inconsistent (such as zalloc or state being Z_NULL).
838*/
839
840ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
841 int windowBits));
842/*
843 This function is the same as inflateReset, but it also permits changing
844 the wrap and window size requests. The windowBits parameter is
845 interpreted the same as it is for inflateInit2.
846
847 inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
848 stream state was inconsistent (such as zalloc or state being Z_NULL), or if
849 the windowBits parameter is invalid.
809*/ 850*/
810 851
811ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, 852ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
@@ -820,10 +861,43 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
820 inflateReset(). bits must be less than or equal to 16, and that many of the 861 inflateReset(). bits must be less than or equal to 16, and that many of the
821 least significant bits of value will be inserted in the input. 862 least significant bits of value will be inserted in the input.
822 863
864 If bits is negative, then the input stream bit buffer is emptied. Then
865 inflatePrime() can be called again to put bits in the buffer. This is used
866 to clear out bits leftover after feeding inflate a block description prior
867 to feeding inflate codes.
868
823 inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source 869 inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
824 stream state was inconsistent. 870 stream state was inconsistent.
825*/ 871*/
826 872
873ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
874/*
875 This function returns two values, one in the lower 16 bits of the return
876 value, and the other in the remaining upper bits, obtained by shifting the
877 return value down 16 bits. If the upper value is -1 and the lower value is
878 zero, then inflate() is currently decoding information outside of a block.
879 If the upper value is -1 and the lower value is non-zero, then inflate is in
880 the middle of a stored block, with the lower value equaling the number of
881 bytes from the input remaining to copy. If the upper value is not -1, then
882 it is the number of bits back from the current bit position in the input of
883 the code (literal or length/distance pair) currently being processed. In
884 that case the lower value is the number of bytes already emitted for that
885 code.
886
887 A code is being processed if inflate is waiting for more input to complete
888 decoding of the code, or if it has completed decoding but is waiting for
889 more output space to write the literal or match data.
890
891 inflateMark() is used to mark locations in the input data for random
892 access, which may be at bit positions, and to note those cases where the
893 output of a code may span boundaries of random access blocks. The current
894 location in the input stream can be determined from avail_in and data_type
895 as noted in the description for the Z_BLOCK flush parameter for inflate.
896
897 inflateMark returns the value noted above or -1 << 16 if the provided
898 source stream state was inconsistent.
899*/
900
827ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, 901ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
828 gz_headerp head)); 902 gz_headerp head));
829/* 903/*
@@ -833,9 +907,9 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
833 As inflate() processes the gzip stream, head->done is zero until the header 907 As inflate() processes the gzip stream, head->done is zero until the header
834 is completed, at which time head->done is set to one. If a zlib stream is 908 is completed, at which time head->done is set to one. If a zlib stream is
835 being decoded, then head->done is set to -1 to indicate that there will be 909 being decoded, then head->done is set to -1 to indicate that there will be
836 no gzip header information forthcoming. Note that Z_BLOCK can be used to 910 no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
837 force inflate() to return immediately after header processing is complete 911 used to force inflate() to return immediately after header processing is
838 and before any actual data is decompressed. 912 complete and before any actual data is decompressed.
839 913
840 The text, time, xflags, and os fields are filled in with the gzip header 914 The text, time, xflags, and os fields are filled in with the gzip header
841 contents. hcrc is set to true if there is a header CRC. (The header CRC 915 contents. hcrc is set to true if there is a header CRC. (The header CRC
@@ -952,7 +1026,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
952 nature of the error), or Z_STREAM_ERROR if the stream was not properly 1026 nature of the error), or Z_STREAM_ERROR if the stream was not properly
953 initialized. In the case of Z_BUF_ERROR, an input or output error can be 1027 initialized. In the case of Z_BUF_ERROR, an input or output error can be
954 distinguished using strm->next_in which will be Z_NULL only if in() returned 1028 distinguished using strm->next_in which will be Z_NULL only if in() returned
955 an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to 1029 an error. If strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to
956 out() returning non-zero. (in() will always be called before out(), so 1030 out() returning non-zero. (in() will always be called before out(), so
957 strm->next_in is assured to be defined if out() returns non-zero.) Note 1031 strm->next_in is assured to be defined if out() returns non-zero.) Note
958 that inflateBack() cannot return Z_OK. 1032 that inflateBack() cannot return Z_OK.
@@ -1065,7 +1139,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
1065 entire uncompressed data. (The size of the uncompressed data must have 1139 entire uncompressed data. (The size of the uncompressed data must have
1066 been saved previously by the compressor and transmitted to the decompressor 1140 been saved previously by the compressor and transmitted to the decompressor
1067 by some mechanism outside the scope of this compression library.) 1141 by some mechanism outside the scope of this compression library.)
1068 Upon exit, destLen is the actual size of the compressed buffer. 1142 Upon exit, destLen is the actual size of the uncompressed buffer.
1069 This function can be used to decompress a whole file at once if the 1143 This function can be used to decompress a whole file at once if the
1070 input file is mmap'ed. 1144 input file is mmap'ed.
1071 1145
@@ -1279,7 +1353,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
1279ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); 1353ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
1280/* 1354/*
1281 Update a running Adler-32 checksum with the bytes buf[0..len-1] and 1355 Update a running Adler-32 checksum with the bytes buf[0..len-1] and
1282 return the updated checksum. If buf is NULL, this function returns 1356 return the updated checksum. If buf is Z_NULL, this function returns
1283 the required initial value for the checksum. 1357 the required initial value for the checksum.
1284 An Adler-32 checksum is almost as reliable as a CRC32 but can be computed 1358 An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
1285 much faster. Usage example: 1359 much faster. Usage example:
@@ -1305,7 +1379,7 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
1305ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); 1379ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
1306/* 1380/*
1307 Update a running CRC-32 with the bytes buf[0..len-1] and return the 1381 Update a running CRC-32 with the bytes buf[0..len-1] and return the
1308 updated CRC-32. If buf is NULL, this function returns the required initial 1382 updated CRC-32. If buf is Z_NULL, this function returns the required initial
1309 value for the for the crc. Pre- and post-conditioning (one's complement) is 1383 value for the for the crc. Pre- and post-conditioning (one's complement) is
1310 performed within this function so it shouldn't be done by the application. 1384 performed within this function so it shouldn't be done by the application.
1311 Usage example: 1385 Usage example:
@@ -1369,12 +1443,19 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
1369 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off64_t)); 1443 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off64_t));
1370#endif 1444#endif
1371 1445
1372#if _FILE_OFFSET_BITS == 64 1446#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS == 64
1373# define gzopen gzopen64 1447# define gzopen gzopen64
1374# define gzseek gzseek64 1448# define gzseek gzseek64
1375# define gztell gztell64 1449# define gztell gztell64
1376# define adler32_combine adler32_combine64 1450# define adler32_combine adler32_combine64
1377# define crc32_combine crc32_combine64 1451# define crc32_combine crc32_combine64
1452# ifndef _LARGEFILE64_SOURCE
1453 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
1454 ZEXTERN off_t ZEXPORT gzseek64 OF((gzFile, off_t, int));
1455 ZEXTERN off_t ZEXPORT gztell64 OF((gzFile));
1456 ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off_t));
1457 ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off_t));
1458# endif
1378#else 1459#else
1379 ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); 1460 ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
1380 ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); 1461 ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
diff --git a/zlib.map b/zlib.map
index da683a8..499213d 100644
--- a/zlib.map
+++ b/zlib.map
@@ -42,3 +42,12 @@ ZLIB_1.2.2.3 {
42ZLIB_1.2.2.4 { 42ZLIB_1.2.2.4 {
43 inflatePrime; 43 inflatePrime;
44} ZLIB_1.2.2.3; 44} ZLIB_1.2.2.3;
45
46ZLIB_1.2.3.3 {
47 inflateUndermine;
48} ZLIB_1.2.2.4;
49
50ZLIB_1.2.3.4 {
51 inflateReset2;
52 inflateMark;
53} ZLIB_1.2.3.3;
diff --git a/zlib2ansi b/zlib2ansi
new file mode 100755
index 0000000..0695f6b
--- /dev/null
+++ b/zlib2ansi
@@ -0,0 +1,152 @@
1#!/usr/bin/perl
2
3# Transform K&R C function definitions into ANSI equivalent.
4#
5# Author: Paul Marquess
6# Version: 1.0
7# Date: 3 October 2006
8
9# TODO
10#
11# Asumes no function pointer parameters. unless they are typedefed.
12# Assumes no literal strings that look like function definitions
13# Assumes functions start at the beginning of a line
14
15use strict;
16use warnings;
17
18local $/;
19$_ = <>;
20
21my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
22
23my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
24my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
25my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
26
27
28while (s/^
29 ( # Start $1
30 ( # Start $2
31 .*? # Minimal eat content
32 ( ^ \w [\w\s\*]+ ) # $3 -- function name
33 \s* # optional whitespace
34 ) # $2 - Matched up to before parameter list
35
36 \( \s* # Literal "(" + optional whitespace
37 ( [^\)]+ ) # $4 - one or more anythings except ")"
38 \s* \) # optional whitespace surrounding a Literal ")"
39
40 ( (?: $dList )+ ) # $5
41
42 $sp ^ { # literal "{" at start of line
43 ) # Remember to $1
44 //xsom
45 )
46{
47 my $all = $1 ;
48 my $prefix = $2;
49 my $param_list = $4 ;
50 my $params = $5;
51
52 StripComments($params);
53 StripComments($param_list);
54 $param_list =~ s/^\s+//;
55 $param_list =~ s/\s+$//;
56
57 my $i = 0 ;
58 my %pList = map { $_ => $i++ }
59 split /\s*,\s*/, $param_list;
60 my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
61
62 my @params = split /\s*;\s*/, $params;
63 my @outParams = ();
64 foreach my $p (@params)
65 {
66 if ($p =~ /,/)
67 {
68 my @bits = split /\s*,\s*/, $p;
69 my $first = shift @bits;
70 $first =~ s/^\s*//;
71 push @outParams, $first;
72 $first =~ /^(\w+\s*)/;
73 my $type = $1 ;
74 push @outParams, map { $type . $_ } @bits;
75 }
76 else
77 {
78 $p =~ s/^\s+//;
79 push @outParams, $p;
80 }
81 }
82
83
84 my %tmp = map { /$pMatch/; $_ => $pList{$1} }
85 @outParams ;
86
87 @outParams = map { " $_" }
88 sort { $tmp{$a} <=> $tmp{$b} }
89 @outParams ;
90
91 print $prefix ;
92 print "(\n" . join(",\n", @outParams) . ")\n";
93 print "{" ;
94
95}
96
97# Output any trailing code.
98print ;
99exit 0;
100
101
102sub StripComments
103{
104
105 no warnings;
106
107 # Strip C & C++ coments
108 # From the perlfaq
109 $_[0] =~
110
111 s{
112 /\* ## Start of /* ... */ comment
113 [^*]*\*+ ## Non-* followed by 1-or-more *'s
114 (
115 [^/*][^*]*\*+
116 )* ## 0-or-more things which don't start with /
117 ## but do end with '*'
118 / ## End of /* ... */ comment
119
120 | ## OR C++ Comment
121 // ## Start of C++ comment //
122 [^\n]* ## followed by 0-or-more non end of line characters
123
124 | ## OR various things which aren't comments:
125
126 (
127 " ## Start of " ... " string
128 (
129 \\. ## Escaped char
130 | ## OR
131 [^"\\] ## Non "\
132 )*
133 " ## End of " ... " string
134
135 | ## OR
136
137 ' ## Start of ' ... ' string
138 (
139 \\. ## Escaped char
140 | ## OR
141 [^'\\] ## Non '\
142 )*
143 ' ## End of ' ... ' string
144
145 | ## OR
146
147 . ## Anything other char
148 [^/"'\\]* ## Chars which doesn't start a comment, string or escape
149 )
150 }{$2}gxs;
151
152}
diff --git a/zutil.h b/zutil.h
index 32e9c89..bccc581 100644
--- a/zutil.h
+++ b/zutil.h
@@ -167,6 +167,12 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
167#pragma warn -8066 167#pragma warn -8066
168#endif 168#endif
169 169
170#ifdef _LARGEFILE64_SOURCE
171# define z_off64_t off64_t
172#else
173# define z_off64_t z_off_t
174#endif
175
170 /* common defaults */ 176 /* common defaults */
171 177
172#ifndef OS_CODE 178#ifndef OS_CODE