mirror of
git://sourceware.org/git/bzip2.git
synced 2024-11-23 11:43:28 +08:00
bzip2-1.0.1
This commit is contained in:
parent
f93cd82a9a
commit
795b859eee
67
CHANGES
67
CHANGES
@ -98,3 +98,70 @@ functioning of the bzip2 program or library. Added a couple of casts
|
||||
so the library compiles without warnings at level 3 in MS Visual
|
||||
Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
|
||||
changes are minor documentation changes.
|
||||
|
||||
1.0
|
||||
~~~
|
||||
Several minor bugfixes and enhancements:
|
||||
|
||||
* Large file support. The library uses 64-bit counters to
|
||||
count the volume of data passing through it. bzip2.c
|
||||
is now compiled with -D_FILE_OFFSET_BITS=64 to get large
|
||||
file support from the C library. -v correctly prints out
|
||||
file sizes greater than 4 gigabytes. All these changes have
|
||||
been made without assuming a 64-bit platform or a C compiler
|
||||
which supports 64-bit ints, so, except for the C library
|
||||
aspect, they are fully portable.
|
||||
|
||||
* Decompression robustness. The library/program should be
|
||||
robust to any corruption of compressed data, detecting and
|
||||
handling _all_ corruption, instead of merely relying on
|
||||
the CRCs. What this means is that the program should
|
||||
never crash, given corrupted data, and the library should
|
||||
always return BZ_DATA_ERROR.
|
||||
|
||||
* Fixed an obscure race-condition bug only ever observed on
|
||||
Solaris, in which, if you were very unlucky and issued
|
||||
control-C at exactly the wrong time, both input and output
|
||||
files would be deleted.
|
||||
|
||||
* Don't run out of file handles on test/decompression when
|
||||
large numbers of files have invalid magic numbers.
|
||||
|
||||
* Avoid library namespace pollution. Prefix all exported
|
||||
symbols with BZ2_.
|
||||
|
||||
* Minor sorting enhancements from my DCC2000 paper.
|
||||
|
||||
* Advance the version number to 1.0, so as to counteract the
|
||||
(false-in-this-case) impression some people have that programs
|
||||
with version numbers less than 1.0 are in someway, experimental,
|
||||
pre-release versions.
|
||||
|
||||
* Create an initial Makefile-libbz2_so to build a shared library.
|
||||
Yes, I know I should really use libtool et al ...
|
||||
|
||||
* Make the program exit with 2 instead of 0 when decompression
|
||||
fails due to a bad magic number (ie, an invalid bzip2 header).
|
||||
Also exit with 1 (as the manual claims :-) whenever a diagnostic
|
||||
message would have been printed AND the corresponding operation
|
||||
is aborted, for example
|
||||
bzip2: Output file xx already exists.
|
||||
When a diagnostic message is printed but the operation is not
|
||||
aborted, for example
|
||||
bzip2: Can't guess original name for wurble -- using wurble.out
|
||||
then the exit value 0 is returned, unless some other problem is
|
||||
also detected.
|
||||
|
||||
I think it corresponds more closely to what the manual claims now.
|
||||
|
||||
|
||||
1.0.1
|
||||
~~~~~
|
||||
* Modified dlltest.c so it uses the new BZ2_ naming scheme.
|
||||
* Modified makefile-msc to fix minor build probs on Win2k.
|
||||
* Updated README.COMPILATION.PROBLEMS.
|
||||
|
||||
There are no functionality changes or bug fixes relative to version
|
||||
1.0.0. This is just a documentation update + a fix for minor Win32
|
||||
build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
|
||||
utterly pointless. Don't bother.
|
||||
|
4
LICENSE
4
LICENSE
@ -1,6 +1,6 @@
|
||||
|
||||
This program, "bzip2" and associated library "libbzip2", are
|
||||
copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -35,5 +35,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
|
58
Makefile
58
Makefile
@ -1,7 +1,8 @@
|
||||
|
||||
SHELL=/bin/sh
|
||||
CC=gcc
|
||||
CFLAGS=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce
|
||||
BIGFILES=-D_FILE_OFFSET_BITS=64
|
||||
CFLAGS=-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
|
||||
|
||||
OBJS= blocksort.o \
|
||||
huffman.o \
|
||||
@ -73,6 +74,7 @@ clean:
|
||||
sample1.tst sample2.tst sample3.tst
|
||||
|
||||
blocksort.o: blocksort.c
|
||||
@cat words0
|
||||
$(CC) $(CFLAGS) -c blocksort.c
|
||||
huffman.o: huffman.c
|
||||
$(CC) $(CFLAGS) -c huffman.c
|
||||
@ -91,13 +93,49 @@ bzip2.o: bzip2.c
|
||||
bzip2recover.o: bzip2recover.c
|
||||
$(CC) $(CFLAGS) -c bzip2recover.c
|
||||
|
||||
DISTNAME=bzip2-1.0.1
|
||||
tarfile:
|
||||
tar cvf interim.tar blocksort.c huffman.c crctable.c \
|
||||
randtable.c compress.c decompress.c bzlib.c bzip2.c \
|
||||
bzip2recover.c bzlib.h bzlib_private.h Makefile manual.texi \
|
||||
manual.ps LICENSE bzip2.1 bzip2.1.preformatted bzip2.txt \
|
||||
words1 words2 words3 sample1.ref sample2.ref sample3.ref \
|
||||
sample1.bz2 sample2.bz2 sample3.bz2 dlltest.c \
|
||||
*.html README CHANGES libbz2.def libbz2.dsp \
|
||||
dlltest.dsp makefile.msc Y2K_INFO
|
||||
|
||||
rm -f $(DISTNAME)
|
||||
ln -sf . $(DISTNAME)
|
||||
tar cvf $(DISTNAME).tar \
|
||||
$(DISTNAME)/blocksort.c \
|
||||
$(DISTNAME)/huffman.c \
|
||||
$(DISTNAME)/crctable.c \
|
||||
$(DISTNAME)/randtable.c \
|
||||
$(DISTNAME)/compress.c \
|
||||
$(DISTNAME)/decompress.c \
|
||||
$(DISTNAME)/bzlib.c \
|
||||
$(DISTNAME)/bzip2.c \
|
||||
$(DISTNAME)/bzip2recover.c \
|
||||
$(DISTNAME)/bzlib.h \
|
||||
$(DISTNAME)/bzlib_private.h \
|
||||
$(DISTNAME)/Makefile \
|
||||
$(DISTNAME)/manual.texi \
|
||||
$(DISTNAME)/manual.ps \
|
||||
$(DISTNAME)/LICENSE \
|
||||
$(DISTNAME)/bzip2.1 \
|
||||
$(DISTNAME)/bzip2.1.preformatted \
|
||||
$(DISTNAME)/bzip2.txt \
|
||||
$(DISTNAME)/words0 \
|
||||
$(DISTNAME)/words1 \
|
||||
$(DISTNAME)/words2 \
|
||||
$(DISTNAME)/words3 \
|
||||
$(DISTNAME)/sample1.ref \
|
||||
$(DISTNAME)/sample2.ref \
|
||||
$(DISTNAME)/sample3.ref \
|
||||
$(DISTNAME)/sample1.bz2 \
|
||||
$(DISTNAME)/sample2.bz2 \
|
||||
$(DISTNAME)/sample3.bz2 \
|
||||
$(DISTNAME)/dlltest.c \
|
||||
$(DISTNAME)/*.html \
|
||||
$(DISTNAME)/README \
|
||||
$(DISTNAME)/README.COMPILATION.PROBLEMS \
|
||||
$(DISTNAME)/CHANGES \
|
||||
$(DISTNAME)/libbz2.def \
|
||||
$(DISTNAME)/libbz2.dsp \
|
||||
$(DISTNAME)/dlltest.dsp \
|
||||
$(DISTNAME)/makefile.msc \
|
||||
$(DISTNAME)/Y2K_INFO \
|
||||
$(DISTNAME)/unzcrash.c \
|
||||
$(DISTNAME)/spewG.c \
|
||||
$(DISTNAME)/Makefile-libbz2_so
|
||||
|
43
Makefile-libbz2_so
Normal file
43
Makefile-libbz2_so
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
# This Makefile builds a shared version of the library,
|
||||
# libbz2.so.1.0.1, with soname libbz2.so.1.0,
|
||||
# at least on x86-Linux (RedHat 5.2),
|
||||
# with gcc-2.7.2.3. Please see the README file for some
|
||||
# important info about building the library like this.
|
||||
|
||||
SHELL=/bin/sh
|
||||
CC=gcc
|
||||
BIGFILES=-D_FILE_OFFSET_BITS=64
|
||||
CFLAGS=-fpic -fPIC -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce $(BIGFILES)
|
||||
|
||||
OBJS= blocksort.o \
|
||||
huffman.o \
|
||||
crctable.o \
|
||||
randtable.o \
|
||||
compress.o \
|
||||
decompress.o \
|
||||
bzlib.o
|
||||
|
||||
all: $(OBJS)
|
||||
$(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.1 $(OBJS)
|
||||
$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.1
|
||||
rm -f libbz2.so.1.0
|
||||
ln -s libbz2.so.1.0.1 libbz2.so.1.0
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) bzip2.o libbz2.so.1.0.1 libbz2.so.1.0 bzip2-shared
|
||||
|
||||
blocksort.o: blocksort.c
|
||||
$(CC) $(CFLAGS) -c blocksort.c
|
||||
huffman.o: huffman.c
|
||||
$(CC) $(CFLAGS) -c huffman.c
|
||||
crctable.o: crctable.c
|
||||
$(CC) $(CFLAGS) -c crctable.c
|
||||
randtable.o: randtable.c
|
||||
$(CC) $(CFLAGS) -c randtable.c
|
||||
compress.o: compress.c
|
||||
$(CC) $(CFLAGS) -c compress.c
|
||||
decompress.o: decompress.c
|
||||
$(CC) $(CFLAGS) -c decompress.c
|
||||
bzlib.o: bzlib.c
|
||||
$(CC) $(CFLAGS) -c bzlib.c
|
43
README
43
README
@ -1,9 +1,9 @@
|
||||
|
||||
This is the README for bzip2, a block-sorting file compressor, version
|
||||
0.9.5d. This version is fully compatible with the previous public
|
||||
releases, bzip2-0.1pl2 and bzip2-0.9.0.
|
||||
1.0. This version is fully compatible with the previous public
|
||||
releases, bzip2-0.1pl2, bzip2-0.9.0 and bzip2-0.9.5.
|
||||
|
||||
bzip2-0.9.5 is distributed under a BSD-style license. For details,
|
||||
bzip2-1.0 is distributed under a BSD-style license. For details,
|
||||
see the file LICENSE.
|
||||
|
||||
Complete 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
|
||||
not actually execute them.
|
||||
|
||||
|
||||
HOW TO BUILD -- UNIX, shared library libbz2.so.
|
||||
|
||||
Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for
|
||||
Linux-ELF (RedHat 5.2 on an x86 box), with gcc. I make no claims
|
||||
that it works for any other platform, though I suspect it probably
|
||||
will work for most platforms employing both ELF and gcc.
|
||||
|
||||
bzip2-shared, a client of the shared library, is also build, but
|
||||
not self-tested. So I suggest you also build using the normal
|
||||
Makefile, since that conducts a self-test.
|
||||
|
||||
Important note for people upgrading .so's from 0.9.0/0.9.5 to
|
||||
version 1.0. All the functions in the library have been renamed,
|
||||
from (eg) bzCompress to BZ2_bzCompress, to avoid namespace pollution.
|
||||
Unfortunately this means that the libbz2.so created by
|
||||
Makefile-libbz2_so will not work with any program which used an
|
||||
older version of the library. Sorry. I do encourage library
|
||||
clients to make the effort to upgrade to use version 1.0, since
|
||||
it is both faster and more robust than previous versions.
|
||||
|
||||
|
||||
HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
|
||||
|
||||
It's difficult for me to support compilation on all these platforms.
|
||||
My approach is to collect binaries for these platforms, and put them
|
||||
on my web page (http://www.muraroa.demon.co.uk). Look there. However
|
||||
(FWIW), bzip2-0.9.5 is very standard ANSI C and should compile
|
||||
unmodified with MS Visual C. For Win32, there is one important
|
||||
caveat: in bzip2.c, you must set BZ_UNIX to 0 and BZ_LCCWIN32 to 1
|
||||
before building.
|
||||
on the master web page (http://sourceware.cygnus.com/bzip2). Look
|
||||
there. However (FWIW), bzip2-1.0 is very standard ANSI C and should
|
||||
compile unmodified with MS Visual C. For Win32, there is one
|
||||
important caveat: in bzip2.c, you must set BZ_UNIX to 0 and
|
||||
BZ_LCCWIN32 to 1 before building. If you have difficulties building,
|
||||
you might want to read README.COMPILATION.PROBLEMS.
|
||||
|
||||
|
||||
VALIDATION
|
||||
@ -116,6 +138,10 @@ WHAT'S NEW IN 0.9.5 ?
|
||||
* Many small improvements in file and flag handling.
|
||||
* A Y2K statement.
|
||||
|
||||
WHAT'S NEW IN 1.0
|
||||
|
||||
See the CHANGES file.
|
||||
|
||||
I hope you find bzip2 useful. Feel free to contact me at
|
||||
jseward@acm.org
|
||||
if you have any suggestions or queries. Many people mailed me with
|
||||
@ -137,3 +163,4 @@ Cambridge, UK
|
||||
23 August 1998 (bzip2, version 0.9.0)
|
||||
8 June 1999 (bzip2, version 0.9.5)
|
||||
4 Sept 1999 (bzip2, version 0.9.5d)
|
||||
5 May 2000 (bzip2, version 1.0pre8)
|
||||
|
130
README.COMPILATION.PROBLEMS
Normal file
130
README.COMPILATION.PROBLEMS
Normal file
@ -0,0 +1,130 @@
|
||||
|
||||
bzip2-1.0 should compile without problems on the vast majority of
|
||||
platforms. Using the supplied Makefile, I've built and tested it
|
||||
myself for x86-linux, sparc-solaris, alpha-linux, x86-cygwin32 and
|
||||
alpha-tru64unix. With makefile.msc, Visual C++ 6.0 and nmake, you can
|
||||
build a native Win32 version too. Large file support seems to work
|
||||
correctly on at least alpha-tru64unix and x86-cygwin32 (on Windows
|
||||
2000).
|
||||
|
||||
When I say "large file" I mean a file of size 2,147,483,648 (2^31)
|
||||
bytes or above. Many older OSs can't handle files above this size,
|
||||
but many newer ones can. Large files are pretty huge -- most files
|
||||
you'll encounter are not Large Files.
|
||||
|
||||
Earlier versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide
|
||||
variety of platforms without difficulty, and I hope this version will
|
||||
continue in that tradition. However, in order to support large files,
|
||||
I've had to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.
|
||||
This can cause problems.
|
||||
|
||||
The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
|
||||
support is, as far as I know, the Recommended Way to get correct large
|
||||
file support. For more details, see the Large File Support
|
||||
Specification, published by the Large File Summit, at
|
||||
http://www.sas.com/standard/large.file/
|
||||
|
||||
As a general comment, if you get compilation errors which you think
|
||||
are related to large file support, try removing the above define from
|
||||
the Makefile, ie, delete the line
|
||||
BIGFILES=-D_FILE_OFFSET_BITS=64
|
||||
from the Makefile, and do 'make clean ; make'. This will give you a
|
||||
version of bzip2 without large file support, which, for most
|
||||
applications, is probably not a problem.
|
||||
|
||||
Alternatively, try some of the platform-specific hints listed below.
|
||||
|
||||
You can use the spewG.c program to generate huge files to test bzip2's
|
||||
large file support, if you are feeling paranoid. Be aware though that
|
||||
any compilation problems which affect bzip2 will also affect spewG.c,
|
||||
alas.
|
||||
|
||||
|
||||
Known problems as of 1.0pre8:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* HP/UX 10.20 and 11.00, using gcc (2.7.2.3 and 2.95.2): A large
|
||||
number of warnings appear, including the following:
|
||||
|
||||
/usr/include/sys/resource.h: In function `getrlimit':
|
||||
/usr/include/sys/resource.h:168:
|
||||
warning: implicit declaration of function `__getrlimit64'
|
||||
/usr/include/sys/resource.h: In function `setrlimit':
|
||||
/usr/include/sys/resource.h:170:
|
||||
warning: implicit declaration of function `__setrlimit64'
|
||||
|
||||
This would appear to be a problem with large file support, header
|
||||
files and gcc. gcc may or may not give up at this point. If it
|
||||
fails, you might be able to improve matters by adding
|
||||
-D__STDC_EXT__=1
|
||||
to the BIGFILES variable in the Makefile (ie, change its definition
|
||||
to
|
||||
BIGFILES=-D_FILE_OFFSET_BITS=64 -D__STDC_EXT__=1
|
||||
|
||||
Even if gcc does produce a binary which appears to work (ie passes
|
||||
its self-tests), you might want to test it to see if it works properly
|
||||
on large files.
|
||||
|
||||
|
||||
* HP/UX 10.20 and 11.00, using HP's cc compiler.
|
||||
|
||||
No specific problems for this combination, except that you'll need to
|
||||
specify the -Ae flag, and zap the gcc-specific stuff
|
||||
-Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce.
|
||||
You should retain -D_FILE_OFFSET_BITS=64 in order to get large
|
||||
file support -- which is reported to work ok for this HP/UX + cc
|
||||
combination.
|
||||
|
||||
|
||||
* SunOS 4.1.X.
|
||||
|
||||
Amazingly, there are still people out there using this venerable old
|
||||
banger. I shouldn't be too rude -- I started life on SunOS, and
|
||||
it was a pretty darn good OS, way back then. Anyway:
|
||||
|
||||
SunOS doesn't seem to have strerror(), so you'll have to use
|
||||
perror(), perhaps by doing adding this (warning: UNTESTED CODE):
|
||||
|
||||
char* strerror ( int errnum )
|
||||
{
|
||||
if (errnum < 0 || errnum >= sys_nerr)
|
||||
return "Unknown error";
|
||||
else
|
||||
return sys_errlist[errnum];
|
||||
}
|
||||
|
||||
Or you could comment out the relevant calls to strerror; they're
|
||||
not mission-critical. Or you could upgrade to Solaris. Ha ha ha!
|
||||
(what?? you think I've got Bad Attitude?)
|
||||
|
||||
|
||||
* Making a shared library on Solaris. (Not really a compilation
|
||||
problem, but many people ask ...)
|
||||
|
||||
Firstly, if you have Solaris 8, either you have libbz2.so already
|
||||
on your system, or you can install it from the Solaris CD.
|
||||
|
||||
Secondly, be aware that there are potential naming conflicts
|
||||
between the .so file supplied with Solaris 8, and the .so file
|
||||
which Makefile-libbz2_so will make. Makefile-libbz2_so creates
|
||||
a .so which has the names which I intend to be "official" as
|
||||
of version 1.0.0 and onwards. Unfortunately, the .so in
|
||||
Solaris 8 appeared before I decided on the final names, so
|
||||
the two libraries are incompatible. We have since communicated
|
||||
and I hope that the problems will have been solved in the next
|
||||
version of Solaris, whenever that might appear.
|
||||
|
||||
All that said: you might be able to get somewhere
|
||||
by finding the line in Makefile-libbz2_so which says
|
||||
|
||||
$(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.1 $(OBJS)
|
||||
|
||||
and replacing with
|
||||
|
||||
($CC) -G -shared -o libbz2.so.1.0.1 -h libbz2.so.1.0 $(OBJS)
|
||||
|
||||
If gcc objects to the combination -fpic -fPIC, get rid of
|
||||
the second one, leaving just "-fpic".
|
||||
|
||||
|
||||
That's the end of the currently known compilation problems.
|
343
blocksort.c
343
blocksort.c
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -56,6 +56,13 @@
|
||||
Jon L. Bentley
|
||||
|
||||
For more information on these sources, see the manual.
|
||||
|
||||
To get some idea how the block sorting algorithms in this file
|
||||
work, read my paper
|
||||
On the Performance of BWT Sorting Algorithms
|
||||
in Proceedings of the IEEE Data Compression Conference 2000,
|
||||
Snowbird, Utah, USA, 27-30 March 2000. The main sort in this
|
||||
file implements the algorithm called cache in the paper.
|
||||
--*/
|
||||
|
||||
|
||||
@ -232,11 +239,11 @@ void fallbackQSort3 ( UInt32* fmap,
|
||||
/* Pre:
|
||||
nblock > 0
|
||||
eclass exists for [0 .. nblock-1]
|
||||
((UInt16*)eclass) [0 .. nblock-1] [15:8] holds block
|
||||
((UChar*)eclass) [0 .. nblock-1] holds block
|
||||
ptr exists for [0 .. nblock-1]
|
||||
|
||||
Post:
|
||||
((UInt16*)eclass) [0 .. nblock-1] [15:8] holds block
|
||||
((UChar*)eclass) [0 .. nblock-1] holds block
|
||||
All other areas of eclass destroyed
|
||||
fmap [0 .. nblock-1] holds sorted order
|
||||
bhtab [ 0 .. 2+(nblock/32) ] destroyed
|
||||
@ -260,7 +267,7 @@ void fallbackSort ( UInt32* fmap,
|
||||
Int32 H, i, j, k, l, r, cc, cc1;
|
||||
Int32 nNotDone;
|
||||
Int32 nBhtab;
|
||||
UInt16* eclass16 = (UInt16*)eclass;
|
||||
UChar* eclass8 = (UChar*)eclass;
|
||||
|
||||
/*--
|
||||
Initial 1-char radix sort to generate
|
||||
@ -269,12 +276,12 @@ void fallbackSort ( UInt32* fmap,
|
||||
if (verb >= 4)
|
||||
VPrintf0 ( " bucket sorting ...\n" );
|
||||
for (i = 0; i < 257; i++) ftab[i] = 0;
|
||||
for (i = 0; i < nblock; i++) ftab[eclass16[i] >> 8]++;
|
||||
for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
|
||||
for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
|
||||
for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
|
||||
|
||||
for (i = 0; i < nblock; i++) {
|
||||
j = eclass16[i] >> 8;
|
||||
j = eclass8[i];
|
||||
k = ftab[j] - 1;
|
||||
ftab[j] = k;
|
||||
fmap[k] = i;
|
||||
@ -354,7 +361,7 @@ void fallbackSort ( UInt32* fmap,
|
||||
|
||||
/*--
|
||||
Reconstruct the original block in
|
||||
eclass16 [0 .. nblock-1] [15:8], since the
|
||||
eclass8 [0 .. nblock-1], since the
|
||||
previous phase destroyed it.
|
||||
--*/
|
||||
if (verb >= 4)
|
||||
@ -363,7 +370,7 @@ void fallbackSort ( UInt32* fmap,
|
||||
for (i = 0; i < nblock; i++) {
|
||||
while (ftabCopy[j] == 0) j++;
|
||||
ftabCopy[j]--;
|
||||
eclass16[fmap[i]] = j << 8;
|
||||
eclass8[fmap[i]] = (UChar)j;
|
||||
}
|
||||
AssertH ( j < 256, 1005 );
|
||||
}
|
||||
@ -386,67 +393,116 @@ static
|
||||
__inline__
|
||||
Bool mainGtU ( UInt32 i1,
|
||||
UInt32 i2,
|
||||
UInt16* block,
|
||||
UChar* block,
|
||||
UInt16* quadrant,
|
||||
UInt32 nblock,
|
||||
Int32* budget )
|
||||
{
|
||||
Int32 k;
|
||||
Int32 k;
|
||||
UChar c1, c2;
|
||||
UInt16 s1, s2;
|
||||
|
||||
AssertD ( i1 != i2, "mainGtU" );
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
/* 1 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 2 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 3 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 4 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 5 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 6 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 7 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 8 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 9 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 10 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 11 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
/* 12 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
i1++; i2++;
|
||||
|
||||
k = nblock + 8;
|
||||
|
||||
do {
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
/* 1 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
/* 2 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
/* 3 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
|
||||
s1 = block[i1]; s2 = block[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
/* 4 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1 += 2; i2 += 2;
|
||||
i1++; i2++;
|
||||
/* 5 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
/* 6 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
/* 7 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
/* 8 */
|
||||
c1 = block[i1]; c2 = block[i2];
|
||||
if (c1 != c2) return (c1 > c2);
|
||||
s1 = quadrant[i1]; s2 = quadrant[i2];
|
||||
if (s1 != s2) return (s1 > s2);
|
||||
i1++; i2++;
|
||||
|
||||
if (i1 >= nblock) i1 -= nblock;
|
||||
if (i2 >= nblock) i2 -= nblock;
|
||||
@ -467,13 +523,14 @@ Bool mainGtU ( UInt32 i1,
|
||||
because the number of elems to sort is
|
||||
usually small, typically <= 20.
|
||||
--*/
|
||||
static
|
||||
Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
|
||||
9841, 29524, 88573, 265720,
|
||||
797161, 2391484 };
|
||||
|
||||
static
|
||||
void mainSimpleSort ( UInt32* ptr,
|
||||
UInt16* block,
|
||||
UChar* block,
|
||||
UInt16* quadrant,
|
||||
Int32 nblock,
|
||||
Int32 lo,
|
||||
@ -568,19 +625,19 @@ void mainSimpleSort ( UInt32* ptr,
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
__inline__
|
||||
UInt16 mmed3 ( UInt16 a, UInt16 b, UInt16 c )
|
||||
UChar mmed3 ( UChar a, UChar b, UChar c )
|
||||
{
|
||||
UInt16 t;
|
||||
UChar t;
|
||||
if (a > b) { t = a; a = b; b = t; };
|
||||
if (b > c) { t = b; b = c; c = t; };
|
||||
if (a > b) b = a;
|
||||
if (b > c) {
|
||||
b = c;
|
||||
if (a > b) b = a;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
#define mmin(a,b) ((a) < (b)) ? (a) : (b)
|
||||
|
||||
#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
|
||||
@ -609,7 +666,7 @@ UInt16 mmed3 ( UInt16 a, UInt16 b, UInt16 c )
|
||||
|
||||
static
|
||||
void mainQSort3 ( UInt32* ptr,
|
||||
UInt16* block,
|
||||
UChar* block,
|
||||
UInt16* quadrant,
|
||||
Int32 nblock,
|
||||
Int32 loSt,
|
||||
@ -679,7 +736,7 @@ void mainQSort3 ( UInt32* ptr,
|
||||
AssertD ( unHi == unLo-1, "mainQSort3(2)" );
|
||||
|
||||
if (gtHi < ltLo) {
|
||||
mpush(lo, hi, d+2 );
|
||||
mpush(lo, hi, d+1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -691,7 +748,7 @@ void mainQSort3 ( UInt32* ptr,
|
||||
|
||||
nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
|
||||
nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
|
||||
nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+2;
|
||||
nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
|
||||
|
||||
if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
|
||||
if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
|
||||
@ -722,11 +779,11 @@ void mainQSort3 ( UInt32* ptr,
|
||||
/* Pre:
|
||||
nblock > N_OVERSHOOT
|
||||
block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
|
||||
((UInt16*)block32) [0 .. nblock-1] [15:8] holds block
|
||||
((UChar*)block32) [0 .. nblock-1] holds block
|
||||
ptr exists for [0 .. nblock-1]
|
||||
|
||||
Post:
|
||||
((UInt16*)block32) [0 .. nblock-1] [15:8] holds block
|
||||
((UChar*)block32) [0 .. nblock-1] holds block
|
||||
All other areas of block32 destroyed
|
||||
ftab [0 .. 65536 ] destroyed
|
||||
ptr [0 .. nblock-1] holds sorted order
|
||||
@ -739,40 +796,47 @@ void mainQSort3 ( UInt32* ptr,
|
||||
|
||||
static
|
||||
void mainSort ( UInt32* ptr,
|
||||
UInt16* block,
|
||||
UChar* block,
|
||||
UInt16* quadrant,
|
||||
UInt32* ftab,
|
||||
Int32 nblock,
|
||||
Int32 verb,
|
||||
Int32* budget )
|
||||
{
|
||||
Int32 i, j, k, m, ss, sb;
|
||||
Int32 i, j, k, ss, sb;
|
||||
Int32 runningOrder[256];
|
||||
Int32 copy[256];
|
||||
Bool bigDone[256];
|
||||
Int32 copyStart[256];
|
||||
Int32 copyEnd [256];
|
||||
UChar c1;
|
||||
Int32 numQSorted;
|
||||
Int32 biggestSoFar;
|
||||
UInt16 s;
|
||||
|
||||
if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
|
||||
|
||||
/*-- Stripe the block data into 16 bits, and at the
|
||||
same time set up the 2-byte frequency table
|
||||
--*/
|
||||
/*-- set up the 2-byte frequency table --*/
|
||||
for (i = 65536; i >= 0; i--) ftab[i] = 0;
|
||||
|
||||
s = block[0];
|
||||
for (i = 1; i < nblock; i++) {
|
||||
j = block[0] << 8;
|
||||
i = nblock-1;
|
||||
for (; i >= 3; i -= 4) {
|
||||
quadrant[i] = 0;
|
||||
s = (s << 8) | block[i];
|
||||
block[i-1] = s;
|
||||
ftab[s]++;
|
||||
j = (j >> 8) | ( ((UInt16)block[i]) << 8);
|
||||
ftab[j]++;
|
||||
quadrant[i-1] = 0;
|
||||
j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
|
||||
ftab[j]++;
|
||||
quadrant[i-2] = 0;
|
||||
j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
|
||||
ftab[j]++;
|
||||
quadrant[i-3] = 0;
|
||||
j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
|
||||
ftab[j]++;
|
||||
}
|
||||
for (; i >= 0; i--) {
|
||||
quadrant[i] = 0;
|
||||
j = (j >> 8) | ( ((UInt16)block[i]) << 8);
|
||||
ftab[j]++;
|
||||
}
|
||||
quadrant[0] = 0;
|
||||
s = (s << 8) | (block[0] >> 8);
|
||||
block[nblock-1] = s;
|
||||
ftab[s]++;
|
||||
|
||||
/*-- (emphasises close relationship of block & quadrant) --*/
|
||||
for (i = 0; i < BZ_N_OVERSHOOT; i++) {
|
||||
@ -785,9 +849,29 @@ void mainSort ( UInt32* ptr,
|
||||
/*-- Complete the initial radix sort --*/
|
||||
for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
|
||||
|
||||
for (i = 0; i < nblock; i++) {
|
||||
s = block[i];
|
||||
j = ftab[s] - 1;
|
||||
s = block[0] << 8;
|
||||
i = nblock-1;
|
||||
for (; i >= 3; i -= 4) {
|
||||
s = (s >> 8) | (block[i] << 8);
|
||||
j = ftab[s] -1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i;
|
||||
s = (s >> 8) | (block[i-1] << 8);
|
||||
j = ftab[s] -1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i-1;
|
||||
s = (s >> 8) | (block[i-2] << 8);
|
||||
j = ftab[s] -1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i-2;
|
||||
s = (s >> 8) | (block[i-3] << 8);
|
||||
j = ftab[s] -1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i-3;
|
||||
}
|
||||
for (; i >= 0; i--) {
|
||||
s = (s >> 8) | (block[i] << 8);
|
||||
j = ftab[s] -1;
|
||||
ftab[s] = j;
|
||||
ptr[j] = i;
|
||||
}
|
||||
@ -826,13 +910,13 @@ void mainSort ( UInt32* ptr,
|
||||
The main sorting loop.
|
||||
--*/
|
||||
|
||||
biggestSoFar = numQSorted = 0;
|
||||
numQSorted = 0;
|
||||
|
||||
for (i = 0; i <= 255; i++) {
|
||||
|
||||
/*--
|
||||
Process big buckets, starting with the least full.
|
||||
Basically this is a 4-step process in which we call
|
||||
Basically this is a 3-step process in which we call
|
||||
mainQSort3 to sort the small buckets [ss, j], but
|
||||
also make a big effort to avoid the calls if we can.
|
||||
--*/
|
||||
@ -869,39 +953,38 @@ void mainSort ( UInt32* ptr,
|
||||
}
|
||||
}
|
||||
|
||||
AssertH ( !bigDone[ss], 1006 );
|
||||
|
||||
/*--
|
||||
Step 2:
|
||||
Deal specially with case [ss, ss]. This establishes the
|
||||
sorted order for [ss, ss] without any comparisons.
|
||||
A clever trick, cryptically described as steps Q6b and Q6c
|
||||
in SRC-124 (aka BW94). Compared to bzip2, this makes it
|
||||
practical not to use a preliminary run-length coder.
|
||||
Now scan this big bucket [ss] so as to synthesise the
|
||||
sorted order for small buckets [t, ss] for all t,
|
||||
including, magically, the bucket [ss,ss] too.
|
||||
This will avoid doing Real Work in subsequent Step 1's.
|
||||
--*/
|
||||
{
|
||||
Int32 put0, get0, put1, get1;
|
||||
Int32 sbn = (ss << 8) + ss;
|
||||
Int32 lo = ftab[sbn] & CLEARMASK;
|
||||
Int32 hi = (ftab[sbn+1] & CLEARMASK) - 1;
|
||||
UChar ssc = (UChar)ss;
|
||||
put0 = lo;
|
||||
get0 = ftab[ss << 8] & CLEARMASK;
|
||||
put1 = hi;
|
||||
get1 = (ftab[(ss+1) << 8] & CLEARMASK) - 1;
|
||||
while (get0 < put0) {
|
||||
j = ptr[get0]-1; if (j < 0) j += nblock;
|
||||
c1 = (UChar)(block[j] >> 8);
|
||||
if (c1 == ssc) { ptr[put0] = j; put0++; };
|
||||
get0++;
|
||||
for (j = 0; j <= 255; j++) {
|
||||
copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
|
||||
copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
|
||||
}
|
||||
while (get1 > put1) {
|
||||
j = ptr[get1]-1; if (j < 0) j += nblock;
|
||||
c1 = (UChar)(block[j] >> 8);
|
||||
if (c1 == ssc) { ptr[put1] = j; put1--; };
|
||||
get1--;
|
||||
for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
|
||||
k = ptr[j]-1; if (k < 0) k += nblock;
|
||||
c1 = block[k];
|
||||
if (!bigDone[c1])
|
||||
ptr[ copyStart[c1]++ ] = k;
|
||||
}
|
||||
for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
|
||||
k = ptr[j]-1; if (k < 0) k += nblock;
|
||||
c1 = block[k];
|
||||
if (!bigDone[c1])
|
||||
ptr[ copyEnd[c1]-- ] = k;
|
||||
}
|
||||
ftab[sbn] |= SETMASK;
|
||||
}
|
||||
|
||||
AssertH ( copyStart[ss]-1 == copyEnd[ss], 1007 );
|
||||
|
||||
for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
|
||||
|
||||
/*--
|
||||
Step 3:
|
||||
The [ss] big bucket is now done. Record this fact,
|
||||
@ -950,7 +1033,7 @@ void mainSort ( UInt32* ptr,
|
||||
|
||||
while ((bbSize >> shifts) > 65534) shifts++;
|
||||
|
||||
for (j = 0; j < bbSize; j++) {
|
||||
for (j = bbSize-1; j >= 0; j--) {
|
||||
Int32 a2update = ptr[bbStart + j];
|
||||
UInt16 qVal = (UInt16)(j >> shifts);
|
||||
quadrant[a2update] = qVal;
|
||||
@ -960,26 +1043,6 @@ void mainSort ( UInt32* ptr,
|
||||
AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
|
||||
}
|
||||
|
||||
/*--
|
||||
Step 4:
|
||||
Now scan this big bucket [ss] so as to synthesise the
|
||||
sorted order for small buckets [t, ss] for all t != ss.
|
||||
This will avoid doing Real Work in subsequent Step 1's.
|
||||
--*/
|
||||
for (j = 0; j <= 255; j++)
|
||||
copy[j] = ftab[(j << 8) + ss] & CLEARMASK;
|
||||
|
||||
m = ftab[(ss+1) << 8] & CLEARMASK;
|
||||
for (j = ftab[ss << 8] & CLEARMASK; j < m; j++) {
|
||||
k = ptr[j] - 1; if (k < 0) k += nblock;
|
||||
c1 = (UChar)(block[k] >> 8);
|
||||
if ( ! bigDone[c1] ) {
|
||||
ptr[copy[c1]] = k;
|
||||
copy[c1] ++;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
|
||||
}
|
||||
|
||||
if (verb >= 4)
|
||||
@ -996,19 +1059,19 @@ void mainSort ( UInt32* ptr,
|
||||
/* Pre:
|
||||
nblock > 0
|
||||
arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
|
||||
((UInt16*)arr2) [0 .. nblock-1] [15:8] holds block
|
||||
((UChar*)arr2) [0 .. nblock-1] holds block
|
||||
arr1 exists for [0 .. nblock-1]
|
||||
|
||||
Post:
|
||||
((UInt16*)arr2) [0 .. nblock-1] [15:8] holds block
|
||||
((UChar*)arr2) [0 .. nblock-1] holds block
|
||||
All other areas of block destroyed
|
||||
ftab [ 0 .. 65536 ] destroyed
|
||||
arr1 [0 .. nblock-1] holds sorted order
|
||||
*/
|
||||
void blockSort ( EState* s )
|
||||
void BZ2_blockSort ( EState* s )
|
||||
{
|
||||
UInt32* ptr = s->ptr;
|
||||
UInt16* block = s->block;
|
||||
UChar* block = s->block;
|
||||
UInt32* ftab = s->ftab;
|
||||
Int32 nblock = s->nblock;
|
||||
Int32 verb = s->verbosity;
|
||||
@ -1019,10 +1082,16 @@ void blockSort ( EState* s )
|
||||
Int32 i;
|
||||
|
||||
if (nblock < 10000) {
|
||||
for (i = 0; i < nblock; i++) block[i] <<= 8;
|
||||
fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
|
||||
} else {
|
||||
quadrant = &(block[nblock+BZ_N_OVERSHOOT]);
|
||||
/* Calculate the location for quadrant, remembering to get
|
||||
the alignment right. Assumes that &(block[0]) is at least
|
||||
2-byte aligned -- this should be ok since block is really
|
||||
the first section of arr2.
|
||||
*/
|
||||
i = nblock+BZ_N_OVERSHOOT;
|
||||
if (i & 1) i++;
|
||||
quadrant = (UInt16*)(&(block[i]));
|
||||
|
||||
/* (wfact-1) / 3 puts the default-factor-30
|
||||
transition point at very roughly the same place as
|
||||
|
8
bzip2.1
8
bzip2.1
@ -1,7 +1,7 @@
|
||||
.PU
|
||||
.TH bzip2 1
|
||||
.SH NAME
|
||||
bzip2, bunzip2 \- a block-sorting file compressor, v0.9.5
|
||||
bzip2, bunzip2 \- a block-sorting file compressor, v1.0
|
||||
.br
|
||||
bzcat \- decompresses files to stdout
|
||||
.br
|
||||
@ -397,11 +397,12 @@ I/O error messages are not as helpful as they could be.
|
||||
tries hard to detect I/O errors and exit cleanly, but the details of
|
||||
what the problem is sometimes seem rather misleading.
|
||||
|
||||
This manual page pertains to version 0.9.5 of
|
||||
This manual page pertains to version 1.0 of
|
||||
.I bzip2.
|
||||
Compressed
|
||||
data created by this version is entirely forwards and backwards
|
||||
compatible with the previous public releases, versions 0.1pl2 and 0.9.0,
|
||||
compatible with the previous public releases, versions 0.1pl2, 0.9.0
|
||||
and 0.9.5,
|
||||
but with the following exception: 0.9.0 and above can correctly
|
||||
decompress multiple concatenated compressed files. 0.1pl2 cannot do
|
||||
this; it will stop after decompressing just the first file in the
|
||||
@ -415,6 +416,7 @@ megabytes long. This could easily be fixed.
|
||||
.SH AUTHOR
|
||||
Julian Seward, jseward@acm.org.
|
||||
|
||||
http://sourceware.cygnus.com/bzip2
|
||||
http://www.muraroa.demon.co.uk
|
||||
|
||||
The ideas embodied in
|
||||
|
@ -1,7 +1,11 @@
|
||||
|
||||
|
||||
|
||||
bzip2(1) bzip2(1)
|
||||
|
||||
|
||||
NNAAMMEE
|
||||
bzip2, bunzip2 - a block-sorting file compressor, v0.9.5
|
||||
bzip2, bunzip2 - a block-sorting file compressor, v1.0
|
||||
bzcat - decompresses files to stdout
|
||||
bzip2recover - recovers data from damaged bzip2 files
|
||||
|
||||
@ -54,6 +58,18 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
filename.bz2 becomes filename
|
||||
filename.bz becomes filename
|
||||
filename.tbz2 becomes filename.tar
|
||||
|
||||
|
||||
|
||||
1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bzip2(1) bzip2(1)
|
||||
|
||||
|
||||
filename.tbz becomes filename.tar
|
||||
anyothername becomes anyothername.out
|
||||
|
||||
@ -109,6 +125,17 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
you recover the original uncompressed data. You can use
|
||||
_b_z_i_p_2_r_e_c_o_v_e_r to try to recover data from damaged files.
|
||||
|
||||
|
||||
|
||||
2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bzip2(1) bzip2(1)
|
||||
|
||||
|
||||
Return values: 0 for a normal exit, 1 for environmental
|
||||
problems (file not found, invalid flags, I/O errors, &c),
|
||||
2 to indicate a corrupt compressed file, 3 for an internal
|
||||
@ -163,6 +190,18 @@ OOPPTTIIOONNSS
|
||||
--qq ----qquuiieett
|
||||
Suppress non-essential warning messages. Messages
|
||||
pertaining to I/O errors and other critical events
|
||||
|
||||
|
||||
|
||||
3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bzip2(1) bzip2(1)
|
||||
|
||||
|
||||
will not be suppressed.
|
||||
|
||||
--vv ----vveerrbboossee
|
||||
@ -217,6 +256,18 @@ MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
|
||||
|
||||
Larger block sizes give rapidly diminishing marginal
|
||||
returns. Most of the compression comes from the first two
|
||||
|
||||
|
||||
|
||||
4
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bzip2(1) bzip2(1)
|
||||
|
||||
|
||||
or three hundred k of block size, a fact worth bearing in
|
||||
mind when using _b_z_i_p_2 on small machines. It is also
|
||||
important to appreciate that the decompression memory
|
||||
@ -270,6 +321,19 @@ MMEEMMOORRYY MMAANNAAGGEEMMEENNTT
|
||||
-9 7600k 3700k 2350k 828642
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
5
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bzip2(1) bzip2(1)
|
||||
|
||||
|
||||
RREECCOOVVEERRIINNGG DDAATTAA FFRROOMM DDAAMMAAGGEEDD FFIILLEESS
|
||||
_b_z_i_p_2 compresses files in blocks, usually 900kbytes long.
|
||||
Each block is handled independently. If a media or trans-
|
||||
@ -324,6 +388,18 @@ PPEERRFFOORRMMAANNCCEE NNOOTTEESS
|
||||
operate in, and then charges all over it in a fairly ran-
|
||||
dom fashion. This means that performance, both for com-
|
||||
pressing and decompressing, is largely determined by the
|
||||
|
||||
|
||||
|
||||
6
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bzip2(1) bzip2(1)
|
||||
|
||||
|
||||
speed at which your machine can service cache misses.
|
||||
Because of this, small changes to the code to reduce the
|
||||
miss rate have been observed to give disproportionately
|
||||
@ -337,14 +413,14 @@ CCAAVVEEAATTSS
|
||||
but the details of what the problem is sometimes seem
|
||||
rather misleading.
|
||||
|
||||
This manual page pertains to version 0.9.5 of _b_z_i_p_2_. Com-
|
||||
This manual page pertains to version 1.0 of _b_z_i_p_2_. Com-
|
||||
pressed data created by this version is entirely forwards
|
||||
and backwards compatible with the previous public
|
||||
releases, versions 0.1pl2 and 0.9.0, but with the follow-
|
||||
ing exception: 0.9.0 and above can correctly decompress
|
||||
multiple concatenated compressed files. 0.1pl2 cannot do
|
||||
this; it will stop after decompressing just the first file
|
||||
in the stream.
|
||||
releases, versions 0.1pl2, 0.9.0 and 0.9.5, but with the
|
||||
following exception: 0.9.0 and above can correctly decom-
|
||||
press multiple concatenated compressed files. 0.1pl2 can-
|
||||
not do this; it will stop after decompressing just the
|
||||
first file in the stream.
|
||||
|
||||
_b_z_i_p_2_r_e_c_o_v_e_r uses 32-bit integers to represent bit posi-
|
||||
tions in compressed files, so it cannot handle compressed
|
||||
@ -355,21 +431,32 @@ CCAAVVEEAATTSS
|
||||
AAUUTTHHOORR
|
||||
Julian Seward, jseward@acm.org.
|
||||
|
||||
http://sourceware.cygnus.com/bzip2
|
||||
http://www.muraroa.demon.co.uk
|
||||
|
||||
The ideas embodied in _b_z_i_p_2 are due to (at least) the fol-
|
||||
lowing people: Michael Burrows and David Wheeler (for the
|
||||
block sorting transformation), David Wheeler (again, for
|
||||
lowing people: Michael Burrows and David Wheeler (for the
|
||||
block sorting transformation), David Wheeler (again, for
|
||||
the Huffman coder), Peter Fenwick (for the structured cod-
|
||||
ing model in the original _b_z_i_p_, and many refinements), and
|
||||
Alistair Moffat, Radford Neal and Ian Witten (for the
|
||||
Alistair Moffat, Radford Neal and Ian Witten (for the
|
||||
arithmetic coder in the original _b_z_i_p_)_. I am much
|
||||
indebted for their help, support and advice. See the man-
|
||||
ual in the source distribution for pointers to sources of
|
||||
ual in the source distribution for pointers to sources of
|
||||
documentation. Christian von Roques encouraged me to look
|
||||
for faster sorting algorithms, so as to speed up compres-
|
||||
for faster sorting algorithms, so as to speed up compres-
|
||||
sion. Bela Lubkin encouraged me to improve the worst-case
|
||||
compression performance. Many people sent patches, helped
|
||||
with portability problems, lent machines, gave advice and
|
||||
with portability problems, lent machines, gave advice and
|
||||
were generally helpful.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
7
|
||||
|
||||
|
||||
|
15
bzip2.txt
15
bzip2.txt
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
NAME
|
||||
bzip2, bunzip2 - a block-sorting file compressor, v0.9.5
|
||||
bzip2, bunzip2 - a block-sorting file compressor, v1.0
|
||||
bzcat - decompresses files to stdout
|
||||
bzip2recover - recovers data from damaged bzip2 files
|
||||
|
||||
@ -337,14 +337,14 @@ CAVEATS
|
||||
but the details of what the problem is sometimes seem
|
||||
rather misleading.
|
||||
|
||||
This manual page pertains to version 0.9.5 of bzip2. Com-
|
||||
This manual page pertains to version 1.0 of bzip2. Com-
|
||||
pressed data created by this version is entirely forwards
|
||||
and backwards compatible with the previous public
|
||||
releases, versions 0.1pl2 and 0.9.0, but with the follow-
|
||||
ing exception: 0.9.0 and above can correctly decompress
|
||||
multiple concatenated compressed files. 0.1pl2 cannot do
|
||||
this; it will stop after decompressing just the first file
|
||||
in the stream.
|
||||
releases, versions 0.1pl2, 0.9.0 and 0.9.5, but with the
|
||||
following exception: 0.9.0 and above can correctly decom-
|
||||
press multiple concatenated compressed files. 0.1pl2 can-
|
||||
not do this; it will stop after decompressing just the
|
||||
first file in the stream.
|
||||
|
||||
bzip2recover uses 32-bit integers to represent bit posi-
|
||||
tions in compressed files, so it cannot handle compressed
|
||||
@ -355,6 +355,7 @@ CAVEATS
|
||||
AUTHOR
|
||||
Julian Seward, jseward@acm.org.
|
||||
|
||||
http://sourceware.cygnus.com/bzip2
|
||||
http://www.muraroa.demon.co.uk
|
||||
|
||||
The ideas embodied in bzip2 are due to (at least) the fol-
|
||||
|
@ -7,9 +7,9 @@
|
||||
/*--
|
||||
This program is bzip2recover, a program to attempt data
|
||||
salvage from damaged files created by the accompanying
|
||||
bzip2-0.9.5 program.
|
||||
bzip2-1.0 program.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
--*/
|
||||
|
||||
/*--
|
||||
@ -282,7 +282,7 @@ Int32 main ( Int32 argc, Char** argv )
|
||||
strcpy ( progName, argv[0] );
|
||||
inFileName[0] = outFileName[0] = 0;
|
||||
|
||||
fprintf ( stderr, "bzip2recover 0.9.5d: extracts blocks from damaged .bz2 files.\n" );
|
||||
fprintf ( stderr, "bzip2recover 1.0: extracts blocks from damaged .bz2 files.\n" );
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
|
||||
|
248
bzlib.c
248
bzlib.c
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -83,24 +83,36 @@
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#ifndef BZ_NO_STDIO
|
||||
void bz__AssertH__fail ( int errcode )
|
||||
void BZ2_bz__AssertH__fail ( int errcode )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"\n\nbzip2/libbzip2, v0.9.5d: internal error number %d.\n"
|
||||
"This is a bug in bzip2/libbzip2, v0.9.5d. Please report\n"
|
||||
"it to me at: jseward@acm.org. If this happened when\n"
|
||||
"you were using some program which uses libbzip2 as a\n"
|
||||
"\n\nbzip2/libbzip2: internal error number %d.\n"
|
||||
"This is a bug in bzip2/libbzip2, %s.\n"
|
||||
"Please report it to me at: jseward@acm.org. If this happened\n"
|
||||
"when you were using some program which uses libbzip2 as a\n"
|
||||
"component, you should also report this bug to the author(s)\n"
|
||||
"of that program. Please make an effort to report this bug;\n"
|
||||
"timely and accurate bug reports eventually lead to higher\n"
|
||||
"quality software. Thanks. Julian Seward, 4 Sept 1999.\n\n",
|
||||
errcode
|
||||
"quality software. Thanks. Julian Seward, 21 March 2000.\n\n",
|
||||
errcode,
|
||||
BZ2_bzlibVersion()
|
||||
);
|
||||
exit(3);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
int bz_config_ok ( void )
|
||||
{
|
||||
if (sizeof(int) != 4) return 0;
|
||||
if (sizeof(short) != 2) return 0;
|
||||
if (sizeof(char) != 1) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
|
||||
@ -149,7 +161,7 @@ Bool isempty_RL ( EState* s )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzCompressInit)
|
||||
int BZ_API(BZ2_bzCompressInit)
|
||||
( bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
@ -158,6 +170,8 @@ int BZ_API(bzCompressInit)
|
||||
Int32 n;
|
||||
EState* s;
|
||||
|
||||
if (!bz_config_ok()) return BZ_CONFIG_ERROR;
|
||||
|
||||
if (strm == NULL ||
|
||||
blockSize100k < 1 || blockSize100k > 9 ||
|
||||
workFactor < 0 || workFactor > 250)
|
||||
@ -197,14 +211,16 @@ int BZ_API(bzCompressInit)
|
||||
s->verbosity = verbosity;
|
||||
s->workFactor = workFactor;
|
||||
|
||||
s->block = (UInt16*)s->arr2;
|
||||
s->block = (UChar*)s->arr2;
|
||||
s->mtfv = (UInt16*)s->arr1;
|
||||
s->zbits = NULL;
|
||||
s->ptr = (UInt32*)s->arr1;
|
||||
|
||||
strm->state = s;
|
||||
strm->total_in = 0;
|
||||
strm->total_out = 0;
|
||||
strm->total_in_lo32 = 0;
|
||||
strm->total_in_hi32 = 0;
|
||||
strm->total_out_lo32 = 0;
|
||||
strm->total_out_hi32 = 0;
|
||||
init_RL ( s );
|
||||
prepare_new_block ( s );
|
||||
return BZ_OK;
|
||||
@ -223,24 +239,24 @@ void add_pair_to_block ( EState* s )
|
||||
s->inUse[s->state_in_ch] = True;
|
||||
switch (s->state_in_len) {
|
||||
case 1:
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
break;
|
||||
case 2:
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
break;
|
||||
case 3:
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
break;
|
||||
default:
|
||||
s->inUse[s->state_in_len-4] = True;
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UInt16)ch; s->nblock++;
|
||||
s->block[s->nblock] = ((UInt16)(s->state_in_len-4));
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
s->block[s->nblock] = (UChar)ch; s->nblock++;
|
||||
s->block[s->nblock] = ((UChar)(s->state_in_len-4));
|
||||
s->nblock++;
|
||||
break;
|
||||
}
|
||||
@ -266,7 +282,7 @@ void flush_RL ( EState* s )
|
||||
UChar ch = (UChar)(zs->state_in_ch); \
|
||||
BZ_UPDATE_CRC( zs->blockCRC, ch ); \
|
||||
zs->inUse[zs->state_in_ch] = True; \
|
||||
zs->block[zs->nblock] = (UInt16)ch; \
|
||||
zs->block[zs->nblock] = (UChar)ch; \
|
||||
zs->nblock++; \
|
||||
zs->state_in_ch = zchh; \
|
||||
} \
|
||||
@ -302,7 +318,8 @@ Bool copy_input_until_stop ( EState* s )
|
||||
ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
|
||||
s->strm->next_in++;
|
||||
s->strm->avail_in--;
|
||||
s->strm->total_in++;
|
||||
s->strm->total_in_lo32++;
|
||||
if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -319,7 +336,8 @@ Bool copy_input_until_stop ( EState* s )
|
||||
ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
|
||||
s->strm->next_in++;
|
||||
s->strm->avail_in--;
|
||||
s->strm->total_in++;
|
||||
s->strm->total_in_lo32++;
|
||||
if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
|
||||
s->avail_in_expect--;
|
||||
}
|
||||
}
|
||||
@ -346,8 +364,8 @@ Bool copy_output_until_stop ( EState* s )
|
||||
s->state_out_pos++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->next_out++;
|
||||
s->strm->total_out++;
|
||||
|
||||
s->strm->total_out_lo32++;
|
||||
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
||||
}
|
||||
|
||||
return progress_out;
|
||||
@ -381,12 +399,12 @@ Bool handle_compress ( bz_stream* strm )
|
||||
progress_in |= copy_input_until_stop ( s );
|
||||
if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
|
||||
flush_RL ( s );
|
||||
compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
|
||||
BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
|
||||
s->state = BZ_S_OUTPUT;
|
||||
}
|
||||
else
|
||||
if (s->nblock >= s->nblockMAX) {
|
||||
compressBlock ( s, False );
|
||||
BZ2_compressBlock ( s, False );
|
||||
s->state = BZ_S_OUTPUT;
|
||||
}
|
||||
else
|
||||
@ -402,7 +420,7 @@ Bool handle_compress ( bz_stream* strm )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzCompress) ( bz_stream *strm, int action )
|
||||
int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
|
||||
{
|
||||
Bool progress;
|
||||
EState* s;
|
||||
@ -439,7 +457,8 @@ int BZ_API(bzCompress) ( bz_stream *strm, int action )
|
||||
|
||||
case BZ_M_FLUSHING:
|
||||
if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
|
||||
if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR;
|
||||
if (s->avail_in_expect != s->strm->avail_in)
|
||||
return BZ_SEQUENCE_ERROR;
|
||||
progress = handle_compress ( strm );
|
||||
if (s->avail_in_expect > 0 || !isempty_RL(s) ||
|
||||
s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
|
||||
@ -448,7 +467,8 @@ int BZ_API(bzCompress) ( bz_stream *strm, int action )
|
||||
|
||||
case BZ_M_FINISHING:
|
||||
if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
|
||||
if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR;
|
||||
if (s->avail_in_expect != s->strm->avail_in)
|
||||
return BZ_SEQUENCE_ERROR;
|
||||
progress = handle_compress ( strm );
|
||||
if (!progress) return BZ_SEQUENCE_ERROR;
|
||||
if (s->avail_in_expect > 0 || !isempty_RL(s) ||
|
||||
@ -461,7 +481,7 @@ int BZ_API(bzCompress) ( bz_stream *strm, int action )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzCompressEnd) ( bz_stream *strm )
|
||||
int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
|
||||
{
|
||||
EState* s;
|
||||
if (strm == NULL) return BZ_PARAM_ERROR;
|
||||
@ -485,13 +505,15 @@ int BZ_API(bzCompressEnd) ( bz_stream *strm )
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzDecompressInit)
|
||||
int BZ_API(BZ2_bzDecompressInit)
|
||||
( bz_stream* strm,
|
||||
int verbosity,
|
||||
int small )
|
||||
{
|
||||
DState* s;
|
||||
|
||||
if (!bz_config_ok()) return BZ_CONFIG_ERROR;
|
||||
|
||||
if (strm == NULL) return BZ_PARAM_ERROR;
|
||||
if (small != 0 && small != 1) return BZ_PARAM_ERROR;
|
||||
if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
|
||||
@ -507,8 +529,10 @@ int BZ_API(bzDecompressInit)
|
||||
s->bsLive = 0;
|
||||
s->bsBuff = 0;
|
||||
s->calculatedCombinedCRC = 0;
|
||||
strm->total_in = 0;
|
||||
strm->total_out = 0;
|
||||
strm->total_in_lo32 = 0;
|
||||
strm->total_in_hi32 = 0;
|
||||
strm->total_out_lo32 = 0;
|
||||
strm->total_out_hi32 = 0;
|
||||
s->smallDecompress = (Bool)small;
|
||||
s->ll4 = NULL;
|
||||
s->ll16 = NULL;
|
||||
@ -538,7 +562,8 @@ void unRLE_obuf_to_output_FAST ( DState* s )
|
||||
s->state_out_len--;
|
||||
s->strm->next_out++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->total_out++;
|
||||
s->strm->total_out_lo32++;
|
||||
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
||||
}
|
||||
|
||||
/* can a new run be started? */
|
||||
@ -585,8 +610,9 @@ void unRLE_obuf_to_output_FAST ( DState* s )
|
||||
unsigned int cs_avail_out = s->strm->avail_out;
|
||||
/* end restore */
|
||||
|
||||
UInt32 avail_out_INIT = cs_avail_out;
|
||||
Int32 s_save_nblockPP = s->save_nblock+1;
|
||||
UInt32 avail_out_INIT = cs_avail_out;
|
||||
Int32 s_save_nblockPP = s->save_nblock+1;
|
||||
unsigned int total_out_lo32_old;
|
||||
|
||||
while (True) {
|
||||
|
||||
@ -640,7 +666,10 @@ void unRLE_obuf_to_output_FAST ( DState* s )
|
||||
}
|
||||
|
||||
return_notr:
|
||||
s->strm->total_out += (avail_out_INIT - cs_avail_out);
|
||||
total_out_lo32_old = s->strm->total_out_lo32;
|
||||
s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
|
||||
if (s->strm->total_out_lo32 < total_out_lo32_old)
|
||||
s->strm->total_out_hi32++;
|
||||
|
||||
/* save */
|
||||
s->calculatedBlockCRC = c_calculatedBlockCRC;
|
||||
@ -659,7 +688,7 @@ void unRLE_obuf_to_output_FAST ( DState* s )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
__inline__ Int32 indexIntoF ( Int32 indx, Int32 *cftab )
|
||||
__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
|
||||
{
|
||||
Int32 nb, na, mid;
|
||||
nb = 0;
|
||||
@ -691,7 +720,8 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
|
||||
s->state_out_len--;
|
||||
s->strm->next_out++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->total_out++;
|
||||
s->strm->total_out_lo32++;
|
||||
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
||||
}
|
||||
|
||||
/* can a new run be started? */
|
||||
@ -736,7 +766,8 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
|
||||
s->state_out_len--;
|
||||
s->strm->next_out++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->total_out++;
|
||||
s->strm->total_out_lo32++;
|
||||
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
||||
}
|
||||
|
||||
/* can a new run be started? */
|
||||
@ -768,7 +799,7 @@ void unRLE_obuf_to_output_SMALL ( DState* s )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzDecompress) ( bz_stream *strm )
|
||||
int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
|
||||
{
|
||||
DState* s;
|
||||
if (strm == NULL) return BZ_PARAM_ERROR;
|
||||
@ -800,7 +831,7 @@ int BZ_API(bzDecompress) ( bz_stream *strm )
|
||||
}
|
||||
}
|
||||
if (s->state >= BZ_X_MAGIC_1) {
|
||||
Int32 r = decompress ( s );
|
||||
Int32 r = BZ2_decompress ( s );
|
||||
if (r == BZ_STREAM_END) {
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
|
||||
@ -820,7 +851,7 @@ int BZ_API(bzDecompress) ( bz_stream *strm )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzDecompressEnd) ( bz_stream *strm )
|
||||
int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
|
||||
{
|
||||
DState* s;
|
||||
if (strm == NULL) return BZ_PARAM_ERROR;
|
||||
@ -874,7 +905,7 @@ static Bool myfeof ( FILE* f )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
BZFILE* BZ_API(bzWriteOpen)
|
||||
BZFILE* BZ_API(BZ2_bzWriteOpen)
|
||||
( int* bzerror,
|
||||
FILE* f,
|
||||
int blockSize100k,
|
||||
@ -909,8 +940,8 @@ BZFILE* BZ_API(bzWriteOpen)
|
||||
bzf->strm.opaque = NULL;
|
||||
|
||||
if (workFactor == 0) workFactor = 30;
|
||||
ret = bzCompressInit ( &(bzf->strm), blockSize100k,
|
||||
verbosity, workFactor );
|
||||
ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
|
||||
verbosity, workFactor );
|
||||
if (ret != BZ_OK)
|
||||
{ BZ_SETERR(ret); free(bzf); return NULL; };
|
||||
|
||||
@ -922,7 +953,7 @@ BZFILE* BZ_API(bzWriteOpen)
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ_API(bzWrite)
|
||||
void BZ_API(BZ2_bzWrite)
|
||||
( int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
@ -948,7 +979,7 @@ void BZ_API(bzWrite)
|
||||
while (True) {
|
||||
bzf->strm.avail_out = BZ_MAX_UNUSED;
|
||||
bzf->strm.next_out = bzf->buf;
|
||||
ret = bzCompress ( &(bzf->strm), BZ_RUN );
|
||||
ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
|
||||
if (ret != BZ_RUN_OK)
|
||||
{ BZ_SETERR(ret); return; };
|
||||
|
||||
@ -967,12 +998,26 @@ void BZ_API(bzWrite)
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ_API(bzWriteClose)
|
||||
void BZ_API(BZ2_bzWriteClose)
|
||||
( int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in,
|
||||
unsigned int* nbytes_out )
|
||||
{
|
||||
BZ2_bzWriteClose64 ( bzerror, b, abandon,
|
||||
nbytes_in, NULL, nbytes_out, NULL );
|
||||
}
|
||||
|
||||
|
||||
void BZ_API(BZ2_bzWriteClose64)
|
||||
( int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in_lo32,
|
||||
unsigned int* nbytes_in_hi32,
|
||||
unsigned int* nbytes_out_lo32,
|
||||
unsigned int* nbytes_out_hi32 )
|
||||
{
|
||||
Int32 n, n2, ret;
|
||||
bzFile* bzf = (bzFile*)b;
|
||||
@ -984,14 +1029,16 @@ void BZ_API(bzWriteClose)
|
||||
if (ferror(bzf->handle))
|
||||
{ BZ_SETERR(BZ_IO_ERROR); return; };
|
||||
|
||||
if (nbytes_in != NULL) *nbytes_in = 0;
|
||||
if (nbytes_out != NULL) *nbytes_out = 0;
|
||||
if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
|
||||
if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
|
||||
if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
|
||||
if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
|
||||
|
||||
if ((!abandon) && bzf->lastErr == BZ_OK) {
|
||||
while (True) {
|
||||
bzf->strm.avail_out = BZ_MAX_UNUSED;
|
||||
bzf->strm.next_out = bzf->buf;
|
||||
ret = bzCompress ( &(bzf->strm), BZ_FINISH );
|
||||
ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
|
||||
if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
|
||||
{ BZ_SETERR(ret); return; };
|
||||
|
||||
@ -1013,17 +1060,23 @@ void BZ_API(bzWriteClose)
|
||||
{ BZ_SETERR(BZ_IO_ERROR); return; };
|
||||
}
|
||||
|
||||
if (nbytes_in != NULL) *nbytes_in = bzf->strm.total_in;
|
||||
if (nbytes_out != NULL) *nbytes_out = bzf->strm.total_out;
|
||||
if (nbytes_in_lo32 != NULL)
|
||||
*nbytes_in_lo32 = bzf->strm.total_in_lo32;
|
||||
if (nbytes_in_hi32 != NULL)
|
||||
*nbytes_in_hi32 = bzf->strm.total_in_hi32;
|
||||
if (nbytes_out_lo32 != NULL)
|
||||
*nbytes_out_lo32 = bzf->strm.total_out_lo32;
|
||||
if (nbytes_out_hi32 != NULL)
|
||||
*nbytes_out_hi32 = bzf->strm.total_out_hi32;
|
||||
|
||||
BZ_SETERR(BZ_OK);
|
||||
bzCompressEnd ( &(bzf->strm) );
|
||||
BZ2_bzCompressEnd ( &(bzf->strm) );
|
||||
free ( bzf );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
BZFILE* BZ_API(bzReadOpen)
|
||||
BZFILE* BZ_API(BZ2_bzReadOpen)
|
||||
( int* bzerror,
|
||||
FILE* f,
|
||||
int verbosity,
|
||||
@ -1066,7 +1119,7 @@ BZFILE* BZ_API(bzReadOpen)
|
||||
nUnused--;
|
||||
}
|
||||
|
||||
ret = bzDecompressInit ( &(bzf->strm), verbosity, small );
|
||||
ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
|
||||
if (ret != BZ_OK)
|
||||
{ BZ_SETERR(ret); free(bzf); return NULL; };
|
||||
|
||||
@ -1079,7 +1132,7 @@ BZFILE* BZ_API(bzReadOpen)
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ_API(bzReadClose) ( int *bzerror, BZFILE *b )
|
||||
void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
|
||||
{
|
||||
bzFile* bzf = (bzFile*)b;
|
||||
|
||||
@ -1091,13 +1144,13 @@ void BZ_API(bzReadClose) ( int *bzerror, BZFILE *b )
|
||||
{ BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
|
||||
|
||||
if (bzf->initialisedOk)
|
||||
(void)bzDecompressEnd ( &(bzf->strm) );
|
||||
(void)BZ2_bzDecompressEnd ( &(bzf->strm) );
|
||||
free ( bzf );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzRead)
|
||||
int BZ_API(BZ2_bzRead)
|
||||
( int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
@ -1135,7 +1188,7 @@ int BZ_API(bzRead)
|
||||
bzf->strm.next_in = bzf->buf;
|
||||
}
|
||||
|
||||
ret = bzDecompress ( &(bzf->strm) );
|
||||
ret = BZ2_bzDecompress ( &(bzf->strm) );
|
||||
|
||||
if (ret != BZ_OK && ret != BZ_STREAM_END)
|
||||
{ BZ_SETERR(ret); return 0; };
|
||||
@ -1157,7 +1210,7 @@ int BZ_API(bzRead)
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ_API(bzReadGetUnused)
|
||||
void BZ_API(BZ2_bzReadGetUnused)
|
||||
( int* bzerror,
|
||||
BZFILE* b,
|
||||
void** unused,
|
||||
@ -1183,7 +1236,7 @@ void BZ_API(bzReadGetUnused)
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzBuffToBuffCompress)
|
||||
int BZ_API(BZ2_bzBuffToBuffCompress)
|
||||
( char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
@ -1206,8 +1259,8 @@ int BZ_API(bzBuffToBuffCompress)
|
||||
strm.bzalloc = NULL;
|
||||
strm.bzfree = NULL;
|
||||
strm.opaque = NULL;
|
||||
ret = bzCompressInit ( &strm, blockSize100k,
|
||||
verbosity, workFactor );
|
||||
ret = BZ2_bzCompressInit ( &strm, blockSize100k,
|
||||
verbosity, workFactor );
|
||||
if (ret != BZ_OK) return ret;
|
||||
|
||||
strm.next_in = source;
|
||||
@ -1215,27 +1268,27 @@ int BZ_API(bzBuffToBuffCompress)
|
||||
strm.avail_in = sourceLen;
|
||||
strm.avail_out = *destLen;
|
||||
|
||||
ret = bzCompress ( &strm, BZ_FINISH );
|
||||
ret = BZ2_bzCompress ( &strm, BZ_FINISH );
|
||||
if (ret == BZ_FINISH_OK) goto output_overflow;
|
||||
if (ret != BZ_STREAM_END) goto errhandler;
|
||||
|
||||
/* normal termination */
|
||||
*destLen -= strm.avail_out;
|
||||
bzCompressEnd ( &strm );
|
||||
BZ2_bzCompressEnd ( &strm );
|
||||
return BZ_OK;
|
||||
|
||||
output_overflow:
|
||||
bzCompressEnd ( &strm );
|
||||
BZ2_bzCompressEnd ( &strm );
|
||||
return BZ_OUTBUFF_FULL;
|
||||
|
||||
errhandler:
|
||||
bzCompressEnd ( &strm );
|
||||
BZ2_bzCompressEnd ( &strm );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzBuffToBuffDecompress)
|
||||
int BZ_API(BZ2_bzBuffToBuffDecompress)
|
||||
( char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
@ -1255,7 +1308,7 @@ int BZ_API(bzBuffToBuffDecompress)
|
||||
strm.bzalloc = NULL;
|
||||
strm.bzfree = NULL;
|
||||
strm.opaque = NULL;
|
||||
ret = bzDecompressInit ( &strm, verbosity, small );
|
||||
ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
|
||||
if (ret != BZ_OK) return ret;
|
||||
|
||||
strm.next_in = source;
|
||||
@ -1263,26 +1316,26 @@ int BZ_API(bzBuffToBuffDecompress)
|
||||
strm.avail_in = sourceLen;
|
||||
strm.avail_out = *destLen;
|
||||
|
||||
ret = bzDecompress ( &strm );
|
||||
ret = BZ2_bzDecompress ( &strm );
|
||||
if (ret == BZ_OK) goto output_overflow_or_eof;
|
||||
if (ret != BZ_STREAM_END) goto errhandler;
|
||||
|
||||
/* normal termination */
|
||||
*destLen -= strm.avail_out;
|
||||
bzDecompressEnd ( &strm );
|
||||
BZ2_bzDecompressEnd ( &strm );
|
||||
return BZ_OK;
|
||||
|
||||
output_overflow_or_eof:
|
||||
if (strm.avail_out > 0) {
|
||||
bzDecompressEnd ( &strm );
|
||||
BZ2_bzDecompressEnd ( &strm );
|
||||
return BZ_UNEXPECTED_EOF;
|
||||
} else {
|
||||
bzDecompressEnd ( &strm );
|
||||
BZ2_bzDecompressEnd ( &strm );
|
||||
return BZ_OUTBUFF_FULL;
|
||||
};
|
||||
|
||||
errhandler:
|
||||
bzDecompressEnd ( &strm );
|
||||
BZ2_bzDecompressEnd ( &strm );
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1303,7 +1356,7 @@ int BZ_API(bzBuffToBuffDecompress)
|
||||
/*--
|
||||
return version like "0.9.0c".
|
||||
--*/
|
||||
const char * BZ_API(bzlibVersion)(void)
|
||||
const char * BZ_API(BZ2_bzlibVersion)(void)
|
||||
{
|
||||
return BZ_VERSION;
|
||||
}
|
||||
@ -1377,9 +1430,11 @@ BZFILE * bzopen_or_bzdopen
|
||||
/* Guard against total chaos and anarchy -- JRS */
|
||||
if (blockSize100k < 1) blockSize100k = 1;
|
||||
if (blockSize100k > 9) blockSize100k = 9;
|
||||
bzfp = bzWriteOpen(&bzerr,fp,blockSize100k,verbosity,workFactor);
|
||||
bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
|
||||
verbosity,workFactor);
|
||||
} else {
|
||||
bzfp = bzReadOpen(&bzerr,fp,verbosity,smallMode,unused,nUnused);
|
||||
bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
|
||||
unused,nUnused);
|
||||
}
|
||||
if (bzfp == NULL) {
|
||||
if (fp != stdin && fp != stdout) fclose(fp);
|
||||
@ -1395,7 +1450,7 @@ BZFILE * bzopen_or_bzdopen
|
||||
ex) bzopen("file","w9")
|
||||
case path="" or NULL => use stdin or stdout.
|
||||
--*/
|
||||
BZFILE * BZ_API(bzopen)
|
||||
BZFILE * BZ_API(BZ2_bzopen)
|
||||
( const char *path,
|
||||
const char *mode )
|
||||
{
|
||||
@ -1404,7 +1459,7 @@ BZFILE * BZ_API(bzopen)
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
BZFILE * BZ_API(bzdopen)
|
||||
BZFILE * BZ_API(BZ2_bzdopen)
|
||||
( int fd,
|
||||
const char *mode )
|
||||
{
|
||||
@ -1413,11 +1468,11 @@ BZFILE * BZ_API(bzdopen)
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzread) (BZFILE* b, void* buf, int len )
|
||||
int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
|
||||
{
|
||||
int bzerr, nread;
|
||||
if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
|
||||
nread = bzRead(&bzerr,b,buf,len);
|
||||
nread = BZ2_bzRead(&bzerr,b,buf,len);
|
||||
if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
|
||||
return nread;
|
||||
} else {
|
||||
@ -1427,11 +1482,11 @@ int BZ_API(bzread) (BZFILE* b, void* buf, int len )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzwrite) (BZFILE* b, void* buf, int len )
|
||||
int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
|
||||
{
|
||||
int bzerr;
|
||||
|
||||
bzWrite(&bzerr,b,buf,len);
|
||||
BZ2_bzWrite(&bzerr,b,buf,len);
|
||||
if(bzerr == BZ_OK){
|
||||
return len;
|
||||
}else{
|
||||
@ -1441,7 +1496,7 @@ int BZ_API(bzwrite) (BZFILE* b, void* buf, int len )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(bzflush) (BZFILE *b)
|
||||
int BZ_API(BZ2_bzflush) (BZFILE *b)
|
||||
{
|
||||
/* do nothing now... */
|
||||
return 0;
|
||||
@ -1449,19 +1504,19 @@ int BZ_API(bzflush) (BZFILE *b)
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ_API(bzclose) (BZFILE* b)
|
||||
void BZ_API(BZ2_bzclose) (BZFILE* b)
|
||||
{
|
||||
int bzerr;
|
||||
FILE *fp = ((bzFile *)b)->handle;
|
||||
|
||||
if (b==NULL) {return;}
|
||||
if(((bzFile*)b)->writing){
|
||||
bzWriteClose(&bzerr,b,0,NULL,NULL);
|
||||
BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
|
||||
if(bzerr != BZ_OK){
|
||||
bzWriteClose(NULL,b,1,NULL,NULL);
|
||||
BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
|
||||
}
|
||||
}else{
|
||||
bzReadClose(&bzerr,b);
|
||||
BZ2_bzReadClose(&bzerr,b);
|
||||
}
|
||||
if(fp!=stdin && fp!=stdout){
|
||||
fclose(fp);
|
||||
@ -1483,6 +1538,7 @@ static char *bzerrorstrings[] = {
|
||||
,"IO_ERROR"
|
||||
,"UNEXPECTED_EOF"
|
||||
,"OUTBUFF_FULL"
|
||||
,"CONFIG_ERROR"
|
||||
,"???" /* for future */
|
||||
,"???" /* for future */
|
||||
,"???" /* for future */
|
||||
@ -1492,7 +1548,7 @@ static char *bzerrorstrings[] = {
|
||||
};
|
||||
|
||||
|
||||
const char * BZ_API(bzerror) (BZFILE *b, int *errnum)
|
||||
const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
|
||||
{
|
||||
int err = ((bzFile *)b)->lastErr;
|
||||
|
||||
|
67
bzlib.h
67
bzlib.h
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -83,16 +83,19 @@ extern "C" {
|
||||
#define BZ_IO_ERROR (-6)
|
||||
#define BZ_UNEXPECTED_EOF (-7)
|
||||
#define BZ_OUTBUFF_FULL (-8)
|
||||
#define BZ_CONFIG_ERROR (-9)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
char *next_in;
|
||||
unsigned int avail_in;
|
||||
unsigned int total_in;
|
||||
unsigned int total_in_lo32;
|
||||
unsigned int total_in_hi32;
|
||||
|
||||
char *next_out;
|
||||
unsigned int avail_out;
|
||||
unsigned int total_out;
|
||||
unsigned int total_out_lo32;
|
||||
unsigned int total_out_hi32;
|
||||
|
||||
void *state;
|
||||
|
||||
@ -130,33 +133,33 @@ typedef
|
||||
|
||||
/*-- Core (low-level) library functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(bzCompressInit) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
|
||||
bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzCompress) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
|
||||
bz_stream* strm,
|
||||
int action
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzCompressEnd) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzDecompressInit) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
|
||||
bz_stream *strm,
|
||||
int verbosity,
|
||||
int small
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzDecompress) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzDecompressEnd) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
@ -169,7 +172,7 @@ BZ_EXTERN int BZ_API(bzDecompressEnd) (
|
||||
|
||||
typedef void BZFILE;
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(bzReadOpen) (
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int verbosity,
|
||||
@ -178,26 +181,26 @@ BZ_EXTERN BZFILE* BZ_API(bzReadOpen) (
|
||||
int nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(bzReadClose) (
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(bzReadGetUnused) (
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void** unused,
|
||||
int* nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzRead) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzRead) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(bzWriteOpen) (
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int blockSize100k,
|
||||
@ -205,26 +208,36 @@ BZ_EXTERN BZFILE* BZ_API(bzWriteOpen) (
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(bzWrite) (
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(bzWriteClose) (
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in,
|
||||
unsigned int* nbytes_out
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in_lo32,
|
||||
unsigned int* nbytes_in_hi32,
|
||||
unsigned int* nbytes_out_lo32,
|
||||
unsigned int* nbytes_out_hi32
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Utility functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(bzBuffToBuffCompress) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
@ -234,7 +247,7 @@ BZ_EXTERN int BZ_API(bzBuffToBuffCompress) (
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzBuffToBuffDecompress) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
@ -254,42 +267,42 @@ BZ_EXTERN int BZ_API(bzBuffToBuffDecompress) (
|
||||
If this code breaks, please contact both Yoshioka and me.
|
||||
--*/
|
||||
|
||||
BZ_EXTERN const char * BZ_API(bzlibVersion) (
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
|
||||
void
|
||||
);
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
BZ_EXTERN BZFILE * BZ_API(bzopen) (
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
|
||||
const char *path,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE * BZ_API(bzdopen) (
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
|
||||
int fd,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzread) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzread) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzwrite) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(bzflush) (
|
||||
BZ_EXTERN int BZ_API(BZ2_bzflush) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(bzclose) (
|
||||
BZ_EXTERN void BZ_API(BZ2_bzclose) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN const char * BZ_API(bzerror) (
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
|
||||
BZFILE *b,
|
||||
int *errnum
|
||||
);
|
||||
|
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -76,7 +76,7 @@
|
||||
|
||||
/*-- General stuff. --*/
|
||||
|
||||
#define BZ_VERSION "0.9.5d"
|
||||
#define BZ_VERSION "1.0.1, 23-June-2000"
|
||||
|
||||
typedef char Char;
|
||||
typedef unsigned char Bool;
|
||||
@ -94,9 +94,9 @@ typedef unsigned short UInt16;
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
extern void bz__AssertH__fail ( int errcode );
|
||||
extern void BZ2_bz__AssertH__fail ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) bz__AssertH__fail ( errcode ); }
|
||||
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
|
||||
#if BZ_DEBUG
|
||||
#define AssertD(cond,msg) \
|
||||
{ if (!(cond)) { \
|
||||
@ -155,7 +155,7 @@ extern void bz_internal_error ( int errcode );
|
||||
|
||||
/*-- Stuff for randomising repetitive blocks. --*/
|
||||
|
||||
extern Int32 rNums[512];
|
||||
extern Int32 BZ2_rNums[512];
|
||||
|
||||
#define BZ_RAND_DECLS \
|
||||
Int32 rNToGo; \
|
||||
@ -169,7 +169,7 @@ extern Int32 rNums[512];
|
||||
|
||||
#define BZ_RAND_UPD_MASK \
|
||||
if (s->rNToGo == 0) { \
|
||||
s->rNToGo = rNums[s->rTPos]; \
|
||||
s->rNToGo = BZ2_rNums[s->rTPos]; \
|
||||
s->rTPos++; \
|
||||
if (s->rTPos == 512) s->rTPos = 0; \
|
||||
} \
|
||||
@ -179,7 +179,7 @@ extern Int32 rNums[512];
|
||||
|
||||
/*-- Stuff for doing CRCs. --*/
|
||||
|
||||
extern UInt32 crc32Table[256];
|
||||
extern UInt32 BZ2_crc32Table[256];
|
||||
|
||||
#define BZ_INITIALISE_CRC(crcVar) \
|
||||
{ \
|
||||
@ -194,8 +194,8 @@ extern UInt32 crc32Table[256];
|
||||
#define BZ_UPDATE_CRC(crcVar,cha) \
|
||||
{ \
|
||||
crcVar = (crcVar << 8) ^ \
|
||||
crc32Table[(crcVar >> 24) ^ \
|
||||
((UChar)cha)]; \
|
||||
BZ2_crc32Table[(crcVar >> 24) ^ \
|
||||
((UChar)cha)]; \
|
||||
}
|
||||
|
||||
|
||||
@ -241,7 +241,7 @@ typedef
|
||||
|
||||
/* aliases for arr1 and arr2 */
|
||||
UInt32* ptr;
|
||||
UInt16* block;
|
||||
UChar* block;
|
||||
UInt16* mtfv;
|
||||
UChar* zbits;
|
||||
|
||||
@ -283,9 +283,11 @@ typedef
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
/* second dimension: only 3 needed; 4 makes index calculations faster */
|
||||
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
|
||||
|
||||
}
|
||||
EState;
|
||||
@ -295,19 +297,19 @@ typedef
|
||||
/*-- externs for compression. --*/
|
||||
|
||||
extern void
|
||||
blockSort ( EState* );
|
||||
BZ2_blockSort ( EState* );
|
||||
|
||||
extern void
|
||||
compressBlock ( EState*, Bool );
|
||||
BZ2_compressBlock ( EState*, Bool );
|
||||
|
||||
extern void
|
||||
bsInitWrite ( EState* );
|
||||
BZ2_bsInitWrite ( EState* );
|
||||
|
||||
extern void
|
||||
hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
|
||||
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
|
||||
|
||||
extern void
|
||||
hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
|
||||
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
|
||||
|
||||
|
||||
|
||||
@ -493,22 +495,22 @@ typedef
|
||||
#define GET_LL(i) \
|
||||
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
|
||||
|
||||
#define BZ_GET_SMALL(cccc) \
|
||||
cccc = indexIntoF ( s->tPos, s->cftab ); \
|
||||
#define BZ_GET_SMALL(cccc) \
|
||||
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
|
||||
s->tPos = GET_LL(s->tPos);
|
||||
|
||||
|
||||
/*-- externs for decompression. --*/
|
||||
|
||||
extern Int32
|
||||
indexIntoF ( Int32, Int32* );
|
||||
BZ2_indexIntoF ( Int32, Int32* );
|
||||
|
||||
extern Int32
|
||||
decompress ( DState* );
|
||||
BZ2_decompress ( DState* );
|
||||
|
||||
extern void
|
||||
hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
|
||||
Int32, Int32, Int32 );
|
||||
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
|
||||
Int32, Int32, Int32 );
|
||||
|
||||
|
||||
#endif
|
||||
|
193
compress.c
193
compress.c
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -78,7 +78,7 @@
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void bsInitWrite ( EState* s )
|
||||
void BZ2_bsInitWrite ( EState* s )
|
||||
{
|
||||
s->bsLive = 0;
|
||||
s->bsBuff = 0;
|
||||
@ -113,6 +113,7 @@ void bsFinishWrite ( EState* s )
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
__inline__
|
||||
void bsW ( EState* s, Int32 n, UInt32 v )
|
||||
{
|
||||
bsNEEDW ( n );
|
||||
@ -164,8 +165,6 @@ void generateMTFValues ( EState* s )
|
||||
{
|
||||
UChar yy[256];
|
||||
Int32 i, j;
|
||||
UChar tmp;
|
||||
UChar tmp2;
|
||||
Int32 zPend;
|
||||
Int32 wr;
|
||||
Int32 EOB;
|
||||
@ -174,7 +173,7 @@ void generateMTFValues ( EState* s )
|
||||
After sorting (eg, here),
|
||||
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
|
||||
and
|
||||
((UInt16*)s->arr2) [ 0 .. s->nblock-1 ] [15:8]
|
||||
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
|
||||
holds the original block data.
|
||||
|
||||
The first thing to do is generate the MTF values,
|
||||
@ -186,14 +185,14 @@ void generateMTFValues ( EState* s )
|
||||
|
||||
The final compressed bitstream is generated into the
|
||||
area starting at
|
||||
(UChar*) (&((UInt16)s->arr2)[s->nblock])
|
||||
(UChar*) (&((UChar*)s->arr2)[s->nblock])
|
||||
|
||||
These storage aliases are set up in bzCompressInit(),
|
||||
except for the last one, which is arranged in
|
||||
compressBlock().
|
||||
*/
|
||||
UInt32* ptr = s->ptr;
|
||||
UInt16* block = s->block;
|
||||
UChar* block = s->block;
|
||||
UInt16* mtfv = s->mtfv;
|
||||
|
||||
makeMaps_e ( s );
|
||||
@ -207,27 +206,14 @@ void generateMTFValues ( EState* s )
|
||||
|
||||
for (i = 0; i < s->nblock; i++) {
|
||||
UChar ll_i;
|
||||
|
||||
AssertD ( wr <= i, "generateMTFValues(1)" );
|
||||
j = ptr[i]-1; if (j < 0) j += s->nblock;
|
||||
ll_i = s->unseqToSeq[block[j] >> 8];
|
||||
ll_i = s->unseqToSeq[block[j]];
|
||||
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
|
||||
|
||||
tmp = yy[0];
|
||||
if (tmp == ll_i) {
|
||||
if (yy[0] == ll_i) {
|
||||
zPend++;
|
||||
} else {
|
||||
tmp2 = tmp;
|
||||
tmp = yy[1];
|
||||
yy[1] = tmp2;
|
||||
j = 1;
|
||||
while ( ll_i != tmp ) {
|
||||
j++;
|
||||
tmp2 = tmp;
|
||||
tmp = yy[j];
|
||||
yy[j] = tmp2;
|
||||
};
|
||||
yy[0] = tmp;
|
||||
|
||||
if (zPend > 0) {
|
||||
zPend--;
|
||||
@ -244,7 +230,26 @@ void generateMTFValues ( EState* s )
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
|
||||
{
|
||||
register UChar rtmp;
|
||||
register UChar* ryy_j;
|
||||
register UChar rll_i;
|
||||
rtmp = yy[1];
|
||||
yy[1] = yy[0];
|
||||
ryy_j = &(yy[1]);
|
||||
rll_i = ll_i;
|
||||
while ( rll_i != rtmp ) {
|
||||
register UChar rtmp2;
|
||||
ryy_j++;
|
||||
rtmp2 = rtmp;
|
||||
rtmp = *ryy_j;
|
||||
*ryy_j = rtmp2;
|
||||
};
|
||||
yy[0] = rtmp;
|
||||
j = ryy_j - &(yy[0]);
|
||||
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,6 +266,7 @@ void generateMTFValues ( EState* s )
|
||||
if (zPend < 2) break;
|
||||
zPend = (zPend - 2) / 2;
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
|
||||
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
|
||||
@ -365,6 +371,18 @@ void sendMTFValues ( EState* s )
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->rfreq[t][v] = 0;
|
||||
|
||||
/*---
|
||||
Set up an auxiliary length table which is used to fast-track
|
||||
the common case (nGroups == 6).
|
||||
---*/
|
||||
if (nGroups == 6) {
|
||||
for (v = 0; v < alphaSize; v++) {
|
||||
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
|
||||
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
|
||||
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
|
||||
}
|
||||
}
|
||||
|
||||
nSelectors = 0;
|
||||
totc = 0;
|
||||
gs = 0;
|
||||
@ -381,21 +399,37 @@ void sendMTFValues ( EState* s )
|
||||
--*/
|
||||
for (t = 0; t < nGroups; t++) cost[t] = 0;
|
||||
|
||||
if (nGroups == 6) {
|
||||
register UInt16 cost0, cost1, cost2, cost3, cost4, cost5;
|
||||
cost0 = cost1 = cost2 = cost3 = cost4 = cost5 = 0;
|
||||
for (i = gs; i <= ge; i++) {
|
||||
UInt16 icv = mtfv[i];
|
||||
cost0 += s->len[0][icv];
|
||||
cost1 += s->len[1][icv];
|
||||
cost2 += s->len[2][icv];
|
||||
cost3 += s->len[3][icv];
|
||||
cost4 += s->len[4][icv];
|
||||
cost5 += s->len[5][icv];
|
||||
}
|
||||
cost[0] = cost0; cost[1] = cost1; cost[2] = cost2;
|
||||
cost[3] = cost3; cost[4] = cost4; cost[5] = cost5;
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
register UInt32 cost01, cost23, cost45;
|
||||
register UInt16 icv;
|
||||
cost01 = cost23 = cost45 = 0;
|
||||
|
||||
# define BZ_ITER(nn) \
|
||||
icv = mtfv[gs+(nn)]; \
|
||||
cost01 += s->len_pack[icv][0]; \
|
||||
cost23 += s->len_pack[icv][1]; \
|
||||
cost45 += s->len_pack[icv][2]; \
|
||||
|
||||
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
|
||||
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
|
||||
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
|
||||
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
|
||||
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
|
||||
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
|
||||
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
|
||||
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
|
||||
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
|
||||
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
|
||||
|
||||
# undef BZ_ITER
|
||||
|
||||
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
|
||||
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
|
||||
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
UInt16 icv = mtfv[i];
|
||||
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
|
||||
@ -417,8 +451,29 @@ void sendMTFValues ( EState* s )
|
||||
/*--
|
||||
Increment the symbol frequencies for the selected table.
|
||||
--*/
|
||||
for (i = gs; i <= ge; i++)
|
||||
s->rfreq[bt][ mtfv[i] ]++;
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
|
||||
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
|
||||
|
||||
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
|
||||
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
|
||||
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
|
||||
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
|
||||
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
|
||||
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
|
||||
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
|
||||
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
|
||||
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
|
||||
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
|
||||
|
||||
# undef BZ_ITUR
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++)
|
||||
s->rfreq[bt][ mtfv[i] ]++;
|
||||
}
|
||||
|
||||
gs = ge+1;
|
||||
}
|
||||
@ -434,8 +489,8 @@ void sendMTFValues ( EState* s )
|
||||
Recompute the tables based on the accumulated frequencies.
|
||||
--*/
|
||||
for (t = 0; t < nGroups; t++)
|
||||
hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
|
||||
alphaSize, 20 );
|
||||
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
|
||||
alphaSize, 20 );
|
||||
}
|
||||
|
||||
|
||||
@ -474,8 +529,8 @@ void sendMTFValues ( EState* s )
|
||||
}
|
||||
AssertH ( !(maxLen > 20), 3004 );
|
||||
AssertH ( !(minLen < 1), 3005 );
|
||||
hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize );
|
||||
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize );
|
||||
}
|
||||
|
||||
/*--- Transmit the mapping table. ---*/
|
||||
@ -536,13 +591,45 @@ void sendMTFValues ( EState* s )
|
||||
if (gs >= s->nMTF) break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF) ge = s->nMTF-1;
|
||||
for (i = gs; i <= ge; i++) {
|
||||
AssertH ( s->selector[selCtr] < nGroups, 3006 );
|
||||
bsW ( s,
|
||||
s->len [s->selector[selCtr]] [mtfv[i]],
|
||||
s->code [s->selector[selCtr]] [mtfv[i]] );
|
||||
AssertH ( s->selector[selCtr] < nGroups, 3006 );
|
||||
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
UInt16 mtfv_i;
|
||||
UChar* s_len_sel_selCtr
|
||||
= &(s->len[s->selector[selCtr]][0]);
|
||||
Int32* s_code_sel_selCtr
|
||||
= &(s->code[s->selector[selCtr]][0]);
|
||||
|
||||
# define BZ_ITAH(nn) \
|
||||
mtfv_i = mtfv[gs+(nn)]; \
|
||||
bsW ( s, \
|
||||
s_len_sel_selCtr[mtfv_i], \
|
||||
s_code_sel_selCtr[mtfv_i] )
|
||||
|
||||
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
|
||||
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
|
||||
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
|
||||
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
|
||||
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
|
||||
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
|
||||
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
|
||||
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
|
||||
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
|
||||
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
|
||||
|
||||
# undef BZ_ITAH
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
bsW ( s,
|
||||
s->len [s->selector[selCtr]] [mtfv[i]],
|
||||
s->code [s->selector[selCtr]] [mtfv[i]] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gs = ge+1;
|
||||
selCtr++;
|
||||
}
|
||||
@ -554,7 +641,7 @@ void sendMTFValues ( EState* s )
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void compressBlock ( EState* s, Bool is_last_block )
|
||||
void BZ2_compressBlock ( EState* s, Bool is_last_block )
|
||||
{
|
||||
if (s->nblock > 0) {
|
||||
|
||||
@ -568,14 +655,14 @@ void compressBlock ( EState* s, Bool is_last_block )
|
||||
"combined CRC = 0x%8x, size = %d\n",
|
||||
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
|
||||
|
||||
blockSort ( s );
|
||||
BZ2_blockSort ( s );
|
||||
}
|
||||
|
||||
s->zbits = (UChar*) (&((UInt16*)s->arr2)[s->nblock]);
|
||||
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
|
||||
|
||||
/*-- If this is the first block, create the stream header. --*/
|
||||
if (s->blockNo == 1) {
|
||||
bsInitWrite ( s );
|
||||
BZ2_bsInitWrite ( s );
|
||||
bsPutUChar ( s, 'B' );
|
||||
bsPutUChar ( s, 'Z' );
|
||||
bsPutUChar ( s, 'h' );
|
||||
|
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -68,7 +68,7 @@
|
||||
comp.compression FAQ.
|
||||
--*/
|
||||
|
||||
UInt32 crc32Table[256] = {
|
||||
UInt32 BZ2_crc32Table[256] = {
|
||||
|
||||
/*-- Ugly, innit? --*/
|
||||
|
||||
|
44
decompress.c
44
decompress.c
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -99,7 +99,9 @@ void makeMaps_d ( DState* s )
|
||||
s->bsLive += 8; \
|
||||
s->strm->next_in++; \
|
||||
s->strm->avail_in--; \
|
||||
s->strm->total_in++; \
|
||||
s->strm->total_in_lo32++; \
|
||||
if (s->strm->total_in_lo32 == 0) \
|
||||
s->strm->total_in_hi32++; \
|
||||
}
|
||||
|
||||
#define GET_UCHAR(lll,uuu) \
|
||||
@ -113,6 +115,8 @@ void makeMaps_d ( DState* s )
|
||||
{ \
|
||||
if (groupPos == 0) { \
|
||||
groupNo++; \
|
||||
if (groupNo >= nSelectors) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
groupPos = BZ_G_SIZE; \
|
||||
gSel = s->selector[groupNo]; \
|
||||
gMinlen = s->minLens[gSel]; \
|
||||
@ -123,17 +127,23 @@ void makeMaps_d ( DState* s )
|
||||
groupPos--; \
|
||||
zn = gMinlen; \
|
||||
GET_BITS(label1, zvec, zn); \
|
||||
while (zvec > gLimit[zn]) { \
|
||||
while (1) { \
|
||||
if (zn > 20 /* the longest code */) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
if (zvec <= gLimit[zn]) break; \
|
||||
zn++; \
|
||||
GET_BIT(label2, zj); \
|
||||
zvec = (zvec << 1) | zj; \
|
||||
}; \
|
||||
if (zvec - gBase[zn] < 0 \
|
||||
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
lval = gPerm[zvec - gBase[zn]]; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
Int32 decompress ( DState* s )
|
||||
Int32 BZ2_decompress ( DState* s )
|
||||
{
|
||||
UChar uc;
|
||||
Int32 retVal;
|
||||
@ -288,6 +298,11 @@ Int32 decompress ( DState* s )
|
||||
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
|
||||
if (s->origPtr < 0)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
if (s->origPtr > 10 + 100000*s->blockSize100k)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*--- Receive the mapping table ---*/
|
||||
for (i = 0; i < 16; i++) {
|
||||
GET_BIT(BZ_X_MAPPING_1, uc);
|
||||
@ -305,18 +320,21 @@ Int32 decompress ( DState* s )
|
||||
if (uc == 1) s->inUse[i * 16 + j] = True;
|
||||
}
|
||||
makeMaps_d ( s );
|
||||
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
|
||||
alphaSize = s->nInUse+2;
|
||||
|
||||
/*--- Now the selectors ---*/
|
||||
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
|
||||
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
|
||||
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
|
||||
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
j = 0;
|
||||
while (True) {
|
||||
GET_BIT(BZ_X_SELECTOR_3, uc);
|
||||
if (uc == 0) break;
|
||||
j++;
|
||||
if (j > 5) RETURN(BZ_DATA_ERROR);
|
||||
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
@ -358,7 +376,7 @@ Int32 decompress ( DState* s )
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
hbCreateDecodeTables (
|
||||
BZ2_hbCreateDecodeTables (
|
||||
&(s->limit[t][0]),
|
||||
&(s->base[t][0]),
|
||||
&(s->perm[t][0]),
|
||||
@ -392,7 +410,6 @@ Int32 decompress ( DState* s )
|
||||
/*-- end MTF init --*/
|
||||
|
||||
nblock = 0;
|
||||
|
||||
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
|
||||
|
||||
while (True) {
|
||||
@ -417,23 +434,24 @@ Int32 decompress ( DState* s )
|
||||
|
||||
if (s->smallDecompress)
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->ll16[nblock] = (UInt16)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
}
|
||||
else
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->tt[nblock] = (UInt32)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
};
|
||||
|
||||
if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
continue;
|
||||
|
||||
} else {
|
||||
|
||||
if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*-- uc = MTF ( nextSym-1 ) --*/
|
||||
{
|
||||
@ -500,6 +518,12 @@ Int32 decompress ( DState* s )
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we know what nblock is, we can do a better sanity
|
||||
check on s->origPtr.
|
||||
*/
|
||||
if (s->origPtr < 0 || s->origPtr >= nblock)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->state_out_len = 0;
|
||||
s->state_out_ch = 0;
|
||||
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
|
||||
|
341
dlltest.c
341
dlltest.c
@ -1,165 +1,176 @@
|
||||
/*
|
||||
minibz2
|
||||
libbz2.dll test program.
|
||||
by Yoshioka Tsuneo(QWF00133@nifty.ne.jp/tsuneo-y@is.aist-nara.ac.jp)
|
||||
This file is Public Domain.
|
||||
welcome any email to me.
|
||||
|
||||
usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
|
||||
*/
|
||||
|
||||
#define BZ_IMPORT
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "bzlib.h"
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
static int BZ2DLLLoaded = 0;
|
||||
static HINSTANCE BZ2DLLhLib;
|
||||
int BZ2DLLLoadLibrary(void)
|
||||
{
|
||||
HINSTANCE hLib;
|
||||
|
||||
if(BZ2DLLLoaded==1){return 0;}
|
||||
hLib=LoadLibrary("libbz2.dll");
|
||||
if(hLib == NULL){
|
||||
puts("Can't load libbz2.dll");
|
||||
return -1;
|
||||
}
|
||||
BZ2DLLLoaded=1;
|
||||
BZ2DLLhLib=hLib;
|
||||
bzlibVersion=GetProcAddress(hLib,"bzlibVersion");
|
||||
bzopen=GetProcAddress(hLib,"bzopen");
|
||||
bzdopen=GetProcAddress(hLib,"bzdopen");
|
||||
bzread=GetProcAddress(hLib,"bzread");
|
||||
bzwrite=GetProcAddress(hLib,"bzwrite");
|
||||
bzflush=GetProcAddress(hLib,"bzflush");
|
||||
bzclose=GetProcAddress(hLib,"bzclose");
|
||||
bzerror=GetProcAddress(hLib,"bzerror");
|
||||
return 0;
|
||||
|
||||
}
|
||||
int BZ2DLLFreeLibrary(void)
|
||||
{
|
||||
if(BZ2DLLLoaded==0){return 0;}
|
||||
FreeLibrary(BZ2DLLhLib);
|
||||
BZ2DLLLoaded=0;
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int decompress = 0;
|
||||
int level = 9;
|
||||
char *fn_r = NULL;
|
||||
char *fn_w = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(BZ2DLLLoadLibrary()<0){
|
||||
puts("can't load dll");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
while(++argv,--argc){
|
||||
if(**argv =='-' || **argv=='/'){
|
||||
char *p;
|
||||
|
||||
for(p=*argv+1;*p;p++){
|
||||
if(*p=='d'){
|
||||
decompress = 1;
|
||||
}else if('1'<=*p && *p<='9'){
|
||||
level = *p - '0';
|
||||
}else{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(argc>=1){
|
||||
fn_r = *argv;
|
||||
argc--;argv++;
|
||||
}else{
|
||||
fn_r = NULL;
|
||||
}
|
||||
if(argc>=1){
|
||||
fn_w = *argv;
|
||||
argc--;argv++;
|
||||
}else{
|
||||
fn_w = NULL;
|
||||
}
|
||||
{
|
||||
int len;
|
||||
char buff[0x1000];
|
||||
char mode[10];
|
||||
|
||||
if(decompress){
|
||||
BZFILE *BZ2fp_r = NULL;
|
||||
FILE *fp_w = NULL;
|
||||
|
||||
if(fn_w){
|
||||
if((fp_w = fopen(fn_w,"wb"))==NULL){
|
||||
printf("can't open [%s]\n",fn_w);
|
||||
perror("reason:");
|
||||
exit(1);
|
||||
}
|
||||
}else{
|
||||
fp_w = stdout;
|
||||
}
|
||||
if((BZ2fp_r == NULL && (BZ2fp_r = bzdopen(fileno(stdin),"rb"))==NULL)
|
||||
|| (BZ2fp_r != NULL && (BZ2fp_r = bzopen(fn_r,"rb"))==NULL)){
|
||||
printf("can't bz2openstream\n");
|
||||
exit(1);
|
||||
}
|
||||
while((len=bzread(BZ2fp_r,buff,0x1000))>0){
|
||||
fwrite(buff,1,len,fp_w);
|
||||
}
|
||||
bzclose(BZ2fp_r);
|
||||
if(fp_w != stdout) fclose(fp_w);
|
||||
}else{
|
||||
BZFILE *BZ2fp_w = NULL;
|
||||
FILE *fp_r = NULL;
|
||||
|
||||
if(fn_r){
|
||||
if((fp_r = fopen(fn_r,"rb"))==NULL){
|
||||
printf("can't open [%s]\n",fn_r);
|
||||
perror("reason:");
|
||||
exit(1);
|
||||
}
|
||||
}else{
|
||||
fp_r = stdin;
|
||||
}
|
||||
mode[0]='w';
|
||||
mode[1] = '0' + level;
|
||||
mode[2] = '\0';
|
||||
|
||||
if((fn_w == NULL && (BZ2fp_w = bzdopen(fileno(stdout),mode))==NULL)
|
||||
|| (fn_w !=NULL && (BZ2fp_w = bzopen(fn_w,mode))==NULL)){
|
||||
printf("can't bz2openstream\n");
|
||||
exit(1);
|
||||
}
|
||||
while((len=fread(buff,1,0x1000,fp_r))>0){
|
||||
bzwrite(BZ2fp_w,buff,len);
|
||||
}
|
||||
bzclose(BZ2fp_w);
|
||||
if(fp_r!=stdin)fclose(fp_r);
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
BZ2DLLFreeLibrary();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
minibz2
|
||||
libbz2.dll test program.
|
||||
by Yoshioka Tsuneo(QWF00133@nifty.ne.jp/tsuneo-y@is.aist-nara.ac.jp)
|
||||
This file is Public Domain.
|
||||
welcome any email to me.
|
||||
|
||||
usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
|
||||
*/
|
||||
|
||||
#define BZ_IMPORT
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "bzlib.h"
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define BZ2_LIBNAME "libbz2-1.0.0.DLL"
|
||||
|
||||
#include <windows.h>
|
||||
static int BZ2DLLLoaded = 0;
|
||||
static HINSTANCE BZ2DLLhLib;
|
||||
int BZ2DLLLoadLibrary(void)
|
||||
{
|
||||
HINSTANCE hLib;
|
||||
|
||||
if(BZ2DLLLoaded==1){return 0;}
|
||||
hLib=LoadLibrary(BZ2_LIBNAME);
|
||||
if(hLib == NULL){
|
||||
fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
|
||||
return -1;
|
||||
}
|
||||
BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
|
||||
BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
|
||||
BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
|
||||
BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
|
||||
BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
|
||||
BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
|
||||
BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
|
||||
BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");
|
||||
|
||||
if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
|
||||
|| !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
|
||||
|| !BZ2_bzclose || !BZ2_bzerror) {
|
||||
fprintf(stderr,"GetProcAddress failed.\n");
|
||||
return -1;
|
||||
}
|
||||
BZ2DLLLoaded=1;
|
||||
BZ2DLLhLib=hLib;
|
||||
return 0;
|
||||
|
||||
}
|
||||
int BZ2DLLFreeLibrary(void)
|
||||
{
|
||||
if(BZ2DLLLoaded==0){return 0;}
|
||||
FreeLibrary(BZ2DLLhLib);
|
||||
BZ2DLLLoaded=0;
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int decompress = 0;
|
||||
int level = 9;
|
||||
char *fn_r = NULL;
|
||||
char *fn_w = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(BZ2DLLLoadLibrary()<0){
|
||||
fprintf(stderr,"Loading of %s failed. Giving up.\n", BZ2_LIBNAME);
|
||||
exit(1);
|
||||
}
|
||||
printf("Loading of %s succeeded. Library version is %s.\n",
|
||||
BZ2_LIBNAME, BZ2_bzlibVersion() );
|
||||
#endif
|
||||
while(++argv,--argc){
|
||||
if(**argv =='-' || **argv=='/'){
|
||||
char *p;
|
||||
|
||||
for(p=*argv+1;*p;p++){
|
||||
if(*p=='d'){
|
||||
decompress = 1;
|
||||
}else if('1'<=*p && *p<='9'){
|
||||
level = *p - '0';
|
||||
}else{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(argc>=1){
|
||||
fn_r = *argv;
|
||||
argc--;argv++;
|
||||
}else{
|
||||
fn_r = NULL;
|
||||
}
|
||||
if(argc>=1){
|
||||
fn_w = *argv;
|
||||
argc--;argv++;
|
||||
}else{
|
||||
fn_w = NULL;
|
||||
}
|
||||
{
|
||||
int len;
|
||||
char buff[0x1000];
|
||||
char mode[10];
|
||||
|
||||
if(decompress){
|
||||
BZFILE *BZ2fp_r = NULL;
|
||||
FILE *fp_w = NULL;
|
||||
|
||||
if(fn_w){
|
||||
if((fp_w = fopen(fn_w,"wb"))==NULL){
|
||||
printf("can't open [%s]\n",fn_w);
|
||||
perror("reason:");
|
||||
exit(1);
|
||||
}
|
||||
}else{
|
||||
fp_w = stdout;
|
||||
}
|
||||
if((BZ2fp_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
|
||||
|| (BZ2fp_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
|
||||
printf("can't bz2openstream\n");
|
||||
exit(1);
|
||||
}
|
||||
while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
|
||||
fwrite(buff,1,len,fp_w);
|
||||
}
|
||||
BZ2_bzclose(BZ2fp_r);
|
||||
if(fp_w != stdout) fclose(fp_w);
|
||||
}else{
|
||||
BZFILE *BZ2fp_w = NULL;
|
||||
FILE *fp_r = NULL;
|
||||
|
||||
if(fn_r){
|
||||
if((fp_r = fopen(fn_r,"rb"))==NULL){
|
||||
printf("can't open [%s]\n",fn_r);
|
||||
perror("reason:");
|
||||
exit(1);
|
||||
}
|
||||
}else{
|
||||
fp_r = stdin;
|
||||
}
|
||||
mode[0]='w';
|
||||
mode[1] = '0' + level;
|
||||
mode[2] = '\0';
|
||||
|
||||
if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
|
||||
|| (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
|
||||
printf("can't bz2openstream\n");
|
||||
exit(1);
|
||||
}
|
||||
while((len=fread(buff,1,0x1000,fp_r))>0){
|
||||
BZ2_bzwrite(BZ2fp_w,buff,len);
|
||||
}
|
||||
BZ2_bzclose(BZ2fp_w);
|
||||
if(fp_r!=stdin)fclose(fp_r);
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
BZ2DLLFreeLibrary();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
36
huffman.c
36
huffman.c
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -100,10 +100,10 @@
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void hbMakeCodeLengths ( UChar *len,
|
||||
Int32 *freq,
|
||||
Int32 alphaSize,
|
||||
Int32 maxLen )
|
||||
void BZ2_hbMakeCodeLengths ( UChar *len,
|
||||
Int32 *freq,
|
||||
Int32 alphaSize,
|
||||
Int32 maxLen )
|
||||
{
|
||||
/*--
|
||||
Nodes and heap entries run from 1. Entry 0
|
||||
@ -172,11 +172,11 @@ void hbMakeCodeLengths ( UChar *len,
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void hbAssignCodes ( Int32 *code,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
void BZ2_hbAssignCodes ( Int32 *code,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 n, vec, i;
|
||||
|
||||
@ -190,13 +190,13 @@ void hbAssignCodes ( Int32 *code,
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void hbCreateDecodeTables ( Int32 *limit,
|
||||
Int32 *base,
|
||||
Int32 *perm,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
void BZ2_hbCreateDecodeTables ( Int32 *limit,
|
||||
Int32 *base,
|
||||
Int32 *perm,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 pp, i, j, vec;
|
||||
|
||||
|
46
libbz2.def
46
libbz2.def
@ -1,25 +1,27 @@
|
||||
LIBRARY LIBBZ2
|
||||
DESCRIPTION "libbzip2: library for data compression"
|
||||
EXPORTS
|
||||
bzCompressInit
|
||||
bzCompress
|
||||
bzCompressEnd
|
||||
bzDecompressInit
|
||||
bzDecompress
|
||||
bzDecompressEnd
|
||||
bzReadOpen
|
||||
bzReadClose
|
||||
bzReadGetUnused
|
||||
bzRead
|
||||
bzWriteOpen
|
||||
bzWrite
|
||||
bzWriteClose
|
||||
bzBuffToBuffCompress
|
||||
bzBuffToBuffDecompress
|
||||
bzlibVersion
|
||||
bzopen
|
||||
bzdopen
|
||||
bzread
|
||||
bzwrite
|
||||
bzflush
|
||||
bzclose
|
||||
BZ2_bzCompressInit
|
||||
BZ2_bzCompress
|
||||
BZ2_bzCompressEnd
|
||||
BZ2_bzDecompressInit
|
||||
BZ2_bzDecompress
|
||||
BZ2_bzDecompressEnd
|
||||
BZ2_bzReadOpen
|
||||
BZ2_bzReadClose
|
||||
BZ2_bzReadGetUnused
|
||||
BZ2_bzRead
|
||||
BZ2_bzWriteOpen
|
||||
BZ2_bzWrite
|
||||
BZ2_bzWriteClose
|
||||
BZ2_bzWriteClose64
|
||||
BZ2_bzBuffToBuffCompress
|
||||
BZ2_bzBuffToBuffDecompress
|
||||
BZ2_bzlibVersion
|
||||
BZ2_bzopen
|
||||
BZ2_bzdopen
|
||||
BZ2_bzread
|
||||
BZ2_bzwrite
|
||||
BZ2_bzflush
|
||||
BZ2_bzclose
|
||||
BZ2_bzerror
|
||||
|
18
makefile.msc
18
makefile.msc
@ -4,7 +4,7 @@
|
||||
# Fixed up by JRS for bzip2-0.9.5d release.
|
||||
|
||||
CC=cl
|
||||
CFLAGS= -DWIN32 -MD -Ox
|
||||
CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64
|
||||
|
||||
OBJS= blocksort.obj \
|
||||
huffman.obj \
|
||||
@ -21,7 +21,6 @@ bzip2: lib
|
||||
$(CC) $(CFLAGS) -o bzip2recover bzip2recover.c
|
||||
|
||||
lib: $(OBJS)
|
||||
del libbz2.lib
|
||||
lib /out:libbz2.lib $(OBJS)
|
||||
|
||||
test: bzip2
|
||||
@ -32,20 +31,19 @@ test: bzip2
|
||||
.\\bzip2 -d < sample1.bz2 > sample1.tst
|
||||
.\\bzip2 -d < sample2.bz2 > sample2.tst
|
||||
.\\bzip2 -ds < sample3.bz2 > sample3.tst
|
||||
@echo All six of the fc's should find no differences.
|
||||
@echo If fc finds an error on sample3.bz2, this could be
|
||||
@echo because WinZip's 'TAR file smart CR/LF conversion'
|
||||
@echo is too clever for its own good. Disable this option.
|
||||
@echo The correct size for sample3.ref is 120,244. If it
|
||||
@echo is 150,251, WinZip has messed it up.
|
||||
fc sample1.bz2 sample1.rb2
|
||||
fc sample2.bz2 sample2.rb2
|
||||
fc sample3.bz2 sample3.rb2
|
||||
fc sample1.tst sample1.ref
|
||||
fc sample2.tst sample2.ref
|
||||
fc sample3.tst sample3.ref
|
||||
@echo All six of the fc's should find no differences.
|
||||
@echo If fc finds an error on sample3.tst, this could be
|
||||
@echo because WinZips 'TAR file smart CR/LF conversion'
|
||||
@echo is too clever for its own good. Disable this option.
|
||||
@echo The correct size for sample3.ref is 120,244. If it
|
||||
@echo is around 150k, WinZip has stuffed it up.
|
||||
@echo Also remember to set BZ_UNIX to 0 and BZ_LCCWIN32
|
||||
@echo to 1 in bzip2.c.
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
|
516
manual.texi
516
manual.texi
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
This file is a part of bzip2 and/or libbzip2, a program and
|
||||
library for lossless, block-sorting data compression.
|
||||
|
||||
Copyright (C) 1996-1999 Julian R Seward. All rights reserved.
|
||||
Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
Julian Seward, Cambridge, UK.
|
||||
jseward@acm.org
|
||||
bzip2/libbzip2 version 0.9.5 of 24 May 1999
|
||||
bzip2/libbzip2 version 1.0 of 21 March 2000
|
||||
|
||||
This program is based on (at least) the work of:
|
||||
Mike Burrows
|
||||
@ -63,7 +63,7 @@
|
||||
|
||||
|
||||
/*---------------------------------------------*/
|
||||
Int32 rNums[512] = {
|
||||
Int32 BZ2_rNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
|
39
spewG.c
Normal file
39
spewG.c
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/* spew out a thoroughly gigantic file designed so that bzip2
|
||||
can compress it reasonably rapidly. This is to help test
|
||||
support for large files (> 2GB) in a reasonable amount of time.
|
||||
I suggest you use the undocumented --exponential option to
|
||||
bzip2 when compressing the resulting file; this saves a bit of
|
||||
time. Note: *don't* bother with --exponential when compressing
|
||||
Real Files; it'll just waste a lot of CPU time :-)
|
||||
(but is otherwise harmless).
|
||||
*/
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* The number of megabytes of junk to spew out (roughly) */
|
||||
#define MEGABYTES 5000
|
||||
|
||||
#define N_BUF 1000000
|
||||
char buf[N_BUF];
|
||||
|
||||
int main ( int argc, char** argv )
|
||||
{
|
||||
int ii, kk, p;
|
||||
srandom(1);
|
||||
setbuffer ( stdout, buf, N_BUF );
|
||||
for (kk = 0; kk < MEGABYTES * 515; kk+=3) {
|
||||
p = 25+random()%50;
|
||||
for (ii = 0; ii < p; ii++)
|
||||
printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
|
||||
for (ii = 0; ii < p-1; ii++)
|
||||
printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" );
|
||||
for (ii = 0; ii < p+1; ii++)
|
||||
printf ( "ccccccccccccccccccccccccccccccccccccc" );
|
||||
}
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
126
unzcrash.c
Normal file
126
unzcrash.c
Normal file
@ -0,0 +1,126 @@
|
||||
|
||||
/* A test program written to test robustness to decompression of
|
||||
corrupted data. Usage is
|
||||
unzcrash filename
|
||||
and the program will read the specified file, compress it (in memory),
|
||||
and then repeatedly decompress it, each time with a different bit of
|
||||
the compressed data inverted, so as to test all possible one-bit errors.
|
||||
This should not cause any invalid memory accesses. If it does,
|
||||
I want to know about it!
|
||||
|
||||
p.s. As you can see from the above description, the process is
|
||||
incredibly slow. A file of size eg 5KB will cause it to run for
|
||||
many hours.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "bzlib.h"
|
||||
|
||||
#define M_BLOCK 1000000
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
#define M_BLOCK_OUT (M_BLOCK + 1000000)
|
||||
uchar inbuf[M_BLOCK];
|
||||
uchar outbuf[M_BLOCK_OUT];
|
||||
uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
|
||||
|
||||
int nIn, nOut, nZ;
|
||||
|
||||
static char *bzerrorstrings[] = {
|
||||
"OK"
|
||||
,"SEQUENCE_ERROR"
|
||||
,"PARAM_ERROR"
|
||||
,"MEM_ERROR"
|
||||
,"DATA_ERROR"
|
||||
,"DATA_ERROR_MAGIC"
|
||||
,"IO_ERROR"
|
||||
,"UNEXPECTED_EOF"
|
||||
,"OUTBUFF_FULL"
|
||||
,"???" /* for future */
|
||||
,"???" /* for future */
|
||||
,"???" /* for future */
|
||||
,"???" /* for future */
|
||||
,"???" /* for future */
|
||||
,"???" /* for future */
|
||||
};
|
||||
|
||||
void flip_bit ( int bit )
|
||||
{
|
||||
int byteno = bit / 8;
|
||||
int bitno = bit % 8;
|
||||
uchar mask = 1 << bitno;
|
||||
//fprintf ( stderr, "(byte %d bit %d mask %d)",
|
||||
// byteno, bitno, (int)mask );
|
||||
zbuf[byteno] ^= mask;
|
||||
}
|
||||
|
||||
int main ( int argc, char** argv )
|
||||
{
|
||||
FILE* f;
|
||||
int r;
|
||||
int bit;
|
||||
int i;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf ( stderr, "usage: unzcrash filename\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
f = fopen ( argv[1], "r" );
|
||||
if (!f) {
|
||||
fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
nIn = fread ( inbuf, 1, M_BLOCK, f );
|
||||
fprintf ( stderr, "%d bytes read\n", nIn );
|
||||
|
||||
nZ = M_BLOCK;
|
||||
r = BZ2_bzBuffToBuffCompress (
|
||||
zbuf, &nZ, inbuf, nIn, 9, 0, 30 );
|
||||
|
||||
assert (r == BZ_OK);
|
||||
fprintf ( stderr, "%d after compression\n", nZ );
|
||||
|
||||
for (bit = 0; bit < nZ*8; bit++) {
|
||||
fprintf ( stderr, "bit %d ", bit );
|
||||
flip_bit ( bit );
|
||||
nOut = M_BLOCK_OUT;
|
||||
r = BZ2_bzBuffToBuffDecompress (
|
||||
outbuf, &nOut, zbuf, nZ, 0, 0 );
|
||||
fprintf ( stderr, " %d %s ", r, bzerrorstrings[-r] );
|
||||
|
||||
if (r != BZ_OK) {
|
||||
fprintf ( stderr, "\n" );
|
||||
} else {
|
||||
if (nOut != nIn) {
|
||||
fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
|
||||
return 1;
|
||||
} else {
|
||||
for (i = 0; i < nOut; i++)
|
||||
if (inbuf[i] != outbuf[i]) {
|
||||
fprintf(stderr, "mismatch at %d\n", i );
|
||||
return 1;
|
||||
}
|
||||
if (i == nOut) fprintf(stderr, "really ok!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
flip_bit ( bit );
|
||||
}
|
||||
|
||||
#if 0
|
||||
assert (nOut == nIn);
|
||||
for (i = 0; i < nOut; i++) {
|
||||
if (inbuf[i] != outbuf[i]) {
|
||||
fprintf ( stderr, "difference at %d !\n", i );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf ( stderr, "all ok\n" );
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user