summaryrefslogtreecommitdiffstats
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
parentbzip2-0.9.5d (diff)
downloadbzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.tar.gz
bzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.tar.bz2
bzip2-795b859eee96c700e8f3c3fe68e6a9a39d95797c.tar.xz
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];