aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Seward <jseward@acm.org>2000-06-24 22:13:13 +0200
committerJulian Seward <jseward@acm.org>2000-06-24 22:13:13 +0200
commit795b859eee96c700e8f3c3fe68e6a9a39d95797c (patch)
tree48f8a731cd5ec2f5f15c6d99f2207ebf4a1f35f6
parentf93cd82a9a7094ad90fd19bbc6ccf6f4627f8060 (diff)
downloadbzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.tar.gz
bzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.tar.bz2
bzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.zip
bzip2-1.0.1bzip2-1.0.1
-rw-r--r--CHANGES67
-rw-r--r--LICENSE4
-rw-r--r--Makefile58
-rw-r--r--Makefile-libbz2_so43
-rw-r--r--README43
-rw-r--r--README.COMPILATION.PROBLEMS130
-rw-r--r--blocksort.c335
-rw-r--r--bzip2.18
-rw-r--r--bzip2.1.preformatted113
-rw-r--r--bzip2.c508
-rw-r--r--bzip2.txt15
-rw-r--r--bzip2recover.c8
-rw-r--r--bzlib.c248
-rw-r--r--bzlib.h67
-rw-r--r--bzlib_private.h52
-rw-r--r--compress.c193
-rw-r--r--crctable.c6
-rw-r--r--decompress.c44
-rw-r--r--dlltest.c341
-rw-r--r--huffman.c36
-rw-r--r--libbz2.def46
-rw-r--r--makefile.msc18
-rw-r--r--manual.texi516
-rw-r--r--randtable.c6
-rw-r--r--spewG.c39
-rw-r--r--unzcrash.c126
-rw-r--r--words05
27 files changed, 2160 insertions, 915 deletions
diff --git a/CHANGES b/CHANGES
index 0acb1c2..ecaf417 100644
--- a/CHANGES
+++ b/CHANGES
@@ -98,3 +98,70 @@ functioning of the bzip2 program or library. Added a couple of casts
98so the library compiles without warnings at level 3 in MS Visual 98so the library compiles without warnings at level 3 in MS Visual
99Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other 99Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
100changes are minor documentation changes. 100changes are minor documentation changes.
101
1021.0
103~~~
104Several minor bugfixes and enhancements:
105
106* Large file support. The library uses 64-bit counters to
107 count the volume of data passing through it. bzip2.c
108 is now compiled with -D_FILE_OFFSET_BITS=64 to get large
109 file support from the C library. -v correctly prints out
110 file sizes greater than 4 gigabytes. All these changes have
111 been made without assuming a 64-bit platform or a C compiler
112 which supports 64-bit ints, so, except for the C library
113 aspect, they are fully portable.
114
115* Decompression robustness. The library/program should be
116 robust to any corruption of compressed data, detecting and
117 handling _all_ corruption, instead of merely relying on
118 the CRCs. What this means is that the program should
119 never crash, given corrupted data, and the library should
120 always return BZ_DATA_ERROR.
121
122* Fixed an obscure race-condition bug only ever observed on
123 Solaris, in which, if you were very unlucky and issued
124 control-C at exactly the wrong time, both input and output
125 files would be deleted.
126
127* Don't run out of file handles on test/decompression when
128 large numbers of files have invalid magic numbers.
129
130* Avoid library namespace pollution. Prefix all exported
131 symbols with BZ2_.
132
133* Minor sorting enhancements from my DCC2000 paper.
134
135* Advance the version number to 1.0, so as to counteract the
136 (false-in-this-case) impression some people have that programs
137 with version numbers less than 1.0 are in someway, experimental,
138 pre-release versions.
139
140* Create an initial Makefile-libbz2_so to build a shared library.
141 Yes, I know I should really use libtool et al ...
142
143* Make the program exit with 2 instead of 0 when decompression
144 fails due to a bad magic number (ie, an invalid bzip2 header).
145 Also exit with 1 (as the manual claims :-) whenever a diagnostic
146 message would have been printed AND the corresponding operation
147 is aborted, for example
148 bzip2: Output file xx already exists.
149 When a diagnostic message is printed but the operation is not
150 aborted, for example
151 bzip2: Can't guess original name for wurble -- using wurble.out
152 then the exit value 0 is returned, unless some other problem is
153 also detected.
154
155 I think it corresponds more closely to what the manual claims now.
156
157
1581.0.1
159~~~~~
160* Modified dlltest.c so it uses the new BZ2_ naming scheme.
161* Modified makefile-msc to fix minor build probs on Win2k.
162* Updated README.COMPILATION.PROBLEMS.
163
164There are no functionality changes or bug fixes relative to version
1651.0.0. This is just a documentation update + a fix for minor Win32
166build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
167utterly pointless. Don't bother.
diff --git a/LICENSE b/LICENSE
index bc0069a..88fa6d8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
1 1
2This program, "bzip2" and associated library "libbzip2", are 2This program, "bzip2" and associated library "libbzip2", are
3copyright (C) 1996-1999 Julian R Seward. All rights reserved. 3copyright (C) 1996-2000 Julian R Seward. All rights reserved.
4 4
5Redistribution and use in source and binary forms, with or without 5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions 6modification, are permitted provided that the following conditions
@@ -35,5 +35,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 35
36Julian Seward, Cambridge, UK. 36Julian Seward, Cambridge, UK.
37jseward@acm.org 37jseward@acm.org
38bzip2/libbzip2 version 0.9.5 of 24 May 1999 38bzip2/libbzip2 version 1.0 of 21 March 2000
39 39
diff --git a/Makefile b/Makefile
index 8a1235d..ab17f49 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,8 @@
1 1
2SHELL=/bin/sh 2SHELL=/bin/sh
3CC=gcc 3CC=gcc
4CFLAGS=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce 4BIGFILES=-D_FILE_OFFSET_BITS=64
5CFLAGS=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
5 6
6OBJS= blocksort.o \ 7OBJS= blocksort.o \
7 huffman.o \ 8 huffman.o \
@@ -73,6 +74,7 @@ clean:
73 sample1.tst sample2.tst sample3.tst 74 sample1.tst sample2.tst sample3.tst
74 75
75blocksort.o: blocksort.c 76blocksort.o: blocksort.c
77 @cat words0
76 $(CC) $(CFLAGS) -c blocksort.c 78 $(CC) $(CFLAGS) -c blocksort.c
77huffman.o: huffman.c 79huffman.o: huffman.c
78 $(CC) $(CFLAGS) -c huffman.c 80 $(CC) $(CFLAGS) -c huffman.c
@@ -91,13 +93,49 @@ bzip2.o: bzip2.c
91bzip2recover.o: bzip2recover.c 93bzip2recover.o: bzip2recover.c
92 $(CC) $(CFLAGS) -c bzip2recover.c 94 $(CC) $(CFLAGS) -c bzip2recover.c
93 95
96DISTNAME=bzip2-1.0.1
94tarfile: 97tarfile:
95 tar cvf interim.tar blocksort.c huffman.c crctable.c \ 98 rm -f $(DISTNAME)
96 randtable.c compress.c decompress.c bzlib.c bzip2.c \ 99 ln -sf . $(DISTNAME)
97 bzip2recover.c bzlib.h bzlib_private.h Makefile manual.texi \ 100 tar cvf $(DISTNAME).tar \
98 manual.ps LICENSE bzip2.1 bzip2.1.preformatted bzip2.txt \ 101 $(DISTNAME)/blocksort.c \
99 words1 words2 words3 sample1.ref sample2.ref sample3.ref \ 102 $(DISTNAME)/huffman.c \
100 sample1.bz2 sample2.bz2 sample3.bz2 dlltest.c \ 103 $(DISTNAME)/crctable.c \
101 *.html README CHANGES libbz2.def libbz2.dsp \ 104 $(DISTNAME)/randtable.c \
102 dlltest.dsp makefile.msc Y2K_INFO 105 $(DISTNAME)/compress.c \
103 106 $(DISTNAME)/decompress.c \
107 $(DISTNAME)/bzlib.c \
108 $(DISTNAME)/bzip2.c \
109 $(DISTNAME)/bzip2recover.c \
110 $(DISTNAME)/bzlib.h \
111 $(DISTNAME)/bzlib_private.h \
112 $(DISTNAME)/Makefile \
113 $(DISTNAME)/manual.texi \
114 $(DISTNAME)/manual.ps \
115 $(DISTNAME)/LICENSE \
116 $(DISTNAME)/bzip2.1 \
117 $(DISTNAME)/bzip2.1.preformatted \
118 $(DISTNAME)/bzip2.txt \
119 $(DISTNAME)/words0 \
120 $(DISTNAME)/words1 \
121 $(DISTNAME)/words2 \
122 $(DISTNAME)/words3 \
123 $(DISTNAME)/sample1.ref \
124 $(DISTNAME)/sample2.ref \
125 $(DISTNAME)/sample3.ref \
126 $(DISTNAME)/sample1.bz2 \
127 $(DISTNAME)/sample2.bz2 \
128 $(DISTNAME)/sample3.bz2 \
129 $(DISTNAME)/dlltest.c \
130 $(DISTNAME)/*.html \
131 $(DISTNAME)/README \
132 $(DISTNAME)/README.COMPILATION.PROBLEMS \
133 $(DISTNAME)/CHANGES \
134 $(DISTNAME)/libbz2.def \
135 $(DISTNAME)/libbz2.dsp \
136 $(DISTNAME)/dlltest.dsp \
137 $(DISTNAME)/makefile.msc \
138 $(DISTNAME)/Y2K_INFO \
139 $(DISTNAME)/unzcrash.c \
140 $(DISTNAME)/spewG.c \
141 $(DISTNAME)/Makefile-libbz2_so
diff --git a/Makefile-libbz2_so b/Makefile-libbz2_so
new file mode 100644
index 0000000..a347c50
--- /dev/null
+++ b/Makefile-libbz2_so
@@ -0,0 +1,43 @@
1
2# This Makefile builds a shared version of the library,
3# libbz2.so.1.0.1, with soname libbz2.so.1.0,
4# at least on x86-Linux (RedHat 5.2),
5# with gcc-2.7.2.3. Please see the README file for some
6# important info about building the library like this.
7
8SHELL=/bin/sh
9CC=gcc
10BIGFILES=-D_FILE_OFFSET_BITS=64
11CFLAGS=-fpic -fPIC -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
12
13OBJS= blocksort.o \
14 huffman.o \
15 crctable.o \
16 randtable.o \
17 compress.o \
18 decompress.o \
19 bzlib.o
20
21all: $(OBJS)
22 $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.1 $(OBJS)
23 $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.1
24 rm -f libbz2.so.1.0
25 ln -s libbz2.so.1.0.1 libbz2.so.1.0
26
27clean:
28 rm -f $(OBJS) bzip2.o libbz2.so.1.0.1 libbz2.so.1.0 bzip2-shared
29
30blocksort.o: blocksort.c
31 $(CC) $(CFLAGS) -c blocksort.c
32huffman.o: huffman.c
33 $(CC) $(CFLAGS) -c huffman.c
34crctable.o: crctable.c
35 $(CC) $(CFLAGS) -c crctable.c
36randtable.o: randtable.c
37 $(CC) $(CFLAGS) -c randtable.c
38compress.o: compress.c
39 $(CC) $(CFLAGS) -c compress.c
40decompress.o: decompress.c
41 $(CC) $(CFLAGS) -c decompress.c
42bzlib.o: bzlib.c
43 $(CC) $(CFLAGS) -c bzlib.c
diff --git a/README b/README
index ee70649..22945a2 100644
--- a/README
+++ b/README
@@ -1,9 +1,9 @@
1 1
2This is the README for bzip2, a block-sorting file compressor, version 2This is the README for bzip2, a block-sorting file compressor, version
30.9.5d. This version is fully compatible with the previous public 31.0. This version is fully compatible with the previous public
4releases, bzip2-0.1pl2 and bzip2-0.9.0. 4releases, bzip2-0.1pl2, bzip2-0.9.0 and bzip2-0.9.5.
5 5
6bzip2-0.9.5 is distributed under a BSD-style license. For details, 6bzip2-1.0 is distributed under a BSD-style license. For details,
7see the file LICENSE. 7see the file LICENSE.
8 8
9Complete documentation is available in Postscript form (manual.ps) or 9Complete documentation is available in Postscript form (manual.ps) or
@@ -30,15 +30,37 @@ The -n instructs make to show the commands it would execute, but
30not actually execute them. 30not actually execute them.
31 31
32 32
33HOW TO BUILD -- UNIX, shared library libbz2.so.
34
35Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for
36Linux-ELF (RedHat 5.2 on an x86 box), with gcc. I make no claims
37that it works for any other platform, though I suspect it probably
38will work for most platforms employing both ELF and gcc.
39
40bzip2-shared, a client of the shared library, is also build, but
41not self-tested. So I suggest you also build using the normal
42Makefile, since that conducts a self-test.
43
44Important note for people upgrading .so's from 0.9.0/0.9.5 to
45version 1.0. All the functions in the library have been renamed,
46from (eg) bzCompress to BZ2_bzCompress, to avoid namespace pollution.
47Unfortunately this means that the libbz2.so created by
48Makefile-libbz2_so will not work with any program which used an
49older version of the library. Sorry. I do encourage library
50clients to make the effort to upgrade to use version 1.0, since
51it is both faster and more robust than previous versions.
52
53
33HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc. 54HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
34 55
35It's difficult for me to support compilation on all these platforms. 56It's difficult for me to support compilation on all these platforms.
36My approach is to collect binaries for these platforms, and put them 57My approach is to collect binaries for these platforms, and put them
37on my web page (http://www.muraroa.demon.co.uk). Look there. However 58on the master web page (http://sourceware.cygnus.com/bzip2). Look
38(FWIW), bzip2-0.9.5 is very standard ANSI C and should compile 59there. However (FWIW), bzip2-1.0 is very standard ANSI C and should
39unmodified with MS Visual C. For Win32, there is one important 60compile unmodified with MS Visual C. For Win32, there is one
40caveat: in bzip2.c, you must set BZ_UNIX to 0 and BZ_LCCWIN32 to 1 61important caveat: in bzip2.c, you must set BZ_UNIX to 0 and
41before building. 62BZ_LCCWIN32 to 1 before building. If you have difficulties building,
63you might want to read README.COMPILATION.PROBLEMS.
42 64
43 65
44VALIDATION 66VALIDATION
@@ -116,6 +138,10 @@ WHAT'S NEW IN 0.9.5 ?
116 * Many small improvements in file and flag handling. 138 * Many small improvements in file and flag handling.
117 * A Y2K statement. 139 * A Y2K statement.
118 140
141WHAT'S NEW IN 1.0
142
143 See the CHANGES file.
144
119I hope you find bzip2 useful. Feel free to contact me at 145I hope you find bzip2 useful. Feel free to contact me at
120 jseward@acm.org 146 jseward@acm.org
121if you have any suggestions or queries. Many people mailed me with 147if you have any suggestions or queries. Many people mailed me with
@@ -137,3 +163,4 @@ Cambridge, UK
13723 August 1998 (bzip2, version 0.9.0) 16323 August 1998 (bzip2, version 0.9.0)
138 8 June 1999 (bzip2, version 0.9.5) 164 8 June 1999 (bzip2, version 0.9.5)
139 4 Sept 1999 (bzip2, version 0.9.5d) 165 4 Sept 1999 (bzip2, version 0.9.5d)
166 5 May 2000 (bzip2, version 1.0pre8)
diff --git a/README.COMPILATION.PROBLEMS b/README.COMPILATION.PROBLEMS
new file mode 100644
index 0000000..d621ad5
--- /dev/null
+++ b/README.COMPILATION.PROBLEMS
@@ -0,0 +1,130 @@
1
2bzip2-1.0 should compile without problems on the vast majority of
3platforms. Using the supplied Makefile, I've built and tested it
4myself for x86-linux, sparc-solaris, alpha-linux, x86-cygwin32 and
5alpha-tru64unix. With makefile.msc, Visual C++ 6.0 and nmake, you can
6build a native Win32 version too. Large file support seems to work
7correctly on at least alpha-tru64unix and x86-cygwin32 (on Windows
82000).
9
10When I say "large file" I mean a file of size 2,147,483,648 (2^31)
11bytes or above. Many older OSs can't handle files above this size,
12but many newer ones can. Large files are pretty huge -- most files
13you'll encounter are not Large Files.
14
15Earlier versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide
16variety of platforms without difficulty, and I hope this version will
17continue in that tradition. However, in order to support large files,
18I've had to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.
19This can cause problems.
20
21The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
22support is, as far as I know, the Recommended Way to get correct large
23file support. For more details, see the Large File Support
24Specification, published by the Large File Summit, at
25 http://www.sas.com/standard/large.file/
26
27As a general comment, if you get compilation errors which you think
28are related to large file support, try removing the above define from
29the Makefile, ie, delete the line
30 BIGFILES=-D_FILE_OFFSET_BITS=64
31from the Makefile, and do 'make clean ; make'. This will give you a
32version of bzip2 without large file support, which, for most
33applications, is probably not a problem.
34
35Alternatively, try some of the platform-specific hints listed below.
36
37You can use the spewG.c program to generate huge files to test bzip2's
38large file support, if you are feeling paranoid. Be aware though that
39any compilation problems which affect bzip2 will also affect spewG.c,
40alas.
41
42
43Known problems as of 1.0pre8:
44~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45
46* HP/UX 10.20 and 11.00, using gcc (2.7.2.3 and 2.95.2): A large
47 number of warnings appear, including the following:
48
49 /usr/include/sys/resource.h: In function `getrlimit':
50 /usr/include/sys/resource.h:168:
51 warning: implicit declaration of function `__getrlimit64'
52 /usr/include/sys/resource.h: In function `setrlimit':
53 /usr/include/sys/resource.h:170:
54 warning: implicit declaration of function `__setrlimit64'
55
56 This would appear to be a problem with large file support, header
57 files and gcc. gcc may or may not give up at this point. If it
58 fails, you might be able to improve matters by adding
59 -D__STDC_EXT__=1
60 to the BIGFILES variable in the Makefile (ie, change its definition
61 to
62 BIGFILES=-D_FILE_OFFSET_BITS=64 -D__STDC_EXT__=1
63
64 Even if gcc does produce a binary which appears to work (ie passes
65 its self-tests), you might want to test it to see if it works properly
66 on large files.
67
68
69* HP/UX 10.20 and 11.00, using HP's cc compiler.
70
71 No specific problems for this combination, except that you'll need to
72 specify the -Ae flag, and zap the gcc-specific stuff
73 -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce.
74 You should retain -D_FILE_OFFSET_BITS=64 in order to get large
75 file support -- which is reported to work ok for this HP/UX + cc
76 combination.
77
78
79* SunOS 4.1.X.
80
81 Amazingly, there are still people out there using this venerable old
82 banger. I shouldn't be too rude -- I started life on SunOS, and
83 it was a pretty darn good OS, way back then. Anyway:
84
85 SunOS doesn't seem to have strerror(), so you'll have to use
86 perror(), perhaps by doing adding this (warning: UNTESTED CODE):
87
88 char* strerror ( int errnum )
89 {
90 if (errnum < 0 || errnum >= sys_nerr)
91 return "Unknown error";
92 else
93 return sys_errlist[errnum];
94 }
95
96 Or you could comment out the relevant calls to strerror; they're
97 not mission-critical. Or you could upgrade to Solaris. Ha ha ha!
98 (what?? you think I've got Bad Attitude?)
99
100
101* Making a shared library on Solaris. (Not really a compilation
102 problem, but many people ask ...)
103
104 Firstly, if you have Solaris 8, either you have libbz2.so already
105 on your system, or you can install it from the Solaris CD.
106
107 Secondly, be aware that there are potential naming conflicts
108 between the .so file supplied with Solaris 8, and the .so file
109 which Makefile-libbz2_so will make. Makefile-libbz2_so creates
110 a .so which has the names which I intend to be "official" as
111 of version 1.0.0 and onwards. Unfortunately, the .so in
112 Solaris 8 appeared before I decided on the final names, so
113 the two libraries are incompatible. We have since communicated
114 and I hope that the problems will have been solved in the next
115 version of Solaris, whenever that might appear.
116
117 All that said: you might be able to get somewhere
118 by finding the line in Makefile-libbz2_so which says
119
120 $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.1 $(OBJS)
121
122 and replacing with
123
124 ($CC) -G -shared -o libbz2.so.1.0.1 -h libbz2.so.1.0 $(OBJS)
125
126 If gcc objects to the combination -fpic -fPIC, get rid of
127 the second one, leaving just "-fpic".
128
129
130That's the end of the currently known compilation problems.
diff --git a/blocksort.c b/blocksort.c
index 85a02de..ec42672 100644
--- a/blocksort.c
+++ b/blocksort.c
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -56,6 +56,13 @@
56 Jon L. Bentley 56 Jon L. Bentley
57 57
58 For more information on these sources, see the manual. 58 For more information on these sources, see the manual.
59
60 To get some idea how the block sorting algorithms in this file
61 work, read my paper
62 On the Performance of BWT Sorting Algorithms
63 in Proceedings of the IEEE Data Compression Conference 2000,
64 Snowbird, Utah, USA, 27-30 March 2000. The main sort in this
65 file implements the algorithm called cache in the paper.
59--*/ 66--*/
60 67
61 68
@@ -232,11 +239,11 @@ void fallbackQSort3 ( UInt32* fmap,
232/* Pre: 239/* Pre:
233 nblock > 0 240 nblock > 0
234 eclass exists for [0 .. nblock-1] 241 eclass exists for [0 .. nblock-1]
235 ((UInt16*)eclass) [0 .. nblock-1] [15:8] holds block 242 ((UChar*)eclass) [0 .. nblock-1] holds block
236 ptr exists for [0 .. nblock-1] 243 ptr exists for [0 .. nblock-1]
237 244
238 Post: 245 Post:
239 ((UInt16*)eclass) [0 .. nblock-1] [15:8] holds block 246 ((UChar*)eclass) [0 .. nblock-1] holds block
240 All other areas of eclass destroyed 247 All other areas of eclass destroyed
241 fmap [0 .. nblock-1] holds sorted order 248 fmap [0 .. nblock-1] holds sorted order
242 bhtab [ 0 .. 2+(nblock/32) ] destroyed 249 bhtab [ 0 .. 2+(nblock/32) ] destroyed
@@ -260,7 +267,7 @@ void fallbackSort ( UInt32* fmap,
260 Int32 H, i, j, k, l, r, cc, cc1; 267 Int32 H, i, j, k, l, r, cc, cc1;
261 Int32 nNotDone; 268 Int32 nNotDone;
262 Int32 nBhtab; 269 Int32 nBhtab;
263 UInt16* eclass16 = (UInt16*)eclass; 270 UChar* eclass8 = (UChar*)eclass;
264 271
265 /*-- 272 /*--
266 Initial 1-char radix sort to generate 273 Initial 1-char radix sort to generate
@@ -269,12 +276,12 @@ void fallbackSort ( UInt32* fmap,
269 if (verb >= 4) 276 if (verb >= 4)
270 VPrintf0 ( " bucket sorting ...\n" ); 277 VPrintf0 ( " bucket sorting ...\n" );
271 for (i = 0; i < 257; i++) ftab[i] = 0; 278 for (i = 0; i < 257; i++) ftab[i] = 0;
272 for (i = 0; i < nblock; i++) ftab[eclass16[i] >> 8]++; 279 for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
273 for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; 280 for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
274 for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; 281 for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
275 282
276 for (i = 0; i < nblock; i++) { 283 for (i = 0; i < nblock; i++) {
277 j = eclass16[i] >> 8; 284 j = eclass8[i];
278 k = ftab[j] - 1; 285 k = ftab[j] - 1;
279 ftab[j] = k; 286 ftab[j] = k;
280 fmap[k] = i; 287 fmap[k] = i;
@@ -354,7 +361,7 @@ void fallbackSort ( UInt32* fmap,
354 361
355 /*-- 362 /*--
356 Reconstruct the original block in 363 Reconstruct the original block in
357 eclass16 [0 .. nblock-1] [15:8], since the 364 eclass8 [0 .. nblock-1], since the
358 previous phase destroyed it. 365 previous phase destroyed it.
359 --*/ 366 --*/
360 if (verb >= 4) 367 if (verb >= 4)
@@ -363,7 +370,7 @@ void fallbackSort ( UInt32* fmap,
363 for (i = 0; i < nblock; i++) { 370 for (i = 0; i < nblock; i++) {
364 while (ftabCopy[j] == 0) j++; 371 while (ftabCopy[j] == 0) j++;
365 ftabCopy[j]--; 372 ftabCopy[j]--;
366 eclass16[fmap[i]] = j << 8; 373 eclass8[fmap[i]] = (UChar)j;
367 } 374 }
368 AssertH ( j < 256, 1005 ); 375 AssertH ( j < 256, 1005 );
369} 376}
@@ -386,67 +393,116 @@ static
386__inline__ 393__inline__
387Bool mainGtU ( UInt32 i1, 394Bool mainGtU ( UInt32 i1,
388 UInt32 i2, 395 UInt32 i2,
389 UInt16* block, 396 UChar* block,
390 UInt16* quadrant, 397 UInt16* quadrant,
391 UInt32 nblock, 398 UInt32 nblock,
392 Int32* budget ) 399 Int32* budget )
393{ 400{
394 Int32 k; 401 Int32 k;
402 UChar c1, c2;
395 UInt16 s1, s2; 403 UInt16 s1, s2;
396 404
397 AssertD ( i1 != i2, "mainGtU" ); 405 AssertD ( i1 != i2, "mainGtU" );
398 406 /* 1 */
399 s1 = block[i1]; s2 = block[i2]; 407 c1 = block[i1]; c2 = block[i2];
400 if (s1 != s2) return (s1 > s2); 408 if (c1 != c2) return (c1 > c2);
401 i1 += 2; i2 += 2; 409 i1++; i2++;
402 410 /* 2 */
403 s1 = block[i1]; s2 = block[i2]; 411 c1 = block[i1]; c2 = block[i2];
404 if (s1 != s2) return (s1 > s2); 412 if (c1 != c2) return (c1 > c2);
405 i1 += 2; i2 += 2; 413 i1++; i2++;
406 414 /* 3 */
407 s1 = block[i1]; s2 = block[i2]; 415 c1 = block[i1]; c2 = block[i2];
408 if (s1 != s2) return (s1 > s2); 416 if (c1 != c2) return (c1 > c2);
409 i1 += 2; i2 += 2; 417 i1++; i2++;
410 418 /* 4 */
411 s1 = block[i1]; s2 = block[i2]; 419 c1 = block[i1]; c2 = block[i2];
412 if (s1 != s2) return (s1 > s2); 420 if (c1 != c2) return (c1 > c2);
413 i1 += 2; i2 += 2; 421 i1++; i2++;
414 422 /* 5 */
415 s1 = block[i1]; s2 = block[i2]; 423 c1 = block[i1]; c2 = block[i2];
416 if (s1 != s2) return (s1 > s2); 424 if (c1 != c2) return (c1 > c2);
417 i1 += 2; i2 += 2; 425 i1++; i2++;
418 426 /* 6 */
419 s1 = block[i1]; s2 = block[i2]; 427 c1 = block[i1]; c2 = block[i2];
420 if (s1 != s2) return (s1 > s2); 428 if (c1 != c2) return (c1 > c2);
421 i1 += 2; i2 += 2; 429 i1++; i2++;
430 /* 7 */
431 c1 = block[i1]; c2 = block[i2];
432 if (c1 != c2) return (c1 > c2);
433 i1++; i2++;
434 /* 8 */
435 c1 = block[i1]; c2 = block[i2];
436 if (c1 != c2) return (c1 > c2);
437 i1++; i2++;
438 /* 9 */
439 c1 = block[i1]; c2 = block[i2];
440 if (c1 != c2) return (c1 > c2);
441 i1++; i2++;
442 /* 10 */
443 c1 = block[i1]; c2 = block[i2];
444 if (c1 != c2) return (c1 > c2);
445 i1++; i2++;
446 /* 11 */
447 c1 = block[i1]; c2 = block[i2];
448 if (c1 != c2) return (c1 > c2);
449 i1++; i2++;
450 /* 12 */
451 c1 = block[i1]; c2 = block[i2];
452 if (c1 != c2) return (c1 > c2);
453 i1++; i2++;
422 454
423 k = nblock + 8; 455 k = nblock + 8;
424 456
425 do { 457 do {
426 458 /* 1 */
427 s1 = block[i1]; s2 = block[i2]; 459 c1 = block[i1]; c2 = block[i2];
460 if (c1 != c2) return (c1 > c2);
461 s1 = quadrant[i1]; s2 = quadrant[i2];
428 if (s1 != s2) return (s1 > s2); 462 if (s1 != s2) return (s1 > s2);
463 i1++; i2++;
464 /* 2 */
465 c1 = block[i1]; c2 = block[i2];
466 if (c1 != c2) return (c1 > c2);
429 s1 = quadrant[i1]; s2 = quadrant[i2]; 467 s1 = quadrant[i1]; s2 = quadrant[i2];
430 if (s1 != s2) return (s1 > s2); 468 if (s1 != s2) return (s1 > s2);
431 i1 += 2; i2 += 2; 469 i1++; i2++;
432 470 /* 3 */
433 s1 = block[i1]; s2 = block[i2]; 471 c1 = block[i1]; c2 = block[i2];
472 if (c1 != c2) return (c1 > c2);
473 s1 = quadrant[i1]; s2 = quadrant[i2];
434 if (s1 != s2) return (s1 > s2); 474 if (s1 != s2) return (s1 > s2);
475 i1++; i2++;
476 /* 4 */
477 c1 = block[i1]; c2 = block[i2];
478 if (c1 != c2) return (c1 > c2);
435 s1 = quadrant[i1]; s2 = quadrant[i2]; 479 s1 = quadrant[i1]; s2 = quadrant[i2];
436 if (s1 != s2) return (s1 > s2); 480 if (s1 != s2) return (s1 > s2);
437 i1 += 2; i2 += 2; 481 i1++; i2++;
438 482 /* 5 */
439 s1 = block[i1]; s2 = block[i2]; 483 c1 = block[i1]; c2 = block[i2];
484 if (c1 != c2) return (c1 > c2);
485 s1 = quadrant[i1]; s2 = quadrant[i2];
440 if (s1 != s2) return (s1 > s2); 486 if (s1 != s2) return (s1 > s2);
487 i1++; i2++;
488 /* 6 */
489 c1 = block[i1]; c2 = block[i2];
490 if (c1 != c2) return (c1 > c2);
441 s1 = quadrant[i1]; s2 = quadrant[i2]; 491 s1 = quadrant[i1]; s2 = quadrant[i2];
442 if (s1 != s2) return (s1 > s2); 492 if (s1 != s2) return (s1 > s2);
443 i1 += 2; i2 += 2; 493 i1++; i2++;
444 494 /* 7 */
445 s1 = block[i1]; s2 = block[i2]; 495 c1 = block[i1]; c2 = block[i2];
496 if (c1 != c2) return (c1 > c2);
497 s1 = quadrant[i1]; s2 = quadrant[i2];
446 if (s1 != s2) return (s1 > s2); 498 if (s1 != s2) return (s1 > s2);
499 i1++; i2++;
500 /* 8 */
501 c1 = block[i1]; c2 = block[i2];
502 if (c1 != c2) return (c1 > c2);
447 s1 = quadrant[i1]; s2 = quadrant[i2]; 503 s1 = quadrant[i1]; s2 = quadrant[i2];
448 if (s1 != s2) return (s1 > s2); 504 if (s1 != s2) return (s1 > s2);
449 i1 += 2; i2 += 2; 505 i1++; i2++;
450 506
451 if (i1 >= nblock) i1 -= nblock; 507 if (i1 >= nblock) i1 -= nblock;
452 if (i2 >= nblock) i2 -= nblock; 508 if (i2 >= nblock) i2 -= nblock;
@@ -467,13 +523,14 @@ Bool mainGtU ( UInt32 i1,
467 because the number of elems to sort is 523 because the number of elems to sort is
468 usually small, typically <= 20. 524 usually small, typically <= 20.
469--*/ 525--*/
526static
470Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, 527Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
471 9841, 29524, 88573, 265720, 528 9841, 29524, 88573, 265720,
472 797161, 2391484 }; 529 797161, 2391484 };
473 530
474static 531static
475void mainSimpleSort ( UInt32* ptr, 532void mainSimpleSort ( UInt32* ptr,
476 UInt16* block, 533 UChar* block,
477 UInt16* quadrant, 534 UInt16* quadrant,
478 Int32 nblock, 535 Int32 nblock,
479 Int32 lo, 536 Int32 lo,
@@ -568,19 +625,19 @@ void mainSimpleSort ( UInt32* ptr,
568 } \ 625 } \
569} 626}
570 627
571
572static 628static
573__inline__ 629__inline__
574UInt16 mmed3 ( UInt16 a, UInt16 b, UInt16 c ) 630UChar mmed3 ( UChar a, UChar b, UChar c )
575{ 631{
576 UInt16 t; 632 UChar t;
577 if (a > b) { t = a; a = b; b = t; }; 633 if (a > b) { t = a; a = b; b = t; };
578 if (b > c) { t = b; b = c; c = t; }; 634 if (b > c) {
579 if (a > b) b = a; 635 b = c;
636 if (a > b) b = a;
637 }
580 return b; 638 return b;
581} 639}
582 640
583
584#define mmin(a,b) ((a) < (b)) ? (a) : (b) 641#define mmin(a,b) ((a) < (b)) ? (a) : (b)
585 642
586#define mpush(lz,hz,dz) { stackLo[sp] = lz; \ 643#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
@@ -609,7 +666,7 @@ UInt16 mmed3 ( UInt16 a, UInt16 b, UInt16 c )
609 666
610static 667static
611void mainQSort3 ( UInt32* ptr, 668void mainQSort3 ( UInt32* ptr,
612 UInt16* block, 669 UChar* block,
613 UInt16* quadrant, 670 UInt16* quadrant,
614 Int32 nblock, 671 Int32 nblock,
615 Int32 loSt, 672 Int32 loSt,
@@ -679,7 +736,7 @@ void mainQSort3 ( UInt32* ptr,
679 AssertD ( unHi == unLo-1, "mainQSort3(2)" ); 736 AssertD ( unHi == unLo-1, "mainQSort3(2)" );
680 737
681 if (gtHi < ltLo) { 738 if (gtHi < ltLo) {
682 mpush(lo, hi, d+2 ); 739 mpush(lo, hi, d+1 );
683 continue; 740 continue;
684 } 741 }
685 742
@@ -691,7 +748,7 @@ void mainQSort3 ( UInt32* ptr,
691 748
692 nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; 749 nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
693 nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; 750 nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
694 nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+2; 751 nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
695 752
696 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); 753 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
697 if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); 754 if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
@@ -722,11 +779,11 @@ void mainQSort3 ( UInt32* ptr,
722/* Pre: 779/* Pre:
723 nblock > N_OVERSHOOT 780 nblock > N_OVERSHOOT
724 block32 exists for [0 .. nblock-1 +N_OVERSHOOT] 781 block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
725 ((UInt16*)block32) [0 .. nblock-1] [15:8] holds block 782 ((UChar*)block32) [0 .. nblock-1] holds block
726 ptr exists for [0 .. nblock-1] 783 ptr exists for [0 .. nblock-1]
727 784
728 Post: 785 Post:
729 ((UInt16*)block32) [0 .. nblock-1] [15:8] holds block 786 ((UChar*)block32) [0 .. nblock-1] holds block
730 All other areas of block32 destroyed 787 All other areas of block32 destroyed
731 ftab [0 .. 65536 ] destroyed 788 ftab [0 .. 65536 ] destroyed
732 ptr [0 .. nblock-1] holds sorted order 789 ptr [0 .. nblock-1] holds sorted order
@@ -739,40 +796,47 @@ void mainQSort3 ( UInt32* ptr,
739 796
740static 797static
741void mainSort ( UInt32* ptr, 798void mainSort ( UInt32* ptr,
742 UInt16* block, 799 UChar* block,
743 UInt16* quadrant, 800 UInt16* quadrant,
744 UInt32* ftab, 801 UInt32* ftab,
745 Int32 nblock, 802 Int32 nblock,
746 Int32 verb, 803 Int32 verb,
747 Int32* budget ) 804 Int32* budget )
748{ 805{
749 Int32 i, j, k, m, ss, sb; 806 Int32 i, j, k, ss, sb;
750 Int32 runningOrder[256]; 807 Int32 runningOrder[256];
751 Int32 copy[256];
752 Bool bigDone[256]; 808 Bool bigDone[256];
809 Int32 copyStart[256];
810 Int32 copyEnd [256];
753 UChar c1; 811 UChar c1;
754 Int32 numQSorted; 812 Int32 numQSorted;
755 Int32 biggestSoFar;
756 UInt16 s; 813 UInt16 s;
757
758 if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); 814 if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
759 815
760 /*-- Stripe the block data into 16 bits, and at the 816 /*-- set up the 2-byte frequency table --*/
761 same time set up the 2-byte frequency table
762 --*/
763 for (i = 65536; i >= 0; i--) ftab[i] = 0; 817 for (i = 65536; i >= 0; i--) ftab[i] = 0;
764 818
765 s = block[0]; 819 j = block[0] << 8;
766 for (i = 1; i < nblock; i++) { 820 i = nblock-1;
821 for (; i >= 3; i -= 4) {
822 quadrant[i] = 0;
823 j = (j >> 8) | ( ((UInt16)block[i]) << 8);
824 ftab[j]++;
825 quadrant[i-1] = 0;
826 j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
827 ftab[j]++;
828 quadrant[i-2] = 0;
829 j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
830 ftab[j]++;
831 quadrant[i-3] = 0;
832 j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
833 ftab[j]++;
834 }
835 for (; i >= 0; i--) {
767 quadrant[i] = 0; 836 quadrant[i] = 0;
768 s = (s << 8) | block[i]; 837 j = (j >> 8) | ( ((UInt16)block[i]) << 8);
769 block[i-1] = s; 838 ftab[j]++;
770 ftab[s]++;
771 } 839 }
772 quadrant[0] = 0;
773 s = (s << 8) | (block[0] >> 8);
774 block[nblock-1] = s;
775 ftab[s]++;
776 840
777 /*-- (emphasises close relationship of block & quadrant) --*/ 841 /*-- (emphasises close relationship of block & quadrant) --*/
778 for (i = 0; i < BZ_N_OVERSHOOT; i++) { 842 for (i = 0; i < BZ_N_OVERSHOOT; i++) {
@@ -785,9 +849,29 @@ void mainSort ( UInt32* ptr,
785 /*-- Complete the initial radix sort --*/ 849 /*-- Complete the initial radix sort --*/
786 for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; 850 for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
787 851
788 for (i = 0; i < nblock; i++) { 852 s = block[0] << 8;
789 s = block[i]; 853 i = nblock-1;
790 j = ftab[s] - 1; 854 for (; i >= 3; i -= 4) {
855 s = (s >> 8) | (block[i] << 8);
856 j = ftab[s] -1;
857 ftab[s] = j;
858 ptr[j] = i;
859 s = (s >> 8) | (block[i-1] << 8);
860 j = ftab[s] -1;
861 ftab[s] = j;
862 ptr[j] = i-1;
863 s = (s >> 8) | (block[i-2] << 8);
864 j = ftab[s] -1;
865 ftab[s] = j;
866 ptr[j] = i-2;
867 s = (s >> 8) | (block[i-3] << 8);
868 j = ftab[s] -1;
869 ftab[s] = j;
870 ptr[j] = i-3;
871 }
872 for (; i >= 0; i--) {
873 s = (s >> 8) | (block[i] << 8);
874 j = ftab[s] -1;
791 ftab[s] = j; 875 ftab[s] = j;
792 ptr[j] = i; 876 ptr[j] = i;
793 } 877 }
@@ -826,13 +910,13 @@ void mainSort ( UInt32* ptr,
826 The main sorting loop. 910 The main sorting loop.
827 --*/ 911 --*/
828 912
829 biggestSoFar = numQSorted = 0; 913 numQSorted = 0;
830 914
831 for (i = 0; i <= 255; i++) { 915 for (i = 0; i <= 255; i++) {
832 916
833 /*-- 917 /*--
834 Process big buckets, starting with the least full. 918 Process big buckets, starting with the least full.
835 Basically this is a 4-step process in which we call 919 Basically this is a 3-step process in which we call
836 mainQSort3 to sort the small buckets [ss, j], but 920 mainQSort3 to sort the small buckets [ss, j], but
837 also make a big effort to avoid the calls if we can. 921 also make a big effort to avoid the calls if we can.
838 --*/ 922 --*/
@@ -869,39 +953,38 @@ void mainSort ( UInt32* ptr,
869 } 953 }
870 } 954 }
871 955
956 AssertH ( !bigDone[ss], 1006 );
957
872 /*-- 958 /*--
873 Step 2: 959 Step 2:
874 Deal specially with case [ss, ss]. This establishes the 960 Now scan this big bucket [ss] so as to synthesise the
875 sorted order for [ss, ss] without any comparisons. 961 sorted order for small buckets [t, ss] for all t,
876 A clever trick, cryptically described as steps Q6b and Q6c 962 including, magically, the bucket [ss,ss] too.
877 in SRC-124 (aka BW94). Compared to bzip2, this makes it 963 This will avoid doing Real Work in subsequent Step 1's.
878 practical not to use a preliminary run-length coder.
879 --*/ 964 --*/
880 { 965 {
881 Int32 put0, get0, put1, get1; 966 for (j = 0; j <= 255; j++) {
882 Int32 sbn = (ss << 8) + ss; 967 copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
883 Int32 lo = ftab[sbn] & CLEARMASK; 968 copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
884 Int32 hi = (ftab[sbn+1] & CLEARMASK) - 1; 969 }
885 UChar ssc = (UChar)ss; 970 for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
886 put0 = lo; 971 k = ptr[j]-1; if (k < 0) k += nblock;
887 get0 = ftab[ss << 8] & CLEARMASK; 972 c1 = block[k];
888 put1 = hi; 973 if (!bigDone[c1])
889 get1 = (ftab[(ss+1) << 8] & CLEARMASK) - 1; 974 ptr[ copyStart[c1]++ ] = k;
890 while (get0 < put0) {
891 j = ptr[get0]-1; if (j < 0) j += nblock;
892 c1 = (UChar)(block[j] >> 8);
893 if (c1 == ssc) { ptr[put0] = j; put0++; };
894 get0++;
895 } 975 }
896 while (get1 > put1) { 976 for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
897 j = ptr[get1]-1; if (j < 0) j += nblock; 977 k = ptr[j]-1; if (k < 0) k += nblock;
898 c1 = (UChar)(block[j] >> 8); 978 c1 = block[k];
899 if (c1 == ssc) { ptr[put1] = j; put1--; }; 979 if (!bigDone[c1])
900 get1--; 980 ptr[ copyEnd[c1]-- ] = k;
901 } 981 }
902 ftab[sbn] |= SETMASK;
903 } 982 }
904 983
984 AssertH ( copyStart[ss]-1 == copyEnd[ss], 1007 );
985
986 for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
987
905 /*-- 988 /*--
906 Step 3: 989 Step 3:
907 The [ss] big bucket is now done. Record this fact, 990 The [ss] big bucket is now done. Record this fact,
@@ -950,7 +1033,7 @@ void mainSort ( UInt32* ptr,
950 1033
951 while ((bbSize >> shifts) > 65534) shifts++; 1034 while ((bbSize >> shifts) > 65534) shifts++;
952 1035
953 for (j = 0; j < bbSize; j++) { 1036 for (j = bbSize-1; j >= 0; j--) {
954 Int32 a2update = ptr[bbStart + j]; 1037 Int32 a2update = ptr[bbStart + j];
955 UInt16 qVal = (UInt16)(j >> shifts); 1038 UInt16 qVal = (UInt16)(j >> shifts);
956 quadrant[a2update] = qVal; 1039 quadrant[a2update] = qVal;
@@ -960,26 +1043,6 @@ void mainSort ( UInt32* ptr,
960 AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); 1043 AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
961 } 1044 }
962 1045
963 /*--
964 Step 4:
965 Now scan this big bucket [ss] so as to synthesise the
966 sorted order for small buckets [t, ss] for all t != ss.
967 This will avoid doing Real Work in subsequent Step 1's.
968 --*/
969 for (j = 0; j <= 255; j++)
970 copy[j] = ftab[(j << 8) + ss] & CLEARMASK;
971
972 m = ftab[(ss+1) << 8] & CLEARMASK;
973 for (j = ftab[ss << 8] & CLEARMASK; j < m; j++) {
974 k = ptr[j] - 1; if (k < 0) k += nblock;
975 c1 = (UChar)(block[k] >> 8);
976 if ( ! bigDone[c1] ) {
977 ptr[copy[c1]] = k;
978 copy[c1] ++;
979 }
980 }
981
982 for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
983 } 1046 }
984 1047
985 if (verb >= 4) 1048 if (verb >= 4)
@@ -996,19 +1059,19 @@ void mainSort ( UInt32* ptr,
996/* Pre: 1059/* Pre:
997 nblock > 0 1060 nblock > 0
998 arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] 1061 arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
999 ((UInt16*)arr2) [0 .. nblock-1] [15:8] holds block 1062 ((UChar*)arr2) [0 .. nblock-1] holds block
1000 arr1 exists for [0 .. nblock-1] 1063 arr1 exists for [0 .. nblock-1]
1001 1064
1002 Post: 1065 Post:
1003 ((UInt16*)arr2) [0 .. nblock-1] [15:8] holds block 1066 ((UChar*)arr2) [0 .. nblock-1] holds block
1004 All other areas of block destroyed 1067 All other areas of block destroyed
1005 ftab [ 0 .. 65536 ] destroyed 1068 ftab [ 0 .. 65536 ] destroyed
1006 arr1 [0 .. nblock-1] holds sorted order 1069 arr1 [0 .. nblock-1] holds sorted order
1007*/ 1070*/
1008void blockSort ( EState* s ) 1071void BZ2_blockSort ( EState* s )
1009{ 1072{
1010 UInt32* ptr = s->ptr; 1073 UInt32* ptr = s->ptr;
1011 UInt16* block = s->block; 1074 UChar* block = s->block;
1012 UInt32* ftab = s->ftab; 1075 UInt32* ftab = s->ftab;
1013 Int32 nblock = s->nblock; 1076 Int32 nblock = s->nblock;
1014 Int32 verb = s->verbosity; 1077 Int32 verb = s->verbosity;
@@ -1019,10 +1082,16 @@ void blockSort ( EState* s )
1019 Int32 i; 1082 Int32 i;
1020 1083
1021 if (nblock < 10000) { 1084 if (nblock < 10000) {
1022 for (i = 0; i < nblock; i++) block[i] <<= 8;
1023 fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); 1085 fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1024 } else { 1086 } else {
1025 quadrant = &(block[nblock+BZ_N_OVERSHOOT]); 1087 /* Calculate the location for quadrant, remembering to get
1088 the alignment right. Assumes that &(block[0]) is at least
1089 2-byte aligned -- this should be ok since block is really
1090 the first section of arr2.
1091 */
1092 i = nblock+BZ_N_OVERSHOOT;
1093 if (i & 1) i++;
1094 quadrant = (UInt16*)(&(block[i]));
1026 1095
1027 /* (wfact-1) / 3 puts the default-factor-30 1096 /* (wfact-1) / 3 puts the default-factor-30
1028 transition point at very roughly the same place as 1097 transition point at very roughly the same place as
diff --git a/bzip2.1 b/bzip2.1
index 99eda9b..7de54a0 100644
--- a/bzip2.1
+++ b/bzip2.1
@@ -1,7 +1,7 @@
1.PU 1.PU
2.TH bzip2 1 2.TH bzip2 1
3.SH NAME 3.SH NAME
4bzip2, bunzip2 \- a block-sorting file compressor, v0.9.5 4bzip2, bunzip2 \- a block-sorting file compressor, v1.0
5.br 5.br
6bzcat \- decompresses files to stdout 6bzcat \- decompresses files to stdout
7.br 7.br
@@ -397,11 +397,12 @@ I/O error messages are not as helpful as they could be.
397tries hard to detect I/O errors and exit cleanly, but the details of 397tries hard to detect I/O errors and exit cleanly, but the details of
398what the problem is sometimes seem rather misleading. 398what the problem is sometimes seem rather misleading.
399 399
400This manual page pertains to version 0.9.5 of 400This manual page pertains to version 1.0 of
401.I bzip2. 401.I bzip2.
402Compressed 402Compressed
403data created by this version is entirely forwards and backwards 403data created by this version is entirely forwards and backwards
404compatible with the previous public releases, versions 0.1pl2 and 0.9.0, 404compatible with the previous public releases, versions 0.1pl2, 0.9.0
405and 0.9.5,
405but with the following exception: 0.9.0 and above can correctly 406but with the following exception: 0.9.0 and above can correctly
406decompress multiple concatenated compressed files. 0.1pl2 cannot do 407decompress multiple concatenated compressed files. 0.1pl2 cannot do
407this; it will stop after decompressing just the first file in the 408this; it will stop after decompressing just the first file in the
@@ -415,6 +416,7 @@ megabytes long. This could easily be fixed.
415.SH AUTHOR 416.SH AUTHOR
416Julian Seward, jseward@acm.org. 417Julian Seward, jseward@acm.org.
417 418
419http://sourceware.cygnus.com/bzip2
418http://www.muraroa.demon.co.uk 420http://www.muraroa.demon.co.uk
419 421
420The ideas embodied in 422The ideas embodied in
diff --git a/bzip2.1.preformatted b/bzip2.1.preformatted
index 96b44be..9f18339 100644
--- a/bzip2.1.preformatted
+++ b/bzip2.1.preformatted
@@ -1,7 +1,11 @@
1 1
2 2
3
4bzip2(1) bzip2(1)
5
6
3NNAAMMEE 7NNAAMMEE
4 bzip2, bunzip2 - a block-sorting file compressor, v0.9.5 8 bzip2, bunzip2 - a block-sorting file compressor, v1.0
5 bzcat - decompresses files to stdout 9 bzcat - decompresses files to stdout
6 bzip2recover - recovers data from damaged bzip2 files 10 bzip2recover - recovers data from damaged bzip2 files
7 11
@@ -54,6 +58,18 @@ DDEESSCCRRIIPPTTIIOONN
54 filename.bz2 becomes filename 58 filename.bz2 becomes filename
55 filename.bz becomes filename 59 filename.bz becomes filename
56 filename.tbz2 becomes filename.tar 60 filename.tbz2 becomes filename.tar
61
62
63
64 1
65
66
67
68
69
70bzip2(1) bzip2(1)
71
72
57 filename.tbz becomes filename.tar 73 filename.tbz becomes filename.tar
58 anyothername becomes anyothername.out 74 anyothername becomes anyothername.out
59 75
@@ -109,6 +125,17 @@ DDEESSCCRRIIPPTTIIOONN
109 you recover the original uncompressed data. You can use 125 you recover the original uncompressed data. You can use
110 _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files. 126 _b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
111 127
128
129
130 2
131
132
133
134
135
136bzip2(1) bzip2(1)
137
138
112 Return values: 0 for a normal exit, 1 for environmental 139 Return values: 0 for a normal exit, 1 for environmental
113 problems (file not found, invalid flags, I/O errors, &c), 140 problems (file not found, invalid flags, I/O errors, &c),
114 2 to indicate a corrupt compressed file, 3 for an internal 141 2 to indicate a corrupt compressed file, 3 for an internal
@@ -163,6 +190,18 @@ OOPPTTIIOONNSS
163 --qq ----qquuiieett 190 --qq ----qquuiieett
164 Suppress non-essential warning messages. Messages 191 Suppress non-essential warning messages. Messages
165 pertaining to I/O errors and other critical events 192 pertaining to I/O errors and other critical events
193
194
195
196 3
197
198
199
200
201
202bzip2(1) bzip2(1)
203
204
166 will not be suppressed. 205 will not be suppressed.
167 206
168 --vv ----vveerrbboossee 207 --vv ----vveerrbboossee
@@ -217,6 +256,18 @@ MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
217 256
218 Larger block sizes give rapidly diminishing marginal 257 Larger block sizes give rapidly diminishing marginal
219 returns. Most of the compression comes from the first two 258 returns. Most of the compression comes from the first two
259
260
261
262 4
263
264
265
266
267
268bzip2(1) bzip2(1)
269
270
220 or three hundred k of block size, a fact worth bearing in 271 or three hundred k of block size, a fact worth bearing in
221 mind when using _b_z_i_p_2 on small machines. It is also 272 mind when using _b_z_i_p_2 on small machines. It is also
222 important to appreciate that the decompression memory 273 important to appreciate that the decompression memory
@@ -270,6 +321,19 @@ MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
270 -9 7600k 3700k 2350k 828642 321 -9 7600k 3700k 2350k 828642
271 322
272 323
324
325
326
327
328 5
329
330
331
332
333
334bzip2(1) bzip2(1)
335
336
273RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS 337RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
274 _b_z_i_p_2 compresses files in blocks, usually 900kbytes long. 338 _b_z_i_p_2 compresses files in blocks, usually 900kbytes long.
275 Each block is handled independently. If a media or trans- 339 Each block is handled independently. If a media or trans-
@@ -324,6 +388,18 @@ PPEERRFFOORRMMAANNCCEE NNOOTTEESS
324 operate in, and then charges all over it in a fairly ran- 388 operate in, and then charges all over it in a fairly ran-
325 dom fashion. This means that performance, both for com- 389 dom fashion. This means that performance, both for com-
326 pressing and decompressing, is largely determined by the 390 pressing and decompressing, is largely determined by the
391
392
393
394 6
395
396
397
398
399
400bzip2(1) bzip2(1)
401
402
327 speed at which your machine can service cache misses. 403 speed at which your machine can service cache misses.
328 Because of this, small changes to the code to reduce the 404 Because of this, small changes to the code to reduce the
329 miss rate have been observed to give disproportionately 405 miss rate have been observed to give disproportionately
@@ -337,14 +413,14 @@ CCAAVVEEAATTSS
337 but the details of what the problem is sometimes seem 413 but the details of what the problem is sometimes seem
338 rather misleading. 414 rather misleading.
339 415
340 This manual page pertains to version 0.9.5 of _b_z_i_p_2_. Com- 416 This manual page pertains to version 1.0 of _b_z_i_p_2_. Com-
341 pressed data created by this version is entirely forwards 417 pressed data created by this version is entirely forwards
342 and backwards compatible with the previous public 418 and backwards compatible with the previous public
343 releases, versions 0.1pl2 and 0.9.0, but with the follow- 419 releases, versions 0.1pl2, 0.9.0 and 0.9.5, but with the
344 ing exception: 0.9.0 and above can correctly decompress 420 following exception: 0.9.0 and above can correctly decom-
345 multiple concatenated compressed files. 0.1pl2 cannot do 421 press multiple concatenated compressed files. 0.1pl2 can-
346 this; it will stop after decompressing just the first file 422 not do this; it will stop after decompressing just the
347 in the stream. 423 first file in the stream.
348 424
349 _b_z_i_p_2_r_e_c_o_v_e_r uses 32-bit integers to represent bit posi- 425 _b_z_i_p_2_r_e_c_o_v_e_r uses 32-bit integers to represent bit posi-
350 tions in compressed files, so it cannot handle compressed 426 tions in compressed files, so it cannot handle compressed
@@ -355,21 +431,32 @@ CCAAVVEEAATTSS
355AAUUTTHHOORR 431AAUUTTHHOORR
356 Julian Seward, jseward@acm.org. 432 Julian Seward, jseward@acm.org.
357 433
434 http://sourceware.cygnus.com/bzip2
358 http://www.muraroa.demon.co.uk 435 http://www.muraroa.demon.co.uk
359 436
360 The ideas embodied in _b_z_i_p_2 are due to (at least) the fol- 437 The ideas embodied in _b_z_i_p_2 are due to (at least) the fol-
361 lowing people: Michael Burrows and David Wheeler (for the 438 lowing people: Michael Burrows and David Wheeler (for the
362 block sorting transformation), David Wheeler (again, for 439 block sorting transformation), David Wheeler (again, for
363 the Huffman coder), Peter Fenwick (for the structured cod- 440 the Huffman coder), Peter Fenwick (for the structured cod-
364 ing model in the original _b_z_i_p_, and many refinements), and 441 ing model in the original _b_z_i_p_, and many refinements), and
365 Alistair Moffat, Radford Neal and Ian Witten (for the 442 Alistair Moffat, Radford Neal and Ian Witten (for the
366 arithmetic coder in the original _b_z_i_p_)_. I am much 443 arithmetic coder in the original _b_z_i_p_)_. I am much
367 indebted for their help, support and advice. See the man- 444 indebted for their help, support and advice. See the man-
368 ual in the source distribution for pointers to sources of 445 ual in the source distribution for pointers to sources of
369 documentation. Christian von Roques encouraged me to look 446 documentation. Christian von Roques encouraged me to look
370 for faster sorting algorithms, so as to speed up compres- 447 for faster sorting algorithms, so as to speed up compres-
371 sion. Bela Lubkin encouraged me to improve the worst-case 448 sion. Bela Lubkin encouraged me to improve the worst-case
372 compression performance. Many people sent patches, helped 449 compression performance. Many people sent patches, helped
373 with portability problems, lent machines, gave advice and 450 with portability problems, lent machines, gave advice and
374 were generally helpful. 451 were generally helpful.
375 452
453
454
455
456
457
458
459
460 7
461
462
diff --git a/bzip2.c b/bzip2.c
index abb9530..56adfdc 100644
--- a/bzip2.c
+++ b/bzip2.c
@@ -7,7 +7,7 @@
7 This file is a part of bzip2 and/or libbzip2, a program and 7 This file is a part of bzip2 and/or libbzip2, a program and
8 library for lossless, block-sorting data compression. 8 library for lossless, block-sorting data compression.
9 9
10 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 10 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
11 11
12 Redistribution and use in source and binary forms, with or without 12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions 13 modification, are permitted provided that the following conditions
@@ -42,7 +42,7 @@
42 42
43 Julian Seward, Cambridge, UK. 43 Julian Seward, Cambridge, UK.
44 jseward@acm.org 44 jseward@acm.org
45 bzip2/libbzip2 version 0.9.5 of 24 May 1999 45 bzip2/libbzip2 version 1.0 of 21 March 2000
46 46
47 This program is based on (at least) the work of: 47 This program is based on (at least) the work of:
48 Mike Burrows 48 Mike Burrows
@@ -123,10 +123,10 @@
123--*/ 123--*/
124#define BZ_LCCWIN32 0 124#define BZ_LCCWIN32 0
125 125
126#if defined(_WIN32) && !defined(__CYGWIN32__) 126#if defined(_WIN32) && !defined(__CYGWIN__)
127#undef BZ_LCCWIN32 127#undef BZ_LCCWIN32
128#define BZ_LCCWIN32 1 128#define BZ_LCCWIN32 1
129#undef BZ_UNIX 129#undef BZ_UNIX
130#define BZ_UNIX 0 130#define BZ_UNIX 0
131#endif 131#endif
132 132
@@ -193,6 +193,17 @@
193 ERROR_IF_MINUS_ONE ( retVal ); \ 193 ERROR_IF_MINUS_ONE ( retVal ); \
194 } while ( 0 ) 194 } while ( 0 )
195# endif 195# endif
196# ifdef __CYGWIN__
197# include <io.h>
198# include <fcntl.h>
199# undef SET_BINARY_MODE
200# define SET_BINARY_MODE(fd) \
201 do { \
202 int retVal = setmode ( fileno ( fd ), \
203 O_BINARY ); \
204 ERROR_IF_MINUS_ONE ( retVal ); \
205 } while ( 0 )
206# endif
196#endif 207#endif
197 208
198 209
@@ -276,10 +287,10 @@ typedef int IntNative;
276/*---------------------------------------------------*/ 287/*---------------------------------------------------*/
277 288
278Int32 verbosity; 289Int32 verbosity;
279Bool keepInputFiles, smallMode; 290Bool keepInputFiles, smallMode, deleteOutputOnInterrupt;
280Bool forceOverwrite, testFailsExist, noisy; 291Bool forceOverwrite, testFailsExist, unzFailsExist, noisy;
281Int32 numFileNames, numFilesProcessed, blockSize100k; 292Int32 numFileNames, numFilesProcessed, blockSize100k;
282 293Int32 exitValue;
283 294
284/*-- source modes; F==file, I==stdin, O==stdout --*/ 295/*-- source modes; F==file, I==stdin, O==stdout --*/
285#define SM_I2O 1 296#define SM_I2O 1
@@ -305,27 +316,204 @@ Char progNameReally[FILE_NAME_LEN];
305FILE *outputHandleJustInCase; 316FILE *outputHandleJustInCase;
306Int32 workFactor; 317Int32 workFactor;
307 318
308void panic ( Char* ) NORETURN; 319static void panic ( Char* ) NORETURN;
309void ioError ( void ) NORETURN; 320static void ioError ( void ) NORETURN;
310void outOfMemory ( void ) NORETURN; 321static void outOfMemory ( void ) NORETURN;
311void blockOverrun ( void ) NORETURN; 322static void configError ( void ) NORETURN;
312void badBlockHeader ( void ) NORETURN; 323static void crcError ( void ) NORETURN;
313void badBGLengths ( void ) NORETURN; 324static void cleanUpAndFail ( Int32 ) NORETURN;
314void crcError ( void ) NORETURN; 325static void compressedStreamEOF ( void ) NORETURN;
315void bitStreamEOF ( void ) NORETURN;
316void cleanUpAndFail ( Int32 ) NORETURN;
317void compressedStreamEOF ( void ) NORETURN;
318 326
319void copyFileName ( Char*, Char* ); 327static void copyFileName ( Char*, Char* );
320void* myMalloc ( Int32 ); 328static void* myMalloc ( Int32 );
321 329
322 330
323 331
324/*---------------------------------------------------*/ 332/*---------------------------------------------------*/
333/*--- An implementation of 64-bit ints. Sigh. ---*/
334/*--- Roll on widespread deployment of ANSI C9X ! ---*/
335/*---------------------------------------------------*/
336
337typedef
338 struct { UChar b[8]; }
339 UInt64;
340
341static
342void uInt64_from_UInt32s ( UInt64* n, UInt32 lo32, UInt32 hi32 )
343{
344 n->b[7] = (UChar)((hi32 >> 24) & 0xFF);
345 n->b[6] = (UChar)((hi32 >> 16) & 0xFF);
346 n->b[5] = (UChar)((hi32 >> 8) & 0xFF);
347 n->b[4] = (UChar) (hi32 & 0xFF);
348 n->b[3] = (UChar)((lo32 >> 24) & 0xFF);
349 n->b[2] = (UChar)((lo32 >> 16) & 0xFF);
350 n->b[1] = (UChar)((lo32 >> 8) & 0xFF);
351 n->b[0] = (UChar) (lo32 & 0xFF);
352}
353
354static
355double uInt64_to_double ( UInt64* n )
356{
357 Int32 i;
358 double base = 1.0;
359 double sum = 0.0;
360 for (i = 0; i < 8; i++) {
361 sum += base * (double)(n->b[i]);
362 base *= 256.0;
363 }
364 return sum;
365}
366
367static
368void uInt64_add ( UInt64* src, UInt64* dst )
369{
370 Int32 i;
371 Int32 carry = 0;
372 for (i = 0; i < 8; i++) {
373 carry += ( ((Int32)src->b[i]) + ((Int32)dst->b[i]) );
374 dst->b[i] = (UChar)(carry & 0xFF);
375 carry >>= 8;
376 }
377}
378
379static
380void uInt64_sub ( UInt64* src, UInt64* dst )
381{
382 Int32 t, i;
383 Int32 borrow = 0;
384 for (i = 0; i < 8; i++) {
385 t = ((Int32)dst->b[i]) - ((Int32)src->b[i]) - borrow;
386 if (t < 0) {
387 dst->b[i] = (UChar)(t + 256);
388 borrow = 1;
389 } else {
390 dst->b[i] = (UChar)t;
391 borrow = 0;
392 }
393 }
394}
395
396static
397void uInt64_mul ( UInt64* a, UInt64* b, UInt64* r_hi, UInt64* r_lo )
398{
399 UChar sum[16];
400 Int32 ia, ib, carry;
401 for (ia = 0; ia < 16; ia++) sum[ia] = 0;
402 for (ia = 0; ia < 8; ia++) {
403 carry = 0;
404 for (ib = 0; ib < 8; ib++) {
405 carry += ( ((Int32)sum[ia+ib])
406 + ((Int32)a->b[ia]) * ((Int32)b->b[ib]) );
407 sum[ia+ib] = (UChar)(carry & 0xFF);
408 carry >>= 8;
409 }
410 sum[ia+8] = (UChar)(carry & 0xFF);
411 if ((carry >>= 8) != 0) panic ( "uInt64_mul" );
412 }
413
414 for (ia = 0; ia < 8; ia++) r_hi->b[ia] = sum[ia+8];
415 for (ia = 0; ia < 8; ia++) r_lo->b[ia] = sum[ia];
416}
417
418
419static
420void uInt64_shr1 ( UInt64* n )
421{
422 Int32 i;
423 for (i = 0; i < 8; i++) {
424 n->b[i] >>= 1;
425 if (i < 7 && (n->b[i+1] & 1)) n->b[i] |= 0x80;
426 }
427}
428
429static
430void uInt64_shl1 ( UInt64* n )
431{
432 Int32 i;
433 for (i = 7; i >= 0; i--) {
434 n->b[i] <<= 1;
435 if (i > 0 && (n->b[i-1] & 0x80)) n->b[i]++;
436 }
437}
438
439static
440Bool uInt64_isZero ( UInt64* n )
441{
442 Int32 i;
443 for (i = 0; i < 8; i++)
444 if (n->b[i] != 0) return 0;
445 return 1;
446}
447
448static
449Int32 uInt64_qrm10 ( UInt64* n )
450{
451 /* Divide *n by 10, and return the remainder. Long division
452 is difficult, so we cheat and instead multiply by
453 0xCCCC CCCC CCCC CCCD, which is 0.8 (viz, 0.1 << 3).
454 */
455 Int32 i;
456 UInt64 tmp1, tmp2, n_orig, zero_point_eight;
457
458 zero_point_eight.b[1] = zero_point_eight.b[2] =
459 zero_point_eight.b[3] = zero_point_eight.b[4] =
460 zero_point_eight.b[5] = zero_point_eight.b[6] =
461 zero_point_eight.b[7] = 0xCC;
462 zero_point_eight.b[0] = 0xCD;
463
464 n_orig = *n;
465
466 /* divide n by 10,
467 by multiplying by 0.8 and then shifting right 3 times */
468 uInt64_mul ( n, &zero_point_eight, &tmp1, &tmp2 );
469 uInt64_shr1(&tmp1); uInt64_shr1(&tmp1); uInt64_shr1(&tmp1);
470 *n = tmp1;
471
472 /* tmp1 = 8*n, tmp2 = 2*n */
473 uInt64_shl1(&tmp1); uInt64_shl1(&tmp1); uInt64_shl1(&tmp1);
474 tmp2 = *n; uInt64_shl1(&tmp2);
475
476 /* tmp1 = 10*n */
477 uInt64_add ( &tmp2, &tmp1 );
478
479 /* n_orig = n_orig - 10*n */
480 uInt64_sub ( &tmp1, &n_orig );
481
482 /* n_orig should now hold quotient, in range 0 .. 9 */
483 for (i = 7; i >= 1; i--)
484 if (n_orig.b[i] != 0) panic ( "uInt64_qrm10(1)" );
485 if (n_orig.b[0] > 9)
486 panic ( "uInt64_qrm10(2)" );
487
488 return (int)n_orig.b[0];
489}
490
491/* ... and the Whole Entire Point of all this UInt64 stuff is
492 so that we can supply the following function.
493*/
494static
495void uInt64_toAscii ( char* outbuf, UInt64* n )
496{
497 Int32 i, q;
498 UChar buf[32];
499 Int32 nBuf = 0;
500 UInt64 n_copy = *n;
501 do {
502 q = uInt64_qrm10 ( &n_copy );
503 buf[nBuf] = q + '0';
504 nBuf++;
505 } while (!uInt64_isZero(&n_copy));
506 outbuf[nBuf] = 0;
507 for (i = 0; i < nBuf; i++) outbuf[i] = buf[nBuf-i-1];
508}
509
510
511/*---------------------------------------------------*/
325/*--- Processing of complete files and streams ---*/ 512/*--- Processing of complete files and streams ---*/
326/*---------------------------------------------------*/ 513/*---------------------------------------------------*/
327 514
328/*---------------------------------------------*/ 515/*---------------------------------------------*/
516static
329Bool myfeof ( FILE* f ) 517Bool myfeof ( FILE* f )
330{ 518{
331 Int32 c = fgetc ( f ); 519 Int32 c = fgetc ( f );
@@ -336,12 +524,14 @@ Bool myfeof ( FILE* f )
336 524
337 525
338/*---------------------------------------------*/ 526/*---------------------------------------------*/
527static
339void compressStream ( FILE *stream, FILE *zStream ) 528void compressStream ( FILE *stream, FILE *zStream )
340{ 529{
341 BZFILE* bzf = NULL; 530 BZFILE* bzf = NULL;
342 UChar ibuf[5000]; 531 UChar ibuf[5000];
343 Int32 nIbuf; 532 Int32 nIbuf;
344 UInt32 nbytes_in, nbytes_out; 533 UInt32 nbytes_in_lo32, nbytes_in_hi32;
534 UInt32 nbytes_out_lo32, nbytes_out_hi32;
345 Int32 bzerr, bzerr_dummy, ret; 535 Int32 bzerr, bzerr_dummy, ret;
346 536
347 SET_BINARY_MODE(stream); 537 SET_BINARY_MODE(stream);
@@ -350,8 +540,8 @@ void compressStream ( FILE *stream, FILE *zStream )
350 if (ferror(stream)) goto errhandler_io; 540 if (ferror(stream)) goto errhandler_io;
351 if (ferror(zStream)) goto errhandler_io; 541 if (ferror(zStream)) goto errhandler_io;
352 542
353 bzf = bzWriteOpen ( &bzerr, zStream, 543 bzf = BZ2_bzWriteOpen ( &bzerr, zStream,
354 blockSize100k, verbosity, workFactor ); 544 blockSize100k, verbosity, workFactor );
355 if (bzerr != BZ_OK) goto errhandler; 545 if (bzerr != BZ_OK) goto errhandler;
356 546
357 if (verbosity >= 2) fprintf ( stderr, "\n" ); 547 if (verbosity >= 2) fprintf ( stderr, "\n" );
@@ -361,12 +551,14 @@ void compressStream ( FILE *stream, FILE *zStream )
361 if (myfeof(stream)) break; 551 if (myfeof(stream)) break;
362 nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream ); 552 nIbuf = fread ( ibuf, sizeof(UChar), 5000, stream );
363 if (ferror(stream)) goto errhandler_io; 553 if (ferror(stream)) goto errhandler_io;
364 if (nIbuf > 0) bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf ); 554 if (nIbuf > 0) BZ2_bzWrite ( &bzerr, bzf, (void*)ibuf, nIbuf );
365 if (bzerr != BZ_OK) goto errhandler; 555 if (bzerr != BZ_OK) goto errhandler;
366 556
367 } 557 }
368 558
369 bzWriteClose ( &bzerr, bzf, 0, &nbytes_in, &nbytes_out ); 559 BZ2_bzWriteClose64 ( &bzerr, bzf, 0,
560 &nbytes_in_lo32, &nbytes_in_hi32,
561 &nbytes_out_lo32, &nbytes_out_hi32 );
370 if (bzerr != BZ_OK) goto errhandler; 562 if (bzerr != BZ_OK) goto errhandler;
371 563
372 if (ferror(zStream)) goto errhandler_io; 564 if (ferror(zStream)) goto errhandler_io;
@@ -380,25 +572,42 @@ void compressStream ( FILE *stream, FILE *zStream )
380 ret = fclose ( stream ); 572 ret = fclose ( stream );
381 if (ret == EOF) goto errhandler_io; 573 if (ret == EOF) goto errhandler_io;
382 574
383 if (nbytes_in == 0) nbytes_in = 1; 575 if (nbytes_in_lo32 == 0 && nbytes_in_hi32 == 0)
576 nbytes_in_lo32 = 1;
384 577
385 if (verbosity >= 1) 578 if (verbosity >= 1) {
579 Char buf_nin[32], buf_nout[32];
580 UInt64 nbytes_in, nbytes_out;
581 double nbytes_in_d, nbytes_out_d;
582 uInt64_from_UInt32s ( &nbytes_in,
583 nbytes_in_lo32, nbytes_in_hi32 );
584 uInt64_from_UInt32s ( &nbytes_out,
585 nbytes_out_lo32, nbytes_out_hi32 );
586 nbytes_in_d = uInt64_to_double ( &nbytes_in );
587 nbytes_out_d = uInt64_to_double ( &nbytes_out );
588 uInt64_toAscii ( buf_nin, &nbytes_in );
589 uInt64_toAscii ( buf_nout, &nbytes_out );
386 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, " 590 fprintf ( stderr, "%6.3f:1, %6.3f bits/byte, "
387 "%5.2f%% saved, %d in, %d out.\n", 591 "%5.2f%% saved, %s in, %s out.\n",
388 (float)nbytes_in / (float)nbytes_out, 592 nbytes_in_d / nbytes_out_d,
389 (8.0 * (float)nbytes_out) / (float)nbytes_in, 593 (8.0 * nbytes_out_d) / nbytes_in_d,
390 100.0 * (1.0 - (float)nbytes_out / (float)nbytes_in), 594 100.0 * (1.0 - nbytes_out_d / nbytes_in_d),
391 nbytes_in, 595 buf_nin,
392 nbytes_out 596 buf_nout
393 ); 597 );
598 }
394 599
395 return; 600 return;
396 601
397 errhandler: 602 errhandler:
398 bzWriteClose ( &bzerr_dummy, bzf, 1, &nbytes_in, &nbytes_out ); 603 BZ2_bzWriteClose64 ( &bzerr_dummy, bzf, 1,
604 &nbytes_in_lo32, &nbytes_in_hi32,
605 &nbytes_out_lo32, &nbytes_out_hi32 );
399 switch (bzerr) { 606 switch (bzerr) {
607 case BZ_CONFIG_ERROR:
608 configError(); break;
400 case BZ_MEM_ERROR: 609 case BZ_MEM_ERROR:
401 outOfMemory (); 610 outOfMemory (); break;
402 case BZ_IO_ERROR: 611 case BZ_IO_ERROR:
403 errhandler_io: 612 errhandler_io:
404 ioError(); break; 613 ioError(); break;
@@ -413,6 +622,7 @@ void compressStream ( FILE *stream, FILE *zStream )
413 622
414 623
415/*---------------------------------------------*/ 624/*---------------------------------------------*/
625static
416Bool uncompressStream ( FILE *zStream, FILE *stream ) 626Bool uncompressStream ( FILE *zStream, FILE *stream )
417{ 627{
418 BZFILE* bzf = NULL; 628 BZFILE* bzf = NULL;
@@ -433,7 +643,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
433 643
434 while (True) { 644 while (True) {
435 645
436 bzf = bzReadOpen ( 646 bzf = BZ2_bzReadOpen (
437 &bzerr, zStream, verbosity, 647 &bzerr, zStream, verbosity,
438 (int)smallMode, unused, nUnused 648 (int)smallMode, unused, nUnused
439 ); 649 );
@@ -441,7 +651,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
441 streamNo++; 651 streamNo++;
442 652
443 while (bzerr == BZ_OK) { 653 while (bzerr == BZ_OK) {
444 nread = bzRead ( &bzerr, bzf, obuf, 5000 ); 654 nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
445 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler; 655 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
446 if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0) 656 if ((bzerr == BZ_OK || bzerr == BZ_STREAM_END) && nread > 0)
447 fwrite ( obuf, sizeof(UChar), nread, stream ); 657 fwrite ( obuf, sizeof(UChar), nread, stream );
@@ -449,12 +659,12 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
449 } 659 }
450 if (bzerr != BZ_STREAM_END) goto errhandler; 660 if (bzerr != BZ_STREAM_END) goto errhandler;
451 661
452 bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused ); 662 BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
453 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" ); 663 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
454 664
455 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i]; 665 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
456 666
457 bzReadClose ( &bzerr, bzf ); 667 BZ2_bzReadClose ( &bzerr, bzf );
458 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" ); 668 if (bzerr != BZ_OK) panic ( "decompress:bzReadGetUnused" );
459 669
460 if (nUnused == 0 && myfeof(zStream)) break; 670 if (nUnused == 0 && myfeof(zStream)) break;
@@ -476,8 +686,10 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
476 return True; 686 return True;
477 687
478 errhandler: 688 errhandler:
479 bzReadClose ( &bzerr_dummy, bzf ); 689 BZ2_bzReadClose ( &bzerr_dummy, bzf );
480 switch (bzerr) { 690 switch (bzerr) {
691 case BZ_CONFIG_ERROR:
692 configError(); break;
481 case BZ_IO_ERROR: 693 case BZ_IO_ERROR:
482 errhandler_io: 694 errhandler_io:
483 ioError(); break; 695 ioError(); break;
@@ -488,6 +700,8 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
488 case BZ_UNEXPECTED_EOF: 700 case BZ_UNEXPECTED_EOF:
489 compressedStreamEOF(); 701 compressedStreamEOF();
490 case BZ_DATA_ERROR_MAGIC: 702 case BZ_DATA_ERROR_MAGIC:
703 if (zStream != stdin) fclose(zStream);
704 if (stream != stdout) fclose(stream);
491 if (streamNo == 1) { 705 if (streamNo == 1) {
492 return False; 706 return False;
493 } else { 707 } else {
@@ -507,6 +721,7 @@ Bool uncompressStream ( FILE *zStream, FILE *stream )
507 721
508 722
509/*---------------------------------------------*/ 723/*---------------------------------------------*/
724static
510Bool testStream ( FILE *zStream ) 725Bool testStream ( FILE *zStream )
511{ 726{
512 BZFILE* bzf = NULL; 727 BZFILE* bzf = NULL;
@@ -524,7 +739,7 @@ Bool testStream ( FILE *zStream )
524 739
525 while (True) { 740 while (True) {
526 741
527 bzf = bzReadOpen ( 742 bzf = BZ2_bzReadOpen (
528 &bzerr, zStream, verbosity, 743 &bzerr, zStream, verbosity,
529 (int)smallMode, unused, nUnused 744 (int)smallMode, unused, nUnused
530 ); 745 );
@@ -532,17 +747,17 @@ Bool testStream ( FILE *zStream )
532 streamNo++; 747 streamNo++;
533 748
534 while (bzerr == BZ_OK) { 749 while (bzerr == BZ_OK) {
535 nread = bzRead ( &bzerr, bzf, obuf, 5000 ); 750 nread = BZ2_bzRead ( &bzerr, bzf, obuf, 5000 );
536 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler; 751 if (bzerr == BZ_DATA_ERROR_MAGIC) goto errhandler;
537 } 752 }
538 if (bzerr != BZ_STREAM_END) goto errhandler; 753 if (bzerr != BZ_STREAM_END) goto errhandler;
539 754
540 bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused ); 755 BZ2_bzReadGetUnused ( &bzerr, bzf, (void**)(&unusedTmp), &nUnused );
541 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" ); 756 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
542 757
543 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i]; 758 for (i = 0; i < nUnused; i++) unused[i] = unusedTmp[i];
544 759
545 bzReadClose ( &bzerr, bzf ); 760 BZ2_bzReadClose ( &bzerr, bzf );
546 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" ); 761 if (bzerr != BZ_OK) panic ( "test:bzReadGetUnused" );
547 if (nUnused == 0 && myfeof(zStream)) break; 762 if (nUnused == 0 && myfeof(zStream)) break;
548 763
@@ -556,10 +771,12 @@ Bool testStream ( FILE *zStream )
556 return True; 771 return True;
557 772
558 errhandler: 773 errhandler:
559 bzReadClose ( &bzerr_dummy, bzf ); 774 BZ2_bzReadClose ( &bzerr_dummy, bzf );
560 if (verbosity == 0) 775 if (verbosity == 0)
561 fprintf ( stderr, "%s: %s: ", progName, inName ); 776 fprintf ( stderr, "%s: %s: ", progName, inName );
562 switch (bzerr) { 777 switch (bzerr) {
778 case BZ_CONFIG_ERROR:
779 configError(); break;
563 case BZ_IO_ERROR: 780 case BZ_IO_ERROR:
564 errhandler_io: 781 errhandler_io:
565 ioError(); break; 782 ioError(); break;
@@ -574,6 +791,7 @@ Bool testStream ( FILE *zStream )
574 "file ends unexpectedly\n" ); 791 "file ends unexpectedly\n" );
575 return False; 792 return False;
576 case BZ_DATA_ERROR_MAGIC: 793 case BZ_DATA_ERROR_MAGIC:
794 if (zStream != stdin) fclose(zStream);
577 if (streamNo == 1) { 795 if (streamNo == 1) {
578 fprintf ( stderr, 796 fprintf ( stderr,
579 "bad magic number (file not created by bzip2)\n" ); 797 "bad magic number (file not created by bzip2)\n" );
@@ -598,6 +816,15 @@ Bool testStream ( FILE *zStream )
598/*---------------------------------------------------*/ 816/*---------------------------------------------------*/
599 817
600/*---------------------------------------------*/ 818/*---------------------------------------------*/
819static
820void setExit ( Int32 v )
821{
822 if (v > exitValue) exitValue = v;
823}
824
825
826/*---------------------------------------------*/
827static
601void cadvise ( void ) 828void cadvise ( void )
602{ 829{
603 if (noisy) 830 if (noisy)
@@ -612,6 +839,7 @@ void cadvise ( void )
612 839
613 840
614/*---------------------------------------------*/ 841/*---------------------------------------------*/
842static
615void showFileNames ( void ) 843void showFileNames ( void )
616{ 844{
617 if (noisy) 845 if (noisy)
@@ -624,11 +852,14 @@ void showFileNames ( void )
624 852
625 853
626/*---------------------------------------------*/ 854/*---------------------------------------------*/
855static
627void cleanUpAndFail ( Int32 ec ) 856void cleanUpAndFail ( Int32 ec )
628{ 857{
629 IntNative retVal; 858 IntNative retVal;
630 859
631 if ( srcMode == SM_F2F && opMode != OM_TEST ) { 860 if ( srcMode == SM_F2F
861 && opMode != OM_TEST
862 && deleteOutputOnInterrupt ) {
632 if (noisy) 863 if (noisy)
633 fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n", 864 fprintf ( stderr, "%s: Deleting output file %s, if it exists.\n",
634 progName, outName ); 865 progName, outName );
@@ -647,11 +878,13 @@ void cleanUpAndFail ( Int32 ec )
647 progName, numFileNames, 878 progName, numFileNames,
648 numFileNames - numFilesProcessed ); 879 numFileNames - numFilesProcessed );
649 } 880 }
650 exit ( ec ); 881 setExit(ec);
882 exit(exitValue);
651} 883}
652 884
653 885
654/*---------------------------------------------*/ 886/*---------------------------------------------*/
887static
655void panic ( Char* s ) 888void panic ( Char* s )
656{ 889{
657 fprintf ( stderr, 890 fprintf ( stderr,
@@ -666,6 +899,7 @@ void panic ( Char* s )
666 899
667 900
668/*---------------------------------------------*/ 901/*---------------------------------------------*/
902static
669void crcError ( void ) 903void crcError ( void )
670{ 904{
671 fprintf ( stderr, 905 fprintf ( stderr,
@@ -678,6 +912,7 @@ void crcError ( void )
678 912
679 913
680/*---------------------------------------------*/ 914/*---------------------------------------------*/
915static
681void compressedStreamEOF ( void ) 916void compressedStreamEOF ( void )
682{ 917{
683 fprintf ( stderr, 918 fprintf ( stderr,
@@ -692,10 +927,12 @@ void compressedStreamEOF ( void )
692 927
693 928
694/*---------------------------------------------*/ 929/*---------------------------------------------*/
930static
695void ioError ( void ) 931void ioError ( void )
696{ 932{
697 fprintf ( stderr, 933 fprintf ( stderr,
698 "\n%s: I/O or other error, bailing out. Possible reason follows.\n", 934 "\n%s: I/O or other error, bailing out. "
935 "Possible reason follows.\n",
699 progName ); 936 progName );
700 perror ( progName ); 937 perror ( progName );
701 showFileNames(); 938 showFileNames();
@@ -704,6 +941,7 @@ void ioError ( void )
704 941
705 942
706/*---------------------------------------------*/ 943/*---------------------------------------------*/
944static
707void mySignalCatcher ( IntNative n ) 945void mySignalCatcher ( IntNative n )
708{ 946{
709 fprintf ( stderr, 947 fprintf ( stderr,
@@ -714,20 +952,53 @@ void mySignalCatcher ( IntNative n )
714 952
715 953
716/*---------------------------------------------*/ 954/*---------------------------------------------*/
955static
717void mySIGSEGVorSIGBUScatcher ( IntNative n ) 956void mySIGSEGVorSIGBUScatcher ( IntNative n )
718{ 957{
719 if (opMode == OM_Z) 958 if (opMode == OM_Z)
720 fprintf ( stderr, 959 fprintf (
721 "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing,\n" 960 stderr,
722 "\twhich probably indicates a bug in bzip2. Please\n" 961 "\n%s: Caught a SIGSEGV or SIGBUS whilst compressing.\n"
723 "\treport it to me at: jseward@acm.org\n", 962 "\n"
724 progName ); 963 " Possible causes are (most likely first):\n"
964 " (1) This computer has unreliable memory or cache hardware\n"
965 " (a surprisingly common problem; try a different machine.)\n"
966 " (2) A bug in the compiler used to create this executable\n"
967 " (unlikely, if you didn't compile bzip2 yourself.)\n"
968 " (3) A real bug in bzip2 -- I hope this should never be the case.\n"
969 " The user's manual, Section 4.3, has more info on (1) and (2).\n"
970 " \n"
971 " If you suspect this is a bug in bzip2, or are unsure about (1)\n"
972 " or (2), feel free to report it to me at: jseward@acm.org.\n"
973 " Section 4.3 of the user's manual describes the info a useful\n"
974 " bug report should have. If the manual is available on your\n"
975 " system, please try and read it before mailing me. If you don't\n"
976 " have the manual or can't be bothered to read it, mail me anyway.\n"
977 "\n",
978 progName );
725 else 979 else
726 fprintf ( stderr, 980 fprintf (
727 "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing,\n" 981 stderr,
728 "\twhich probably indicates that the compressed data\n" 982 "\n%s: Caught a SIGSEGV or SIGBUS whilst decompressing.\n"
729 "\tis corrupted.\n", 983 "\n"
730 progName ); 984 " Possible causes are (most likely first):\n"
985 " (1) The compressed data is corrupted, and bzip2's usual checks\n"
986 " failed to detect this. Try bzip2 -tvv my_file.bz2.\n"
987 " (2) This computer has unreliable memory or cache hardware\n"
988 " (a surprisingly common problem; try a different machine.)\n"
989 " (3) A bug in the compiler used to create this executable\n"
990 " (unlikely, if you didn't compile bzip2 yourself.)\n"
991 " (4) A real bug in bzip2 -- I hope this should never be the case.\n"
992 " The user's manual, Section 4.3, has more info on (2) and (3).\n"
993 " \n"
994 " If you suspect this is a bug in bzip2, or are unsure about (2)\n"
995 " or (3), feel free to report it to me at: jseward@acm.org.\n"
996 " Section 4.3 of the user's manual describes the info a useful\n"
997 " bug report should have. If the manual is available on your\n"
998 " system, please try and read it before mailing me. If you don't\n"
999 " have the manual or can't be bothered to read it, mail me anyway.\n"
1000 "\n",
1001 progName );
731 1002
732 showFileNames(); 1003 showFileNames();
733 if (opMode == OM_Z) 1004 if (opMode == OM_Z)
@@ -737,6 +1008,7 @@ void mySIGSEGVorSIGBUScatcher ( IntNative n )
737 1008
738 1009
739/*---------------------------------------------*/ 1010/*---------------------------------------------*/
1011static
740void outOfMemory ( void ) 1012void outOfMemory ( void )
741{ 1013{
742 fprintf ( stderr, 1014 fprintf ( stderr,
@@ -747,11 +1019,27 @@ void outOfMemory ( void )
747} 1019}
748 1020
749 1021
1022/*---------------------------------------------*/
1023static
1024void configError ( void )
1025{
1026 fprintf ( stderr,
1027 "bzip2: I'm not configured correctly for this platform!\n"
1028 "\tI require Int32, Int16 and Char to have sizes\n"
1029 "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
1030 "\tProbably you can fix this by defining them correctly,\n"
1031 "\tand recompiling. Bye!\n" );
1032 setExit(3);
1033 exit(exitValue);
1034}
1035
1036
750/*---------------------------------------------------*/ 1037/*---------------------------------------------------*/
751/*--- The main driver machinery ---*/ 1038/*--- The main driver machinery ---*/
752/*---------------------------------------------------*/ 1039/*---------------------------------------------------*/
753 1040
754/*---------------------------------------------*/ 1041/*---------------------------------------------*/
1042static
755void pad ( Char *s ) 1043void pad ( Char *s )
756{ 1044{
757 Int32 i; 1045 Int32 i;
@@ -762,6 +1050,7 @@ void pad ( Char *s )
762 1050
763 1051
764/*---------------------------------------------*/ 1052/*---------------------------------------------*/
1053static
765void copyFileName ( Char* to, Char* from ) 1054void copyFileName ( Char* to, Char* from )
766{ 1055{
767 if ( strlen(from) > FILE_NAME_LEN-10 ) { 1056 if ( strlen(from) > FILE_NAME_LEN-10 ) {
@@ -772,7 +1061,8 @@ void copyFileName ( Char* to, Char* from )
772 "Try using a reasonable file name instead. Sorry! :-)\n", 1061 "Try using a reasonable file name instead. Sorry! :-)\n",
773 from, FILE_NAME_LEN-10 1062 from, FILE_NAME_LEN-10
774 ); 1063 );
775 exit(1); 1064 setExit(1);
1065 exit(exitValue);
776 } 1066 }
777 1067
778 strncpy(to,from,FILE_NAME_LEN-10); 1068 strncpy(to,from,FILE_NAME_LEN-10);
@@ -781,6 +1071,7 @@ void copyFileName ( Char* to, Char* from )
781 1071
782 1072
783/*---------------------------------------------*/ 1073/*---------------------------------------------*/
1074static
784Bool fileExists ( Char* name ) 1075Bool fileExists ( Char* name )
785{ 1076{
786 FILE *tmp = fopen ( name, "rb" ); 1077 FILE *tmp = fopen ( name, "rb" );
@@ -794,6 +1085,7 @@ Bool fileExists ( Char* name )
794/*-- 1085/*--
795 if in doubt, return True 1086 if in doubt, return True
796--*/ 1087--*/
1088static
797Bool notAStandardFile ( Char* name ) 1089Bool notAStandardFile ( Char* name )
798{ 1090{
799 IntNative i; 1091 IntNative i;
@@ -810,6 +1102,7 @@ Bool notAStandardFile ( Char* name )
810/*-- 1102/*--
811 rac 11/21/98 see if file has hard links to it 1103 rac 11/21/98 see if file has hard links to it
812--*/ 1104--*/
1105static
813Int32 countHardLinks ( Char* name ) 1106Int32 countHardLinks ( Char* name )
814{ 1107{
815 IntNative i; 1108 IntNative i;
@@ -822,6 +1115,7 @@ Int32 countHardLinks ( Char* name )
822 1115
823 1116
824/*---------------------------------------------*/ 1117/*---------------------------------------------*/
1118static
825void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName ) 1119void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
826{ 1120{
827#if BZ_UNIX 1121#if BZ_UNIX
@@ -849,6 +1143,7 @@ void copyDatePermissionsAndOwner ( Char *srcName, Char *dstName )
849 1143
850 1144
851/*---------------------------------------------*/ 1145/*---------------------------------------------*/
1146static
852void setInterimPermissions ( Char *dstName ) 1147void setInterimPermissions ( Char *dstName )
853{ 1148{
854#if BZ_UNIX 1149#if BZ_UNIX
@@ -860,6 +1155,7 @@ void setInterimPermissions ( Char *dstName )
860 1155
861 1156
862/*---------------------------------------------*/ 1157/*---------------------------------------------*/
1158static
863Bool containsDubiousChars ( Char* name ) 1159Bool containsDubiousChars ( Char* name )
864{ 1160{
865 Bool cdc = False; 1161 Bool cdc = False;
@@ -877,6 +1173,7 @@ Char* zSuffix[BZ_N_SUFFIX_PAIRS]
877Char* unzSuffix[BZ_N_SUFFIX_PAIRS] 1173Char* unzSuffix[BZ_N_SUFFIX_PAIRS]
878 = { "", "", ".tar", ".tar" }; 1174 = { "", "", ".tar", ".tar" };
879 1175
1176static
880Bool hasSuffix ( Char* s, Char* suffix ) 1177Bool hasSuffix ( Char* s, Char* suffix )
881{ 1178{
882 Int32 ns = strlen(s); 1179 Int32 ns = strlen(s);
@@ -886,6 +1183,7 @@ Bool hasSuffix ( Char* s, Char* suffix )
886 return False; 1183 return False;
887} 1184}
888 1185
1186static
889Bool mapSuffix ( Char* name, 1187Bool mapSuffix ( Char* name,
890 Char* oldSuffix, Char* newSuffix ) 1188 Char* oldSuffix, Char* newSuffix )
891{ 1189{
@@ -897,11 +1195,15 @@ Bool mapSuffix ( Char* name,
897 1195
898 1196
899/*---------------------------------------------*/ 1197/*---------------------------------------------*/
1198static
900void compress ( Char *name ) 1199void compress ( Char *name )
901{ 1200{
902 FILE *inStr; 1201 FILE *inStr;
903 FILE *outStr; 1202 FILE *outStr;
904 Int32 n, i; 1203 Int32 n, i;
1204
1205 deleteOutputOnInterrupt = False;
1206
905 if (name == NULL && srcMode != SM_I2O) 1207 if (name == NULL && srcMode != SM_I2O)
906 panic ( "compress: bad modes\n" ); 1208 panic ( "compress: bad modes\n" );
907 1209
@@ -924,12 +1226,14 @@ void compress ( Char *name )
924 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) { 1226 if ( srcMode != SM_I2O && containsDubiousChars ( inName ) ) {
925 if (noisy) 1227 if (noisy)
926 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1228 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
927 progName, inName ); 1229 progName, inName );
1230 setExit(1);
928 return; 1231 return;
929 } 1232 }
930 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1233 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
931 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1234 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
932 progName, inName, strerror(errno) ); 1235 progName, inName, strerror(errno) );
1236 setExit(1);
933 return; 1237 return;
934 } 1238 }
935 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) { 1239 for (i = 0; i < BZ_N_SUFFIX_PAIRS; i++) {
@@ -938,6 +1242,7 @@ void compress ( Char *name )
938 fprintf ( stderr, 1242 fprintf ( stderr,
939 "%s: Input file %s already has %s suffix.\n", 1243 "%s: Input file %s already has %s suffix.\n",
940 progName, inName, zSuffix[i] ); 1244 progName, inName, zSuffix[i] );
1245 setExit(1);
941 return; 1246 return;
942 } 1247 }
943 } 1248 }
@@ -945,17 +1250,20 @@ void compress ( Char *name )
945 if (noisy) 1250 if (noisy)
946 fprintf ( stderr, "%s: Input file %s is not a normal file.\n", 1251 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
947 progName, inName ); 1252 progName, inName );
1253 setExit(1);
948 return; 1254 return;
949 } 1255 }
950 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) { 1256 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
951 fprintf ( stderr, "%s: Output file %s already exists.\n", 1257 fprintf ( stderr, "%s: Output file %s already exists.\n",
952 progName, outName ); 1258 progName, outName );
1259 setExit(1);
953 return; 1260 return;
954 } 1261 }
955 if ( srcMode == SM_F2F && !forceOverwrite && 1262 if ( srcMode == SM_F2F && !forceOverwrite &&
956 (n=countHardLinks ( inName )) > 0) { 1263 (n=countHardLinks ( inName )) > 0) {
957 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n", 1264 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
958 progName, inName, n, n > 1 ? "s" : "" ); 1265 progName, inName, n, n > 1 ? "s" : "" );
1266 setExit(1);
959 return; 1267 return;
960 } 1268 }
961 1269
@@ -970,6 +1278,7 @@ void compress ( Char *name )
970 progName ); 1278 progName );
971 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1279 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
972 progName, progName ); 1280 progName, progName );
1281 setExit(1);
973 return; 1282 return;
974 }; 1283 };
975 break; 1284 break;
@@ -984,11 +1293,13 @@ void compress ( Char *name )
984 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1293 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
985 progName, progName ); 1294 progName, progName );
986 if ( inStr != NULL ) fclose ( inStr ); 1295 if ( inStr != NULL ) fclose ( inStr );
1296 setExit(1);
987 return; 1297 return;
988 }; 1298 };
989 if ( inStr == NULL ) { 1299 if ( inStr == NULL ) {
990 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1300 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
991 progName, inName, strerror(errno) ); 1301 progName, inName, strerror(errno) );
1302 setExit(1);
992 return; 1303 return;
993 }; 1304 };
994 break; 1305 break;
@@ -1000,12 +1311,14 @@ void compress ( Char *name )
1000 fprintf ( stderr, "%s: Can't create output file %s: %s.\n", 1311 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
1001 progName, outName, strerror(errno) ); 1312 progName, outName, strerror(errno) );
1002 if ( inStr != NULL ) fclose ( inStr ); 1313 if ( inStr != NULL ) fclose ( inStr );
1314 setExit(1);
1003 return; 1315 return;
1004 } 1316 }
1005 if ( inStr == NULL ) { 1317 if ( inStr == NULL ) {
1006 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1318 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1007 progName, inName, strerror(errno) ); 1319 progName, inName, strerror(errno) );
1008 if ( outStr != NULL ) fclose ( outStr ); 1320 if ( outStr != NULL ) fclose ( outStr );
1321 setExit(1);
1009 return; 1322 return;
1010 }; 1323 };
1011 setInterimPermissions ( outName ); 1324 setInterimPermissions ( outName );
@@ -1024,21 +1337,26 @@ void compress ( Char *name )
1024 1337
1025 /*--- Now the input and output handles are sane. Do the Biz. ---*/ 1338 /*--- Now the input and output handles are sane. Do the Biz. ---*/
1026 outputHandleJustInCase = outStr; 1339 outputHandleJustInCase = outStr;
1340 deleteOutputOnInterrupt = True;
1027 compressStream ( inStr, outStr ); 1341 compressStream ( inStr, outStr );
1028 outputHandleJustInCase = NULL; 1342 outputHandleJustInCase = NULL;
1029 1343
1030 /*--- If there was an I/O error, we won't get here. ---*/ 1344 /*--- If there was an I/O error, we won't get here. ---*/
1031 if ( srcMode == SM_F2F ) { 1345 if ( srcMode == SM_F2F ) {
1032 copyDatePermissionsAndOwner ( inName, outName ); 1346 copyDatePermissionsAndOwner ( inName, outName );
1347 deleteOutputOnInterrupt = False;
1033 if ( !keepInputFiles ) { 1348 if ( !keepInputFiles ) {
1034 IntNative retVal = remove ( inName ); 1349 IntNative retVal = remove ( inName );
1035 ERROR_IF_NOT_ZERO ( retVal ); 1350 ERROR_IF_NOT_ZERO ( retVal );
1036 } 1351 }
1037 } 1352 }
1353
1354 deleteOutputOnInterrupt = False;
1038} 1355}
1039 1356
1040 1357
1041/*---------------------------------------------*/ 1358/*---------------------------------------------*/
1359static
1042void uncompress ( Char *name ) 1360void uncompress ( Char *name )
1043{ 1361{
1044 FILE *inStr; 1362 FILE *inStr;
@@ -1047,6 +1365,8 @@ void uncompress ( Char *name )
1047 Bool magicNumberOK; 1365 Bool magicNumberOK;
1048 Bool cantGuess; 1366 Bool cantGuess;
1049 1367
1368 deleteOutputOnInterrupt = False;
1369
1050 if (name == NULL && srcMode != SM_I2O) 1370 if (name == NULL && srcMode != SM_I2O)
1051 panic ( "uncompress: bad modes\n" ); 1371 panic ( "uncompress: bad modes\n" );
1052 1372
@@ -1076,17 +1396,20 @@ void uncompress ( Char *name )
1076 if (noisy) 1396 if (noisy)
1077 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1397 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1078 progName, inName ); 1398 progName, inName );
1399 setExit(1);
1079 return; 1400 return;
1080 } 1401 }
1081 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1402 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1082 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1403 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1083 progName, inName, strerror(errno) ); 1404 progName, inName, strerror(errno) );
1405 setExit(1);
1084 return; 1406 return;
1085 } 1407 }
1086 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) { 1408 if ( srcMode == SM_F2F && !forceOverwrite && notAStandardFile ( inName )) {
1087 if (noisy) 1409 if (noisy)
1088 fprintf ( stderr, "%s: Input file %s is not a normal file.\n", 1410 fprintf ( stderr, "%s: Input file %s is not a normal file.\n",
1089 progName, inName ); 1411 progName, inName );
1412 setExit(1);
1090 return; 1413 return;
1091 } 1414 }
1092 if ( /* srcMode == SM_F2F implied && */ cantGuess ) { 1415 if ( /* srcMode == SM_F2F implied && */ cantGuess ) {
@@ -1099,12 +1422,14 @@ void uncompress ( Char *name )
1099 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) { 1422 if ( srcMode == SM_F2F && !forceOverwrite && fileExists ( outName ) ) {
1100 fprintf ( stderr, "%s: Output file %s already exists.\n", 1423 fprintf ( stderr, "%s: Output file %s already exists.\n",
1101 progName, outName ); 1424 progName, outName );
1425 setExit(1);
1102 return; 1426 return;
1103 } 1427 }
1104 if ( srcMode == SM_F2F && !forceOverwrite && 1428 if ( srcMode == SM_F2F && !forceOverwrite &&
1105 (n=countHardLinks ( inName ) ) > 0) { 1429 (n=countHardLinks ( inName ) ) > 0) {
1106 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n", 1430 fprintf ( stderr, "%s: Input file %s has %d other link%s.\n",
1107 progName, inName, n, n > 1 ? "s" : "" ); 1431 progName, inName, n, n > 1 ? "s" : "" );
1432 setExit(1);
1108 return; 1433 return;
1109 } 1434 }
1110 1435
@@ -1119,6 +1444,7 @@ void uncompress ( Char *name )
1119 progName ); 1444 progName );
1120 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1445 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1121 progName, progName ); 1446 progName, progName );
1447 setExit(1);
1122 return; 1448 return;
1123 }; 1449 };
1124 break; 1450 break;
@@ -1130,6 +1456,7 @@ void uncompress ( Char *name )
1130 fprintf ( stderr, "%s: Can't open input file %s:%s.\n", 1456 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1131 progName, inName, strerror(errno) ); 1457 progName, inName, strerror(errno) );
1132 if ( inStr != NULL ) fclose ( inStr ); 1458 if ( inStr != NULL ) fclose ( inStr );
1459 setExit(1);
1133 return; 1460 return;
1134 }; 1461 };
1135 break; 1462 break;
@@ -1141,12 +1468,14 @@ void uncompress ( Char *name )
1141 fprintf ( stderr, "%s: Can't create output file %s: %s.\n", 1468 fprintf ( stderr, "%s: Can't create output file %s: %s.\n",
1142 progName, outName, strerror(errno) ); 1469 progName, outName, strerror(errno) );
1143 if ( inStr != NULL ) fclose ( inStr ); 1470 if ( inStr != NULL ) fclose ( inStr );
1471 setExit(1);
1144 return; 1472 return;
1145 } 1473 }
1146 if ( inStr == NULL ) { 1474 if ( inStr == NULL ) {
1147 fprintf ( stderr, "%s: Can't open input file %s: %s.\n", 1475 fprintf ( stderr, "%s: Can't open input file %s: %s.\n",
1148 progName, inName, strerror(errno) ); 1476 progName, inName, strerror(errno) );
1149 if ( outStr != NULL ) fclose ( outStr ); 1477 if ( outStr != NULL ) fclose ( outStr );
1478 setExit(1);
1150 return; 1479 return;
1151 }; 1480 };
1152 setInterimPermissions ( outName ); 1481 setInterimPermissions ( outName );
@@ -1165,6 +1494,7 @@ void uncompress ( Char *name )
1165 1494
1166 /*--- Now the input and output handles are sane. Do the Biz. ---*/ 1495 /*--- Now the input and output handles are sane. Do the Biz. ---*/
1167 outputHandleJustInCase = outStr; 1496 outputHandleJustInCase = outStr;
1497 deleteOutputOnInterrupt = True;
1168 magicNumberOK = uncompressStream ( inStr, outStr ); 1498 magicNumberOK = uncompressStream ( inStr, outStr );
1169 outputHandleJustInCase = NULL; 1499 outputHandleJustInCase = NULL;
1170 1500
@@ -1172,22 +1502,27 @@ void uncompress ( Char *name )
1172 if ( magicNumberOK ) { 1502 if ( magicNumberOK ) {
1173 if ( srcMode == SM_F2F ) { 1503 if ( srcMode == SM_F2F ) {
1174 copyDatePermissionsAndOwner ( inName, outName ); 1504 copyDatePermissionsAndOwner ( inName, outName );
1505 deleteOutputOnInterrupt = False;
1175 if ( !keepInputFiles ) { 1506 if ( !keepInputFiles ) {
1176 IntNative retVal = remove ( inName ); 1507 IntNative retVal = remove ( inName );
1177 ERROR_IF_NOT_ZERO ( retVal ); 1508 ERROR_IF_NOT_ZERO ( retVal );
1178 } 1509 }
1179 } 1510 }
1180 } else { 1511 } else {
1512 unzFailsExist = True;
1513 deleteOutputOnInterrupt = False;
1181 if ( srcMode == SM_F2F ) { 1514 if ( srcMode == SM_F2F ) {
1182 IntNative retVal = remove ( outName ); 1515 IntNative retVal = remove ( outName );
1183 ERROR_IF_NOT_ZERO ( retVal ); 1516 ERROR_IF_NOT_ZERO ( retVal );
1184 } 1517 }
1185 } 1518 }
1519 deleteOutputOnInterrupt = False;
1186 1520
1187 if ( magicNumberOK ) { 1521 if ( magicNumberOK ) {
1188 if (verbosity >= 1) 1522 if (verbosity >= 1)
1189 fprintf ( stderr, "done\n" ); 1523 fprintf ( stderr, "done\n" );
1190 } else { 1524 } else {
1525 setExit(2);
1191 if (verbosity >= 1) 1526 if (verbosity >= 1)
1192 fprintf ( stderr, "not a bzip2 file.\n" ); else 1527 fprintf ( stderr, "not a bzip2 file.\n" ); else
1193 fprintf ( stderr, 1528 fprintf ( stderr,
@@ -1199,11 +1534,14 @@ void uncompress ( Char *name )
1199 1534
1200 1535
1201/*---------------------------------------------*/ 1536/*---------------------------------------------*/
1537static
1202void testf ( Char *name ) 1538void testf ( Char *name )
1203{ 1539{
1204 FILE *inStr; 1540 FILE *inStr;
1205 Bool allOK; 1541 Bool allOK;
1206 1542
1543 deleteOutputOnInterrupt = False;
1544
1207 if (name == NULL && srcMode != SM_I2O) 1545 if (name == NULL && srcMode != SM_I2O)
1208 panic ( "testf: bad modes\n" ); 1546 panic ( "testf: bad modes\n" );
1209 1547
@@ -1218,11 +1556,13 @@ void testf ( Char *name )
1218 if (noisy) 1556 if (noisy)
1219 fprintf ( stderr, "%s: There are no files matching `%s'.\n", 1557 fprintf ( stderr, "%s: There are no files matching `%s'.\n",
1220 progName, inName ); 1558 progName, inName );
1559 setExit(1);
1221 return; 1560 return;
1222 } 1561 }
1223 if ( srcMode != SM_I2O && !fileExists ( inName ) ) { 1562 if ( srcMode != SM_I2O && !fileExists ( inName ) ) {
1224 fprintf ( stderr, "%s: Can't open input %s: %s.\n", 1563 fprintf ( stderr, "%s: Can't open input %s: %s.\n",
1225 progName, inName, strerror(errno) ); 1564 progName, inName, strerror(errno) );
1565 setExit(1);
1226 return; 1566 return;
1227 } 1567 }
1228 1568
@@ -1235,6 +1575,7 @@ void testf ( Char *name )
1235 progName ); 1575 progName );
1236 fprintf ( stderr, "%s: For help, type: `%s --help'.\n", 1576 fprintf ( stderr, "%s: For help, type: `%s --help'.\n",
1237 progName, progName ); 1577 progName, progName );
1578 setExit(1);
1238 return; 1579 return;
1239 }; 1580 };
1240 inStr = stdin; 1581 inStr = stdin;
@@ -1245,6 +1586,7 @@ void testf ( Char *name )
1245 if ( inStr == NULL ) { 1586 if ( inStr == NULL ) {
1246 fprintf ( stderr, "%s: Can't open input file %s:%s.\n", 1587 fprintf ( stderr, "%s: Can't open input file %s:%s.\n",
1247 progName, inName, strerror(errno) ); 1588 progName, inName, strerror(errno) );
1589 setExit(1);
1248 return; 1590 return;
1249 }; 1591 };
1250 break; 1592 break;
@@ -1269,35 +1611,38 @@ void testf ( Char *name )
1269 1611
1270 1612
1271/*---------------------------------------------*/ 1613/*---------------------------------------------*/
1614static
1272void license ( void ) 1615void license ( void )
1273{ 1616{
1274 fprintf ( stderr, 1617 fprintf ( stderr,
1275 1618
1276 "bzip2, a block-sorting file compressor. " 1619 "bzip2, a block-sorting file compressor. "
1277 "Version 0.9.5d, 4-Sept-99.\n" 1620 "Version %s.\n"
1278 " \n" 1621 " \n"
1279 " Copyright (C) 1996, 1997, 1998, 1999 by Julian Seward.\n" 1622 " Copyright (C) 1996-2000 by Julian Seward.\n"
1280 " \n" 1623 " \n"
1281 " This program is free software; you can redistribute it and/or modify\n" 1624 " This program is free software; you can redistribute it and/or modify\n"
1282 " it under the terms set out in the LICENSE file, which is included\n" 1625 " it under the terms set out in the LICENSE file, which is included\n"
1283 " in the bzip2-0.9.5 source distribution.\n" 1626 " in the bzip2-1.0 source distribution.\n"
1284 " \n" 1627 " \n"
1285 " This program is distributed in the hope that it will be useful,\n" 1628 " This program is distributed in the hope that it will be useful,\n"
1286 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 1629 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1287 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 1630 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1288 " LICENSE file for more details.\n" 1631 " LICENSE file for more details.\n"
1289 " \n" 1632 " \n",
1633 BZ2_bzlibVersion()
1290 ); 1634 );
1291} 1635}
1292 1636
1293 1637
1294/*---------------------------------------------*/ 1638/*---------------------------------------------*/
1639static
1295void usage ( Char *fullProgName ) 1640void usage ( Char *fullProgName )
1296{ 1641{
1297 fprintf ( 1642 fprintf (
1298 stderr, 1643 stderr,
1299 "bzip2, a block-sorting file compressor. " 1644 "bzip2, a block-sorting file compressor. "
1300 "Version 0.9.5d, 4-Sept-99.\n" 1645 "Version %s.\n"
1301 "\n usage: %s [flags and input files in any order]\n" 1646 "\n usage: %s [flags and input files in any order]\n"
1302 "\n" 1647 "\n"
1303 " -h --help print this message\n" 1648 " -h --help print this message\n"
@@ -1326,12 +1671,14 @@ void usage ( Char *fullProgName )
1326#endif 1671#endif
1327 , 1672 ,
1328 1673
1674 BZ2_bzlibVersion(),
1329 fullProgName 1675 fullProgName
1330 ); 1676 );
1331} 1677}
1332 1678
1333 1679
1334/*---------------------------------------------*/ 1680/*---------------------------------------------*/
1681static
1335void redundant ( Char* flag ) 1682void redundant ( Char* flag )
1336{ 1683{
1337 fprintf ( 1684 fprintf (
@@ -1365,6 +1712,7 @@ typedef
1365 1712
1366 1713
1367/*---------------------------------------------*/ 1714/*---------------------------------------------*/
1715static
1368void *myMalloc ( Int32 n ) 1716void *myMalloc ( Int32 n )
1369{ 1717{
1370 void* p; 1718 void* p;
@@ -1376,6 +1724,7 @@ void *myMalloc ( Int32 n )
1376 1724
1377 1725
1378/*---------------------------------------------*/ 1726/*---------------------------------------------*/
1727static
1379Cell *mkCell ( void ) 1728Cell *mkCell ( void )
1380{ 1729{
1381 Cell *c; 1730 Cell *c;
@@ -1388,6 +1737,7 @@ Cell *mkCell ( void )
1388 1737
1389 1738
1390/*---------------------------------------------*/ 1739/*---------------------------------------------*/
1740static
1391Cell *snocString ( Cell *root, Char *name ) 1741Cell *snocString ( Cell *root, Char *name )
1392{ 1742{
1393 if (root == NULL) { 1743 if (root == NULL) {
@@ -1405,6 +1755,7 @@ Cell *snocString ( Cell *root, Char *name )
1405 1755
1406 1756
1407/*---------------------------------------------*/ 1757/*---------------------------------------------*/
1758static
1408void addFlagsFromEnvVar ( Cell** argList, Char* varName ) 1759void addFlagsFromEnvVar ( Cell** argList, Char* varName )
1409{ 1760{
1410 Int32 i, j, k; 1761 Int32 i, j, k;
@@ -1445,16 +1796,8 @@ IntNative main ( IntNative argc, Char *argv[] )
1445 /*-- Be really really really paranoid :-) --*/ 1796 /*-- Be really really really paranoid :-) --*/
1446 if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 || 1797 if (sizeof(Int32) != 4 || sizeof(UInt32) != 4 ||
1447 sizeof(Int16) != 2 || sizeof(UInt16) != 2 || 1798 sizeof(Int16) != 2 || sizeof(UInt16) != 2 ||
1448 sizeof(Char) != 1 || sizeof(UChar) != 1) { 1799 sizeof(Char) != 1 || sizeof(UChar) != 1)
1449 fprintf ( stderr, 1800 configError();
1450 "bzip2: I'm not configured correctly for this platform!\n"
1451 "\tI require Int32, Int16 and Char to have sizes\n"
1452 "\tof 4, 2 and 1 bytes to run properly, and they don't.\n"
1453 "\tProbably you can fix this by defining them correctly,\n"
1454 "\tand recompiling. Bye!\n" );
1455 exit(3);
1456 }
1457
1458 1801
1459 /*-- Initialise --*/ 1802 /*-- Initialise --*/
1460 outputHandleJustInCase = NULL; 1803 outputHandleJustInCase = NULL;
@@ -1465,9 +1808,12 @@ IntNative main ( IntNative argc, Char *argv[] )
1465 verbosity = 0; 1808 verbosity = 0;
1466 blockSize100k = 9; 1809 blockSize100k = 9;
1467 testFailsExist = False; 1810 testFailsExist = False;
1811 unzFailsExist = False;
1468 numFileNames = 0; 1812 numFileNames = 0;
1469 numFilesProcessed = 0; 1813 numFilesProcessed = 0;
1470 workFactor = 30; 1814 workFactor = 30;
1815 deleteOutputOnInterrupt = False;
1816 exitValue = 0;
1471 i = j = 0; /* avoid bogus warning from egcs-1.1.X */ 1817 i = j = 0; /* avoid bogus warning from egcs-1.1.X */
1472 1818
1473 /*-- Set up signal handlers for mem access errors --*/ 1819 /*-- Set up signal handlers for mem access errors --*/
@@ -1636,6 +1982,7 @@ IntNative main ( IntNative argc, Char *argv[] )
1636 else 1982 else
1637 1983
1638 if (opMode == OM_UNZ) { 1984 if (opMode == OM_UNZ) {
1985 unzFailsExist = False;
1639 if (srcMode == SM_I2O) { 1986 if (srcMode == SM_I2O) {
1640 uncompress ( NULL ); 1987 uncompress ( NULL );
1641 } else { 1988 } else {
@@ -1647,6 +1994,10 @@ IntNative main ( IntNative argc, Char *argv[] )
1647 uncompress ( aa->name ); 1994 uncompress ( aa->name );
1648 } 1995 }
1649 } 1996 }
1997 if (unzFailsExist) {
1998 setExit(2);
1999 exit(exitValue);
2000 }
1650 } 2001 }
1651 2002
1652 else { 2003 else {
@@ -1668,7 +2019,8 @@ IntNative main ( IntNative argc, Char *argv[] )
1668 "You can use the `bzip2recover' program to attempt to recover\n" 2019 "You can use the `bzip2recover' program to attempt to recover\n"
1669 "data from undamaged sections of corrupted files.\n\n" 2020 "data from undamaged sections of corrupted files.\n\n"
1670 ); 2021 );
1671 exit(2); 2022 setExit(2);
2023 exit(exitValue);
1672 } 2024 }
1673 } 2025 }
1674 2026
@@ -1678,12 +2030,12 @@ IntNative main ( IntNative argc, Char *argv[] )
1678 aa = argList; 2030 aa = argList;
1679 while (aa != NULL) { 2031 while (aa != NULL) {
1680 Cell* aa2 = aa->link; 2032 Cell* aa2 = aa->link;
1681 if (aa->name) free(aa->name); 2033 if (aa->name != NULL) free(aa->name);
1682 free(aa); 2034 free(aa);
1683 aa = aa2; 2035 aa = aa2;
1684 } 2036 }
1685 2037
1686 return 0; 2038 return exitValue;
1687} 2039}
1688 2040
1689 2041
diff --git a/bzip2.txt b/bzip2.txt
index da23c64..4f1ae86 100644
--- a/bzip2.txt
+++ b/bzip2.txt
@@ -1,7 +1,7 @@
1 1
2 2
3NAME 3NAME
4 bzip2, bunzip2 - a block-sorting file compressor, v0.9.5 4 bzip2, bunzip2 - a block-sorting file compressor, v1.0
5 bzcat - decompresses files to stdout 5 bzcat - decompresses files to stdout
6 bzip2recover - recovers data from damaged bzip2 files 6 bzip2recover - recovers data from damaged bzip2 files
7 7
@@ -337,14 +337,14 @@ CAVEATS
337 but the details of what the problem is sometimes seem 337 but the details of what the problem is sometimes seem
338 rather misleading. 338 rather misleading.
339 339
340 This manual page pertains to version 0.9.5 of bzip2. Com- 340 This manual page pertains to version 1.0 of bzip2. Com-
341 pressed data created by this version is entirely forwards 341 pressed data created by this version is entirely forwards
342 and backwards compatible with the previous public 342 and backwards compatible with the previous public
343 releases, versions 0.1pl2 and 0.9.0, but with the follow- 343 releases, versions 0.1pl2, 0.9.0 and 0.9.5, but with the
344 ing exception: 0.9.0 and above can correctly decompress 344 following exception: 0.9.0 and above can correctly decom-
345 multiple concatenated compressed files. 0.1pl2 cannot do 345 press multiple concatenated compressed files. 0.1pl2 can-
346 this; it will stop after decompressing just the first file 346 not do this; it will stop after decompressing just the
347 in the stream. 347 first file in the stream.
348 348
349 bzip2recover uses 32-bit integers to represent bit posi- 349 bzip2recover uses 32-bit integers to represent bit posi-
350 tions in compressed files, so it cannot handle compressed 350 tions in compressed files, so it cannot handle compressed
@@ -355,6 +355,7 @@ CAVEATS
355AUTHOR 355AUTHOR
356 Julian Seward, jseward@acm.org. 356 Julian Seward, jseward@acm.org.
357 357
358 http://sourceware.cygnus.com/bzip2
358 http://www.muraroa.demon.co.uk 359 http://www.muraroa.demon.co.uk
359 360
360 The ideas embodied in bzip2 are due to (at least) the fol- 361 The ideas embodied in bzip2 are due to (at least) the fol-
diff --git a/bzip2recover.c b/bzip2recover.c
index 1323b36..ba3d175 100644
--- a/bzip2recover.c
+++ b/bzip2recover.c
@@ -7,9 +7,9 @@
7/*-- 7/*--
8 This program is bzip2recover, a program to attempt data 8 This program is bzip2recover, a program to attempt data
9 salvage from damaged files created by the accompanying 9 salvage from damaged files created by the accompanying
10 bzip2-0.9.5 program. 10 bzip2-1.0 program.
11 11
12 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 12 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
13 13
14 Redistribution and use in source and binary forms, with or without 14 Redistribution and use in source and binary forms, with or without
15 modification, are permitted provided that the following conditions 15 modification, are permitted provided that the following conditions
@@ -44,7 +44,7 @@
44 44
45 Julian Seward, Cambridge, UK. 45 Julian Seward, Cambridge, UK.
46 jseward@acm.org 46 jseward@acm.org
47 bzip2/libbzip2 version 0.9.5 of 24 May 1999 47 bzip2/libbzip2 version 1.0 of 21 March 2000
48--*/ 48--*/
49 49
50/*-- 50/*--
@@ -282,7 +282,7 @@ Int32 main ( Int32 argc, Char** argv )
282 strcpy ( progName, argv[0] ); 282 strcpy ( progName, argv[0] );
283 inFileName[0] = outFileName[0] = 0; 283 inFileName[0] = outFileName[0] = 0;
284 284
285 fprintf ( stderr, "bzip2recover 0.9.5d: extracts blocks from damaged .bz2 files.\n" ); 285 fprintf ( stderr, "bzip2recover 1.0: extracts blocks from damaged .bz2 files.\n" );
286 286
287 if (argc != 2) { 287 if (argc != 2) {
288 fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n", 288 fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
diff --git a/bzlib.c b/bzlib.c
index 24e8bd5..4a06d9f 100644
--- a/bzlib.c
+++ b/bzlib.c
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -83,18 +83,19 @@
83 83
84/*---------------------------------------------------*/ 84/*---------------------------------------------------*/
85#ifndef BZ_NO_STDIO 85#ifndef BZ_NO_STDIO
86void bz__AssertH__fail ( int errcode ) 86void BZ2_bz__AssertH__fail ( int errcode )
87{ 87{
88 fprintf(stderr, 88 fprintf(stderr,
89 "\n\nbzip2/libbzip2, v0.9.5d: internal error number %d.\n" 89 "\n\nbzip2/libbzip2: internal error number %d.\n"
90 "This is a bug in bzip2/libbzip2, v0.9.5d. Please report\n" 90 "This is a bug in bzip2/libbzip2, %s.\n"
91 "it to me at: jseward@acm.org. If this happened when\n" 91 "Please report it to me at: jseward@acm.org. If this happened\n"
92 "you were using some program which uses libbzip2 as a\n" 92 "when you were using some program which uses libbzip2 as a\n"
93 "component, you should also report this bug to the author(s)\n" 93 "component, you should also report this bug to the author(s)\n"
94 "of that program. Please make an effort to report this bug;\n" 94 "of that program. Please make an effort to report this bug;\n"
95 "timely and accurate bug reports eventually lead to higher\n" 95 "timely and accurate bug reports eventually lead to higher\n"
96 "quality software. Thanks. Julian Seward, 4 Sept 1999.\n\n", 96 "quality software. Thanks. Julian Seward, 21 March 2000.\n\n",
97 errcode 97 errcode,
98 BZ2_bzlibVersion()
98 ); 99 );
99 exit(3); 100 exit(3);
100} 101}
@@ -103,6 +104,17 @@ void bz__AssertH__fail ( int errcode )
103 104
104/*---------------------------------------------------*/ 105/*---------------------------------------------------*/
105static 106static
107int bz_config_ok ( void )
108{
109 if (sizeof(int) != 4) return 0;
110 if (sizeof(short) != 2) return 0;
111 if (sizeof(char) != 1) return 0;
112 return 1;
113}
114
115
116/*---------------------------------------------------*/
117static
106void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) 118void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
107{ 119{
108 void* v = malloc ( items * size ); 120 void* v = malloc ( items * size );
@@ -149,7 +161,7 @@ Bool isempty_RL ( EState* s )
149 161
150 162
151/*---------------------------------------------------*/ 163/*---------------------------------------------------*/
152int BZ_API(bzCompressInit) 164int BZ_API(BZ2_bzCompressInit)
153 ( bz_stream* strm, 165 ( bz_stream* strm,
154 int blockSize100k, 166 int blockSize100k,
155 int verbosity, 167 int verbosity,
@@ -158,6 +170,8 @@ int BZ_API(bzCompressInit)
158 Int32 n; 170 Int32 n;
159 EState* s; 171 EState* s;
160 172
173 if (!bz_config_ok()) return BZ_CONFIG_ERROR;
174
161 if (strm == NULL || 175 if (strm == NULL ||
162 blockSize100k < 1 || blockSize100k > 9 || 176 blockSize100k < 1 || blockSize100k > 9 ||
163 workFactor < 0 || workFactor > 250) 177 workFactor < 0 || workFactor > 250)
@@ -197,14 +211,16 @@ int BZ_API(bzCompressInit)
197 s->verbosity = verbosity; 211 s->verbosity = verbosity;
198 s->workFactor = workFactor; 212 s->workFactor = workFactor;
199 213
200 s->block = (UInt16*)s->arr2; 214 s->block = (UChar*)s->arr2;
201 s->mtfv = (UInt16*)s->arr1; 215 s->mtfv = (UInt16*)s->arr1;
202 s->zbits = NULL; 216 s->zbits = NULL;
203 s->ptr = (UInt32*)s->arr1; 217 s->ptr = (UInt32*)s->arr1;
204 218
205 strm->state = s; 219 strm->state = s;
206 strm->total_in = 0; 220 strm->total_in_lo32 = 0;
207 strm->total_out = 0; 221 strm->total_in_hi32 = 0;
222 strm->total_out_lo32 = 0;
223 strm->total_out_hi32 = 0;
208 init_RL ( s ); 224 init_RL ( s );
209 prepare_new_block ( s ); 225 prepare_new_block ( s );
210 return BZ_OK; 226 return BZ_OK;
@@ -223,24 +239,24 @@ void add_pair_to_block ( EState* s )
223 s->inUse[s->state_in_ch] = True; 239 s->inUse[s->state_in_ch] = True;
224 switch (s->state_in_len) { 240 switch (s->state_in_len) {
225 case 1: 241 case 1:
226 s->block[s->nblock] = (UInt16)ch; s->nblock++; 242 s->block[s->nblock] = (UChar)ch; s->nblock++;
227 break; 243 break;
228 case 2: 244 case 2:
229 s->block[s->nblock] = (UInt16)ch; s->nblock++; 245 s->block[s->nblock] = (UChar)ch; s->nblock++;
230 s->block[s->nblock] = (UInt16)ch; s->nblock++; 246 s->block[s->nblock] = (UChar)ch; s->nblock++;
231 break; 247 break;
232 case 3: 248 case 3:
233 s->block[s->nblock] = (UInt16)ch; s->nblock++; 249 s->block[s->nblock] = (UChar)ch; s->nblock++;
234 s->block[s->nblock] = (UInt16)ch; s->nblock++; 250 s->block[s->nblock] = (UChar)ch; s->nblock++;
235 s->block[s->nblock] = (UInt16)ch; s->nblock++; 251 s->block[s->nblock] = (UChar)ch; s->nblock++;
236 break; 252 break;
237 default: 253 default:
238 s->inUse[s->state_in_len-4] = True; 254 s->inUse[s->state_in_len-4] = True;
239 s->block[s->nblock] = (UInt16)ch; s->nblock++; 255 s->block[s->nblock] = (UChar)ch; s->nblock++;
240 s->block[s->nblock] = (UInt16)ch; s->nblock++; 256 s->block[s->nblock] = (UChar)ch; s->nblock++;
241 s->block[s->nblock] = (UInt16)ch; s->nblock++; 257 s->block[s->nblock] = (UChar)ch; s->nblock++;
242 s->block[s->nblock] = (UInt16)ch; s->nblock++; 258 s->block[s->nblock] = (UChar)ch; s->nblock++;
243 s->block[s->nblock] = ((UInt16)(s->state_in_len-4)); 259 s->block[s->nblock] = ((UChar)(s->state_in_len-4));
244 s->nblock++; 260 s->nblock++;
245 break; 261 break;
246 } 262 }
@@ -266,7 +282,7 @@ void flush_RL ( EState* s )
266 UChar ch = (UChar)(zs->state_in_ch); \ 282 UChar ch = (UChar)(zs->state_in_ch); \
267 BZ_UPDATE_CRC( zs->blockCRC, ch ); \ 283 BZ_UPDATE_CRC( zs->blockCRC, ch ); \
268 zs->inUse[zs->state_in_ch] = True; \ 284 zs->inUse[zs->state_in_ch] = True; \
269 zs->block[zs->nblock] = (UInt16)ch; \ 285 zs->block[zs->nblock] = (UChar)ch; \
270 zs->nblock++; \ 286 zs->nblock++; \
271 zs->state_in_ch = zchh; \ 287 zs->state_in_ch = zchh; \
272 } \ 288 } \
@@ -302,7 +318,8 @@ Bool copy_input_until_stop ( EState* s )
302 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 318 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
303 s->strm->next_in++; 319 s->strm->next_in++;
304 s->strm->avail_in--; 320 s->strm->avail_in--;
305 s->strm->total_in++; 321 s->strm->total_in_lo32++;
322 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
306 } 323 }
307 324
308 } else { 325 } else {
@@ -319,7 +336,8 @@ Bool copy_input_until_stop ( EState* s )
319 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 336 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
320 s->strm->next_in++; 337 s->strm->next_in++;
321 s->strm->avail_in--; 338 s->strm->avail_in--;
322 s->strm->total_in++; 339 s->strm->total_in_lo32++;
340 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
323 s->avail_in_expect--; 341 s->avail_in_expect--;
324 } 342 }
325 } 343 }
@@ -346,8 +364,8 @@ Bool copy_output_until_stop ( EState* s )
346 s->state_out_pos++; 364 s->state_out_pos++;
347 s->strm->avail_out--; 365 s->strm->avail_out--;
348 s->strm->next_out++; 366 s->strm->next_out++;
349 s->strm->total_out++; 367 s->strm->total_out_lo32++;
350 368 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
351 } 369 }
352 370
353 return progress_out; 371 return progress_out;
@@ -381,12 +399,12 @@ Bool handle_compress ( bz_stream* strm )
381 progress_in |= copy_input_until_stop ( s ); 399 progress_in |= copy_input_until_stop ( s );
382 if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { 400 if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
383 flush_RL ( s ); 401 flush_RL ( s );
384 compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) ); 402 BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
385 s->state = BZ_S_OUTPUT; 403 s->state = BZ_S_OUTPUT;
386 } 404 }
387 else 405 else
388 if (s->nblock >= s->nblockMAX) { 406 if (s->nblock >= s->nblockMAX) {
389 compressBlock ( s, False ); 407 BZ2_compressBlock ( s, False );
390 s->state = BZ_S_OUTPUT; 408 s->state = BZ_S_OUTPUT;
391 } 409 }
392 else 410 else
@@ -402,7 +420,7 @@ Bool handle_compress ( bz_stream* strm )
402 420
403 421
404/*---------------------------------------------------*/ 422/*---------------------------------------------------*/
405int BZ_API(bzCompress) ( bz_stream *strm, int action ) 423int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
406{ 424{
407 Bool progress; 425 Bool progress;
408 EState* s; 426 EState* s;
@@ -439,7 +457,8 @@ int BZ_API(bzCompress) ( bz_stream *strm, int action )
439 457
440 case BZ_M_FLUSHING: 458 case BZ_M_FLUSHING:
441 if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; 459 if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
442 if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR; 460 if (s->avail_in_expect != s->strm->avail_in)
461 return BZ_SEQUENCE_ERROR;
443 progress = handle_compress ( strm ); 462 progress = handle_compress ( strm );
444 if (s->avail_in_expect > 0 || !isempty_RL(s) || 463 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
445 s->state_out_pos < s->numZ) return BZ_FLUSH_OK; 464 s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
@@ -448,7 +467,8 @@ int BZ_API(bzCompress) ( bz_stream *strm, int action )
448 467
449 case BZ_M_FINISHING: 468 case BZ_M_FINISHING:
450 if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; 469 if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
451 if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR; 470 if (s->avail_in_expect != s->strm->avail_in)
471 return BZ_SEQUENCE_ERROR;
452 progress = handle_compress ( strm ); 472 progress = handle_compress ( strm );
453 if (!progress) return BZ_SEQUENCE_ERROR; 473 if (!progress) return BZ_SEQUENCE_ERROR;
454 if (s->avail_in_expect > 0 || !isempty_RL(s) || 474 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
@@ -461,7 +481,7 @@ int BZ_API(bzCompress) ( bz_stream *strm, int action )
461 481
462 482
463/*---------------------------------------------------*/ 483/*---------------------------------------------------*/
464int BZ_API(bzCompressEnd) ( bz_stream *strm ) 484int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
465{ 485{
466 EState* s; 486 EState* s;
467 if (strm == NULL) return BZ_PARAM_ERROR; 487 if (strm == NULL) return BZ_PARAM_ERROR;
@@ -485,13 +505,15 @@ int BZ_API(bzCompressEnd) ( bz_stream *strm )
485/*---------------------------------------------------*/ 505/*---------------------------------------------------*/
486 506
487/*---------------------------------------------------*/ 507/*---------------------------------------------------*/
488int BZ_API(bzDecompressInit) 508int BZ_API(BZ2_bzDecompressInit)
489 ( bz_stream* strm, 509 ( bz_stream* strm,
490 int verbosity, 510 int verbosity,
491 int small ) 511 int small )
492{ 512{
493 DState* s; 513 DState* s;
494 514
515 if (!bz_config_ok()) return BZ_CONFIG_ERROR;
516
495 if (strm == NULL) return BZ_PARAM_ERROR; 517 if (strm == NULL) return BZ_PARAM_ERROR;
496 if (small != 0 && small != 1) return BZ_PARAM_ERROR; 518 if (small != 0 && small != 1) return BZ_PARAM_ERROR;
497 if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; 519 if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
@@ -507,8 +529,10 @@ int BZ_API(bzDecompressInit)
507 s->bsLive = 0; 529 s->bsLive = 0;
508 s->bsBuff = 0; 530 s->bsBuff = 0;
509 s->calculatedCombinedCRC = 0; 531 s->calculatedCombinedCRC = 0;
510 strm->total_in = 0; 532 strm->total_in_lo32 = 0;
511 strm->total_out = 0; 533 strm->total_in_hi32 = 0;
534 strm->total_out_lo32 = 0;
535 strm->total_out_hi32 = 0;
512 s->smallDecompress = (Bool)small; 536 s->smallDecompress = (Bool)small;
513 s->ll4 = NULL; 537 s->ll4 = NULL;
514 s->ll16 = NULL; 538 s->ll16 = NULL;
@@ -538,7 +562,8 @@ void unRLE_obuf_to_output_FAST ( DState* s )
538 s->state_out_len--; 562 s->state_out_len--;
539 s->strm->next_out++; 563 s->strm->next_out++;
540 s->strm->avail_out--; 564 s->strm->avail_out--;
541 s->strm->total_out++; 565 s->strm->total_out_lo32++;
566 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
542 } 567 }
543 568
544 /* can a new run be started? */ 569 /* can a new run be started? */
@@ -585,8 +610,9 @@ void unRLE_obuf_to_output_FAST ( DState* s )
585 unsigned int cs_avail_out = s->strm->avail_out; 610 unsigned int cs_avail_out = s->strm->avail_out;
586 /* end restore */ 611 /* end restore */
587 612
588 UInt32 avail_out_INIT = cs_avail_out; 613 UInt32 avail_out_INIT = cs_avail_out;
589 Int32 s_save_nblockPP = s->save_nblock+1; 614 Int32 s_save_nblockPP = s->save_nblock+1;
615 unsigned int total_out_lo32_old;
590 616
591 while (True) { 617 while (True) {
592 618
@@ -640,7 +666,10 @@ void unRLE_obuf_to_output_FAST ( DState* s )
640 } 666 }
641 667
642 return_notr: 668 return_notr:
643 s->strm->total_out += (avail_out_INIT - cs_avail_out); 669 total_out_lo32_old = s->strm->total_out_lo32;
670 s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
671 if (s->strm->total_out_lo32 < total_out_lo32_old)
672 s->strm->total_out_hi32++;
644 673
645 /* save */ 674 /* save */
646 s->calculatedBlockCRC = c_calculatedBlockCRC; 675 s->calculatedBlockCRC = c_calculatedBlockCRC;
@@ -659,7 +688,7 @@ void unRLE_obuf_to_output_FAST ( DState* s )
659 688
660 689
661/*---------------------------------------------------*/ 690/*---------------------------------------------------*/
662__inline__ Int32 indexIntoF ( Int32 indx, Int32 *cftab ) 691__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
663{ 692{
664 Int32 nb, na, mid; 693 Int32 nb, na, mid;
665 nb = 0; 694 nb = 0;
@@ -691,7 +720,8 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
691 s->state_out_len--; 720 s->state_out_len--;
692 s->strm->next_out++; 721 s->strm->next_out++;
693 s->strm->avail_out--; 722 s->strm->avail_out--;
694 s->strm->total_out++; 723 s->strm->total_out_lo32++;
724 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
695 } 725 }
696 726
697 /* can a new run be started? */ 727 /* can a new run be started? */
@@ -736,7 +766,8 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
736 s->state_out_len--; 766 s->state_out_len--;
737 s->strm->next_out++; 767 s->strm->next_out++;
738 s->strm->avail_out--; 768 s->strm->avail_out--;
739 s->strm->total_out++; 769 s->strm->total_out_lo32++;
770 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
740 } 771 }
741 772
742 /* can a new run be started? */ 773 /* can a new run be started? */
@@ -768,7 +799,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
768 799
769 800
770/*---------------------------------------------------*/ 801/*---------------------------------------------------*/
771int BZ_API(bzDecompress) ( bz_stream *strm ) 802int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
772{ 803{
773 DState* s; 804 DState* s;
774 if (strm == NULL) return BZ_PARAM_ERROR; 805 if (strm == NULL) return BZ_PARAM_ERROR;
@@ -800,7 +831,7 @@ int BZ_API(bzDecompress) ( bz_stream *strm )
800 } 831 }
801 } 832 }
802 if (s->state >= BZ_X_MAGIC_1) { 833 if (s->state >= BZ_X_MAGIC_1) {
803 Int32 r = decompress ( s ); 834 Int32 r = BZ2_decompress ( s );
804 if (r == BZ_STREAM_END) { 835 if (r == BZ_STREAM_END) {
805 if (s->verbosity >= 3) 836 if (s->verbosity >= 3)
806 VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x", 837 VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
@@ -820,7 +851,7 @@ int BZ_API(bzDecompress) ( bz_stream *strm )
820 851
821 852
822/*---------------------------------------------------*/ 853/*---------------------------------------------------*/
823int BZ_API(bzDecompressEnd) ( bz_stream *strm ) 854int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
824{ 855{
825 DState* s; 856 DState* s;
826 if (strm == NULL) return BZ_PARAM_ERROR; 857 if (strm == NULL) return BZ_PARAM_ERROR;
@@ -874,7 +905,7 @@ static Bool myfeof ( FILE* f )
874 905
875 906
876/*---------------------------------------------------*/ 907/*---------------------------------------------------*/
877BZFILE* BZ_API(bzWriteOpen) 908BZFILE* BZ_API(BZ2_bzWriteOpen)
878 ( int* bzerror, 909 ( int* bzerror,
879 FILE* f, 910 FILE* f,
880 int blockSize100k, 911 int blockSize100k,
@@ -909,8 +940,8 @@ BZFILE* BZ_API(bzWriteOpen)
909 bzf->strm.opaque = NULL; 940 bzf->strm.opaque = NULL;
910 941
911 if (workFactor == 0) workFactor = 30; 942 if (workFactor == 0) workFactor = 30;
912 ret = bzCompressInit ( &(bzf->strm), blockSize100k, 943 ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
913 verbosity, workFactor ); 944 verbosity, workFactor );
914 if (ret != BZ_OK) 945 if (ret != BZ_OK)
915 { BZ_SETERR(ret); free(bzf); return NULL; }; 946 { BZ_SETERR(ret); free(bzf); return NULL; };
916 947
@@ -922,7 +953,7 @@ BZFILE* BZ_API(bzWriteOpen)
922 953
923 954
924/*---------------------------------------------------*/ 955/*---------------------------------------------------*/
925void BZ_API(bzWrite) 956void BZ_API(BZ2_bzWrite)
926 ( int* bzerror, 957 ( int* bzerror,
927 BZFILE* b, 958 BZFILE* b,
928 void* buf, 959 void* buf,
@@ -948,7 +979,7 @@ void BZ_API(bzWrite)
948 while (True) { 979 while (True) {
949 bzf->strm.avail_out = BZ_MAX_UNUSED; 980 bzf->strm.avail_out = BZ_MAX_UNUSED;
950 bzf->strm.next_out = bzf->buf; 981 bzf->strm.next_out = bzf->buf;
951 ret = bzCompress ( &(bzf->strm), BZ_RUN ); 982 ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
952 if (ret != BZ_RUN_OK) 983 if (ret != BZ_RUN_OK)
953 { BZ_SETERR(ret); return; }; 984 { BZ_SETERR(ret); return; };
954 985
@@ -967,13 +998,27 @@ void BZ_API(bzWrite)
967 998
968 999
969/*---------------------------------------------------*/ 1000/*---------------------------------------------------*/
970void BZ_API(bzWriteClose) 1001void BZ_API(BZ2_bzWriteClose)
971 ( int* bzerror, 1002 ( int* bzerror,
972 BZFILE* b, 1003 BZFILE* b,
973 int abandon, 1004 int abandon,
974 unsigned int* nbytes_in, 1005 unsigned int* nbytes_in,
975 unsigned int* nbytes_out ) 1006 unsigned int* nbytes_out )
976{ 1007{
1008 BZ2_bzWriteClose64 ( bzerror, b, abandon,
1009 nbytes_in, NULL, nbytes_out, NULL );
1010}
1011
1012
1013void BZ_API(BZ2_bzWriteClose64)
1014 ( int* bzerror,
1015 BZFILE* b,
1016 int abandon,
1017 unsigned int* nbytes_in_lo32,
1018 unsigned int* nbytes_in_hi32,
1019 unsigned int* nbytes_out_lo32,
1020 unsigned int* nbytes_out_hi32 )
1021{
977 Int32 n, n2, ret; 1022 Int32 n, n2, ret;
978 bzFile* bzf = (bzFile*)b; 1023 bzFile* bzf = (bzFile*)b;
979 1024
@@ -984,14 +1029,16 @@ void BZ_API(bzWriteClose)
984 if (ferror(bzf->handle)) 1029 if (ferror(bzf->handle))
985 { BZ_SETERR(BZ_IO_ERROR); return; }; 1030 { BZ_SETERR(BZ_IO_ERROR); return; };
986 1031
987 if (nbytes_in != NULL) *nbytes_in = 0; 1032 if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
988 if (nbytes_out != NULL) *nbytes_out = 0; 1033 if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
1034 if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
1035 if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
989 1036
990 if ((!abandon) && bzf->lastErr == BZ_OK) { 1037 if ((!abandon) && bzf->lastErr == BZ_OK) {
991 while (True) { 1038 while (True) {
992 bzf->strm.avail_out = BZ_MAX_UNUSED; 1039 bzf->strm.avail_out = BZ_MAX_UNUSED;
993 bzf->strm.next_out = bzf->buf; 1040 bzf->strm.next_out = bzf->buf;
994 ret = bzCompress ( &(bzf->strm), BZ_FINISH ); 1041 ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
995 if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) 1042 if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
996 { BZ_SETERR(ret); return; }; 1043 { BZ_SETERR(ret); return; };
997 1044
@@ -1013,17 +1060,23 @@ void BZ_API(bzWriteClose)
1013 { BZ_SETERR(BZ_IO_ERROR); return; }; 1060 { BZ_SETERR(BZ_IO_ERROR); return; };
1014 } 1061 }
1015 1062
1016 if (nbytes_in != NULL) *nbytes_in = bzf->strm.total_in; 1063 if (nbytes_in_lo32 != NULL)
1017 if (nbytes_out != NULL) *nbytes_out = bzf->strm.total_out; 1064 *nbytes_in_lo32 = bzf->strm.total_in_lo32;
1065 if (nbytes_in_hi32 != NULL)
1066 *nbytes_in_hi32 = bzf->strm.total_in_hi32;
1067 if (nbytes_out_lo32 != NULL)
1068 *nbytes_out_lo32 = bzf->strm.total_out_lo32;
1069 if (nbytes_out_hi32 != NULL)
1070 *nbytes_out_hi32 = bzf->strm.total_out_hi32;
1018 1071
1019 BZ_SETERR(BZ_OK); 1072 BZ_SETERR(BZ_OK);
1020 bzCompressEnd ( &(bzf->strm) ); 1073 BZ2_bzCompressEnd ( &(bzf->strm) );
1021 free ( bzf ); 1074 free ( bzf );
1022} 1075}
1023 1076
1024 1077
1025/*---------------------------------------------------*/ 1078/*---------------------------------------------------*/
1026BZFILE* BZ_API(bzReadOpen) 1079BZFILE* BZ_API(BZ2_bzReadOpen)
1027 ( int* bzerror, 1080 ( int* bzerror,
1028 FILE* f, 1081 FILE* f,
1029 int verbosity, 1082 int verbosity,
@@ -1066,7 +1119,7 @@ BZFILE* BZ_API(bzReadOpen)
1066 nUnused--; 1119 nUnused--;
1067 } 1120 }
1068 1121
1069 ret = bzDecompressInit ( &(bzf->strm), verbosity, small ); 1122 ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
1070 if (ret != BZ_OK) 1123 if (ret != BZ_OK)
1071 { BZ_SETERR(ret); free(bzf); return NULL; }; 1124 { BZ_SETERR(ret); free(bzf); return NULL; };
1072 1125
@@ -1079,7 +1132,7 @@ BZFILE* BZ_API(bzReadOpen)
1079 1132
1080 1133
1081/*---------------------------------------------------*/ 1134/*---------------------------------------------------*/
1082void BZ_API(bzReadClose) ( int *bzerror, BZFILE *b ) 1135void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
1083{ 1136{
1084 bzFile* bzf = (bzFile*)b; 1137 bzFile* bzf = (bzFile*)b;
1085 1138
@@ -1091,13 +1144,13 @@ void BZ_API(bzReadClose) ( int *bzerror, BZFILE *b )
1091 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; 1144 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1092 1145
1093 if (bzf->initialisedOk) 1146 if (bzf->initialisedOk)
1094 (void)bzDecompressEnd ( &(bzf->strm) ); 1147 (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
1095 free ( bzf ); 1148 free ( bzf );
1096} 1149}
1097 1150
1098 1151
1099/*---------------------------------------------------*/ 1152/*---------------------------------------------------*/
1100int BZ_API(bzRead) 1153int BZ_API(BZ2_bzRead)
1101 ( int* bzerror, 1154 ( int* bzerror,
1102 BZFILE* b, 1155 BZFILE* b,
1103 void* buf, 1156 void* buf,
@@ -1135,7 +1188,7 @@ int BZ_API(bzRead)
1135 bzf->strm.next_in = bzf->buf; 1188 bzf->strm.next_in = bzf->buf;
1136 } 1189 }
1137 1190
1138 ret = bzDecompress ( &(bzf->strm) ); 1191 ret = BZ2_bzDecompress ( &(bzf->strm) );
1139 1192
1140 if (ret != BZ_OK && ret != BZ_STREAM_END) 1193 if (ret != BZ_OK && ret != BZ_STREAM_END)
1141 { BZ_SETERR(ret); return 0; }; 1194 { BZ_SETERR(ret); return 0; };
@@ -1157,7 +1210,7 @@ int BZ_API(bzRead)
1157 1210
1158 1211
1159/*---------------------------------------------------*/ 1212/*---------------------------------------------------*/
1160void BZ_API(bzReadGetUnused) 1213void BZ_API(BZ2_bzReadGetUnused)
1161 ( int* bzerror, 1214 ( int* bzerror,
1162 BZFILE* b, 1215 BZFILE* b,
1163 void** unused, 1216 void** unused,
@@ -1183,7 +1236,7 @@ void BZ_API(bzReadGetUnused)
1183/*---------------------------------------------------*/ 1236/*---------------------------------------------------*/
1184 1237
1185/*---------------------------------------------------*/ 1238/*---------------------------------------------------*/
1186int BZ_API(bzBuffToBuffCompress) 1239int BZ_API(BZ2_bzBuffToBuffCompress)
1187 ( char* dest, 1240 ( char* dest,
1188 unsigned int* destLen, 1241 unsigned int* destLen,
1189 char* source, 1242 char* source,
@@ -1206,8 +1259,8 @@ int BZ_API(bzBuffToBuffCompress)
1206 strm.bzalloc = NULL; 1259 strm.bzalloc = NULL;
1207 strm.bzfree = NULL; 1260 strm.bzfree = NULL;
1208 strm.opaque = NULL; 1261 strm.opaque = NULL;
1209 ret = bzCompressInit ( &strm, blockSize100k, 1262 ret = BZ2_bzCompressInit ( &strm, blockSize100k,
1210 verbosity, workFactor ); 1263 verbosity, workFactor );
1211 if (ret != BZ_OK) return ret; 1264 if (ret != BZ_OK) return ret;
1212 1265
1213 strm.next_in = source; 1266 strm.next_in = source;
@@ -1215,27 +1268,27 @@ int BZ_API(bzBuffToBuffCompress)
1215 strm.avail_in = sourceLen; 1268 strm.avail_in = sourceLen;
1216 strm.avail_out = *destLen; 1269 strm.avail_out = *destLen;
1217 1270
1218 ret = bzCompress ( &strm, BZ_FINISH ); 1271 ret = BZ2_bzCompress ( &strm, BZ_FINISH );
1219 if (ret == BZ_FINISH_OK) goto output_overflow; 1272 if (ret == BZ_FINISH_OK) goto output_overflow;
1220 if (ret != BZ_STREAM_END) goto errhandler; 1273 if (ret != BZ_STREAM_END) goto errhandler;
1221 1274
1222 /* normal termination */ 1275 /* normal termination */
1223 *destLen -= strm.avail_out; 1276 *destLen -= strm.avail_out;
1224 bzCompressEnd ( &strm ); 1277 BZ2_bzCompressEnd ( &strm );
1225 return BZ_OK; 1278 return BZ_OK;
1226 1279
1227 output_overflow: 1280 output_overflow:
1228 bzCompressEnd ( &strm ); 1281 BZ2_bzCompressEnd ( &strm );
1229 return BZ_OUTBUFF_FULL; 1282 return BZ_OUTBUFF_FULL;
1230 1283
1231 errhandler: 1284 errhandler:
1232 bzCompressEnd ( &strm ); 1285 BZ2_bzCompressEnd ( &strm );
1233 return ret; 1286 return ret;
1234} 1287}
1235 1288
1236 1289
1237/*---------------------------------------------------*/ 1290/*---------------------------------------------------*/
1238int BZ_API(bzBuffToBuffDecompress) 1291int BZ_API(BZ2_bzBuffToBuffDecompress)
1239 ( char* dest, 1292 ( char* dest,
1240 unsigned int* destLen, 1293 unsigned int* destLen,
1241 char* source, 1294 char* source,
@@ -1255,7 +1308,7 @@ int BZ_API(bzBuffToBuffDecompress)
1255 strm.bzalloc = NULL; 1308 strm.bzalloc = NULL;
1256 strm.bzfree = NULL; 1309 strm.bzfree = NULL;
1257 strm.opaque = NULL; 1310 strm.opaque = NULL;
1258 ret = bzDecompressInit ( &strm, verbosity, small ); 1311 ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
1259 if (ret != BZ_OK) return ret; 1312 if (ret != BZ_OK) return ret;
1260 1313
1261 strm.next_in = source; 1314 strm.next_in = source;
@@ -1263,26 +1316,26 @@ int BZ_API(bzBuffToBuffDecompress)
1263 strm.avail_in = sourceLen; 1316 strm.avail_in = sourceLen;
1264 strm.avail_out = *destLen; 1317 strm.avail_out = *destLen;
1265 1318
1266 ret = bzDecompress ( &strm ); 1319 ret = BZ2_bzDecompress ( &strm );
1267 if (ret == BZ_OK) goto output_overflow_or_eof; 1320 if (ret == BZ_OK) goto output_overflow_or_eof;
1268 if (ret != BZ_STREAM_END) goto errhandler; 1321 if (ret != BZ_STREAM_END) goto errhandler;
1269 1322
1270 /* normal termination */ 1323 /* normal termination */
1271 *destLen -= strm.avail_out; 1324 *destLen -= strm.avail_out;
1272 bzDecompressEnd ( &strm ); 1325 BZ2_bzDecompressEnd ( &strm );
1273 return BZ_OK; 1326 return BZ_OK;
1274 1327
1275 output_overflow_or_eof: 1328 output_overflow_or_eof:
1276 if (strm.avail_out > 0) { 1329 if (strm.avail_out > 0) {
1277 bzDecompressEnd ( &strm ); 1330 BZ2_bzDecompressEnd ( &strm );
1278 return BZ_UNEXPECTED_EOF; 1331 return BZ_UNEXPECTED_EOF;
1279 } else { 1332 } else {
1280 bzDecompressEnd ( &strm ); 1333 BZ2_bzDecompressEnd ( &strm );
1281 return BZ_OUTBUFF_FULL; 1334 return BZ_OUTBUFF_FULL;
1282 }; 1335 };
1283 1336
1284 errhandler: 1337 errhandler:
1285 bzDecompressEnd ( &strm ); 1338 BZ2_bzDecompressEnd ( &strm );
1286 return ret; 1339 return ret;
1287} 1340}
1288 1341
@@ -1303,7 +1356,7 @@ int BZ_API(bzBuffToBuffDecompress)
1303/*-- 1356/*--
1304 return version like "0.9.0c". 1357 return version like "0.9.0c".
1305--*/ 1358--*/
1306const char * BZ_API(bzlibVersion)(void) 1359const char * BZ_API(BZ2_bzlibVersion)(void)
1307{ 1360{
1308 return BZ_VERSION; 1361 return BZ_VERSION;
1309} 1362}
@@ -1377,9 +1430,11 @@ BZFILE * bzopen_or_bzdopen
1377 /* Guard against total chaos and anarchy -- JRS */ 1430 /* Guard against total chaos and anarchy -- JRS */
1378 if (blockSize100k < 1) blockSize100k = 1; 1431 if (blockSize100k < 1) blockSize100k = 1;
1379 if (blockSize100k > 9) blockSize100k = 9; 1432 if (blockSize100k > 9) blockSize100k = 9;
1380 bzfp = bzWriteOpen(&bzerr,fp,blockSize100k,verbosity,workFactor); 1433 bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
1434 verbosity,workFactor);
1381 } else { 1435 } else {
1382 bzfp = bzReadOpen(&bzerr,fp,verbosity,smallMode,unused,nUnused); 1436 bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
1437 unused,nUnused);
1383 } 1438 }
1384 if (bzfp == NULL) { 1439 if (bzfp == NULL) {
1385 if (fp != stdin && fp != stdout) fclose(fp); 1440 if (fp != stdin && fp != stdout) fclose(fp);
@@ -1395,7 +1450,7 @@ BZFILE * bzopen_or_bzdopen
1395 ex) bzopen("file","w9") 1450 ex) bzopen("file","w9")
1396 case path="" or NULL => use stdin or stdout. 1451 case path="" or NULL => use stdin or stdout.
1397--*/ 1452--*/
1398BZFILE * BZ_API(bzopen) 1453BZFILE * BZ_API(BZ2_bzopen)
1399 ( const char *path, 1454 ( const char *path,
1400 const char *mode ) 1455 const char *mode )
1401{ 1456{
@@ -1404,7 +1459,7 @@ BZFILE * BZ_API(bzopen)
1404 1459
1405 1460
1406/*---------------------------------------------------*/ 1461/*---------------------------------------------------*/
1407BZFILE * BZ_API(bzdopen) 1462BZFILE * BZ_API(BZ2_bzdopen)
1408 ( int fd, 1463 ( int fd,
1409 const char *mode ) 1464 const char *mode )
1410{ 1465{
@@ -1413,11 +1468,11 @@ BZFILE * BZ_API(bzdopen)
1413 1468
1414 1469
1415/*---------------------------------------------------*/ 1470/*---------------------------------------------------*/
1416int BZ_API(bzread) (BZFILE* b, void* buf, int len ) 1471int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
1417{ 1472{
1418 int bzerr, nread; 1473 int bzerr, nread;
1419 if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0; 1474 if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
1420 nread = bzRead(&bzerr,b,buf,len); 1475 nread = BZ2_bzRead(&bzerr,b,buf,len);
1421 if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) { 1476 if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
1422 return nread; 1477 return nread;
1423 } else { 1478 } else {
@@ -1427,11 +1482,11 @@ int BZ_API(bzread) (BZFILE* b, void* buf, int len )
1427 1482
1428 1483
1429/*---------------------------------------------------*/ 1484/*---------------------------------------------------*/
1430int BZ_API(bzwrite) (BZFILE* b, void* buf, int len ) 1485int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
1431{ 1486{
1432 int bzerr; 1487 int bzerr;
1433 1488
1434 bzWrite(&bzerr,b,buf,len); 1489 BZ2_bzWrite(&bzerr,b,buf,len);
1435 if(bzerr == BZ_OK){ 1490 if(bzerr == BZ_OK){
1436 return len; 1491 return len;
1437 }else{ 1492 }else{
@@ -1441,7 +1496,7 @@ int BZ_API(bzwrite) (BZFILE* b, void* buf, int len )
1441 1496
1442 1497
1443/*---------------------------------------------------*/ 1498/*---------------------------------------------------*/
1444int BZ_API(bzflush) (BZFILE *b) 1499int BZ_API(BZ2_bzflush) (BZFILE *b)
1445{ 1500{
1446 /* do nothing now... */ 1501 /* do nothing now... */
1447 return 0; 1502 return 0;
@@ -1449,19 +1504,19 @@ int BZ_API(bzflush) (BZFILE *b)
1449 1504
1450 1505
1451/*---------------------------------------------------*/ 1506/*---------------------------------------------------*/
1452void BZ_API(bzclose) (BZFILE* b) 1507void BZ_API(BZ2_bzclose) (BZFILE* b)
1453{ 1508{
1454 int bzerr; 1509 int bzerr;
1455 FILE *fp = ((bzFile *)b)->handle; 1510 FILE *fp = ((bzFile *)b)->handle;
1456 1511
1457 if (b==NULL) {return;} 1512 if (b==NULL) {return;}
1458 if(((bzFile*)b)->writing){ 1513 if(((bzFile*)b)->writing){
1459 bzWriteClose(&bzerr,b,0,NULL,NULL); 1514 BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
1460 if(bzerr != BZ_OK){ 1515 if(bzerr != BZ_OK){
1461 bzWriteClose(NULL,b,1,NULL,NULL); 1516 BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
1462 } 1517 }
1463 }else{ 1518 }else{
1464 bzReadClose(&bzerr,b); 1519 BZ2_bzReadClose(&bzerr,b);
1465 } 1520 }
1466 if(fp!=stdin && fp!=stdout){ 1521 if(fp!=stdin && fp!=stdout){
1467 fclose(fp); 1522 fclose(fp);
@@ -1483,6 +1538,7 @@ static char *bzerrorstrings[] = {
1483 ,"IO_ERROR" 1538 ,"IO_ERROR"
1484 ,"UNEXPECTED_EOF" 1539 ,"UNEXPECTED_EOF"
1485 ,"OUTBUFF_FULL" 1540 ,"OUTBUFF_FULL"
1541 ,"CONFIG_ERROR"
1486 ,"???" /* for future */ 1542 ,"???" /* for future */
1487 ,"???" /* for future */ 1543 ,"???" /* for future */
1488 ,"???" /* for future */ 1544 ,"???" /* for future */
@@ -1492,7 +1548,7 @@ static char *bzerrorstrings[] = {
1492}; 1548};
1493 1549
1494 1550
1495const char * BZ_API(bzerror) (BZFILE *b, int *errnum) 1551const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
1496{ 1552{
1497 int err = ((bzFile *)b)->lastErr; 1553 int err = ((bzFile *)b)->lastErr;
1498 1554
diff --git a/bzlib.h b/bzlib.h
index d74938d..c9447a2 100644
--- a/bzlib.h
+++ b/bzlib.h
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -83,16 +83,19 @@ extern "C" {
83#define BZ_IO_ERROR (-6) 83#define BZ_IO_ERROR (-6)
84#define BZ_UNEXPECTED_EOF (-7) 84#define BZ_UNEXPECTED_EOF (-7)
85#define BZ_OUTBUFF_FULL (-8) 85#define BZ_OUTBUFF_FULL (-8)
86#define BZ_CONFIG_ERROR (-9)
86 87
87typedef 88typedef
88 struct { 89 struct {
89 char *next_in; 90 char *next_in;
90 unsigned int avail_in; 91 unsigned int avail_in;
91 unsigned int total_in; 92 unsigned int total_in_lo32;
93 unsigned int total_in_hi32;
92 94
93 char *next_out; 95 char *next_out;
94 unsigned int avail_out; 96 unsigned int avail_out;
95 unsigned int total_out; 97 unsigned int total_out_lo32;
98 unsigned int total_out_hi32;
96 99
97 void *state; 100 void *state;
98 101
@@ -130,33 +133,33 @@ typedef
130 133
131/*-- Core (low-level) library functions --*/ 134/*-- Core (low-level) library functions --*/
132 135
133BZ_EXTERN int BZ_API(bzCompressInit) ( 136BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
134 bz_stream* strm, 137 bz_stream* strm,
135 int blockSize100k, 138 int blockSize100k,
136 int verbosity, 139 int verbosity,
137 int workFactor 140 int workFactor
138 ); 141 );
139 142
140BZ_EXTERN int BZ_API(bzCompress) ( 143BZ_EXTERN int BZ_API(BZ2_bzCompress) (
141 bz_stream* strm, 144 bz_stream* strm,
142 int action 145 int action
143 ); 146 );
144 147
145BZ_EXTERN int BZ_API(bzCompressEnd) ( 148BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
146 bz_stream* strm 149 bz_stream* strm
147 ); 150 );
148 151
149BZ_EXTERN int BZ_API(bzDecompressInit) ( 152BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
150 bz_stream *strm, 153 bz_stream *strm,
151 int verbosity, 154 int verbosity,
152 int small 155 int small
153 ); 156 );
154 157
155BZ_EXTERN int BZ_API(bzDecompress) ( 158BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
156 bz_stream* strm 159 bz_stream* strm
157 ); 160 );
158 161
159BZ_EXTERN int BZ_API(bzDecompressEnd) ( 162BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
160 bz_stream *strm 163 bz_stream *strm
161 ); 164 );
162 165
@@ -169,7 +172,7 @@ BZ_EXTERN int BZ_API(bzDecompressEnd) (
169 172
170typedef void BZFILE; 173typedef void BZFILE;
171 174
172BZ_EXTERN BZFILE* BZ_API(bzReadOpen) ( 175BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
173 int* bzerror, 176 int* bzerror,
174 FILE* f, 177 FILE* f,
175 int verbosity, 178 int verbosity,
@@ -178,26 +181,26 @@ BZ_EXTERN BZFILE* BZ_API(bzReadOpen) (
178 int nUnused 181 int nUnused
179 ); 182 );
180 183
181BZ_EXTERN void BZ_API(bzReadClose) ( 184BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
182 int* bzerror, 185 int* bzerror,
183 BZFILE* b 186 BZFILE* b
184 ); 187 );
185 188
186BZ_EXTERN void BZ_API(bzReadGetUnused) ( 189BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
187 int* bzerror, 190 int* bzerror,
188 BZFILE* b, 191 BZFILE* b,
189 void** unused, 192 void** unused,
190 int* nUnused 193 int* nUnused
191 ); 194 );
192 195
193BZ_EXTERN int BZ_API(bzRead) ( 196BZ_EXTERN int BZ_API(BZ2_bzRead) (
194 int* bzerror, 197 int* bzerror,
195 BZFILE* b, 198 BZFILE* b,
196 void* buf, 199 void* buf,
197 int len 200 int len
198 ); 201 );
199 202
200BZ_EXTERN BZFILE* BZ_API(bzWriteOpen) ( 203BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
201 int* bzerror, 204 int* bzerror,
202 FILE* f, 205 FILE* f,
203 int blockSize100k, 206 int blockSize100k,
@@ -205,26 +208,36 @@ BZ_EXTERN BZFILE* BZ_API(bzWriteOpen) (
205 int workFactor 208 int workFactor
206 ); 209 );
207 210
208BZ_EXTERN void BZ_API(bzWrite) ( 211BZ_EXTERN void BZ_API(BZ2_bzWrite) (
209 int* bzerror, 212 int* bzerror,
210 BZFILE* b, 213 BZFILE* b,
211 void* buf, 214 void* buf,
212 int len 215 int len
213 ); 216 );
214 217
215BZ_EXTERN void BZ_API(bzWriteClose) ( 218BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
216 int* bzerror, 219 int* bzerror,
217 BZFILE* b, 220 BZFILE* b,
218 int abandon, 221 int abandon,
219 unsigned int* nbytes_in, 222 unsigned int* nbytes_in,
220 unsigned int* nbytes_out 223 unsigned int* nbytes_out
221 ); 224 );
225
226BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
227 int* bzerror,
228 BZFILE* b,
229 int abandon,
230 unsigned int* nbytes_in_lo32,
231 unsigned int* nbytes_in_hi32,
232 unsigned int* nbytes_out_lo32,
233 unsigned int* nbytes_out_hi32
234 );
222#endif 235#endif
223 236
224 237
225/*-- Utility functions --*/ 238/*-- Utility functions --*/
226 239
227BZ_EXTERN int BZ_API(bzBuffToBuffCompress) ( 240BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
228 char* dest, 241 char* dest,
229 unsigned int* destLen, 242 unsigned int* destLen,
230 char* source, 243 char* source,
@@ -234,7 +247,7 @@ BZ_EXTERN int BZ_API(bzBuffToBuffCompress) (
234 int workFactor 247 int workFactor
235 ); 248 );
236 249
237BZ_EXTERN int BZ_API(bzBuffToBuffDecompress) ( 250BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
238 char* dest, 251 char* dest,
239 unsigned int* destLen, 252 unsigned int* destLen,
240 char* source, 253 char* source,
@@ -254,42 +267,42 @@ BZ_EXTERN int BZ_API(bzBuffToBuffDecompress) (
254 If this code breaks, please contact both Yoshioka and me. 267 If this code breaks, please contact both Yoshioka and me.
255--*/ 268--*/
256 269
257BZ_EXTERN const char * BZ_API(bzlibVersion) ( 270BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
258 void 271 void
259 ); 272 );
260 273
261#ifndef BZ_NO_STDIO 274#ifndef BZ_NO_STDIO
262BZ_EXTERN BZFILE * BZ_API(bzopen) ( 275BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
263 const char *path, 276 const char *path,
264 const char *mode 277 const char *mode
265 ); 278 );
266 279
267BZ_EXTERN BZFILE * BZ_API(bzdopen) ( 280BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
268 int fd, 281 int fd,
269 const char *mode 282 const char *mode
270 ); 283 );
271 284
272BZ_EXTERN int BZ_API(bzread) ( 285BZ_EXTERN int BZ_API(BZ2_bzread) (
273 BZFILE* b, 286 BZFILE* b,
274 void* buf, 287 void* buf,
275 int len 288 int len
276 ); 289 );
277 290
278BZ_EXTERN int BZ_API(bzwrite) ( 291BZ_EXTERN int BZ_API(BZ2_bzwrite) (
279 BZFILE* b, 292 BZFILE* b,
280 void* buf, 293 void* buf,
281 int len 294 int len
282 ); 295 );
283 296
284BZ_EXTERN int BZ_API(bzflush) ( 297BZ_EXTERN int BZ_API(BZ2_bzflush) (
285 BZFILE* b 298 BZFILE* b
286 ); 299 );
287 300
288BZ_EXTERN void BZ_API(bzclose) ( 301BZ_EXTERN void BZ_API(BZ2_bzclose) (
289 BZFILE* b 302 BZFILE* b
290 ); 303 );
291 304
292BZ_EXTERN const char * BZ_API(bzerror) ( 305BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
293 BZFILE *b, 306 BZFILE *b,
294 int *errnum 307 int *errnum
295 ); 308 );
diff --git a/bzlib_private.h b/bzlib_private.h
index 8e93480..fb51c7a 100644
--- a/bzlib_private.h
+++ b/bzlib_private.h
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -76,7 +76,7 @@
76 76
77/*-- General stuff. --*/ 77/*-- General stuff. --*/
78 78
79#define BZ_VERSION "0.9.5d" 79#define BZ_VERSION "1.0.1, 23-June-2000"
80 80
81typedef char Char; 81typedef char Char;
82typedef unsigned char Bool; 82typedef unsigned char Bool;
@@ -94,9 +94,9 @@ typedef unsigned short UInt16;
94#endif 94#endif
95 95
96#ifndef BZ_NO_STDIO 96#ifndef BZ_NO_STDIO
97extern void bz__AssertH__fail ( int errcode ); 97extern void BZ2_bz__AssertH__fail ( int errcode );
98#define AssertH(cond,errcode) \ 98#define AssertH(cond,errcode) \
99 { if (!(cond)) bz__AssertH__fail ( errcode ); } 99 { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
100#if BZ_DEBUG 100#if BZ_DEBUG
101#define AssertD(cond,msg) \ 101#define AssertD(cond,msg) \
102 { if (!(cond)) { \ 102 { if (!(cond)) { \
@@ -155,7 +155,7 @@ extern void bz_internal_error ( int errcode );
155 155
156/*-- Stuff for randomising repetitive blocks. --*/ 156/*-- Stuff for randomising repetitive blocks. --*/
157 157
158extern Int32 rNums[512]; 158extern Int32 BZ2_rNums[512];
159 159
160#define BZ_RAND_DECLS \ 160#define BZ_RAND_DECLS \
161 Int32 rNToGo; \ 161 Int32 rNToGo; \
@@ -169,7 +169,7 @@ extern Int32 rNums[512];
169 169
170#define BZ_RAND_UPD_MASK \ 170#define BZ_RAND_UPD_MASK \
171 if (s->rNToGo == 0) { \ 171 if (s->rNToGo == 0) { \
172 s->rNToGo = rNums[s->rTPos]; \ 172 s->rNToGo = BZ2_rNums[s->rTPos]; \
173 s->rTPos++; \ 173 s->rTPos++; \
174 if (s->rTPos == 512) s->rTPos = 0; \ 174 if (s->rTPos == 512) s->rTPos = 0; \
175 } \ 175 } \
@@ -179,7 +179,7 @@ extern Int32 rNums[512];
179 179
180/*-- Stuff for doing CRCs. --*/ 180/*-- Stuff for doing CRCs. --*/
181 181
182extern UInt32 crc32Table[256]; 182extern UInt32 BZ2_crc32Table[256];
183 183
184#define BZ_INITIALISE_CRC(crcVar) \ 184#define BZ_INITIALISE_CRC(crcVar) \
185{ \ 185{ \
@@ -194,8 +194,8 @@ extern UInt32 crc32Table[256];
194#define BZ_UPDATE_CRC(crcVar,cha) \ 194#define BZ_UPDATE_CRC(crcVar,cha) \
195{ \ 195{ \
196 crcVar = (crcVar << 8) ^ \ 196 crcVar = (crcVar << 8) ^ \
197 crc32Table[(crcVar >> 24) ^ \ 197 BZ2_crc32Table[(crcVar >> 24) ^ \
198 ((UChar)cha)]; \ 198 ((UChar)cha)]; \
199} 199}
200 200
201 201
@@ -241,7 +241,7 @@ typedef
241 241
242 /* aliases for arr1 and arr2 */ 242 /* aliases for arr1 and arr2 */
243 UInt32* ptr; 243 UInt32* ptr;
244 UInt16* block; 244 UChar* block;
245 UInt16* mtfv; 245 UInt16* mtfv;
246 UChar* zbits; 246 UChar* zbits;
247 247
@@ -283,9 +283,11 @@ typedef
283 UChar selector [BZ_MAX_SELECTORS]; 283 UChar selector [BZ_MAX_SELECTORS];
284 UChar selectorMtf[BZ_MAX_SELECTORS]; 284 UChar selectorMtf[BZ_MAX_SELECTORS];
285 285
286 UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 286 UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
287 Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 287 Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
288 Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; 288 Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
289 /* second dimension: only 3 needed; 4 makes index calculations faster */
290 UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
289 291
290 } 292 }
291 EState; 293 EState;
@@ -295,19 +297,19 @@ typedef
295/*-- externs for compression. --*/ 297/*-- externs for compression. --*/
296 298
297extern void 299extern void
298blockSort ( EState* ); 300BZ2_blockSort ( EState* );
299 301
300extern void 302extern void
301compressBlock ( EState*, Bool ); 303BZ2_compressBlock ( EState*, Bool );
302 304
303extern void 305extern void
304bsInitWrite ( EState* ); 306BZ2_bsInitWrite ( EState* );
305 307
306extern void 308extern void
307hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); 309BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
308 310
309extern void 311extern void
310hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); 312BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
311 313
312 314
313 315
@@ -493,22 +495,22 @@ typedef
493#define GET_LL(i) \ 495#define GET_LL(i) \
494 (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) 496 (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
495 497
496#define BZ_GET_SMALL(cccc) \ 498#define BZ_GET_SMALL(cccc) \
497 cccc = indexIntoF ( s->tPos, s->cftab ); \ 499 cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
498 s->tPos = GET_LL(s->tPos); 500 s->tPos = GET_LL(s->tPos);
499 501
500 502
501/*-- externs for decompression. --*/ 503/*-- externs for decompression. --*/
502 504
503extern Int32 505extern Int32
504indexIntoF ( Int32, Int32* ); 506BZ2_indexIntoF ( Int32, Int32* );
505 507
506extern Int32 508extern Int32
507decompress ( DState* ); 509BZ2_decompress ( DState* );
508 510
509extern void 511extern void
510hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, 512BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
511 Int32, Int32, Int32 ); 513 Int32, Int32, Int32 );
512 514
513 515
514#endif 516#endif
diff --git a/compress.c b/compress.c
index 7b192c3..cc5e31d 100644
--- a/compress.c
+++ b/compress.c
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -78,7 +78,7 @@
78/*---------------------------------------------------*/ 78/*---------------------------------------------------*/
79 79
80/*---------------------------------------------------*/ 80/*---------------------------------------------------*/
81void bsInitWrite ( EState* s ) 81void BZ2_bsInitWrite ( EState* s )
82{ 82{
83 s->bsLive = 0; 83 s->bsLive = 0;
84 s->bsBuff = 0; 84 s->bsBuff = 0;
@@ -113,6 +113,7 @@ void bsFinishWrite ( EState* s )
113 113
114/*---------------------------------------------------*/ 114/*---------------------------------------------------*/
115static 115static
116__inline__
116void bsW ( EState* s, Int32 n, UInt32 v ) 117void bsW ( EState* s, Int32 n, UInt32 v )
117{ 118{
118 bsNEEDW ( n ); 119 bsNEEDW ( n );
@@ -164,8 +165,6 @@ void generateMTFValues ( EState* s )
164{ 165{
165 UChar yy[256]; 166 UChar yy[256];
166 Int32 i, j; 167 Int32 i, j;
167 UChar tmp;
168 UChar tmp2;
169 Int32 zPend; 168 Int32 zPend;
170 Int32 wr; 169 Int32 wr;
171 Int32 EOB; 170 Int32 EOB;
@@ -174,7 +173,7 @@ void generateMTFValues ( EState* s )
174 After sorting (eg, here), 173 After sorting (eg, here),
175 s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, 174 s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
176 and 175 and
177 ((UInt16*)s->arr2) [ 0 .. s->nblock-1 ] [15:8] 176 ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
178 holds the original block data. 177 holds the original block data.
179 178
180 The first thing to do is generate the MTF values, 179 The first thing to do is generate the MTF values,
@@ -186,14 +185,14 @@ void generateMTFValues ( EState* s )
186 185
187 The final compressed bitstream is generated into the 186 The final compressed bitstream is generated into the
188 area starting at 187 area starting at
189 (UChar*) (&((UInt16)s->arr2)[s->nblock]) 188 (UChar*) (&((UChar*)s->arr2)[s->nblock])
190 189
191 These storage aliases are set up in bzCompressInit(), 190 These storage aliases are set up in bzCompressInit(),
192 except for the last one, which is arranged in 191 except for the last one, which is arranged in
193 compressBlock(). 192 compressBlock().
194 */ 193 */
195 UInt32* ptr = s->ptr; 194 UInt32* ptr = s->ptr;
196 UInt16* block = s->block; 195 UChar* block = s->block;
197 UInt16* mtfv = s->mtfv; 196 UInt16* mtfv = s->mtfv;
198 197
199 makeMaps_e ( s ); 198 makeMaps_e ( s );
@@ -207,27 +206,14 @@ void generateMTFValues ( EState* s )
207 206
208 for (i = 0; i < s->nblock; i++) { 207 for (i = 0; i < s->nblock; i++) {
209 UChar ll_i; 208 UChar ll_i;
210
211 AssertD ( wr <= i, "generateMTFValues(1)" ); 209 AssertD ( wr <= i, "generateMTFValues(1)" );
212 j = ptr[i]-1; if (j < 0) j += s->nblock; 210 j = ptr[i]-1; if (j < 0) j += s->nblock;
213 ll_i = s->unseqToSeq[block[j] >> 8]; 211 ll_i = s->unseqToSeq[block[j]];
214 AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); 212 AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
215 213
216 tmp = yy[0]; 214 if (yy[0] == ll_i) {
217 if (tmp == ll_i) {
218 zPend++; 215 zPend++;
219 } else { 216 } else {
220 tmp2 = tmp;
221 tmp = yy[1];
222 yy[1] = tmp2;
223 j = 1;
224 while ( ll_i != tmp ) {
225 j++;
226 tmp2 = tmp;
227 tmp = yy[j];
228 yy[j] = tmp2;
229 };
230 yy[0] = tmp;
231 217
232 if (zPend > 0) { 218 if (zPend > 0) {
233 zPend--; 219 zPend--;
@@ -244,7 +230,26 @@ void generateMTFValues ( EState* s )
244 }; 230 };
245 zPend = 0; 231 zPend = 0;
246 } 232 }
247 mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; 233 {
234 register UChar rtmp;
235 register UChar* ryy_j;
236 register UChar rll_i;
237 rtmp = yy[1];
238 yy[1] = yy[0];
239 ryy_j = &(yy[1]);
240 rll_i = ll_i;
241 while ( rll_i != rtmp ) {
242 register UChar rtmp2;
243 ryy_j++;
244 rtmp2 = rtmp;
245 rtmp = *ryy_j;
246 *ryy_j = rtmp2;
247 };
248 yy[0] = rtmp;
249 j = ryy_j - &(yy[0]);
250 mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
251 }
252
248 } 253 }
249 } 254 }
250 255
@@ -261,6 +266,7 @@ void generateMTFValues ( EState* s )
261 if (zPend < 2) break; 266 if (zPend < 2) break;
262 zPend = (zPend - 2) / 2; 267 zPend = (zPend - 2) / 2;
263 }; 268 };
269 zPend = 0;
264 } 270 }
265 271
266 mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; 272 mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
@@ -365,6 +371,18 @@ void sendMTFValues ( EState* s )
365 for (v = 0; v < alphaSize; v++) 371 for (v = 0; v < alphaSize; v++)
366 s->rfreq[t][v] = 0; 372 s->rfreq[t][v] = 0;
367 373
374 /*---
375 Set up an auxiliary length table which is used to fast-track
376 the common case (nGroups == 6).
377 ---*/
378 if (nGroups == 6) {
379 for (v = 0; v < alphaSize; v++) {
380 s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
381 s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
382 s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
383 }
384 }
385
368 nSelectors = 0; 386 nSelectors = 0;
369 totc = 0; 387 totc = 0;
370 gs = 0; 388 gs = 0;
@@ -381,21 +399,37 @@ void sendMTFValues ( EState* s )
381 --*/ 399 --*/
382 for (t = 0; t < nGroups; t++) cost[t] = 0; 400 for (t = 0; t < nGroups; t++) cost[t] = 0;
383 401
384 if (nGroups == 6) { 402 if (nGroups == 6 && 50 == ge-gs+1) {
385 register UInt16 cost0, cost1, cost2, cost3, cost4, cost5; 403 /*--- fast track the common case ---*/
386 cost0 = cost1 = cost2 = cost3 = cost4 = cost5 = 0; 404 register UInt32 cost01, cost23, cost45;
387 for (i = gs; i <= ge; i++) { 405 register UInt16 icv;
388 UInt16 icv = mtfv[i]; 406 cost01 = cost23 = cost45 = 0;
389 cost0 += s->len[0][icv]; 407
390 cost1 += s->len[1][icv]; 408# define BZ_ITER(nn) \
391 cost2 += s->len[2][icv]; 409 icv = mtfv[gs+(nn)]; \
392 cost3 += s->len[3][icv]; 410 cost01 += s->len_pack[icv][0]; \
393 cost4 += s->len[4][icv]; 411 cost23 += s->len_pack[icv][1]; \
394 cost5 += s->len[5][icv]; 412 cost45 += s->len_pack[icv][2]; \
395 } 413
396 cost[0] = cost0; cost[1] = cost1; cost[2] = cost2; 414 BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
397 cost[3] = cost3; cost[4] = cost4; cost[5] = cost5; 415 BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
416 BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
417 BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
418 BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
419 BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
420 BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
421 BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
422 BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
423 BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
424
425# undef BZ_ITER
426
427 cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
428 cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
429 cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
430
398 } else { 431 } else {
432 /*--- slow version which correctly handles all situations ---*/
399 for (i = gs; i <= ge; i++) { 433 for (i = gs; i <= ge; i++) {
400 UInt16 icv = mtfv[i]; 434 UInt16 icv = mtfv[i];
401 for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; 435 for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
@@ -417,8 +451,29 @@ void sendMTFValues ( EState* s )
417 /*-- 451 /*--
418 Increment the symbol frequencies for the selected table. 452 Increment the symbol frequencies for the selected table.
419 --*/ 453 --*/
420 for (i = gs; i <= ge; i++) 454 if (nGroups == 6 && 50 == ge-gs+1) {
421 s->rfreq[bt][ mtfv[i] ]++; 455 /*--- fast track the common case ---*/
456
457# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
458
459 BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
460 BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
461 BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
462 BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
463 BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
464 BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
465 BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
466 BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
467 BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
468 BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
469
470# undef BZ_ITUR
471
472 } else {
473 /*--- slow version which correctly handles all situations ---*/
474 for (i = gs; i <= ge; i++)
475 s->rfreq[bt][ mtfv[i] ]++;
476 }
422 477
423 gs = ge+1; 478 gs = ge+1;
424 } 479 }
@@ -434,8 +489,8 @@ void sendMTFValues ( EState* s )
434 Recompute the tables based on the accumulated frequencies. 489 Recompute the tables based on the accumulated frequencies.
435 --*/ 490 --*/
436 for (t = 0; t < nGroups; t++) 491 for (t = 0; t < nGroups; t++)
437 hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 492 BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
438 alphaSize, 20 ); 493 alphaSize, 20 );
439 } 494 }
440 495
441 496
@@ -474,8 +529,8 @@ void sendMTFValues ( EState* s )
474 } 529 }
475 AssertH ( !(maxLen > 20), 3004 ); 530 AssertH ( !(maxLen > 20), 3004 );
476 AssertH ( !(minLen < 1), 3005 ); 531 AssertH ( !(minLen < 1), 3005 );
477 hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 532 BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
478 minLen, maxLen, alphaSize ); 533 minLen, maxLen, alphaSize );
479 } 534 }
480 535
481 /*--- Transmit the mapping table. ---*/ 536 /*--- Transmit the mapping table. ---*/
@@ -536,13 +591,45 @@ void sendMTFValues ( EState* s )
536 if (gs >= s->nMTF) break; 591 if (gs >= s->nMTF) break;
537 ge = gs + BZ_G_SIZE - 1; 592 ge = gs + BZ_G_SIZE - 1;
538 if (ge >= s->nMTF) ge = s->nMTF-1; 593 if (ge >= s->nMTF) ge = s->nMTF-1;
539 for (i = gs; i <= ge; i++) { 594 AssertH ( s->selector[selCtr] < nGroups, 3006 );
540 AssertH ( s->selector[selCtr] < nGroups, 3006 ); 595
541 bsW ( s, 596 if (nGroups == 6 && 50 == ge-gs+1) {
542 s->len [s->selector[selCtr]] [mtfv[i]], 597 /*--- fast track the common case ---*/
543 s->code [s->selector[selCtr]] [mtfv[i]] ); 598 UInt16 mtfv_i;
599 UChar* s_len_sel_selCtr
600 = &(s->len[s->selector[selCtr]][0]);
601 Int32* s_code_sel_selCtr
602 = &(s->code[s->selector[selCtr]][0]);
603
604# define BZ_ITAH(nn) \
605 mtfv_i = mtfv[gs+(nn)]; \
606 bsW ( s, \
607 s_len_sel_selCtr[mtfv_i], \
608 s_code_sel_selCtr[mtfv_i] )
609
610 BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
611 BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
612 BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
613 BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
614 BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
615 BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
616 BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
617 BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
618 BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
619 BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
620
621# undef BZ_ITAH
622
623 } else {
624 /*--- slow version which correctly handles all situations ---*/
625 for (i = gs; i <= ge; i++) {
626 bsW ( s,
627 s->len [s->selector[selCtr]] [mtfv[i]],
628 s->code [s->selector[selCtr]] [mtfv[i]] );
629 }
544 } 630 }
545 631
632
546 gs = ge+1; 633 gs = ge+1;
547 selCtr++; 634 selCtr++;
548 } 635 }
@@ -554,7 +641,7 @@ void sendMTFValues ( EState* s )
554 641
555 642
556/*---------------------------------------------------*/ 643/*---------------------------------------------------*/
557void compressBlock ( EState* s, Bool is_last_block ) 644void BZ2_compressBlock ( EState* s, Bool is_last_block )
558{ 645{
559 if (s->nblock > 0) { 646 if (s->nblock > 0) {
560 647
@@ -568,14 +655,14 @@ void compressBlock ( EState* s, Bool is_last_block )
568 "combined CRC = 0x%8x, size = %d\n", 655 "combined CRC = 0x%8x, size = %d\n",
569 s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); 656 s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
570 657
571 blockSort ( s ); 658 BZ2_blockSort ( s );
572 } 659 }
573 660
574 s->zbits = (UChar*) (&((UInt16*)s->arr2)[s->nblock]); 661 s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
575 662
576 /*-- If this is the first block, create the stream header. --*/ 663 /*-- If this is the first block, create the stream header. --*/
577 if (s->blockNo == 1) { 664 if (s->blockNo == 1) {
578 bsInitWrite ( s ); 665 BZ2_bsInitWrite ( s );
579 bsPutUChar ( s, 'B' ); 666 bsPutUChar ( s, 'B' );
580 bsPutUChar ( s, 'Z' ); 667 bsPutUChar ( s, 'Z' );
581 bsPutUChar ( s, 'h' ); 668 bsPutUChar ( s, 'h' );
diff --git a/crctable.c b/crctable.c
index ab53df6..61c040c 100644
--- a/crctable.c
+++ b/crctable.c
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -68,7 +68,7 @@
68 comp.compression FAQ. 68 comp.compression FAQ.
69--*/ 69--*/
70 70
71UInt32 crc32Table[256] = { 71UInt32 BZ2_crc32Table[256] = {
72 72
73 /*-- Ugly, innit? --*/ 73 /*-- Ugly, innit? --*/
74 74
diff --git a/decompress.c b/decompress.c
index 31f8b67..cdced18 100644
--- a/decompress.c
+++ b/decompress.c
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -99,7 +99,9 @@ void makeMaps_d ( DState* s )
99 s->bsLive += 8; \ 99 s->bsLive += 8; \
100 s->strm->next_in++; \ 100 s->strm->next_in++; \
101 s->strm->avail_in--; \ 101 s->strm->avail_in--; \
102 s->strm->total_in++; \ 102 s->strm->total_in_lo32++; \
103 if (s->strm->total_in_lo32 == 0) \
104 s->strm->total_in_hi32++; \
103 } 105 }
104 106
105#define GET_UCHAR(lll,uuu) \ 107#define GET_UCHAR(lll,uuu) \
@@ -113,6 +115,8 @@ void makeMaps_d ( DState* s )
113{ \ 115{ \
114 if (groupPos == 0) { \ 116 if (groupPos == 0) { \
115 groupNo++; \ 117 groupNo++; \
118 if (groupNo >= nSelectors) \
119 RETURN(BZ_DATA_ERROR); \
116 groupPos = BZ_G_SIZE; \ 120 groupPos = BZ_G_SIZE; \
117 gSel = s->selector[groupNo]; \ 121 gSel = s->selector[groupNo]; \
118 gMinlen = s->minLens[gSel]; \ 122 gMinlen = s->minLens[gSel]; \
@@ -123,17 +127,23 @@ void makeMaps_d ( DState* s )
123 groupPos--; \ 127 groupPos--; \
124 zn = gMinlen; \ 128 zn = gMinlen; \
125 GET_BITS(label1, zvec, zn); \ 129 GET_BITS(label1, zvec, zn); \
126 while (zvec > gLimit[zn]) { \ 130 while (1) { \
131 if (zn > 20 /* the longest code */) \
132 RETURN(BZ_DATA_ERROR); \
133 if (zvec <= gLimit[zn]) break; \
127 zn++; \ 134 zn++; \
128 GET_BIT(label2, zj); \ 135 GET_BIT(label2, zj); \
129 zvec = (zvec << 1) | zj; \ 136 zvec = (zvec << 1) | zj; \
130 }; \ 137 }; \
138 if (zvec - gBase[zn] < 0 \
139 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
140 RETURN(BZ_DATA_ERROR); \
131 lval = gPerm[zvec - gBase[zn]]; \ 141 lval = gPerm[zvec - gBase[zn]]; \
132} 142}
133 143
134 144
135/*---------------------------------------------------*/ 145/*---------------------------------------------------*/
136Int32 decompress ( DState* s ) 146Int32 BZ2_decompress ( DState* s )
137{ 147{
138 UChar uc; 148 UChar uc;
139 Int32 retVal; 149 Int32 retVal;
@@ -288,6 +298,11 @@ Int32 decompress ( DState* s )
288 GET_UCHAR(BZ_X_ORIGPTR_3, uc); 298 GET_UCHAR(BZ_X_ORIGPTR_3, uc);
289 s->origPtr = (s->origPtr << 8) | ((Int32)uc); 299 s->origPtr = (s->origPtr << 8) | ((Int32)uc);
290 300
301 if (s->origPtr < 0)
302 RETURN(BZ_DATA_ERROR);
303 if (s->origPtr > 10 + 100000*s->blockSize100k)
304 RETURN(BZ_DATA_ERROR);
305
291 /*--- Receive the mapping table ---*/ 306 /*--- Receive the mapping table ---*/
292 for (i = 0; i < 16; i++) { 307 for (i = 0; i < 16; i++) {
293 GET_BIT(BZ_X_MAPPING_1, uc); 308 GET_BIT(BZ_X_MAPPING_1, uc);
@@ -305,18 +320,21 @@ Int32 decompress ( DState* s )
305 if (uc == 1) s->inUse[i * 16 + j] = True; 320 if (uc == 1) s->inUse[i * 16 + j] = True;
306 } 321 }
307 makeMaps_d ( s ); 322 makeMaps_d ( s );
323 if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
308 alphaSize = s->nInUse+2; 324 alphaSize = s->nInUse+2;
309 325
310 /*--- Now the selectors ---*/ 326 /*--- Now the selectors ---*/
311 GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); 327 GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
328 if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
312 GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); 329 GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
330 if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
313 for (i = 0; i < nSelectors; i++) { 331 for (i = 0; i < nSelectors; i++) {
314 j = 0; 332 j = 0;
315 while (True) { 333 while (True) {
316 GET_BIT(BZ_X_SELECTOR_3, uc); 334 GET_BIT(BZ_X_SELECTOR_3, uc);
317 if (uc == 0) break; 335 if (uc == 0) break;
318 j++; 336 j++;
319 if (j > 5) RETURN(BZ_DATA_ERROR); 337 if (j >= nGroups) RETURN(BZ_DATA_ERROR);
320 } 338 }
321 s->selectorMtf[i] = j; 339 s->selectorMtf[i] = j;
322 } 340 }
@@ -358,7 +376,7 @@ Int32 decompress ( DState* s )
358 if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; 376 if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
359 if (s->len[t][i] < minLen) minLen = s->len[t][i]; 377 if (s->len[t][i] < minLen) minLen = s->len[t][i];
360 } 378 }
361 hbCreateDecodeTables ( 379 BZ2_hbCreateDecodeTables (
362 &(s->limit[t][0]), 380 &(s->limit[t][0]),
363 &(s->base[t][0]), 381 &(s->base[t][0]),
364 &(s->perm[t][0]), 382 &(s->perm[t][0]),
@@ -392,7 +410,6 @@ Int32 decompress ( DState* s )
392 /*-- end MTF init --*/ 410 /*-- end MTF init --*/
393 411
394 nblock = 0; 412 nblock = 0;
395
396 GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); 413 GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
397 414
398 while (True) { 415 while (True) {
@@ -417,23 +434,24 @@ Int32 decompress ( DState* s )
417 434
418 if (s->smallDecompress) 435 if (s->smallDecompress)
419 while (es > 0) { 436 while (es > 0) {
437 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
420 s->ll16[nblock] = (UInt16)uc; 438 s->ll16[nblock] = (UInt16)uc;
421 nblock++; 439 nblock++;
422 es--; 440 es--;
423 } 441 }
424 else 442 else
425 while (es > 0) { 443 while (es > 0) {
444 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
426 s->tt[nblock] = (UInt32)uc; 445 s->tt[nblock] = (UInt32)uc;
427 nblock++; 446 nblock++;
428 es--; 447 es--;
429 }; 448 };
430 449
431 if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR);
432 continue; 450 continue;
433 451
434 } else { 452 } else {
435 453
436 if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR); 454 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
437 455
438 /*-- uc = MTF ( nextSym-1 ) --*/ 456 /*-- uc = MTF ( nextSym-1 ) --*/
439 { 457 {
@@ -500,6 +518,12 @@ Int32 decompress ( DState* s )
500 } 518 }
501 } 519 }
502 520
521 /* Now we know what nblock is, we can do a better sanity
522 check on s->origPtr.
523 */
524 if (s->origPtr < 0 || s->origPtr >= nblock)
525 RETURN(BZ_DATA_ERROR);
526
503 s->state_out_len = 0; 527 s->state_out_len = 0;
504 s->state_out_ch = 0; 528 s->state_out_ch = 0;
505 BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); 529 BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
diff --git a/dlltest.c b/dlltest.c
index e5639f1..f79279c 100644
--- a/dlltest.c
+++ b/dlltest.c
@@ -1,165 +1,176 @@
1/* 1/*
2 minibz2 2 minibz2
3 libbz2.dll test program. 3 libbz2.dll test program.
4 by Yoshioka Tsuneo(QWF00133@nifty.ne.jp/tsuneo-y@is.aist-nara.ac.jp) 4 by Yoshioka Tsuneo(QWF00133@nifty.ne.jp/tsuneo-y@is.aist-nara.ac.jp)
5 This file is Public Domain. 5 This file is Public Domain.
6 welcome any email to me. 6 welcome any email to me.
7 7
8 usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename] 8 usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
9*/ 9*/
10 10
11#define BZ_IMPORT 11#define BZ_IMPORT
12#include <stdio.h> 12#include <stdio.h>
13#include <stdlib.h> 13#include <stdlib.h>
14#include "bzlib.h" 14#include "bzlib.h"
15#ifdef _WIN32 15#ifdef _WIN32
16#include <io.h> 16#include <io.h>
17#endif 17#endif
18 18
19 19
20#ifdef _WIN32 20#ifdef _WIN32
21 21
22#include <windows.h> 22#define BZ2_LIBNAME "libbz2-1.0.0.DLL"
23static int BZ2DLLLoaded = 0; 23
24static HINSTANCE BZ2DLLhLib; 24#include <windows.h>
25int BZ2DLLLoadLibrary(void) 25static int BZ2DLLLoaded = 0;
26{ 26static HINSTANCE BZ2DLLhLib;
27 HINSTANCE hLib; 27int BZ2DLLLoadLibrary(void)
28 28{
29 if(BZ2DLLLoaded==1){return 0;} 29 HINSTANCE hLib;
30 hLib=LoadLibrary("libbz2.dll"); 30
31 if(hLib == NULL){ 31 if(BZ2DLLLoaded==1){return 0;}
32 puts("Can't load libbz2.dll"); 32 hLib=LoadLibrary(BZ2_LIBNAME);
33 return -1; 33 if(hLib == NULL){
34 } 34 fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
35 BZ2DLLLoaded=1; 35 return -1;
36 BZ2DLLhLib=hLib; 36 }
37 bzlibVersion=GetProcAddress(hLib,"bzlibVersion"); 37 BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
38 bzopen=GetProcAddress(hLib,"bzopen"); 38 BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
39 bzdopen=GetProcAddress(hLib,"bzdopen"); 39 BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
40 bzread=GetProcAddress(hLib,"bzread"); 40 BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
41 bzwrite=GetProcAddress(hLib,"bzwrite"); 41 BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
42 bzflush=GetProcAddress(hLib,"bzflush"); 42 BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
43 bzclose=GetProcAddress(hLib,"bzclose"); 43 BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
44 bzerror=GetProcAddress(hLib,"bzerror"); 44 BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
45 return 0; 45
46 46 if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
47} 47 || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
48int BZ2DLLFreeLibrary(void) 48 || !BZ2_bzclose || !BZ2_bzerror) {
49{ 49 fprintf(stderr,"GetProcAddress failed.\n");
50 if(BZ2DLLLoaded==0){return 0;} 50 return -1;
51 FreeLibrary(BZ2DLLhLib); 51 }
52 BZ2DLLLoaded=0; 52 BZ2DLLLoaded=1;
53} 53 BZ2DLLhLib=hLib;
54#endif /* WIN32 */ 54 return 0;
55 55
56void usage(void) 56}
57{ 57int BZ2DLLFreeLibrary(void)
58 puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]"); 58{
59} 59 if(BZ2DLLLoaded==0){return 0;}
60 60 FreeLibrary(BZ2DLLhLib);
61int main(int argc,char *argv[]) 61 BZ2DLLLoaded=0;
62{ 62}
63 int decompress = 0; 63#endif /* WIN32 */
64 int level = 9; 64
65 char *fn_r = NULL; 65void usage(void)
66 char *fn_w = NULL; 66{
67 67 puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
68#ifdef _WIN32 68}
69 if(BZ2DLLLoadLibrary()<0){ 69
70 puts("can't load dll"); 70int main(int argc,char *argv[])
71 exit(1); 71{
72 } 72 int decompress = 0;
73#endif 73 int level = 9;
74 while(++argv,--argc){ 74 char *fn_r = NULL;
75 if(**argv =='-' || **argv=='/'){ 75 char *fn_w = NULL;
76 char *p; 76
77 77#ifdef _WIN32
78 for(p=*argv+1;*p;p++){ 78 if(BZ2DLLLoadLibrary()<0){
79 if(*p=='d'){ 79 fprintf(stderr,"Loading of %s failed. Giving up.\n", BZ2_LIBNAME);
80 decompress = 1; 80 exit(1);
81 }else if('1'<=*p && *p<='9'){ 81 }
82 level = *p - '0'; 82 printf("Loading of %s succeeded. Library version is %s.\n",
83 }else{ 83 BZ2_LIBNAME, BZ2_bzlibVersion() );
84 usage(); 84#endif
85 exit(1); 85 while(++argv,--argc){
86 } 86 if(**argv =='-' || **argv=='/'){
87 } 87 char *p;
88 }else{ 88
89 break; 89 for(p=*argv+1;*p;p++){
90 } 90 if(*p=='d'){
91 } 91 decompress = 1;
92 if(argc>=1){ 92 }else if('1'<=*p && *p<='9'){
93 fn_r = *argv; 93 level = *p - '0';
94 argc--;argv++; 94 }else{
95 }else{ 95 usage();
96 fn_r = NULL; 96 exit(1);
97 } 97 }
98 if(argc>=1){ 98 }
99 fn_w = *argv; 99 }else{
100 argc--;argv++; 100 break;
101 }else{ 101 }
102 fn_w = NULL; 102 }
103 } 103 if(argc>=1){
104 { 104 fn_r = *argv;
105 int len; 105 argc--;argv++;
106 char buff[0x1000]; 106 }else{
107 char mode[10]; 107 fn_r = NULL;
108 108 }
109 if(decompress){ 109 if(argc>=1){
110 BZFILE *BZ2fp_r = NULL; 110 fn_w = *argv;
111 FILE *fp_w = NULL; 111 argc--;argv++;
112 112 }else{
113 if(fn_w){ 113 fn_w = NULL;
114 if((fp_w = fopen(fn_w,"wb"))==NULL){ 114 }
115 printf("can't open [%s]\n",fn_w); 115 {
116 perror("reason:"); 116 int len;
117 exit(1); 117 char buff[0x1000];
118 } 118 char mode[10];
119 }else{ 119
120 fp_w = stdout; 120 if(decompress){
121 } 121 BZFILE *BZ2fp_r = NULL;
122 if((BZ2fp_r == NULL && (BZ2fp_r = bzdopen(fileno(stdin),"rb"))==NULL) 122 FILE *fp_w = NULL;
123 || (BZ2fp_r != NULL && (BZ2fp_r = bzopen(fn_r,"rb"))==NULL)){ 123
124 printf("can't bz2openstream\n"); 124 if(fn_w){
125 exit(1); 125 if((fp_w = fopen(fn_w,"wb"))==NULL){
126 } 126 printf("can't open [%s]\n",fn_w);
127 while((len=bzread(BZ2fp_r,buff,0x1000))>0){ 127 perror("reason:");
128 fwrite(buff,1,len,fp_w); 128 exit(1);
129 } 129 }
130 bzclose(BZ2fp_r); 130 }else{
131 if(fp_w != stdout) fclose(fp_w); 131 fp_w = stdout;
132 }else{ 132 }
133 BZFILE *BZ2fp_w = NULL; 133 if((BZ2fp_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
134 FILE *fp_r = NULL; 134 || (BZ2fp_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
135 135 printf("can't bz2openstream\n");
136 if(fn_r){ 136 exit(1);
137 if((fp_r = fopen(fn_r,"rb"))==NULL){ 137 }
138 printf("can't open [%s]\n",fn_r); 138 while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
139 perror("reason:"); 139 fwrite(buff,1,len,fp_w);
140 exit(1); 140 }
141 } 141 BZ2_bzclose(BZ2fp_r);
142 }else{ 142 if(fp_w != stdout) fclose(fp_w);
143 fp_r = stdin; 143 }else{
144 } 144 BZFILE *BZ2fp_w = NULL;
145 mode[0]='w'; 145 FILE *fp_r = NULL;
146 mode[1] = '0' + level; 146
147 mode[2] = '\0'; 147 if(fn_r){
148 148 if((fp_r = fopen(fn_r,"rb"))==NULL){
149 if((fn_w == NULL && (BZ2fp_w = bzdopen(fileno(stdout),mode))==NULL) 149 printf("can't open [%s]\n",fn_r);
150 || (fn_w !=NULL && (BZ2fp_w = bzopen(fn_w,mode))==NULL)){ 150 perror("reason:");
151 printf("can't bz2openstream\n"); 151 exit(1);
152 exit(1); 152 }
153 } 153 }else{
154 while((len=fread(buff,1,0x1000,fp_r))>0){ 154 fp_r = stdin;
155 bzwrite(BZ2fp_w,buff,len); 155 }
156 } 156 mode[0]='w';
157 bzclose(BZ2fp_w); 157 mode[1] = '0' + level;
158 if(fp_r!=stdin)fclose(fp_r); 158 mode[2] = '\0';
159 } 159
160 } 160 if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
161#ifdef _WIN32 161 || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
162 BZ2DLLFreeLibrary(); 162 printf("can't bz2openstream\n");
163#endif 163 exit(1);
164 return 0; 164 }
165} 165 while((len=fread(buff,1,0x1000,fp_r))>0){
166 BZ2_bzwrite(BZ2fp_w,buff,len);
167 }
168 BZ2_bzclose(BZ2fp_w);
169 if(fp_r!=stdin)fclose(fp_r);
170 }
171 }
172#ifdef _WIN32
173 BZ2DLLFreeLibrary();
174#endif
175 return 0;
176}
diff --git a/huffman.c b/huffman.c
index bb2a6cc..9b446c4 100644
--- a/huffman.c
+++ b/huffman.c
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -100,10 +100,10 @@
100 100
101 101
102/*---------------------------------------------------*/ 102/*---------------------------------------------------*/
103void hbMakeCodeLengths ( UChar *len, 103void BZ2_hbMakeCodeLengths ( UChar *len,
104 Int32 *freq, 104 Int32 *freq,
105 Int32 alphaSize, 105 Int32 alphaSize,
106 Int32 maxLen ) 106 Int32 maxLen )
107{ 107{
108 /*-- 108 /*--
109 Nodes and heap entries run from 1. Entry 0 109 Nodes and heap entries run from 1. Entry 0
@@ -172,11 +172,11 @@ void hbMakeCodeLengths ( UChar *len,
172 172
173 173
174/*---------------------------------------------------*/ 174/*---------------------------------------------------*/
175void hbAssignCodes ( Int32 *code, 175void BZ2_hbAssignCodes ( Int32 *code,
176 UChar *length, 176 UChar *length,
177 Int32 minLen, 177 Int32 minLen,
178 Int32 maxLen, 178 Int32 maxLen,
179 Int32 alphaSize ) 179 Int32 alphaSize )
180{ 180{
181 Int32 n, vec, i; 181 Int32 n, vec, i;
182 182
@@ -190,13 +190,13 @@ void hbAssignCodes ( Int32 *code,
190 190
191 191
192/*---------------------------------------------------*/ 192/*---------------------------------------------------*/
193void hbCreateDecodeTables ( Int32 *limit, 193void BZ2_hbCreateDecodeTables ( Int32 *limit,
194 Int32 *base, 194 Int32 *base,
195 Int32 *perm, 195 Int32 *perm,
196 UChar *length, 196 UChar *length,
197 Int32 minLen, 197 Int32 minLen,
198 Int32 maxLen, 198 Int32 maxLen,
199 Int32 alphaSize ) 199 Int32 alphaSize )
200{ 200{
201 Int32 pp, i, j, vec; 201 Int32 pp, i, j, vec;
202 202
diff --git a/libbz2.def b/libbz2.def
index ba0f54e..2dc0dd8 100644
--- a/libbz2.def
+++ b/libbz2.def
@@ -1,25 +1,27 @@
1LIBRARY LIBBZ2 1LIBRARY LIBBZ2
2DESCRIPTION "libbzip2: library for data compression" 2DESCRIPTION "libbzip2: library for data compression"
3EXPORTS 3EXPORTS
4 bzCompressInit 4 BZ2_bzCompressInit
5 bzCompress 5 BZ2_bzCompress
6 bzCompressEnd 6 BZ2_bzCompressEnd
7 bzDecompressInit 7 BZ2_bzDecompressInit
8 bzDecompress 8 BZ2_bzDecompress
9 bzDecompressEnd 9 BZ2_bzDecompressEnd
10 bzReadOpen 10 BZ2_bzReadOpen
11 bzReadClose 11 BZ2_bzReadClose
12 bzReadGetUnused 12 BZ2_bzReadGetUnused
13 bzRead 13 BZ2_bzRead
14 bzWriteOpen 14 BZ2_bzWriteOpen
15 bzWrite 15 BZ2_bzWrite
16 bzWriteClose 16 BZ2_bzWriteClose
17 bzBuffToBuffCompress 17 BZ2_bzWriteClose64
18 bzBuffToBuffDecompress 18 BZ2_bzBuffToBuffCompress
19 bzlibVersion 19 BZ2_bzBuffToBuffDecompress
20 bzopen 20 BZ2_bzlibVersion
21 bzdopen 21 BZ2_bzopen
22 bzread 22 BZ2_bzdopen
23 bzwrite 23 BZ2_bzread
24 bzflush 24 BZ2_bzwrite
25 bzclose 25 BZ2_bzflush
26 BZ2_bzclose
27 BZ2_bzerror
diff --git a/makefile.msc b/makefile.msc
index 4b49f78..3fe4232 100644
--- a/makefile.msc
+++ b/makefile.msc
@@ -4,7 +4,7 @@
4# Fixed up by JRS for bzip2-0.9.5d release. 4# Fixed up by JRS for bzip2-0.9.5d release.
5 5
6CC=cl 6CC=cl
7CFLAGS= -DWIN32 -MD -Ox 7CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64
8 8
9OBJS= blocksort.obj \ 9OBJS= blocksort.obj \
10 huffman.obj \ 10 huffman.obj \
@@ -21,7 +21,6 @@ bzip2: lib
21 $(CC) $(CFLAGS) -o bzip2recover bzip2recover.c 21 $(CC) $(CFLAGS) -o bzip2recover bzip2recover.c
22 22
23lib: $(OBJS) 23lib: $(OBJS)
24 del libbz2.lib
25 lib /out:libbz2.lib $(OBJS) 24 lib /out:libbz2.lib $(OBJS)
26 25
27test: bzip2 26test: bzip2
@@ -32,20 +31,19 @@ test: bzip2
32 .\\bzip2 -d < sample1.bz2 > sample1.tst 31 .\\bzip2 -d < sample1.bz2 > sample1.tst
33 .\\bzip2 -d < sample2.bz2 > sample2.tst 32 .\\bzip2 -d < sample2.bz2 > sample2.tst
34 .\\bzip2 -ds < sample3.bz2 > sample3.tst 33 .\\bzip2 -ds < sample3.bz2 > sample3.tst
34 @echo All six of the fc's should find no differences.
35 @echo If fc finds an error on sample3.bz2, this could be
36 @echo because WinZip's 'TAR file smart CR/LF conversion'
37 @echo is too clever for its own good. Disable this option.
38 @echo The correct size for sample3.ref is 120,244. If it
39 @echo is 150,251, WinZip has messed it up.
35 fc sample1.bz2 sample1.rb2 40 fc sample1.bz2 sample1.rb2
36 fc sample2.bz2 sample2.rb2 41 fc sample2.bz2 sample2.rb2
37 fc sample3.bz2 sample3.rb2 42 fc sample3.bz2 sample3.rb2
38 fc sample1.tst sample1.ref 43 fc sample1.tst sample1.ref
39 fc sample2.tst sample2.ref 44 fc sample2.tst sample2.ref
40 fc sample3.tst sample3.ref 45 fc sample3.tst sample3.ref
41 @echo All six of the fc's should find no differences. 46
42 @echo If fc finds an error on sample3.tst, this could be
43 @echo because WinZips 'TAR file smart CR/LF conversion'
44 @echo is too clever for its own good. Disable this option.
45 @echo The correct size for sample3.ref is 120,244. If it
46 @echo is around 150k, WinZip has stuffed it up.
47 @echo Also remember to set BZ_UNIX to 0 and BZ_LCCWIN32
48 @echo to 1 in bzip2.c.
49 47
50 48
51clean: 49clean:
diff --git a/manual.texi b/manual.texi
index e48e656..336776a 100644
--- a/manual.texi
+++ b/manual.texi
@@ -2,10 +2,10 @@
2@setfilename bzip2.info 2@setfilename bzip2.info
3 3
4@ignore 4@ignore
5This file documents bzip2 version 0.9.5, and associated library 5This file documents bzip2 version 1.0, and associated library
6libbzip2, written by Julian Seward (jseward@acm.org). 6libbzip2, written by Julian Seward (jseward@acm.org).
7 7
8Copyright (C) 1996-1999 Julian R Seward 8Copyright (C) 1996-2000 Julian R Seward
9 9
10Permission is granted to make and distribute verbatim copies of 10Permission is granted to make and distribute verbatim copies of
11this manual provided the copyright notice and this permission notice 11this manual provided the copyright notice and this permission notice
@@ -30,8 +30,8 @@ END-INFO-DIR-ENTRY
30@titlepage 30@titlepage
31@title bzip2 and libbzip2 31@title bzip2 and libbzip2
32@subtitle a program and library for data compression 32@subtitle a program and library for data compression
33@subtitle copyright (C) 1996-1999 Julian Seward 33@subtitle copyright (C) 1996-2000 Julian Seward
34@subtitle version 0.9.5d of 4 September 1999 34@subtitle version 1.0 of 21 March 2000
35@author Julian Seward 35@author Julian Seward
36 36
37@end titlepage 37@end titlepage
@@ -44,7 +44,7 @@ END-INFO-DIR-ENTRY
44 44
45This program, @code{bzip2}, 45This program, @code{bzip2},
46and associated library @code{libbzip2}, are 46and associated library @code{libbzip2}, are
47Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 47Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
48 48
49Redistribution and use in source and binary forms, with or without 49Redistribution and use in source and binary forms, with or without
50modification, are permitted provided that the following conditions 50modification, are permitted provided that the following conditions
@@ -82,9 +82,13 @@ Julian Seward, Cambridge, UK.
82 82
83@code{jseward@@acm.org} 83@code{jseward@@acm.org}
84 84
85@code{http://sourceware.cygnus.com/bzip2}
86
87@code{http://www.cacheprof.org}
88
85@code{http://www.muraroa.demon.co.uk} 89@code{http://www.muraroa.demon.co.uk}
86 90
87@code{bzip2}/@code{libbzip2} version 0.9.5 of 24 May 1999. 91@code{bzip2}/@code{libbzip2} version 1.0 of 21 March 2000.
88 92
89PATENTS: To the best of my knowledge, @code{bzip2} does not use any patented 93PATENTS: To the best of my knowledge, @code{bzip2} does not use any patented
90algorithms. However, I do not have the resources available to carry out 94algorithms. However, I do not have the resources available to carry out
@@ -130,7 +134,7 @@ and nothing else.
130@unnumberedsubsubsec NAME 134@unnumberedsubsubsec NAME
131@itemize 135@itemize
132@item @code{bzip2}, @code{bunzip2} 136@item @code{bzip2}, @code{bunzip2}
133- a block-sorting file compressor, v0.9.5 137- a block-sorting file compressor, v1.0
134@item @code{bzcat} 138@item @code{bzcat}
135- decompresses files to stdout 139- decompresses files to stdout
136@item @code{bzip2recover} 140@item @code{bzip2recover}
@@ -431,10 +435,10 @@ I/O error messages are not as helpful as they could be. @code{bzip2}
431tries hard to detect I/O errors and exit cleanly, but the details of 435tries hard to detect I/O errors and exit cleanly, but the details of
432what the problem is sometimes seem rather misleading. 436what the problem is sometimes seem rather misleading.
433 437
434This manual page pertains to version 0.9.5 of @code{bzip2}. Compressed 438This manual page pertains to version 1.0 of @code{bzip2}. Compressed
435data created by this version is entirely forwards and backwards 439data created by this version is entirely forwards and backwards
436compatible with the previous public releases, versions 0.1pl2 and 0.9.0, 440compatible with the previous public releases, versions 0.1pl2, 0.9.0 and
437but with the following exception: 0.9.0 and above can correctly 4410.9.5, but with the following exception: 0.9.0 and above can correctly
438decompress multiple concatenated compressed files. 0.1pl2 cannot do 442decompress multiple concatenated compressed files. 0.1pl2 cannot do
439this; it will stop after decompressing just the first file in the 443this; it will stop after decompressing just the first file in the
440stream. 444stream.
@@ -486,6 +490,10 @@ The structure of @code{libbzip2}'s interfaces is similar to
486that of Jean-loup Gailly's and Mark Adler's excellent @code{zlib} 490that of Jean-loup Gailly's and Mark Adler's excellent @code{zlib}
487library. 491library.
488 492
493All externally visible symbols have names beginning @code{BZ2_}.
494This is new in version 1.0. The intention is to minimise pollution
495of the namespaces of library clients.
496
489@subsection Low-level summary 497@subsection Low-level summary
490 498
491This interface provides services for compressing and decompressing 499This interface provides services for compressing and decompressing
@@ -498,17 +506,17 @@ The low-level part of the library has no global variables and
498is therefore thread-safe. 506is therefore thread-safe.
499 507
500Six routines make up the low level interface: 508Six routines make up the low level interface:
501@code{bzCompressInit}, @code{bzCompress}, and @* @code{bzCompressEnd} 509@code{BZ2_bzCompressInit}, @code{BZ2_bzCompress}, and @* @code{BZ2_bzCompressEnd}
502for compression, 510for compression,
503and a corresponding trio @code{bzDecompressInit}, @* @code{bzDecompress} 511and a corresponding trio @code{BZ2_bzDecompressInit}, @* @code{BZ2_bzDecompress}
504and @code{bzDecompressEnd} for decompression. 512and @code{BZ2_bzDecompressEnd} for decompression.
505The @code{*Init} functions allocate 513The @code{*Init} functions allocate
506memory for compression/decompression and do other 514memory for compression/decompression and do other
507initialisations, whilst the @code{*End} functions close down operations 515initialisations, whilst the @code{*End} functions close down operations
508and release memory. 516and release memory.
509 517
510The real work is done by @code{bzCompress} and @code{bzDecompress}. 518The real work is done by @code{BZ2_bzCompress} and @code{BZ2_bzDecompress}.
511These compress/decompress data from a user-supplied input buffer 519These compress and decompress data from a user-supplied input buffer
512to a user-supplied output buffer. These buffers can be any size; 520to a user-supplied output buffer. These buffers can be any size;
513arbitrary quantities of data are handled by making repeated calls 521arbitrary quantities of data are handled by making repeated calls
514to these functions. This is a flexible mechanism allowing a 522to these functions. This is a flexible mechanism allowing a
@@ -526,10 +534,10 @@ reading files in which the @code{bzip2} data stream is embedded
526within some larger-scale file structure, or where there are 534within some larger-scale file structure, or where there are
527multiple @code{bzip2} data streams concatenated end-to-end. 535multiple @code{bzip2} data streams concatenated end-to-end.
528 536
529For reading files, @code{bzReadOpen}, @code{bzRead}, @code{bzReadClose} 537For reading files, @code{BZ2_bzReadOpen}, @code{BZ2_bzRead},
530and @code{bzReadGetUnused} are supplied. For writing files, 538@code{BZ2_bzReadClose} and @* @code{BZ2_bzReadGetUnused} are supplied. For
531@code{bzWriteOpen}, @code{bzWrite} and @code{bzWriteFinish} are 539writing files, @code{BZ2_bzWriteOpen}, @code{BZ2_bzWrite} and
532available. 540@code{BZ2_bzWriteFinish} are available.
533 541
534As with the low-level library, no global variables are used 542As with the low-level library, no global variables are used
535so the library is per se thread-safe. However, if I/O errors 543so the library is per se thread-safe. However, if I/O errors
@@ -539,7 +547,7 @@ the error. In that case, you'd need a C library which correctly
539supports @code{errno} in a multithreaded environment. 547supports @code{errno} in a multithreaded environment.
540 548
541To make the library a little simpler and more portable, 549To make the library a little simpler and more portable,
542@code{bzReadOpen} and @code{bzWriteOpen} require you to pass them file 550@code{BZ2_bzReadOpen} and @code{BZ2_bzWriteOpen} require you to pass them file
543handles (@code{FILE*}s) which have previously been opened for reading or 551handles (@code{FILE*}s) which have previously been opened for reading or
544writing respectively. That avoids portability problems associated with 552writing respectively. That avoids portability problems associated with
545file operations and file attributes, whilst not being much of an 553file operations and file attributes, whilst not being much of an
@@ -548,8 +556,8 @@ imposition on the programmer.
548 556
549 557
550@subsection Utility functions summary 558@subsection Utility functions summary
551For very simple needs, @code{bzBuffToBuffCompress} and 559For very simple needs, @code{BZ2_bzBuffToBuffCompress} and
552@code{bzBuffToBuffDecompress} are provided. These compress 560@code{BZ2_bzBuffToBuffDecompress} are provided. These compress
553data in memory from one buffer to another buffer in a single 561data in memory from one buffer to another buffer in a single
554function call. You should assess whether these functions 562function call. You should assess whether these functions
555fulfill your memory-to-memory compression/decompression 563fulfill your memory-to-memory compression/decompression
@@ -559,9 +567,9 @@ general but more complex low-level interface.
559Yoshioka Tsuneo (@code{QWF00133@@niftyserve.or.jp} / 567Yoshioka Tsuneo (@code{QWF00133@@niftyserve.or.jp} /
560@code{tsuneo-y@@is.aist-nara.ac.jp}) has contributed some functions to 568@code{tsuneo-y@@is.aist-nara.ac.jp}) has contributed some functions to
561give better @code{zlib} compatibility. These functions are 569give better @code{zlib} compatibility. These functions are
562@code{bzopen}, @code{bzread}, @code{bzwrite}, @code{bzflush}, 570@code{BZ2_bzopen}, @code{BZ2_bzread}, @code{BZ2_bzwrite}, @code{BZ2_bzflush},
563@code{bzclose}, 571@code{BZ2_bzclose},
564@code{bzerror} and @code{bzlibVersion}. You may find these functions 572@code{BZ2_bzerror} and @code{BZ2_bzlibVersion}. You may find these functions
565more convenient for simple file reading and writing, than those in the 573more convenient for simple file reading and writing, than those in the
566high-level interface. These functions are not (yet) officially part of 574high-level interface. These functions are not (yet) officially part of
567the library, and are minimally documented here. If they break, you 575the library, and are minimally documented here. If they break, you
@@ -582,6 +590,15 @@ if you are feeling especially paranoid. I would be interested in
582hearing more about the robustness of the library to corrupted 590hearing more about the robustness of the library to corrupted
583compressed data. 591compressed data.
584 592
593Version 1.0 is much more robust in this respect than
5940.9.0 or 0.9.5. Investigations with Checker (a tool for
595detecting problems with memory management, similar to Purify)
596indicate that, at least for the few files I tested, all single-bit
597errors in the decompressed data are caught properly, with no
598segmentation faults, no reads of uninitialised data and no
599out of range reads or writes. So it's certainly much improved,
600although I wouldn't claim it to be totally bombproof.
601
585The file @code{bzlib.h} contains all definitions needed to use 602The file @code{bzlib.h} contains all definitions needed to use
586the library. In particular, you should definitely not include 603the library. In particular, you should definitely not include
587@code{bzlib_private.h}. 604@code{bzlib_private.h}.
@@ -598,7 +615,7 @@ The requested action was completed successfully.
598@item BZ_RUN_OK 615@item BZ_RUN_OK
599@itemx BZ_FLUSH_OK 616@itemx BZ_FLUSH_OK
600@itemx BZ_FINISH_OK 617@itemx BZ_FINISH_OK
601In @code{bzCompress}, the requested flush/finish/nothing-special action 618In @code{BZ2_bzCompress}, the requested flush/finish/nothing-special action
602was completed successfully. 619was completed successfully.
603@item BZ_STREAM_END 620@item BZ_STREAM_END
604Compression of data was completed, or the logical stream end was 621Compression of data was completed, or the logical stream end was
@@ -607,6 +624,16 @@ detected during decompression.
607 624
608The following return values indicate an error of some kind. 625The following return values indicate an error of some kind.
609@table @code 626@table @code
627@item BZ_CONFIG_ERROR
628Indicates that the library has been improperly compiled on your
629platform -- a major configuration error. Specifically, it means
630that @code{sizeof(char)}, @code{sizeof(short)} and @code{sizeof(int)}
631are not 1, 2 and 4 respectively, as they should be. Note that the
632library should still work properly on 64-bit platforms which follow
633the LP64 programming model -- that is, where @code{sizeof(long)}
634and @code{sizeof(void*)} are 8. Under LP64, @code{sizeof(int)} is
635still 4, so @code{libbzip2}, which doesn't use the @code{long} type,
636is OK.
610@item BZ_SEQUENCE_ERROR 637@item BZ_SEQUENCE_ERROR
611When using the library, it is important to call the functions in the 638When using the library, it is important to call the functions in the
612correct sequence and with data structures (buffers etc) in the correct 639correct sequence and with data structures (buffers etc) in the correct
@@ -624,10 +651,10 @@ making.
624@item BZ_MEM_ERROR 651@item BZ_MEM_ERROR
625Returned when a request to allocate memory failed. Note that the 652Returned when a request to allocate memory failed. Note that the
626quantity of memory needed to decompress a stream cannot be determined 653quantity of memory needed to decompress a stream cannot be determined
627until the stream's header has been read. So @code{bzDecompress} and 654until the stream's header has been read. So @code{BZ2_bzDecompress} and
628@code{bzRead} may return @code{BZ_MEM_ERROR} even though some of 655@code{BZ2_bzRead} may return @code{BZ_MEM_ERROR} even though some of
629the compressed data has been read. The same is not true for 656the compressed data has been read. The same is not true for
630compression; once @code{bzCompressInit} or @code{bzWriteOpen} have 657compression; once @code{BZ2_bzCompressInit} or @code{BZ2_bzWriteOpen} have
631successfully completed, @code{BZ_MEM_ERROR} cannot occur. 658successfully completed, @code{BZ_MEM_ERROR} cannot occur.
632@item BZ_DATA_ERROR 659@item BZ_DATA_ERROR
633Returned when a data integrity error is detected during decompression. 660Returned when a data integrity error is detected during decompression.
@@ -639,19 +666,19 @@ As a special case of @code{BZ_DATA_ERROR}, it is sometimes useful to
639know when the compressed stream does not start with the correct 666know when the compressed stream does not start with the correct
640magic bytes (@code{'B' 'Z' 'h'}). 667magic bytes (@code{'B' 'Z' 'h'}).
641@item BZ_IO_ERROR 668@item BZ_IO_ERROR
642Returned by @code{bzRead} and @code{bzRead} when there is an error 669Returned by @code{BZ2_bzRead} and @code{BZ2_bzWrite} when there is an error
643reading or writing in the compressed file, and by @code{bzReadOpen} 670reading or writing in the compressed file, and by @code{BZ2_bzReadOpen}
644and @code{bzWriteOpen} for attempts to use a file for which the 671and @code{BZ2_bzWriteOpen} for attempts to use a file for which the
645error indicator (viz, @code{ferror(f)}) is set. 672error indicator (viz, @code{ferror(f)}) is set.
646On receipt of @code{BZ_IO_ERROR}, the caller should consult 673On receipt of @code{BZ_IO_ERROR}, the caller should consult
647@code{errno} and/or @code{perror} to acquire operating-system 674@code{errno} and/or @code{perror} to acquire operating-system
648specific information about the problem. 675specific information about the problem.
649@item BZ_UNEXPECTED_EOF 676@item BZ_UNEXPECTED_EOF
650Returned by @code{bzRead} when the compressed file finishes 677Returned by @code{BZ2_bzRead} when the compressed file finishes
651before the logical end of stream is detected. 678before the logical end of stream is detected.
652@item BZ_OUTBUFF_FULL 679@item BZ_OUTBUFF_FULL
653Returned by @code{bzBuffToBuffCompress} and 680Returned by @code{BZ2_bzBuffToBuffCompress} and
654@code{bzBuffToBuffDecompress} to indicate that the output data 681@code{BZ2_bzBuffToBuffDecompress} to indicate that the output data
655will not fit into the output buffer provided. 682will not fit into the output buffer provided.
656@end table 683@end table
657 684
@@ -659,17 +686,19 @@ will not fit into the output buffer provided.
659 686
660@section Low-level interface 687@section Low-level interface
661 688
662@subsection @code{bzCompressInit} 689@subsection @code{BZ2_bzCompressInit}
663@example 690@example
664typedef 691typedef
665 struct @{ 692 struct @{
666 char *next_in; 693 char *next_in;
667 unsigned int avail_in; 694 unsigned int avail_in;
668 unsigned int total_in; 695 unsigned int total_in_lo32;
696 unsigned int total_in_hi32;
669 697
670 char *next_out; 698 char *next_out;
671 unsigned int avail_out; 699 unsigned int avail_out;
672 unsigned int total_out; 700 unsigned int total_out_lo32;
701 unsigned int total_out_hi32;
673 702
674 void *state; 703 void *state;
675 704
@@ -679,10 +708,10 @@ typedef
679 @} 708 @}
680 bz_stream; 709 bz_stream;
681 710
682int bzCompressInit ( bz_stream *strm, 711int BZ2_bzCompressInit ( bz_stream *strm,
683 int blockSize100k, 712 int blockSize100k,
684 int verbosity, 713 int verbosity,
685 int workFactor ); 714 int workFactor );
686 715
687@end example 716@end example
688 717
@@ -712,14 +741,19 @@ If you don't want to use a custom memory allocator, set @code{bzalloc},
712and the library will then use the standard @code{malloc}/@code{free} 741and the library will then use the standard @code{malloc}/@code{free}
713routines. 742routines.
714 743
715Before calling @code{bzCompressInit}, fields @code{bzalloc}, 744Before calling @code{BZ2_bzCompressInit}, fields @code{bzalloc},
716@code{bzfree} and @code{opaque} should 745@code{bzfree} and @code{opaque} should
717be filled appropriately, as just described. Upon return, the internal 746be filled appropriately, as just described. Upon return, the internal
718state will have been allocated and initialised, and @code{total_in} and 747state will have been allocated and initialised, and @code{total_in_lo32},
719@code{total_out} will have been set to zero. 748@code{total_in_hi32}, @code{total_out_lo32} and
720These last two fields are used by the library 749@code{total_out_hi32} will have been set to zero.
750These four fields are used by the library
721to inform the caller of the total amount of data passed into and out of 751to inform the caller of the total amount of data passed into and out of
722the library, respectively. You should not try to change them. 752the library, respectively. You should not try to change them.
753As of version 1.0, 64-bit counts are maintained, even on 32-bit
754platforms, using the @code{_hi32} fields to store the upper 32 bits
755of the count. So, for example, the total amount of data in
756is @code{(total_in_hi32 << 32) + total_in_lo32}.
723 757
724Parameter @code{blockSize100k} specifies the block size to be used for 758Parameter @code{blockSize100k} specifies the block size to be used for
725compression. It should be a value between 1 and 9 inclusive, and the 759compression. It should be a value between 1 and 9 inclusive, and the
@@ -761,6 +795,8 @@ mechanism would render the parameter obsolete.
761 795
762Possible return values: 796Possible return values:
763@display 797@display
798 @code{BZ_CONFIG_ERROR}
799 if the library has been mis-compiled
764 @code{BZ_PARAM_ERROR} 800 @code{BZ_PARAM_ERROR}
765 if @code{strm} is @code{NULL} 801 if @code{strm} is @code{NULL}
766 or @code{blockSize} < 1 or @code{blockSize} > 9 802 or @code{blockSize} < 1 or @code{blockSize} > 9
@@ -773,86 +809,86 @@ Possible return values:
773@end display 809@end display
774Allowable next actions: 810Allowable next actions:
775@display 811@display
776 @code{bzCompress} 812 @code{BZ2_bzCompress}
777 if @code{BZ_OK} is returned 813 if @code{BZ_OK} is returned
778 no specific action needed in case of error 814 no specific action needed in case of error
779@end display 815@end display
780 816
781@subsection @code{bzCompress} 817@subsection @code{BZ2_bzCompress}
782@example 818@example
783 int bzCompress ( bz_stream *strm, int action ); 819 int BZ2_bzCompress ( bz_stream *strm, int action );
784@end example 820@end example
785Provides more input and/or output buffer space for the library. The 821Provides more input and/or output buffer space for the library. The
786caller maintains input and output buffers, and calls @code{bzCompress} to 822caller maintains input and output buffers, and calls @code{BZ2_bzCompress} to
787transfer data between them. 823transfer data between them.
788 824
789Before each call to @code{bzCompress}, @code{next_in} should point at 825Before each call to @code{BZ2_bzCompress}, @code{next_in} should point at
790the data to be compressed, and @code{avail_in} should indicate how many 826the data to be compressed, and @code{avail_in} should indicate how many
791bytes the library may read. @code{bzCompress} updates @code{next_in}, 827bytes the library may read. @code{BZ2_bzCompress} updates @code{next_in},
792@code{avail_in} and @code{total_in} to reflect the number of bytes it 828@code{avail_in} and @code{total_in} to reflect the number of bytes it
793has read. 829has read.
794 830
795Similarly, @code{next_out} should point to a buffer in which the 831Similarly, @code{next_out} should point to a buffer in which the
796compressed data is to be placed, with @code{avail_out} indicating how 832compressed data is to be placed, with @code{avail_out} indicating how
797much output space is available. @code{bzCompress} updates 833much output space is available. @code{BZ2_bzCompress} updates
798@code{next_out}, @code{avail_out} and @code{total_out} to reflect the 834@code{next_out}, @code{avail_out} and @code{total_out} to reflect the
799number of bytes output. 835number of bytes output.
800 836
801You may provide and remove as little or as much data as you like on each 837You may provide and remove as little or as much data as you like on each
802call of @code{bzCompress}. In the limit, it is acceptable to supply and 838call of @code{BZ2_bzCompress}. In the limit, it is acceptable to supply and
803remove data one byte at a time, although this would be terribly 839remove data one byte at a time, although this would be terribly
804inefficient. You should always ensure that at least one byte of output 840inefficient. You should always ensure that at least one byte of output
805space is available at each call. 841space is available at each call.
806 842
807A second purpose of @code{bzCompress} is to request a change of mode of the 843A second purpose of @code{BZ2_bzCompress} is to request a change of mode of the
808compressed stream. 844compressed stream.
809 845
810Conceptually, a compressed stream can be in one of four states: IDLE, 846Conceptually, a compressed stream can be in one of four states: IDLE,
811RUNNING, FLUSHING and FINISHING. Before initialisation 847RUNNING, FLUSHING and FINISHING. Before initialisation
812(@code{bzCompressInit}) and after termination (@code{bzCompressEnd}), a 848(@code{BZ2_bzCompressInit}) and after termination (@code{BZ2_bzCompressEnd}), a
813stream is regarded as IDLE. 849stream is regarded as IDLE.
814 850
815Upon initialisation (@code{bzCompressInit}), the stream is placed in the 851Upon initialisation (@code{BZ2_bzCompressInit}), the stream is placed in the
816RUNNING state. Subsequent calls to @code{bzCompress} should pass 852RUNNING state. Subsequent calls to @code{BZ2_bzCompress} should pass
817@code{BZ_RUN} as the requested action; other actions are illegal and 853@code{BZ_RUN} as the requested action; other actions are illegal and
818will result in @code{BZ_SEQUENCE_ERROR}. 854will result in @code{BZ_SEQUENCE_ERROR}.
819 855
820At some point, the calling program will have provided all the input data 856At some point, the calling program will have provided all the input data
821it wants to. It will then want to finish up -- in effect, asking the 857it wants to. It will then want to finish up -- in effect, asking the
822library to process any data it might have buffered internally. In this 858library to process any data it might have buffered internally. In this
823state, @code{bzCompress} will no longer attempt to read data from 859state, @code{BZ2_bzCompress} will no longer attempt to read data from
824@code{next_in}, but it will want to write data to @code{next_out}. 860@code{next_in}, but it will want to write data to @code{next_out}.
825Because the output buffer supplied by the user can be arbitrarily small, 861Because the output buffer supplied by the user can be arbitrarily small,
826the finishing-up operation cannot necessarily be done with a single call 862the finishing-up operation cannot necessarily be done with a single call
827of @code{bzCompress}. 863of @code{BZ2_bzCompress}.
828 864
829Instead, the calling program passes @code{BZ_FINISH} as an action to 865Instead, the calling program passes @code{BZ_FINISH} as an action to
830@code{bzCompress}. This changes the stream's state to FINISHING. Any 866@code{BZ2_bzCompress}. This changes the stream's state to FINISHING. Any
831remaining input (ie, @code{next_in[0 .. avail_in-1]}) is compressed and 867remaining input (ie, @code{next_in[0 .. avail_in-1]}) is compressed and
832transferred to the output buffer. To do this, @code{bzCompress} must be 868transferred to the output buffer. To do this, @code{BZ2_bzCompress} must be
833called repeatedly until all the output has been consumed. At that 869called repeatedly until all the output has been consumed. At that
834point, @code{bzCompress} returns @code{BZ_STREAM_END}, and the stream's 870point, @code{BZ2_bzCompress} returns @code{BZ_STREAM_END}, and the stream's
835state is set back to IDLE. @code{bzCompressEnd} should then be 871state is set back to IDLE. @code{BZ2_bzCompressEnd} should then be
836called. 872called.
837 873
838Just to make sure the calling program does not cheat, the library makes 874Just to make sure the calling program does not cheat, the library makes
839a note of @code{avail_in} at the time of the first call to 875a note of @code{avail_in} at the time of the first call to
840@code{bzCompress} which has @code{BZ_FINISH} as an action (ie, at the 876@code{BZ2_bzCompress} which has @code{BZ_FINISH} as an action (ie, at the
841time the program has announced its intention to not supply any more 877time the program has announced its intention to not supply any more
842input). By comparing this value with that of @code{avail_in} over 878input). By comparing this value with that of @code{avail_in} over
843subsequent calls to @code{bzCompress}, the library can detect any 879subsequent calls to @code{BZ2_bzCompress}, the library can detect any
844attempts to slip in more data to compress. Any calls for which this is 880attempts to slip in more data to compress. Any calls for which this is
845detected will return @code{BZ_SEQUENCE_ERROR}. This indicates a 881detected will return @code{BZ_SEQUENCE_ERROR}. This indicates a
846programming mistake which should be corrected. 882programming mistake which should be corrected.
847 883
848Instead of asking to finish, the calling program may ask 884Instead of asking to finish, the calling program may ask
849@code{bzCompress} to take all the remaining input, compress it and 885@code{BZ2_bzCompress} to take all the remaining input, compress it and
850terminate the current (Burrows-Wheeler) compression block. This could 886terminate the current (Burrows-Wheeler) compression block. This could
851be useful for error control purposes. The mechanism is analogous to 887be useful for error control purposes. The mechanism is analogous to
852that for finishing: call @code{bzCompress} with an action of 888that for finishing: call @code{BZ2_bzCompress} with an action of
853@code{BZ_FLUSH}, remove output data, and persist with the 889@code{BZ_FLUSH}, remove output data, and persist with the
854@code{BZ_FLUSH} action until the value @code{BZ_RUN} is returned. As 890@code{BZ_FLUSH} action until the value @code{BZ_RUN} is returned. As
855with finishing, @code{bzCompress} detects any attempt to provide more 891with finishing, @code{BZ2_bzCompress} detects any attempt to provide more
856input data once the flush has begun. 892input data once the flush has begun.
857 893
858Once the flush is complete, the stream returns to the normal RUNNING 894Once the flush is complete, the stream returns to the normal RUNNING
@@ -863,11 +899,11 @@ which shows which actions are allowable in each state, what action
863will be taken, what the next state is, and what the non-error return 899will be taken, what the next state is, and what the non-error return
864values are. Note that you can't explicitly ask what state the 900values are. Note that you can't explicitly ask what state the
865stream is in, but nor do you need to -- it can be inferred from the 901stream is in, but nor do you need to -- it can be inferred from the
866values returned by @code{bzCompress}. 902values returned by @code{BZ2_bzCompress}.
867@display 903@display
868IDLE/@code{any} 904IDLE/@code{any}
869 Illegal. IDLE state only exists after @code{bzCompressEnd} or 905 Illegal. IDLE state only exists after @code{BZ2_bzCompressEnd} or
870 before @code{bzCompressInit}. 906 before @code{BZ2_bzCompressInit}.
871 Return value = @code{BZ_SEQUENCE_ERROR} 907 Return value = @code{BZ_SEQUENCE_ERROR}
872 908
873RUNNING/@code{BZ_RUN} 909RUNNING/@code{BZ_RUN}
@@ -917,21 +953,21 @@ FINISHING/other
917That still looks complicated? Well, fair enough. The usual sequence 953That still looks complicated? Well, fair enough. The usual sequence
918of calls for compressing a load of data is: 954of calls for compressing a load of data is:
919@itemize @bullet 955@itemize @bullet
920@item Get started with @code{bzCompressInit}. 956@item Get started with @code{BZ2_bzCompressInit}.
921@item Shovel data in and shlurp out its compressed form using zero or more 957@item Shovel data in and shlurp out its compressed form using zero or more
922calls of @code{bzCompress} with action = @code{BZ_RUN}. 958calls of @code{BZ2_bzCompress} with action = @code{BZ_RUN}.
923@item Finish up. 959@item Finish up.
924Repeatedly call @code{bzCompress} with action = @code{BZ_FINISH}, 960Repeatedly call @code{BZ2_bzCompress} with action = @code{BZ_FINISH},
925copying out the compressed output, until @code{BZ_STREAM_END} is returned. 961copying out the compressed output, until @code{BZ_STREAM_END} is returned.
926@item Close up and go home. Call @code{bzCompressEnd}. 962@item Close up and go home. Call @code{BZ2_bzCompressEnd}.
927@end itemize 963@end itemize
928If the data you want to compress fits into your input buffer all 964If the data you want to compress fits into your input buffer all
929at once, you can skip the calls of @code{bzCompress ( ..., BZ_RUN )} and 965at once, you can skip the calls of @code{BZ2_bzCompress ( ..., BZ_RUN )} and
930just do the @code{bzCompress ( ..., BZ_FINISH )} calls. 966just do the @code{BZ2_bzCompress ( ..., BZ_FINISH )} calls.
931 967
932All required memory is allocated by @code{bzCompressInit}. The 968All required memory is allocated by @code{BZ2_bzCompressInit}. The
933compression library can accept any data at all (obviously). So you 969compression library can accept any data at all (obviously). So you
934shouldn't get any error return values from the @code{bzCompress} calls. 970shouldn't get any error return values from the @code{BZ2_bzCompress} calls.
935If you do, they will be @code{BZ_SEQUENCE_ERROR}, and indicate a bug in 971If you do, they will be @code{BZ_SEQUENCE_ERROR}, and indicate a bug in
936your programming. 972your programming.
937 973
@@ -941,9 +977,9 @@ Trivial other possible return values:
941 if @code{strm} is @code{NULL}, or @code{strm->s} is @code{NULL} 977 if @code{strm} is @code{NULL}, or @code{strm->s} is @code{NULL}
942@end display 978@end display
943 979
944@subsection @code{bzCompressEnd} 980@subsection @code{BZ2_bzCompressEnd}
945@example 981@example
946int bzCompressEnd ( bz_stream *strm ); 982int BZ2_bzCompressEnd ( bz_stream *strm );
947@end example 983@end example
948Releases all memory associated with a compression stream. 984Releases all memory associated with a compression stream.
949 985
@@ -954,11 +990,11 @@ Possible return values:
954@end display 990@end display
955 991
956 992
957@subsection @code{bzDecompressInit} 993@subsection @code{BZ2_bzDecompressInit}
958@example 994@example
959int bzDecompressInit ( bz_stream *strm, int verbosity, int small ); 995int BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );
960@end example 996@end example
961Prepares for decompression. As with @code{bzCompressInit}, a 997Prepares for decompression. As with @code{BZ2_bzCompressInit}, a
962@code{bz_stream} record should be allocated and initialised before the 998@code{bz_stream} record should be allocated and initialised before the
963call. Fields @code{bzalloc}, @code{bzfree} and @code{opaque} should be 999call. Fields @code{bzalloc}, @code{bzfree} and @code{opaque} should be
964set if a custom memory allocator is required, or made @code{NULL} for 1000set if a custom memory allocator is required, or made @code{NULL} for
@@ -966,7 +1002,7 @@ the normal @code{malloc}/@code{free} routines. Upon return, the internal
966state will have been initialised, and @code{total_in} and 1002state will have been initialised, and @code{total_in} and
967@code{total_out} will be zero. 1003@code{total_out} will be zero.
968 1004
969For the meaning of parameter @code{verbosity}, see @code{bzCompressInit}. 1005For the meaning of parameter @code{verbosity}, see @code{BZ2_bzCompressInit}.
970 1006
971If @code{small} is nonzero, the library will use an alternative 1007If @code{small} is nonzero, the library will use an alternative
972decompression algorithm which uses less memory but at the cost of 1008decompression algorithm which uses less memory but at the cost of
@@ -976,11 +1012,13 @@ more information on memory management.
976 1012
977Note that the amount of memory needed to decompress 1013Note that the amount of memory needed to decompress
978a stream cannot be determined until the stream's header has been read, 1014a stream cannot be determined until the stream's header has been read,
979so even if @code{bzDecompressInit} succeeds, a subsequent 1015so even if @code{BZ2_bzDecompressInit} succeeds, a subsequent
980@code{bzDecompress} could fail with @code{BZ_MEM_ERROR}. 1016@code{BZ2_bzDecompress} could fail with @code{BZ_MEM_ERROR}.
981 1017
982Possible return values: 1018Possible return values:
983@display 1019@display
1020 @code{BZ_CONFIG_ERROR}
1021 if the library has been mis-compiled
984 @code{BZ_PARAM_ERROR} 1022 @code{BZ_PARAM_ERROR}
985 if @code{(small != 0 && small != 1)} 1023 if @code{(small != 0 && small != 1)}
986 or @code{(verbosity < 0 || verbosity > 4)} 1024 or @code{(verbosity < 0 || verbosity > 4)}
@@ -990,54 +1028,54 @@ Possible return values:
990 1028
991Allowable next actions: 1029Allowable next actions:
992@display 1030@display
993 @code{bzDecompress} 1031 @code{BZ2_bzDecompress}
994 if @code{BZ_OK} was returned 1032 if @code{BZ_OK} was returned
995 no specific action required in case of error 1033 no specific action required in case of error
996@end display 1034@end display
997 1035
998 1036
999 1037
1000@subsection @code{bzDecompress} 1038@subsection @code{BZ2_bzDecompress}
1001@example 1039@example
1002int bzDecompress ( bz_stream *strm ); 1040int BZ2_bzDecompress ( bz_stream *strm );
1003@end example 1041@end example
1004Provides more input and/out output buffer space for the library. The 1042Provides more input and/out output buffer space for the library. The
1005caller maintains input and output buffers, and uses @code{bzDecompress} 1043caller maintains input and output buffers, and uses @code{BZ2_bzDecompress}
1006to transfer data between them. 1044to transfer data between them.
1007 1045
1008Before each call to @code{bzDecompress}, @code{next_in} 1046Before each call to @code{BZ2_bzDecompress}, @code{next_in}
1009should point at the compressed data, 1047should point at the compressed data,
1010and @code{avail_in} should indicate how many bytes the library 1048and @code{avail_in} should indicate how many bytes the library
1011may read. @code{bzDecompress} updates @code{next_in}, @code{avail_in} 1049may read. @code{BZ2_bzDecompress} updates @code{next_in}, @code{avail_in}
1012and @code{total_in} 1050and @code{total_in}
1013to reflect the number of bytes it has read. 1051to reflect the number of bytes it has read.
1014 1052
1015Similarly, @code{next_out} should point to a buffer in which the uncompressed 1053Similarly, @code{next_out} should point to a buffer in which the uncompressed
1016output is to be placed, with @code{avail_out} indicating how much output space 1054output is to be placed, with @code{avail_out} indicating how much output space
1017is available. @code{bzCompress} updates @code{next_out}, 1055is available. @code{BZ2_bzCompress} updates @code{next_out},
1018@code{avail_out} and @code{total_out} to reflect 1056@code{avail_out} and @code{total_out} to reflect
1019the number of bytes output. 1057the number of bytes output.
1020 1058
1021You may provide and remove as little or as much data as you like on 1059You may provide and remove as little or as much data as you like on
1022each call of @code{bzDecompress}. 1060each call of @code{BZ2_bzDecompress}.
1023In the limit, it is acceptable to 1061In the limit, it is acceptable to
1024supply and remove data one byte at a time, although this would be 1062supply and remove data one byte at a time, although this would be
1025terribly inefficient. You should always ensure that at least one 1063terribly inefficient. You should always ensure that at least one
1026byte of output space is available at each call. 1064byte of output space is available at each call.
1027 1065
1028Use of @code{bzDecompress} is simpler than @code{bzCompress}. 1066Use of @code{BZ2_bzDecompress} is simpler than @code{BZ2_bzCompress}.
1029 1067
1030You should provide input and remove output as described above, and 1068You should provide input and remove output as described above, and
1031repeatedly call @code{bzDecompress} until @code{BZ_STREAM_END} is 1069repeatedly call @code{BZ2_bzDecompress} until @code{BZ_STREAM_END} is
1032returned. Appearance of @code{BZ_STREAM_END} denotes that 1070returned. Appearance of @code{BZ_STREAM_END} denotes that
1033@code{bzDecompress} has detected the logical end of the compressed 1071@code{BZ2_bzDecompress} has detected the logical end of the compressed
1034stream. @code{bzDecompress} will not produce @code{BZ_STREAM_END} until 1072stream. @code{BZ2_bzDecompress} will not produce @code{BZ_STREAM_END} until
1035all output data has been placed into the output buffer, so once 1073all output data has been placed into the output buffer, so once
1036@code{BZ_STREAM_END} appears, you are guaranteed to have available all 1074@code{BZ_STREAM_END} appears, you are guaranteed to have available all
1037the decompressed output, and @code{bzDecompressEnd} can safely be 1075the decompressed output, and @code{BZ2_bzDecompressEnd} can safely be
1038called. 1076called.
1039 1077
1040If case of an error return value, you should call @code{bzDecompressEnd} 1078If case of an error return value, you should call @code{BZ2_bzDecompressEnd}
1041to clean up and release memory. 1079to clean up and release memory.
1042 1080
1043Possible return values: 1081Possible return values:
@@ -1059,16 +1097,16 @@ Possible return values:
1059@end display 1097@end display
1060Allowable next actions: 1098Allowable next actions:
1061@display 1099@display
1062 @code{bzDecompress} 1100 @code{BZ2_bzDecompress}
1063 if @code{BZ_OK} was returned 1101 if @code{BZ_OK} was returned
1064 @code{bzDecompressEnd} 1102 @code{BZ2_bzDecompressEnd}
1065 otherwise 1103 otherwise
1066@end display 1104@end display
1067 1105
1068 1106
1069@subsection @code{bzDecompressEnd} 1107@subsection @code{BZ2_bzDecompressEnd}
1070@example 1108@example
1071int bzDecompressEnd ( bz_stream *strm ); 1109int BZ2_bzDecompressEnd ( bz_stream *strm );
1072@end example 1110@end example
1073Releases all memory associated with a decompression stream. 1111Releases all memory associated with a decompression stream.
1074 1112
@@ -1107,16 +1145,16 @@ This interface provides functions for reading and writing
1107 given on a per-function basis below. 1145 given on a per-function basis below.
1108@item If @code{bzerror} indicates an error 1146@item If @code{bzerror} indicates an error
1109 (ie, anything except @code{BZ_OK} and @code{BZ_STREAM_END}), 1147 (ie, anything except @code{BZ_OK} and @code{BZ_STREAM_END}),
1110 you should immediately call @code{bzReadClose} (or @code{bzWriteClose}, 1148 you should immediately call @code{BZ2_bzReadClose} (or @code{BZ2_bzWriteClose},
1111 depending on whether you are attempting to read or to write) 1149 depending on whether you are attempting to read or to write)
1112 to free up all resources associated 1150 to free up all resources associated
1113 with the stream. Once an error has been indicated, behaviour of all calls 1151 with the stream. Once an error has been indicated, behaviour of all calls
1114 except @code{bzReadClose} (@code{bzWriteClose}) is undefined. 1152 except @code{BZ2_bzReadClose} (@code{BZ2_bzWriteClose}) is undefined.
1115 The implication is that (1) @code{bzerror} should 1153 The implication is that (1) @code{bzerror} should
1116 be checked after each call, and (2) if @code{bzerror} indicates an error, 1154 be checked after each call, and (2) if @code{bzerror} indicates an error,
1117 @code{bzReadClose} (@code{bzWriteClose}) should then be called to clean up. 1155 @code{BZ2_bzReadClose} (@code{BZ2_bzWriteClose}) should then be called to clean up.
1118@item The @code{FILE*} arguments passed to 1156@item The @code{FILE*} arguments passed to
1119 @code{bzReadOpen}/@code{bzWriteOpen} 1157 @code{BZ2_bzReadOpen}/@code{BZ2_bzWriteOpen}
1120 should be set to binary mode. 1158 should be set to binary mode.
1121 Most Unix systems will do this by default, but other platforms, 1159 Most Unix systems will do this by default, but other platforms,
1122 including Windows and Mac, will not. If you omit this, you may 1160 including Windows and Mac, will not. If you omit this, you may
@@ -1130,13 +1168,13 @@ This interface provides functions for reading and writing
1130 1168
1131 1169
1132 1170
1133@subsection @code{bzReadOpen} 1171@subsection @code{BZ2_bzReadOpen}
1134@example 1172@example
1135 typedef void BZFILE; 1173 typedef void BZFILE;
1136 1174
1137 BZFILE *bzReadOpen ( int *bzerror, FILE *f, 1175 BZFILE *BZ2_bzReadOpen ( int *bzerror, FILE *f,
1138 int small, int verbosity, 1176 int small, int verbosity,
1139 void *unused, int nUnused ); 1177 void *unused, int nUnused );
1140@end example 1178@end example
1141Prepare to read compressed data from file handle @code{f}. @code{f} 1179Prepare to read compressed data from file handle @code{f}. @code{f}
1142should refer to a file which has been opened for reading, and for which 1180should refer to a file which has been opened for reading, and for which
@@ -1144,7 +1182,7 @@ the error indicator (@code{ferror(f)})is not set. If @code{small} is 1,
1144the library will try to decompress using less memory, at the expense of 1182the library will try to decompress using less memory, at the expense of
1145speed. 1183speed.
1146 1184
1147For reasons explained below, @code{bzRead} will decompress the 1185For reasons explained below, @code{BZ2_bzRead} will decompress the
1148@code{nUnused} bytes starting at @code{unused}, before starting to read 1186@code{nUnused} bytes starting at @code{unused}, before starting to read
1149from the file @code{f}. At most @code{BZ_MAX_UNUSED} bytes may be 1187from the file @code{f}. At most @code{BZ_MAX_UNUSED} bytes may be
1150supplied like this. If this facility is not required, you should pass 1188supplied like this. If this facility is not required, you should pass
@@ -1152,15 +1190,17 @@ supplied like this. If this facility is not required, you should pass
1152respectively. 1190respectively.
1153 1191
1154For the meaning of parameters @code{small} and @code{verbosity}, 1192For the meaning of parameters @code{small} and @code{verbosity},
1155see @code{bzDecompressInit}. 1193see @code{BZ2_bzDecompressInit}.
1156 1194
1157The amount of memory needed to decompress a file cannot be determined 1195The amount of memory needed to decompress a file cannot be determined
1158until the file's header has been read. So it is possible that 1196until the file's header has been read. So it is possible that
1159@code{bzReadOpen} returns @code{BZ_OK} but a subsequent call of 1197@code{BZ2_bzReadOpen} returns @code{BZ_OK} but a subsequent call of
1160@code{bzRead} will return @code{BZ_MEM_ERROR}. 1198@code{BZ2_bzRead} will return @code{BZ_MEM_ERROR}.
1161 1199
1162Possible assignments to @code{bzerror}: 1200Possible assignments to @code{bzerror}:
1163@display 1201@display
1202 @code{BZ_CONFIG_ERROR}
1203 if the library has been mis-compiled
1164 @code{BZ_PARAM_ERROR} 1204 @code{BZ_PARAM_ERROR}
1165 if @code{f} is @code{NULL} 1205 if @code{f} is @code{NULL}
1166 or @code{small} is neither @code{0} nor @code{1} 1206 or @code{small} is neither @code{0} nor @code{1}
@@ -1184,16 +1224,16 @@ Possible return values:
1184 1224
1185Allowable next actions: 1225Allowable next actions:
1186@display 1226@display
1187 @code{bzRead} 1227 @code{BZ2_bzRead}
1188 if @code{bzerror} is @code{BZ_OK} 1228 if @code{bzerror} is @code{BZ_OK}
1189 @code{bzClose} 1229 @code{BZ2_bzClose}
1190 otherwise 1230 otherwise
1191@end display 1231@end display
1192 1232
1193 1233
1194@subsection @code{bzRead} 1234@subsection @code{BZ2_bzRead}
1195@example 1235@example
1196 int bzRead ( int *bzerror, BZFILE *b, void *buf, int len ); 1236 int BZ2_bzRead ( int *bzerror, BZFILE *b, void *buf, int len );
1197@end example 1237@end example
1198Reads up to @code{len} (uncompressed) bytes from the compressed file 1238Reads up to @code{len} (uncompressed) bytes from the compressed file
1199@code{b} into 1239@code{b} into
@@ -1204,7 +1244,7 @@ was detected, @code{bzerror} will be set to @code{BZ_STREAM_END},
1204and the number 1244and the number
1205of bytes read is returned. All other @code{bzerror} values denote an error. 1245of bytes read is returned. All other @code{bzerror} values denote an error.
1206 1246
1207@code{bzRead} will supply @code{len} bytes, 1247@code{BZ2_bzRead} will supply @code{len} bytes,
1208unless the logical stream end is detected 1248unless the logical stream end is detected
1209or an error occurs. Because of this, it is possible to detect the 1249or an error occurs. Because of this, it is possible to detect the
1210stream end by observing when the number of bytes returned is 1250stream end by observing when the number of bytes returned is
@@ -1213,20 +1253,20 @@ requested. Nevertheless, this is regarded as inadvisable; you should
1213instead check @code{bzerror} after every call and watch out for 1253instead check @code{bzerror} after every call and watch out for
1214@code{BZ_STREAM_END}. 1254@code{BZ_STREAM_END}.
1215 1255
1216Internally, @code{bzRead} copies data from the compressed file in chunks 1256Internally, @code{BZ2_bzRead} copies data from the compressed file in chunks
1217of size @code{BZ_MAX_UNUSED} bytes 1257of size @code{BZ_MAX_UNUSED} bytes
1218before decompressing it. If the file contains more bytes than strictly 1258before decompressing it. If the file contains more bytes than strictly
1219needed to reach the logical end-of-stream, @code{bzRead} will almost certainly 1259needed to reach the logical end-of-stream, @code{BZ2_bzRead} will almost certainly
1220read some of the trailing data before signalling @code{BZ_SEQUENCE_END}. 1260read some of the trailing data before signalling @code{BZ_SEQUENCE_END}.
1221To collect the read but unused data once @code{BZ_SEQUENCE_END} has 1261To collect the read but unused data once @code{BZ_SEQUENCE_END} has
1222appeared, call @code{bzReadGetUnused} immediately before @code{bzReadClose}. 1262appeared, call @code{BZ2_bzReadGetUnused} immediately before @code{BZ2_bzReadClose}.
1223 1263
1224Possible assignments to @code{bzerror}: 1264Possible assignments to @code{bzerror}:
1225@display 1265@display
1226 @code{BZ_PARAM_ERROR} 1266 @code{BZ_PARAM_ERROR}
1227 if @code{b} is @code{NULL} or @code{buf} is @code{NULL} or @code{len < 0} 1267 if @code{b} is @code{NULL} or @code{buf} is @code{NULL} or @code{len < 0}
1228 @code{BZ_SEQUENCE_ERROR} 1268 @code{BZ_SEQUENCE_ERROR}
1229 if @code{b} was opened with @code{bzWriteOpen} 1269 if @code{b} was opened with @code{BZ2_bzWriteOpen}
1230 @code{BZ_IO_ERROR} 1270 @code{BZ_IO_ERROR}
1231 if there is an error reading from the compressed file 1271 if there is an error reading from the compressed file
1232 @code{BZ_UNEXPECTED_EOF} 1272 @code{BZ_UNEXPECTED_EOF}
@@ -1254,28 +1294,28 @@ Possible return values:
1254 1294
1255Allowable next actions: 1295Allowable next actions:
1256@display 1296@display
1257 collect data from @code{buf}, then @code{bzRead} or @code{bzReadClose} 1297 collect data from @code{buf}, then @code{BZ2_bzRead} or @code{BZ2_bzReadClose}
1258 if @code{bzerror} is @code{BZ_OK} 1298 if @code{bzerror} is @code{BZ_OK}
1259 collect data from @code{buf}, then @code{bzReadClose} or @code{bzReadGetUnused} 1299 collect data from @code{buf}, then @code{BZ2_bzReadClose} or @code{BZ2_bzReadGetUnused}
1260 if @code{bzerror} is @code{BZ_SEQUENCE_END} 1300 if @code{bzerror} is @code{BZ_SEQUENCE_END}
1261 @code{bzReadClose} 1301 @code{BZ2_bzReadClose}
1262 otherwise 1302 otherwise
1263@end display 1303@end display
1264 1304
1265 1305
1266 1306
1267@subsection @code{bzReadGetUnused} 1307@subsection @code{BZ2_bzReadGetUnused}
1268@example 1308@example
1269 void bzReadGetUnused ( int* bzerror, BZFILE *b, 1309 void BZ2_bzReadGetUnused ( int* bzerror, BZFILE *b,
1270 void** unused, int* nUnused ); 1310 void** unused, int* nUnused );
1271@end example 1311@end example
1272Returns data which was read from the compressed file but was not needed 1312Returns data which was read from the compressed file but was not needed
1273to get to the logical end-of-stream. @code{*unused} is set to the address 1313to get to the logical end-of-stream. @code{*unused} is set to the address
1274of the data, and @code{*nUnused} to the number of bytes. @code{*nUnused} will 1314of the data, and @code{*nUnused} to the number of bytes. @code{*nUnused} will
1275be set to a value between @code{0} and @code{BZ_MAX_UNUSED} inclusive. 1315be set to a value between @code{0} and @code{BZ_MAX_UNUSED} inclusive.
1276 1316
1277This function may only be called once @code{bzRead} has signalled 1317This function may only be called once @code{BZ2_bzRead} has signalled
1278@code{BZ_STREAM_END} but before @code{bzReadClose}. 1318@code{BZ_STREAM_END} but before @code{BZ2_bzReadClose}.
1279 1319
1280Possible assignments to @code{bzerror}: 1320Possible assignments to @code{bzerror}:
1281@display 1321@display
@@ -1284,31 +1324,31 @@ Possible assignments to @code{bzerror}:
1284 or @code{unused} is @code{NULL} or @code{nUnused} is @code{NULL} 1324 or @code{unused} is @code{NULL} or @code{nUnused} is @code{NULL}
1285 @code{BZ_SEQUENCE_ERROR} 1325 @code{BZ_SEQUENCE_ERROR}
1286 if @code{BZ_STREAM_END} has not been signalled 1326 if @code{BZ_STREAM_END} has not been signalled
1287 or if @code{b} was opened with @code{bzWriteOpen} 1327 or if @code{b} was opened with @code{BZ2_bzWriteOpen}
1288 @code{BZ_OK} 1328 @code{BZ_OK}
1289 otherwise 1329 otherwise
1290@end display 1330@end display
1291 1331
1292Allowable next actions: 1332Allowable next actions:
1293@display 1333@display
1294 @code{bzReadClose} 1334 @code{BZ2_bzReadClose}
1295@end display 1335@end display
1296 1336
1297 1337
1298@subsection @code{bzReadClose} 1338@subsection @code{BZ2_bzReadClose}
1299@example 1339@example
1300 void bzReadClose ( int *bzerror, BZFILE *b ); 1340 void BZ2_bzReadClose ( int *bzerror, BZFILE *b );
1301@end example 1341@end example
1302Releases all memory pertaining to the compressed file @code{b}. 1342Releases all memory pertaining to the compressed file @code{b}.
1303@code{bzReadClose} does not call @code{fclose} on the underlying file 1343@code{BZ2_bzReadClose} does not call @code{fclose} on the underlying file
1304handle, so you should do that yourself if appropriate. 1344handle, so you should do that yourself if appropriate.
1305@code{bzReadClose} should be called to clean up after all error 1345@code{BZ2_bzReadClose} should be called to clean up after all error
1306situations. 1346situations.
1307 1347
1308Possible assignments to @code{bzerror}: 1348Possible assignments to @code{bzerror}:
1309@display 1349@display
1310 @code{BZ_SEQUENCE_ERROR} 1350 @code{BZ_SEQUENCE_ERROR}
1311 if @code{b} was opened with @code{bzOpenWrite} 1351 if @code{b} was opened with @code{BZ2_bzOpenWrite}
1312 @code{BZ_OK} 1352 @code{BZ_OK}
1313 otherwise 1353 otherwise
1314@end display 1354@end display
@@ -1320,11 +1360,11 @@ Allowable next actions:
1320 1360
1321 1361
1322 1362
1323@subsection @code{bzWriteOpen} 1363@subsection @code{BZ2_bzWriteOpen}
1324@example 1364@example
1325 BZFILE *bzWriteOpen ( int *bzerror, FILE *f, 1365 BZFILE *BZ2_bzWriteOpen ( int *bzerror, FILE *f,
1326 int blockSize100k, int verbosity, 1366 int blockSize100k, int verbosity,
1327 int workFactor ); 1367 int workFactor );
1328@end example 1368@end example
1329Prepare to write compressed data to file handle @code{f}. 1369Prepare to write compressed data to file handle @code{f}.
1330@code{f} should refer to 1370@code{f} should refer to
@@ -1333,14 +1373,16 @@ indicator (@code{ferror(f)})is not set.
1333 1373
1334For the meaning of parameters @code{blockSize100k}, 1374For the meaning of parameters @code{blockSize100k},
1335@code{verbosity} and @code{workFactor}, see 1375@code{verbosity} and @code{workFactor}, see
1336@* @code{bzCompressInit}. 1376@* @code{BZ2_bzCompressInit}.
1337 1377
1338All required memory is allocated at this stage, so if the call 1378All required memory is allocated at this stage, so if the call
1339completes successfully, @code{BZ_MEM_ERROR} cannot be signalled by a 1379completes successfully, @code{BZ_MEM_ERROR} cannot be signalled by a
1340subsequent call to @code{bzWrite}. 1380subsequent call to @code{BZ2_bzWrite}.
1341 1381
1342Possible assignments to @code{bzerror}: 1382Possible assignments to @code{bzerror}:
1343@display 1383@display
1384 @code{BZ_CONFIG_ERROR}
1385 if the library has been mis-compiled
1344 @code{BZ_PARAM_ERROR} 1386 @code{BZ_PARAM_ERROR}
1345 if @code{f} is @code{NULL} 1387 if @code{f} is @code{NULL}
1346 or @code{blockSize100k < 1} or @code{blockSize100k > 9} 1388 or @code{blockSize100k < 1} or @code{blockSize100k > 9}
@@ -1362,18 +1404,18 @@ Possible return values:
1362 1404
1363Allowable next actions: 1405Allowable next actions:
1364@display 1406@display
1365 @code{bzWrite} 1407 @code{BZ2_bzWrite}
1366 if @code{bzerror} is @code{BZ_OK} 1408 if @code{bzerror} is @code{BZ_OK}
1367 (you could go directly to @code{bzWriteClose}, but this would be pretty pointless) 1409 (you could go directly to @code{BZ2_bzWriteClose}, but this would be pretty pointless)
1368 @code{bzWriteClose} 1410 @code{BZ2_bzWriteClose}
1369 otherwise 1411 otherwise
1370@end display 1412@end display
1371 1413
1372 1414
1373 1415
1374@subsection @code{bzWrite} 1416@subsection @code{BZ2_bzWrite}
1375@example 1417@example
1376 void bzWrite ( int *bzerror, BZFILE *b, void *buf, int len ); 1418 void BZ2_bzWrite ( int *bzerror, BZFILE *b, void *buf, int len );
1377@end example 1419@end example
1378Absorbs @code{len} bytes from the buffer @code{buf}, eventually to be 1420Absorbs @code{len} bytes from the buffer @code{buf}, eventually to be
1379compressed and written to the file. 1421compressed and written to the file.
@@ -1383,7 +1425,7 @@ Possible assignments to @code{bzerror}:
1383 @code{BZ_PARAM_ERROR} 1425 @code{BZ_PARAM_ERROR}
1384 if @code{b} is @code{NULL} or @code{buf} is @code{NULL} or @code{len < 0} 1426 if @code{b} is @code{NULL} or @code{buf} is @code{NULL} or @code{len < 0}
1385 @code{BZ_SEQUENCE_ERROR} 1427 @code{BZ_SEQUENCE_ERROR}
1386 if b was opened with @code{bzReadOpen} 1428 if b was opened with @code{BZ2_bzReadOpen}
1387 @code{BZ_IO_ERROR} 1429 @code{BZ_IO_ERROR}
1388 if there is an error writing the compressed file. 1430 if there is an error writing the compressed file.
1389 @code{BZ_OK} 1431 @code{BZ_OK}
@@ -1393,22 +1435,29 @@ Possible assignments to @code{bzerror}:
1393 1435
1394 1436
1395 1437
1396@subsection @code{bzWriteClose} 1438@subsection @code{BZ2_bzWriteClose}
1397@example 1439@example
1398 int bzWriteClose ( int *bzerror, BZFILE* f, 1440 void BZ2_bzWriteClose ( int *bzerror, BZFILE* f,
1399 int abandon, 1441 int abandon,
1400 unsigned int* nbytes_in, 1442 unsigned int* nbytes_in,
1401 unsigned int* nbytes_out ); 1443 unsigned int* nbytes_out );
1444
1445 void BZ2_bzWriteClose64 ( int *bzerror, BZFILE* f,
1446 int abandon,
1447 unsigned int* nbytes_in_lo32,
1448 unsigned int* nbytes_in_hi32,
1449 unsigned int* nbytes_out_lo32,
1450 unsigned int* nbytes_out_hi32 );
1402@end example 1451@end example
1403 1452
1404Compresses and flushes to the compressed file all data so far supplied 1453Compresses and flushes to the compressed file all data so far supplied
1405by @code{bzWrite}. The logical end-of-stream markers are also written, so 1454by @code{BZ2_bzWrite}. The logical end-of-stream markers are also written, so
1406subsequent calls to @code{bzWrite} are illegal. All memory associated 1455subsequent calls to @code{BZ2_bzWrite} are illegal. All memory associated
1407with the compressed file @code{b} is released. 1456with the compressed file @code{b} is released.
1408@code{fflush} is called on the 1457@code{fflush} is called on the
1409compressed file, but it is not @code{fclose}'d. 1458compressed file, but it is not @code{fclose}'d.
1410 1459
1411If @code{bzWriteClose} is called to clean up after an error, the only 1460If @code{BZ2_bzWriteClose} is called to clean up after an error, the only
1412action is to release the memory. The library records the error codes 1461action is to release the memory. The library records the error codes
1413issued by previous calls, so this situation will be detected 1462issued by previous calls, so this situation will be detected
1414automatically. There is no attempt to complete the compression 1463automatically. There is no attempt to complete the compression
@@ -1418,12 +1467,17 @@ value to @code{abandon}.
1418 1467
1419If @code{nbytes_in} is non-null, @code{*nbytes_in} will be set to be the 1468If @code{nbytes_in} is non-null, @code{*nbytes_in} will be set to be the
1420total volume of uncompressed data handled. Similarly, @code{nbytes_out} 1469total volume of uncompressed data handled. Similarly, @code{nbytes_out}
1421will be set to the total volume of compressed data written. 1470will be set to the total volume of compressed data written. For
1471compatibility with older versions of the library, @code{BZ2_bzWriteClose}
1472only yields the lower 32 bits of these counts. Use
1473@code{BZ2_bzWriteClose64} if you want the full 64 bit counts. These
1474two functions are otherwise absolutely identical.
1475
1422 1476
1423Possible assignments to @code{bzerror}: 1477Possible assignments to @code{bzerror}:
1424@display 1478@display
1425 @code{BZ_SEQUENCE_ERROR} 1479 @code{BZ_SEQUENCE_ERROR}
1426 if @code{b} was opened with @code{bzReadOpen} 1480 if @code{b} was opened with @code{BZ2_bzReadOpen}
1427 @code{BZ_IO_ERROR} 1481 @code{BZ_IO_ERROR}
1428 if there is an error writing the compressed file 1482 if there is an error writing the compressed file
1429 @code{BZ_OK} 1483 @code{BZ_OK}
@@ -1442,26 +1496,26 @@ The calling application can write its own data before and after the
1442compressed data stream, using that same file handle. 1496compressed data stream, using that same file handle.
1443@item Reading is more complex, and the facilities are not as general 1497@item Reading is more complex, and the facilities are not as general
1444as they could be since generality is hard to reconcile with efficiency. 1498as they could be since generality is hard to reconcile with efficiency.
1445@code{bzRead} reads from the compressed file in blocks of size 1499@code{BZ2_bzRead} reads from the compressed file in blocks of size
1446@code{BZ_MAX_UNUSED} bytes, and in doing so probably will overshoot 1500@code{BZ_MAX_UNUSED} bytes, and in doing so probably will overshoot
1447the logical end of compressed stream. 1501the logical end of compressed stream.
1448To recover this data once decompression has 1502To recover this data once decompression has
1449ended, call @code{bzReadGetUnused} after the last call of @code{bzRead} 1503ended, call @code{BZ2_bzReadGetUnused} after the last call of @code{BZ2_bzRead}
1450(the one returning @code{BZ_STREAM_END}) but before calling 1504(the one returning @code{BZ_STREAM_END}) but before calling
1451@code{bzReadClose}. 1505@code{BZ2_bzReadClose}.
1452@end itemize 1506@end itemize
1453 1507
1454This mechanism makes it easy to decompress multiple @code{bzip2} 1508This mechanism makes it easy to decompress multiple @code{bzip2}
1455streams placed end-to-end. As the end of one stream, when @code{bzRead} 1509streams placed end-to-end. As the end of one stream, when @code{BZ2_bzRead}
1456returns @code{BZ_STREAM_END}, call @code{bzReadGetUnused} to collect the 1510returns @code{BZ_STREAM_END}, call @code{BZ2_bzReadGetUnused} to collect the
1457unused data (copy it into your own buffer somewhere). 1511unused data (copy it into your own buffer somewhere).
1458That data forms the start of the next compressed stream. 1512That data forms the start of the next compressed stream.
1459To start uncompressing that next stream, call @code{bzReadOpen} again, 1513To start uncompressing that next stream, call @code{BZ2_bzReadOpen} again,
1460feeding in the unused data via the @code{unused}/@code{nUnused} 1514feeding in the unused data via the @code{unused}/@code{nUnused}
1461parameters. 1515parameters.
1462Keep doing this until @code{BZ_STREAM_END} return coincides with the 1516Keep doing this until @code{BZ_STREAM_END} return coincides with the
1463physical end of file (@code{feof(f)}). In this situation 1517physical end of file (@code{feof(f)}). In this situation
1464@code{bzReadGetUnused} 1518@code{BZ2_bzReadGetUnused}
1465will of course return no data. 1519will of course return no data.
1466 1520
1467This should give some feel for how the high-level interface can be used. 1521This should give some feel for how the high-level interface can be used.
@@ -1482,22 +1536,22 @@ f = fopen ( "myfile.bz2", "w" );
1482if (!f) @{ 1536if (!f) @{
1483 /* handle error */ 1537 /* handle error */
1484@} 1538@}
1485b = bzWriteOpen ( &bzerror, f, 9 ); 1539b = BZ2_bzWriteOpen ( &bzerror, f, 9 );
1486if (bzerror != BZ_OK) @{ 1540if (bzerror != BZ_OK) @{
1487 bzWriteClose ( b ); 1541 BZ2_bzWriteClose ( b );
1488 /* handle error */ 1542 /* handle error */
1489@} 1543@}
1490 1544
1491while ( /* condition */ ) @{ 1545while ( /* condition */ ) @{
1492 /* get data to write into buf, and set nBuf appropriately */ 1546 /* get data to write into buf, and set nBuf appropriately */
1493 nWritten = bzWrite ( &bzerror, b, buf, nBuf ); 1547 nWritten = BZ2_bzWrite ( &bzerror, b, buf, nBuf );
1494 if (bzerror == BZ_IO_ERROR) @{ 1548 if (bzerror == BZ_IO_ERROR) @{
1495 bzWriteClose ( &bzerror, b ); 1549 BZ2_bzWriteClose ( &bzerror, b );
1496 /* handle error */ 1550 /* handle error */
1497 @} 1551 @}
1498@} 1552@}
1499 1553
1500bzWriteClose ( &bzerror, b ); 1554BZ2_bzWriteClose ( &bzerror, b );
1501if (bzerror == BZ_IO_ERROR) @{ 1555if (bzerror == BZ_IO_ERROR) @{
1502 /* handle error */ 1556 /* handle error */
1503@} 1557@}
@@ -1515,39 +1569,39 @@ f = fopen ( "myfile.bz2", "r" );
1515if (!f) @{ 1569if (!f) @{
1516 /* handle error */ 1570 /* handle error */
1517@} 1571@}
1518b = bzReadOpen ( &bzerror, f, 0, NULL, 0 ); 1572b = BZ2_bzReadOpen ( &bzerror, f, 0, NULL, 0 );
1519if (bzerror != BZ_OK) @{ 1573if (bzerror != BZ_OK) @{
1520 bzReadClose ( &bzerror, b ); 1574 BZ2_bzReadClose ( &bzerror, b );
1521 /* handle error */ 1575 /* handle error */
1522@} 1576@}
1523 1577
1524bzerror = BZ_OK; 1578bzerror = BZ_OK;
1525while (bzerror == BZ_OK && /* arbitrary other conditions */) @{ 1579while (bzerror == BZ_OK && /* arbitrary other conditions */) @{
1526 nBuf = bzRead ( &bzerror, b, buf, /* size of buf */ ); 1580 nBuf = BZ2_bzRead ( &bzerror, b, buf, /* size of buf */ );
1527 if (bzerror == BZ_OK) @{ 1581 if (bzerror == BZ_OK) @{
1528 /* do something with buf[0 .. nBuf-1] */ 1582 /* do something with buf[0 .. nBuf-1] */
1529 @} 1583 @}
1530@} 1584@}
1531if (bzerror != BZ_STREAM_END) @{ 1585if (bzerror != BZ_STREAM_END) @{
1532 bzReadClose ( &bzerror, b ); 1586 BZ2_bzReadClose ( &bzerror, b );
1533 /* handle error */ 1587 /* handle error */
1534@} else @{ 1588@} else @{
1535 bzReadClose ( &bzerror ); 1589 BZ2_bzReadClose ( &bzerror );
1536@} 1590@}
1537@end example 1591@end example
1538 1592
1539 1593
1540 1594
1541@section Utility functions 1595@section Utility functions
1542@subsection @code{bzBuffToBuffCompress} 1596@subsection @code{BZ2_bzBuffToBuffCompress}
1543@example 1597@example
1544 int bzBuffToBuffCompress( char* dest, 1598 int BZ2_bzBuffToBuffCompress( char* dest,
1545 unsigned int* destLen, 1599 unsigned int* destLen,
1546 char* source, 1600 char* source,
1547 unsigned int sourceLen, 1601 unsigned int sourceLen,
1548 int blockSize100k, 1602 int blockSize100k,
1549 int verbosity, 1603 int verbosity,
1550 int workFactor ); 1604 int workFactor );
1551@end example 1605@end example
1552Attempts to compress the data in @code{source[0 .. sourceLen-1]} 1606Attempts to compress the data in @code{source[0 .. sourceLen-1]}
1553into the destination buffer, @code{dest[0 .. *destLen-1]}. 1607into the destination buffer, @code{dest[0 .. *destLen-1]}.
@@ -1563,17 +1617,19 @@ additional calls to provide extra input data. If you want that kind of
1563mechanism, use the low-level interface. 1617mechanism, use the low-level interface.
1564 1618
1565For the meaning of parameters @code{blockSize100k}, @code{verbosity} 1619For the meaning of parameters @code{blockSize100k}, @code{verbosity}
1566and @code{workFactor}, @* see @code{bzCompressInit}. 1620and @code{workFactor}, @* see @code{BZ2_bzCompressInit}.
1567 1621
1568To guarantee that the compressed data will fit in its buffer, allocate 1622To guarantee that the compressed data will fit in its buffer, allocate
1569an output buffer of size 1% larger than the uncompressed data, plus 1623an output buffer of size 1% larger than the uncompressed data, plus
1570six hundred extra bytes. 1624six hundred extra bytes.
1571 1625
1572@code{bzBuffToBuffDecompress} will not write data at or 1626@code{BZ2_bzBuffToBuffDecompress} will not write data at or
1573beyond @code{dest[*destLen]}, even in case of buffer overflow. 1627beyond @code{dest[*destLen]}, even in case of buffer overflow.
1574 1628
1575Possible return values: 1629Possible return values:
1576@display 1630@display
1631 @code{BZ_CONFIG_ERROR}
1632 if the library has been mis-compiled
1577 @code{BZ_PARAM_ERROR} 1633 @code{BZ_PARAM_ERROR}
1578 if @code{dest} is @code{NULL} or @code{destLen} is @code{NULL} 1634 if @code{dest} is @code{NULL} or @code{destLen} is @code{NULL}
1579 or @code{blockSize100k < 1} or @code{blockSize100k > 9} 1635 or @code{blockSize100k < 1} or @code{blockSize100k > 9}
@@ -1589,14 +1645,14 @@ Possible return values:
1589 1645
1590 1646
1591 1647
1592@subsection @code{bzBuffToBuffDecompress} 1648@subsection @code{BZ2_bzBuffToBuffDecompress}
1593@example 1649@example
1594 int bzBuffToBuffDecompress ( char* dest, 1650 int BZ2_bzBuffToBuffDecompress ( char* dest,
1595 unsigned int* destLen, 1651 unsigned int* destLen,
1596 char* source, 1652 char* source,
1597 unsigned int sourceLen, 1653 unsigned int sourceLen,
1598 int small, 1654 int small,
1599 int verbosity ); 1655 int verbosity );
1600@end example 1656@end example
1601Attempts to decompress the data in @code{source[0 .. sourceLen-1]} 1657Attempts to decompress the data in @code{source[0 .. sourceLen-1]}
1602into the destination buffer, @code{dest[0 .. *destLen-1]}. 1658into the destination buffer, @code{dest[0 .. *destLen-1]}.
@@ -1606,11 +1662,11 @@ returned. If the compressed data won't fit, @code{*destLen}
1606is unchanged, and @code{BZ_OUTBUFF_FULL} is returned. 1662is unchanged, and @code{BZ_OUTBUFF_FULL} is returned.
1607 1663
1608@code{source} is assumed to hold a complete @code{bzip2} format 1664@code{source} is assumed to hold a complete @code{bzip2} format
1609data stream. @code{bzBuffToBuffDecompress} tries to decompress 1665data stream. @* @code{BZ2_bzBuffToBuffDecompress} tries to decompress
1610the entirety of the stream into the output buffer. 1666the entirety of the stream into the output buffer.
1611 1667
1612For the meaning of parameters @code{small} and @code{verbosity}, 1668For the meaning of parameters @code{small} and @code{verbosity},
1613see @code{bzDecompressInit}. 1669see @code{BZ2_bzDecompressInit}.
1614 1670
1615Because the compression ratio of the compressed data cannot be known in 1671Because the compression ratio of the compressed data cannot be known in
1616advance, there is no easy way to guarantee that the output buffer will 1672advance, there is no easy way to guarantee that the output buffer will
@@ -1618,11 +1674,13 @@ be big enough. You may of course make arrangements in your code to
1618record the size of the uncompressed data, but such a mechanism is beyond 1674record the size of the uncompressed data, but such a mechanism is beyond
1619the scope of this library. 1675the scope of this library.
1620 1676
1621@code{bzBuffToBuffDecompress} will not write data at or 1677@code{BZ2_bzBuffToBuffDecompress} will not write data at or
1622beyond @code{dest[*destLen]}, even in case of buffer overflow. 1678beyond @code{dest[*destLen]}, even in case of buffer overflow.
1623 1679
1624Possible return values: 1680Possible return values:
1625@display 1681@display
1682 @code{BZ_CONFIG_ERROR}
1683 if the library has been mis-compiled
1626 @code{BZ_PARAM_ERROR} 1684 @code{BZ_PARAM_ERROR}
1627 if @code{dest} is @code{NULL} or @code{destLen} is @code{NULL} 1685 if @code{dest} is @code{NULL} or @code{destLen} is @code{NULL}
1628 or @code{small != 0 && small != 1} 1686 or @code{small != 0 && small != 1}
@@ -1646,40 +1704,40 @@ Possible return values:
1646@section @code{zlib} compatibility functions 1704@section @code{zlib} compatibility functions
1647Yoshioka Tsuneo has contributed some functions to 1705Yoshioka Tsuneo has contributed some functions to
1648give better @code{zlib} compatibility. These functions are 1706give better @code{zlib} compatibility. These functions are
1649@code{bzopen}, @code{bzread}, @code{bzwrite}, @code{bzflush}, 1707@code{BZ2_bzopen}, @code{BZ2_bzread}, @code{BZ2_bzwrite}, @code{BZ2_bzflush},
1650@code{bzclose}, 1708@code{BZ2_bzclose},
1651@code{bzerror} and @code{bzlibVersion}. 1709@code{BZ2_bzerror} and @code{BZ2_bzlibVersion}.
1652These functions are not (yet) officially part of 1710These functions are not (yet) officially part of
1653the library. If they break, you get to keep all the pieces. 1711the library. If they break, you get to keep all the pieces.
1654Nevertheless, I think they work ok. 1712Nevertheless, I think they work ok.
1655@example 1713@example
1656typedef void BZFILE; 1714typedef void BZFILE;
1657 1715
1658const char * bzlibVersion ( void ); 1716const char * BZ2_bzlibVersion ( void );
1659@end example 1717@end example
1660Returns a string indicating the library version. 1718Returns a string indicating the library version.
1661@example 1719@example
1662BZFILE * bzopen ( const char *path, const char *mode ); 1720BZFILE * BZ2_bzopen ( const char *path, const char *mode );
1663BZFILE * bzdopen ( int fd, const char *mode ); 1721BZFILE * BZ2_bzdopen ( int fd, const char *mode );
1664@end example 1722@end example
1665Opens a @code{.bz2} file for reading or writing, using either its name 1723Opens a @code{.bz2} file for reading or writing, using either its name
1666or a pre-existing file descriptor. 1724or a pre-existing file descriptor.
1667Analogous to @code{fopen} and @code{fdopen}. 1725Analogous to @code{fopen} and @code{fdopen}.
1668@example 1726@example
1669int bzread ( BZFILE* b, void* buf, int len ); 1727int BZ2_bzread ( BZFILE* b, void* buf, int len );
1670int bzwrite ( BZFILE* b, void* buf, int len ); 1728int BZ2_bzwrite ( BZFILE* b, void* buf, int len );
1671@end example 1729@end example
1672Reads/writes data from/to a previously opened @code{BZFILE}. 1730Reads/writes data from/to a previously opened @code{BZFILE}.
1673Analogous to @code{fread} and @code{fwrite}. 1731Analogous to @code{fread} and @code{fwrite}.
1674@example 1732@example
1675int bzflush ( BZFILE* b ); 1733int BZ2_bzflush ( BZFILE* b );
1676void bzclose ( BZFILE* b ); 1734void BZ2_bzclose ( BZFILE* b );
1677@end example 1735@end example
1678Flushes/closes a @code{BZFILE}. @code{bzflush} doesn't actually do 1736Flushes/closes a @code{BZFILE}. @code{BZ2_bzflush} doesn't actually do
1679anything. Analogous to @code{fflush} and @code{fclose}. 1737anything. Analogous to @code{fflush} and @code{fclose}.
1680 1738
1681@example 1739@example
1682const char * bzerror ( BZFILE *b, int *errnum ) 1740const char * BZ2_bzerror ( BZFILE *b, int *errnum )
1683@end example 1741@end example
1684Returns a string describing the more recent error status of 1742Returns a string describing the more recent error status of
1685@code{b}, and also sets @code{*errnum} to its numerical value. 1743@code{b}, and also sets @code{*errnum} to its numerical value.
@@ -1695,9 +1753,9 @@ by compiling the library with preprocessor symbol @code{BZ_NO_STDIO}
1695defined. Doing this gives you a library containing only the following 1753defined. Doing this gives you a library containing only the following
1696eight functions: 1754eight functions:
1697 1755
1698@code{bzCompressInit}, @code{bzCompress}, @code{bzCompressEnd} @* 1756@code{BZ2_bzCompressInit}, @code{BZ2_bzCompress}, @code{BZ2_bzCompressEnd} @*
1699@code{bzDecompressInit}, @code{bzDecompress}, @code{bzDecompressEnd} @* 1757@code{BZ2_bzDecompressInit}, @code{BZ2_bzDecompress}, @code{BZ2_bzDecompressEnd} @*
1700@code{bzBuffToBuffCompress}, @code{bzBuffToBuffDecompress} 1758@code{BZ2_bzBuffToBuffCompress}, @code{BZ2_bzBuffToBuffDecompress}
1701 1759
1702When compiled like this, all functions will ignore @code{verbosity} 1760When compiled like this, all functions will ignore @code{verbosity}
1703settings. 1761settings.
@@ -1710,14 +1768,14 @@ was compiled with @code{BZ_NO_STDIO} set.
1710 1768
1711For a normal compile, an assertion failure yields the message 1769For a normal compile, an assertion failure yields the message
1712@example 1770@example
1713 bzip2/libbzip2, v0.9.5: internal error number N. 1771 bzip2/libbzip2: internal error number N.
1714 This is a bug in bzip2/libbzip2, v0.9.5. Please report 1772 This is a bug in bzip2/libbzip2, 1.0 of 21-Mar-2000.
1715 it to me at: jseward@@acm.org. If this happened when 1773 Please report it to me at: jseward@@acm.org. If this happened
1716 you were using some program which uses libbzip2 as a 1774 when you were using some program which uses libbzip2 as a
1717 component, you should also report this bug to the author(s) 1775 component, you should also report this bug to the author(s)
1718 of that program. Please make an effort to report this bug; 1776 of that program. Please make an effort to report this bug;
1719 timely and accurate bug reports eventually lead to higher 1777 timely and accurate bug reports eventually lead to higher
1720 quality software. Thanks. Julian Seward, 24 May 1999. 1778 quality software. Thanks. Julian Seward, 21 March 2000.
1721@end example 1779@end example
1722where @code{N} is some error code number. @code{exit(3)} 1780where @code{N} is some error code number. @code{exit(3)}
1723is then called. 1781is then called.
@@ -1781,7 +1839,7 @@ These are just some random thoughts of mine. Your mileage may
1781vary. 1839vary.
1782 1840
1783@section Limitations of the compressed file format 1841@section Limitations of the compressed file format
1784@code{bzip2-0.9.5} and @code{0.9.0} 1842@code{bzip2-1.0}, @code{0.9.5} and @code{0.9.0}
1785use exactly the same file format as the previous 1843use exactly the same file format as the previous
1786version, @code{bzip2-0.1}. This decision was made in the interests of 1844version, @code{bzip2-0.1}. This decision was made in the interests of
1787stability. Creating yet another incompatible compressed file format 1845stability. Creating yet another incompatible compressed file format
@@ -1860,7 +1918,7 @@ require some careful design of compressed file formats.
1860 1918
1861@section Portability issues 1919@section Portability issues
1862After some consideration, I have decided not to use 1920After some consideration, I have decided not to use
1863GNU @code{autoconf} to configure 0.9.5. 1921GNU @code{autoconf} to configure 0.9.5 or 1.0.
1864 1922
1865@code{autoconf}, admirable and wonderful though it is, 1923@code{autoconf}, admirable and wonderful though it is,
1866mainly assists with portability problems between Unix-like 1924mainly assists with portability problems between Unix-like
@@ -1925,7 +1983,7 @@ If you get problems, try using the flags
1925@code{-O2} @code{-fomit-frame-pointer} @code{-fno-strength-reduce}. 1983@code{-O2} @code{-fomit-frame-pointer} @code{-fno-strength-reduce}.
1926You should specifically @emph{not} use @code{-funroll-loops}. 1984You should specifically @emph{not} use @code{-funroll-loops}.
1927 1985
1928You may notice that the Makefile runs four tests as part of 1986You may notice that the Makefile runs six tests as part of
1929the build process. If the program passes all of these, it's 1987the build process. If the program passes all of these, it's
1930a pretty good (but not 100%) indication that the compiler has 1988a pretty good (but not 100%) indication that the compiler has
1931done its job correctly. 1989done its job correctly.
@@ -2000,6 +2058,7 @@ memory but gets pretty good compression, and has minimal latency,
2000consider Jean-loup 2058consider Jean-loup
2001Gailly's and Mark Adler's work, @code{zlib-1.1.2} and 2059Gailly's and Mark Adler's work, @code{zlib-1.1.2} and
2002@code{gzip-1.2.4}. Look for them at 2060@code{gzip-1.2.4}. Look for them at
2061
2003@code{http://www.cdrom.com/pub/infozip/zlib} and 2062@code{http://www.cdrom.com/pub/infozip/zlib} and
2004@code{http://www.gzip.org} respectively. 2063@code{http://www.gzip.org} respectively.
2005 2064
@@ -2140,7 +2199,14 @@ available from:
2140@example 2199@example
2141http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps 2200http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps
2142@end example 2201@end example
2143 2202Finally, the following paper documents some recent investigations
2203I made into the performance of sorting algorithms:
2204@example
2205Julian Seward:
2206 On the Performance of BWT Sorting Algorithms
2207 Proceedings of the IEEE Data Compression Conference 2000
2208 Snowbird, Utah. 28-30 March 2000.
2209@end example
2144 2210
2145 2211
2146@contents 2212@contents
diff --git a/randtable.c b/randtable.c
index 8f6266f..983089d 100644
--- a/randtable.c
+++ b/randtable.c
@@ -8,7 +8,7 @@
8 This file is a part of bzip2 and/or libbzip2, a program and 8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression. 9 library for lossless, block-sorting data compression.
10 10
11 Copyright (C) 1996-1999 Julian R Seward. All rights reserved. 11 Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
12 12
13 Redistribution and use in source and binary forms, with or without 13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions 14 modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
43 43
44 Julian Seward, Cambridge, UK. 44 Julian Seward, Cambridge, UK.
45 jseward@acm.org 45 jseward@acm.org
46 bzip2/libbzip2 version 0.9.5 of 24 May 1999 46 bzip2/libbzip2 version 1.0 of 21 March 2000
47 47
48 This program is based on (at least) the work of: 48 This program is based on (at least) the work of:
49 Mike Burrows 49 Mike Burrows
@@ -63,7 +63,7 @@
63 63
64 64
65/*---------------------------------------------*/ 65/*---------------------------------------------*/
66Int32 rNums[512] = { 66Int32 BZ2_rNums[512] = {
67 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 67 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
68 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 68 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
69 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 69 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
diff --git a/spewG.c b/spewG.c
new file mode 100644
index 0000000..7934e76
--- /dev/null
+++ b/spewG.c
@@ -0,0 +1,39 @@
1
2/* spew out a thoroughly gigantic file designed so that bzip2
3 can compress it reasonably rapidly. This is to help test
4 support for large files (> 2GB) in a reasonable amount of time.
5 I suggest you use the undocumented --exponential option to
6 bzip2 when compressing the resulting file; this saves a bit of
7 time. Note: *don't* bother with --exponential when compressing
8 Real Files; it'll just waste a lot of CPU time :-)
9 (but is otherwise harmless).
10*/
11
12#define _FILE_OFFSET_BITS 64
13
14#include <stdio.h>
15#include <stdlib.h>
16
17/* The number of megabytes of junk to spew out (roughly) */
18#define MEGABYTES 5000
19
20#define N_BUF 1000000
21char buf[N_BUF];
22
23int main ( int argc, char** argv )
24{
25 int ii, kk, p;
26 srandom(1);
27 setbuffer ( stdout, buf, N_BUF );
28 for (kk = 0; kk < MEGABYTES * 515; kk+=3) {
29 p = 25+random()%50;
30 for (ii = 0; ii < p; ii++)
31 printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
32 for (ii = 0; ii < p-1; ii++)
33 printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" );
34 for (ii = 0; ii < p+1; ii++)
35 printf ( "ccccccccccccccccccccccccccccccccccccc" );
36 }
37 fflush(stdout);
38 return 0;
39}
diff --git a/unzcrash.c b/unzcrash.c
new file mode 100644
index 0000000..f0f17fc
--- /dev/null
+++ b/unzcrash.c
@@ -0,0 +1,126 @@
1
2/* A test program written to test robustness to decompression of
3 corrupted data. Usage is
4 unzcrash filename
5 and the program will read the specified file, compress it (in memory),
6 and then repeatedly decompress it, each time with a different bit of
7 the compressed data inverted, so as to test all possible one-bit errors.
8 This should not cause any invalid memory accesses. If it does,
9 I want to know about it!
10
11 p.s. As you can see from the above description, the process is
12 incredibly slow. A file of size eg 5KB will cause it to run for
13 many hours.
14*/
15
16#include <stdio.h>
17#include <assert.h>
18#include "bzlib.h"
19
20#define M_BLOCK 1000000
21
22typedef unsigned char uchar;
23
24#define M_BLOCK_OUT (M_BLOCK + 1000000)
25uchar inbuf[M_BLOCK];
26uchar outbuf[M_BLOCK_OUT];
27uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
28
29int nIn, nOut, nZ;
30
31static char *bzerrorstrings[] = {
32 "OK"
33 ,"SEQUENCE_ERROR"
34 ,"PARAM_ERROR"
35 ,"MEM_ERROR"
36 ,"DATA_ERROR"
37 ,"DATA_ERROR_MAGIC"
38 ,"IO_ERROR"
39 ,"UNEXPECTED_EOF"
40 ,"OUTBUFF_FULL"
41 ,"???" /* for future */
42 ,"???" /* for future */
43 ,"???" /* for future */
44 ,"???" /* for future */
45 ,"???" /* for future */
46 ,"???" /* for future */
47};
48
49void flip_bit ( int bit )
50{
51 int byteno = bit / 8;
52 int bitno = bit % 8;
53 uchar mask = 1 << bitno;
54 //fprintf ( stderr, "(byte %d bit %d mask %d)",
55 // byteno, bitno, (int)mask );
56 zbuf[byteno] ^= mask;
57}
58
59int main ( int argc, char** argv )
60{
61 FILE* f;
62 int r;
63 int bit;
64 int i;
65
66 if (argc != 2) {
67 fprintf ( stderr, "usage: unzcrash filename\n" );
68 return 1;
69 }
70
71 f = fopen ( argv[1], "r" );
72 if (!f) {
73 fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
74 return 1;
75 }
76
77 nIn = fread ( inbuf, 1, M_BLOCK, f );
78 fprintf ( stderr, "%d bytes read\n", nIn );
79
80 nZ = M_BLOCK;
81 r = BZ2_bzBuffToBuffCompress (
82 zbuf, &nZ, inbuf, nIn, 9, 0, 30 );
83
84 assert (r == BZ_OK);
85 fprintf ( stderr, "%d after compression\n", nZ );
86
87 for (bit = 0; bit < nZ*8; bit++) {
88 fprintf ( stderr, "bit %d ", bit );
89 flip_bit ( bit );
90 nOut = M_BLOCK_OUT;
91 r = BZ2_bzBuffToBuffDecompress (
92 outbuf, &nOut, zbuf, nZ, 0, 0 );
93 fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] );
94
95 if (r != BZ_OK) {
96 fprintf ( stderr, "\n" );
97 } else {
98 if (nOut != nIn) {
99 fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
100 return 1;
101 } else {
102 for (i = 0; i < nOut; i++)
103 if (inbuf[i] != outbuf[i]) {
104 fprintf(stderr, "mismatch at %d\n", i );
105 return 1;
106 }
107 if (i == nOut) fprintf(stderr, "really ok!\n" );
108 }
109 }
110
111 flip_bit ( bit );
112 }
113
114#if 0
115 assert (nOut == nIn);
116 for (i = 0; i < nOut; i++) {
117 if (inbuf[i] != outbuf[i]) {
118 fprintf ( stderr, "difference at %d !\n", i );
119 return 1;
120 }
121 }
122#endif
123
124 fprintf ( stderr, "all ok\n" );
125 return 0;
126}
diff --git a/words0 b/words0
new file mode 100644
index 0000000..164a8ed
--- /dev/null
+++ b/words0
@@ -0,0 +1,5 @@
1
2If compilation produces errors, or a large number of warnings,
3please read README.COMPILATION.PROBLEMS -- you might be able to
4adjust the flags in this Makefile to improve matters.
5