llvm.org GIT mirror llvm / d6f5959
remove libbzip2, it is dead git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36875 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 13 years ago
15 changed file(s) with 0 addition(s) and 6126 deletion(s). Raw diff Collapse all Expand all
+0
-259
lib/Support/bzip2/CHANGES less more
None ###############################################################################
1 # LLVM CHANGES:
2 # LLVM incorporated version 1.0.2 of bzip2 and removed several files that
3 # were deemed unnecessary. All the programs (bzip2 bzip2recover), test suites
4 # and documentaton were removed. These items are available elsewhere and
5 # LLVM does not use them.
6 ###############################################################################
7
8 0.9.0
9 ~~~~~
10 First version.
11
12
13 0.9.0a
14 ~~~~~~
15 Removed 'ranlib' from Makefile, since most modern Unix-es
16 don't need it, or even know about it.
17
18
19 0.9.0b
20 ~~~~~~
21 Fixed a problem with error reporting in bzip2.c. This does not effect
22 the library in any way. Problem is: versions 0.9.0 and 0.9.0a (of the
23 program proper) compress and decompress correctly, but give misleading
24 error messages (internal panics) when an I/O error occurs, instead of
25 reporting the problem correctly. This shouldn't give any data loss
26 (as far as I can see), but is confusing.
27
28 Made the inline declarations disappear for non-GCC compilers.
29
30
31 0.9.0c
32 ~~~~~~
33 Fixed some problems in the library pertaining to some boundary cases.
34 This makes the library behave more correctly in those situations. The
35 fixes apply only to features (calls and parameters) not used by
36 bzip2.c, so the non-fixedness of them in previous versions has no
37 effect on reliability of bzip2.c.
38
39 In bzlib.c:
40 * made zero-length BZ_FLUSH work correctly in bzCompress().
41 * fixed bzWrite/bzRead to ignore zero-length requests.
42 * fixed bzread to correctly handle read requests after EOF.
43 * wrong parameter order in call to bzDecompressInit in
44 bzBuffToBuffDecompress. Fixed.
45
46 In compress.c:
47 * changed setting of nGroups in sendMTFValues() so as to
48 do a bit better on small files. This _does_ effect
49 bzip2.c.
50
51
52 0.9.5a
53 ~~~~~~
54 Major change: add a fallback sorting algorithm (blocksort.c)
55 to give reasonable behaviour even for very repetitive inputs.
56 Nuked --repetitive-best and --repetitive-fast since they are
57 no longer useful.
58
59 Minor changes: mostly a whole bunch of small changes/
60 bugfixes in the driver (bzip2.c). Changes pertaining to the
61 user interface are:
62
63 allow decompression of symlink'd files to stdout
64 decompress/test files even without .bz2 extension
65 give more accurate error messages for I/O errors
66 when compressing/decompressing to stdout, don't catch control-C
67 read flags from BZIP2 and BZIP environment variables
68 decline to break hard links to a file unless forced with -f
69 allow -c flag even with no filenames
70 preserve file ownerships as far as possible
71 make -s -1 give the expected block size (100k)
72 add a flag -q --quiet to suppress nonessential warnings
73 stop decoding flags after --, so files beginning in - can be handled
74 resolved inconsistent naming: bzcat or bz2cat ?
75 bzip2 --help now returns 0
76
77 Programming-level changes are:
78
79 fixed syntax error in GET_LL4 for Borland C++ 5.02
80 let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
81 fix overshoot of mode-string end in bzopen_or_bzdopen
82 wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
83 close file handles under all error conditions
84 added minor mods so it compiles with DJGPP out of the box
85 fixed Makefile so it doesn't give problems with BSD make
86 fix uninitialised memory reads in dlltest.c
87
88 0.9.5b
89 ~~~~~~
90 Open stdin/stdout in binary mode for DJGPP.
91
92 0.9.5c
93 ~~~~~~
94 Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1. The + 1
95 version could cause the sorted order to be wrong in some extremely
96 obscure cases. Also changed setting of quadrant in blocksort.c.
97
98 0.9.5d
99 ~~~~~~
100 The only functional change is to make bzlibVersion() in the library
101 return the correct string. This has no effect whatsoever on the
102 functioning of the bzip2 program or library. Added a couple of casts
103 so the library compiles without warnings at level 3 in MS Visual
104 Studio 6.0. Included a Y2K statement in the file Y2K_INFO. All other
105 changes are minor documentation changes.
106
107 1.0
108 ~~~
109 Several minor bugfixes and enhancements:
110
111 * Large file support. The library uses 64-bit counters to
112 count the volume of data passing through it. bzip2.c
113 is now compiled with -D_FILE_OFFSET_BITS=64 to get large
114 file support from the C library. -v correctly prints out
115 file sizes greater than 4 gigabytes. All these changes have
116 been made without assuming a 64-bit platform or a C compiler
117 which supports 64-bit ints, so, except for the C library
118 aspect, they are fully portable.
119
120 * Decompression robustness. The library/program should be
121 robust to any corruption of compressed data, detecting and
122 handling _all_ corruption, instead of merely relying on
123 the CRCs. What this means is that the program should
124 never crash, given corrupted data, and the library should
125 always return BZ_DATA_ERROR.
126
127 * Fixed an obscure race-condition bug only ever observed on
128 Solaris, in which, if you were very unlucky and issued
129 control-C at exactly the wrong time, both input and output
130 files would be deleted.
131
132 * Don't run out of file handles on test/decompression when
133 large numbers of files have invalid magic numbers.
134
135 * Avoid library namespace pollution. Prefix all exported
136 symbols with BZ2_.
137
138 * Minor sorting enhancements from my DCC2000 paper.
139
140 * Advance the version number to 1.0, so as to counteract the
141 (false-in-this-case) impression some people have that programs
142 with version numbers less than 1.0 are in some way, experimental,
143 pre-release versions.
144
145 * Create an initial Makefile-libbz2_so to build a shared library.
146 Yes, I know I should really use libtool et al ...
147
148 * Make the program exit with 2 instead of 0 when decompression
149 fails due to a bad magic number (ie, an invalid bzip2 header).
150 Also exit with 1 (as the manual claims :-) whenever a diagnostic
151 message would have been printed AND the corresponding operation
152 is aborted, for example
153 bzip2: Output file xx already exists.
154 When a diagnostic message is printed but the operation is not
155 aborted, for example
156 bzip2: Can't guess original name for wurble -- using wurble.out
157 then the exit value 0 is returned, unless some other problem is
158 also detected.
159
160 I think it corresponds more closely to what the manual claims now.
161
162
163 1.0.1
164 ~~~~~
165 * Modified dlltest.c so it uses the new BZ2_ naming scheme.
166 * Modified makefile-msc to fix minor build probs on Win2k.
167 * Updated README.COMPILATION.PROBLEMS.
168
169 There are no functionality changes or bug fixes relative to version
170 1.0.0. This is just a documentation update + a fix for minor Win32
171 build problems. For almost everyone, upgrading from 1.0.0 to 1.0.1 is
172 utterly pointless. Don't bother.
173
174
175 1.0.2
176 ~~~~~
177 A bug fix release, addressing various minor issues which have appeared
178 in the 18 or so months since 1.0.1 was released. Most of the fixes
179 are to do with file-handling or documentation bugs. To the best of my
180 knowledge, there have been no data-loss-causing bugs reported in the
181 compression/decompression engine of 1.0.0 or 1.0.1.
182
183 Note that this release does not improve the rather crude build system
184 for Unix platforms. The general plan here is to autoconfiscate/
185 libtoolise 1.0.2 soon after release, and release the result as 1.1.0
186 or perhaps 1.2.0. That, however, is still just a plan at this point.
187
188 Here are the changes in 1.0.2. Bug-reporters and/or patch-senders in
189 parentheses.
190
191 * Fix an infinite segfault loop in 1.0.1 when a directory is
192 encountered in -f (force) mode.
193 (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)
194
195 * Avoid double fclose() of output file on certain I/O error paths.
196 (Solar Designer)
197
198 * Don't fail with internal error 1007 when fed a long stream (> 48MB)
199 of byte 251. Also print useful message suggesting that 1007s may be
200 caused by bad memory.
201 (noticed by Juan Pedro Vallejo, fixed by me)
202
203 * Fix uninitialised variable silly bug in demo prog dlltest.c.
204 (Jorj Bauer)
205
206 * Remove 512-MB limitation on recovered file size for bzip2recover
207 on selected platforms which support 64-bit ints. At the moment
208 all GCC supported platforms, and Win32.
209 (me, Alson van der Meulen)
210
211 * Hard-code header byte values, to give correct operation on platforms
212 using EBCDIC as their native character set (IBM's OS/390).
213 (Leland Lucius)
214
215 * Copy file access times correctly.
216 (Marty Leisner)
217
218 * Add distclean and check targets to Makefile.
219 (Michael Carmack)
220
221 * Parameterise use of ar and ranlib in Makefile. Also add $(LDFLAGS).
222 (Rich Ireland, Bo Thorsen)
223
224 * Pass -p (create parent dirs as needed) to mkdir during make install.
225 (Jeremy Fusco)
226
227 * Dereference symlinks when copying file permissions in -f mode.
228 (Volker Schmidt)
229
230 * Majorly simplify implementation of uInt64_qrm10.
231 (Bo Lindbergh)
232
233 * Check the input file still exists before deleting the output one,
234 when aborting in cleanUpAndFail().
235 (Joerg Prante, Robert Linden, Matthias Krings)
236
237 Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
238 of bzip2:
239
240 * Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.
241
242 * Spelling changes and minor enhancements in bzip2.1.
243
244 * Avoid race condition between creating the output file and setting its
245 interim permissions safely, by using fopen_output_safely().
246 No changes to bzip2recover since there is no issue with file
247 permissions there.
248
249 * do not print senseless report with -v when compressing an empty
250 file.
251
252 * bzcat -f works on non-bzip2 files.
253
254 * do not try to escape shell meta-characters on unix (the shell takes
255 care of these).
256
257 * added --fast and --best aliases for -1 -9 for gzip compatibility.
258
+0
-39
lib/Support/bzip2/LICENSE less more
None
1 This program, "bzip2" and associated library "libbzip2", are
2 copyright (C) 1996-2002 Julian R Seward. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 2. The origin of this software must not be misrepresented; you must
12 not claim that you wrote the original software. If you use this
13 software in a product, an acknowledgment in the product
14 documentation would be appreciated but is not required.
15
16 3. Altered source versions must be plainly marked as such, and must
17 not be misrepresented as being the original software.
18
19 4. The name of the author may not be used to endorse or promote
20 products derived from this software without specific prior written
21 permission.
22
23 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
24 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 Julian Seward, Cambridge, UK.
36 jseward@acm.org
37 bzip2/libbzip2 version 1.0.2 of 30 December 2001
38
+0
-17
lib/Support/bzip2/Makefile less more
None ##===- lib/Support/bzip2/Makefile --------------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file was developed by the LLVM research group and is distributed under
5 # the University of Illinois Open Source License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8 LEVEL = ../../..
9 LIBRARYNAME = LLVMbzip2
10 BUILD_ARCHIVE = 1
11 SOURCES = blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c \
12 bzlib.c
13 EXTRA_DIST = bzlib.h bzlib_private.h CHANGES LICENSE README \
14 README.COMPILATION.PROBLEMS Y2K_INFO
15
16 include $(LEVEL)/Makefile.common
+0
-181
lib/Support/bzip2/README less more
None
1 This is the README for bzip2, a block-sorting file compressor, version
2 1.0.2. This version is fully compatible with the previous public
3 releases, versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0 and 1.0.1.
4
5 bzip2-1.0.2 is distributed under a BSD-style license. For details,
6 see the file LICENSE.
7
8 Complete documentation is available in Postscript form (manual.ps),
9 PDF (manual.pdf, amazingly enough) or html (manual_toc.html). A
10 plain-text version of the manual page is available as bzip2.txt.
11 A statement about Y2K issues is now included in the file Y2K_INFO.
12
13
14 HOW TO BUILD -- UNIX
15
16 Type `make'. This builds the library libbz2.a and then the
17 programs bzip2 and bzip2recover. Six self-tests are run.
18 If the self-tests complete ok, carry on to installation:
19
20 To install in /usr/bin, /usr/lib, /usr/man and /usr/include, type
21 make install
22 To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type
23 make install PREFIX=/xxx/yyy
24 If you are (justifiably) paranoid and want to see what 'make install'
25 is going to do, you can first do
26 make -n install or
27 make -n install PREFIX=/xxx/yyy respectively.
28 The -n instructs make to show the commands it would execute, but
29 not actually execute them.
30
31
32 HOW TO BUILD -- UNIX, shared library libbz2.so.
33
34 Do 'make -f Makefile-libbz2_so'. This Makefile seems to work for
35 Linux-ELF (RedHat 7.2 on an x86 box), with gcc. I make no claims
36 that it works for any other platform, though I suspect it probably
37 will work for most platforms employing both ELF and gcc.
38
39 bzip2-shared, a client of the shared library, is also built, but not
40 self-tested. So I suggest you also build using the normal Makefile,
41 since that conducts a self-test. A second reason to prefer the
42 version statically linked to the library is that, on x86 platforms,
43 building shared objects makes a valuable register (%ebx) unavailable
44 to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.
45
46 Important note for people upgrading .so's from 0.9.0/0.9.5 to version
47 1.0.X. All the functions in the library have been renamed, from (eg)
48 bzCompress to BZ2_bzCompress, to avoid namespace pollution.
49 Unfortunately this means that the libbz2.so created by
50 Makefile-libbz2_so will not work with any program which used an older
51 version of the library. Sorry. I do encourage library clients to
52 make the effort to upgrade to use version 1.0, since it is both faster
53 and more robust than previous versions.
54
55
56 HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.
57
58 It's difficult for me to support compilation on all these platforms.
59 My approach is to collect binaries for these platforms, and put them
60 on the master web page (http://sources.redhat.com/bzip2). Look there.
61 However (FWIW), bzip2-1.0.X is very standard ANSI C and should compile
62 unmodified with MS Visual C. If you have difficulties building, you
63 might want to read README.COMPILATION.PROBLEMS.
64
65 At least using MS Visual C++ 6, you can build from the unmodified
66 sources by issuing, in a command shell:
67 nmake -f makefile.msc
68 (you may need to first run the MSVC-provided script VCVARS32.BAT
69 so as to set up paths to the MSVC tools correctly).
70
71
72 VALIDATION
73
74 Correct operation, in the sense that a compressed file can always be
75 decompressed to reproduce the original, is obviously of paramount
76 importance. To validate bzip2, I used a modified version of Mark
77 Nelson's churn program. Churn is an automated test driver which
78 recursively traverses a directory structure, using bzip2 to compress
79 and then decompress each file it encounters, and checking that the
80 decompressed data is the same as the original. There are more details
81 in Section 4 of the user guide.
82
83
84
85 Please read and be aware of the following:
86
87 WARNING:
88
89 This program (attempts to) compress data by performing several
90 non-trivial transformations on it. Unless you are 100% familiar
91 with *all* the algorithms contained herein, and with the
92 consequences of modifying them, you should NOT meddle with the
93 compression or decompression machinery. Incorrect changes can and
94 very likely *will* lead to disastrous loss of data.
95
96
97 DISCLAIMER:
98
99 I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
100 USE OF THIS PROGRAM, HOWSOEVER CAUSED.
101
102 Every compression of a file implies an assumption that the
103 compressed file can be decompressed to reproduce the original.
104 Great efforts in design, coding and testing have been made to
105 ensure that this program works correctly. However, the complexity
106 of the algorithms, and, in particular, the presence of various
107 special cases in the code which occur with very low but non-zero
108 probability make it impossible to rule out the possibility of bugs
109 remaining in the program. DO NOT COMPRESS ANY DATA WITH THIS
110 PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
111 SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
112
113 That is not to say this program is inherently unreliable. Indeed,
114 I very much hope the opposite is true. bzip2 has been carefully
115 constructed and extensively tested.
116
117
118 PATENTS:
119
120 To the best of my knowledge, bzip2 does not use any patented
121 algorithms. However, I do not have the resources available to
122 carry out a full patent search. Therefore I cannot give any
123 guarantee of the above statement.
124
125 End of legalities.
126
127
128 WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?
129
130 * Approx 10% faster compression, 30% faster decompression
131 * -t (test mode) is a lot quicker
132 * Can decompress concatenated compressed files
133 * Programming interface, so programs can directly read/write .bz2 files
134 * Less restrictive (BSD-style) licensing
135 * Flag handling more compatible with GNU gzip
136 * Much more documentation, i.e., a proper user manual
137 * Hopefully, improved portability (at least of the library)
138
139 WHAT'S NEW IN 0.9.5 ?
140
141 * Compression speed is much less sensitive to the input
142 data than in previous versions. Specifically, the very
143 slow performance caused by repetitive data is fixed.
144 * Many small improvements in file and flag handling.
145 * A Y2K statement.
146
147 WHAT'S NEW IN 1.0.0 ?
148
149 See the CHANGES file.
150
151 WHAT'S NEW IN 1.0.2 ?
152
153 See the CHANGES file.
154
155
156 I hope you find bzip2 useful. Feel free to contact me at
157 jseward@acm.org
158 if you have any suggestions or queries. Many people mailed me with
159 comments, suggestions and patches after the releases of bzip-0.15,
160 bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0 and 1.0.1,
161 and the changes in bzip2 are largely a result of this feedback.
162 I thank you for your comments.
163
164 At least for the time being, bzip2's "home" is (or can be reached via)
165 http://sources.redhat.com/bzip2.
166
167 Julian Seward
168 jseward@acm.org
169
170 Cambridge, UK (and what a great town this is!)
171
172 18 July 1996 (version 0.15)
173 25 August 1996 (version 0.21)
174 7 August 1997 (bzip2, version 0.1)
175 29 August 1997 (bzip2, version 0.1pl2)
176 23 August 1998 (bzip2, version 0.9.0)
177 8 June 1999 (bzip2, version 0.9.5)
178 4 Sept 1999 (bzip2, version 0.9.5d)
179 5 May 2000 (bzip2, version 1.0pre8)
180 30 December 2001 (bzip2, version 1.0.2pre1)
+0
-130
lib/Support/bzip2/README.COMPILATION.PROBLEMS less more
None
1 bzip2-1.0 should compile without problems on the vast majority of
2 platforms. Using the supplied Makefile, I've built and tested it
3 myself for x86-linux, sparc-solaris, alpha-linux, x86-cygwin32 and
4 alpha-tru64unix. With makefile.msc, Visual C++ 6.0 and nmake, you can
5 build a native Win32 version too. Large file support seems to work
6 correctly on at least alpha-tru64unix and x86-cygwin32 (on Windows
7 2000).
8
9 When I say "large file" I mean a file of size 2,147,483,648 (2^31)
10 bytes or above. Many older OSs can't handle files above this size,
11 but many newer ones can. Large files are pretty huge -- most files
12 you'll encounter are not Large Files.
13
14 Earlier versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide
15 variety of platforms without difficulty, and I hope this version will
16 continue in that tradition. However, in order to support large files,
17 I've had to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.
18 This can cause problems.
19
20 The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
21 support is, as far as I know, the Recommended Way to get correct large
22 file support. For more details, see the Large File Support
23 Specification, published by the Large File Summit, at
24 http://www.sas.com/standard/large.file/
25
26 As a general comment, if you get compilation errors which you think
27 are related to large file support, try removing the above define from
28 the Makefile, ie, delete the line
29 BIGFILES=-D_FILE_OFFSET_BITS=64
30 from the Makefile, and do 'make clean ; make'. This will give you a
31 version of bzip2 without large file support, which, for most
32 applications, is probably not a problem.
33
34 Alternatively, try some of the platform-specific hints listed below.
35
36 You can use the spewG.c program to generate huge files to test bzip2's
37 large file support, if you are feeling paranoid. Be aware though that
38 any compilation problems which affect bzip2 will also affect spewG.c,
39 alas.
40
41
42 Known problems as of 1.0pre8:
43 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44
45 * HP/UX 10.20 and 11.00, using gcc (2.7.2.3 and 2.95.2): A large
46 number of warnings appear, including the following:
47
48 /usr/include/sys/resource.h: In function `getrlimit':
49 /usr/include/sys/resource.h:168:
50 warning: implicit declaration of function `__getrlimit64'
51 /usr/include/sys/resource.h: In function `setrlimit':
52 /usr/include/sys/resource.h:170:
53 warning: implicit declaration of function `__setrlimit64'
54
55 This would appear to be a problem with large file support, header
56 files and gcc. gcc may or may not give up at this point. If it
57 fails, you might be able to improve matters by adding
58 -D__STDC_EXT__=1
59 to the BIGFILES variable in the Makefile (ie, change its definition
60 to
61 BIGFILES=-D_FILE_OFFSET_BITS=64 -D__STDC_EXT__=1
62
63 Even if gcc does produce a binary which appears to work (ie passes
64 its self-tests), you might want to test it to see if it works properly
65 on large files.
66
67
68 * HP/UX 10.20 and 11.00, using HP's cc compiler.
69
70 No specific problems for this combination, except that you'll need to
71 specify the -Ae flag, and zap the gcc-specific stuff
72 -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce.
73 You should retain -D_FILE_OFFSET_BITS=64 in order to get large
74 file support -- which is reported to work ok for this HP/UX + cc
75 combination.
76
77
78 * SunOS 4.1.X.
79
80 Amazingly, there are still people out there using this venerable old
81 banger. I shouldn't be too rude -- I started life on SunOS, and
82 it was a pretty darn good OS, way back then. Anyway:
83
84 SunOS doesn't seem to have strerror(), so you'll have to use
85 perror(), perhaps by doing adding this (warning: UNTESTED CODE):
86
87 char* strerror ( int errnum )
88 {
89 if (errnum < 0 || errnum >= sys_nerr)
90 return "Unknown error";
91 else
92 return sys_errlist[errnum];
93 }
94
95 Or you could comment out the relevant calls to strerror; they're
96 not mission-critical. Or you could upgrade to Solaris. Ha ha ha!
97 (what?? you think I've got Bad Attitude?)
98
99
100 * Making a shared library on Solaris. (Not really a compilation
101 problem, but many people ask ...)
102
103 Firstly, if you have Solaris 8, either you have libbz2.so already
104 on your system, or you can install it from the Solaris CD.
105
106 Secondly, be aware that there are potential naming conflicts
107 between the .so file supplied with Solaris 8, and the .so file
108 which Makefile-libbz2_so will make. Makefile-libbz2_so creates
109 a .so which has the names which I intend to be "official" as
110 of version 1.0.0 and onwards. Unfortunately, the .so in
111 Solaris 8 appeared before I decided on the final names, so
112 the two libraries are incompatible. We have since communicated
113 and I hope that the problems will have been solved in the next
114 version of Solaris, whenever that might appear.
115
116 All that said: you might be able to get somewhere
117 by finding the line in Makefile-libbz2_so which says
118
119 $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.2 $(OBJS)
120
121 and replacing with
122
123 $(CC) -G -shared -o libbz2.so.1.0.2 -h libbz2.so.1.0 $(OBJS)
124
125 If gcc objects to the combination -fpic -fPIC, get rid of
126 the second one, leaving just "-fpic".
127
128
129 That's the end of the currently known compilation problems.
+0
-34
lib/Support/bzip2/Y2K_INFO less more
None
1 Y2K status of bzip2 and libbzip2, versions 0.1, 0.9.0 and 0.9.5
2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
4 Informally speaking:
5 bzip2 is a compression program built on top of libbzip2,
6 a library which does the real work of compression and
7 decompression. As far as I am aware, libbzip2 does not have
8 any date-related code at all.
9
10 bzip2 itself copies dates from source to destination files
11 when compressing or decompressing, using the 'stat' and 'utime'
12 UNIX system calls. It doesn't examine, manipulate or store the
13 dates in any way. So as far as I can see, there shouldn't be any
14 problem with bzip2 providing 'stat' and 'utime' work correctly
15 on your system.
16
17 On non-unix platforms (those for which BZ_UNIX in bzip2.c is
18 not set to 1), bzip2 doesn't even do the date copying.
19
20 Overall, informally speaking, I don't think bzip2 or libbzip2
21 have a Y2K problem.
22
23 Formally speaking:
24 I am not prepared to offer you any assurance whatsoever
25 regarding Y2K issues in my software. You alone assume the
26 entire risk of using the software. The disclaimer of liability
27 in the LICENSE file in the bzip2 source distribution continues
28 to apply on this issue as with every other issue pertaining
29 to the software.
30
31 Julian Seward
32 Cambridge, UK
33 25 August 1999
+0
-1141
lib/Support/bzip2/blocksort.c less more
None
1 /*-------------------------------------------------------------*/
2 /*--- Block sorting machinery ---*/
3 /*--- blocksort.c ---*/
4 /*-------------------------------------------------------------*/
5
6 /*--
7 This file is a part of bzip2 and/or libbzip2, a program and
8 library for lossless, block-sorting data compression.
9
10 Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. The origin of this software must not be misrepresented; you must
20 not claim that you wrote the original software. If you use this
21 software in a product, an acknowledgment in the product
22 documentation would be appreciated but is not required.
23
24 3. Altered source versions must be plainly marked as such, and must
25 not be misrepresented as being the original software.
26
27 4. The name of the author may not be used to endorse or promote
28 products derived from this software without specific prior written
29 permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
32 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
35 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
37 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
43 Julian Seward, Cambridge, UK.
44 jseward@acm.org
45 bzip2/libbzip2 version 1.0 of 21 March 2000
46
47 This program is based on (at least) the work of:
48 Mike Burrows
49 David Wheeler
50 Peter Fenwick
51 Alistair Moffat
52 Radford Neal
53 Ian H. Witten
54 Robert Sedgewick
55 Jon L. Bentley
56
57 For more information on these sources, see the manual.
58
59 To get some idea how the block sorting algorithms in this file
60 work, read my paper
61 On the Performance of BWT Sorting Algorithms
62 in Proceedings of the IEEE Data Compression Conference 2000,
63 Snowbird, Utah, USA, 27-30 March 2000. The main sort in this
64 file implements the algorithm called cache in the paper.
65 --*/
66
67
68 #include "bzlib_private.h"
69
70 /*---------------------------------------------*/
71 /*--- Fallback O(N log(N)^2) sorting ---*/
72 /*--- algorithm, for repetitive blocks ---*/
73 /*---------------------------------------------*/
74
75 /*---------------------------------------------*/
76 static
77 __inline__
78 void fallbackSimpleSort ( UInt32* fmap,
79 UInt32* eclass,
80 Int32 lo,
81 Int32 hi )
82 {
83 Int32 i, j, tmp;
84 UInt32 ec_tmp;
85
86 if (lo == hi) return;
87
88 if (hi - lo > 3) {
89 for ( i = hi-4; i >= lo; i-- ) {
90 tmp = fmap[i];
91 ec_tmp = eclass[tmp];
92 for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
93 fmap[j-4] = fmap[j];
94 fmap[j-4] = tmp;
95 }
96 }
97
98 for ( i = hi-1; i >= lo; i-- ) {
99 tmp = fmap[i];
100 ec_tmp = eclass[tmp];
101 for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
102 fmap[j-1] = fmap[j];
103 fmap[j-1] = tmp;
104 }
105 }
106
107
108 /*---------------------------------------------*/
109 #define fswap(zz1, zz2) \
110 { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
111
112 #define fvswap(zzp1, zzp2, zzn) \
113 { \
114 Int32 yyp1 = (zzp1); \
115 Int32 yyp2 = (zzp2); \
116 Int32 yyn = (zzn); \
117 while (yyn > 0) { \
118 fswap(fmap[yyp1], fmap[yyp2]); \
119 yyp1++; yyp2++; yyn--; \
120 } \
121 }
122
123
124 #define fmin(a,b) ((a) < (b)) ? (a) : (b)
125
126 #define fpush(lz,hz) { stackLo[sp] = lz; \
127 stackHi[sp] = hz; \
128 sp++; }
129
130 #define fpop(lz,hz) { sp--; \
131 lz = stackLo[sp]; \
132 hz = stackHi[sp]; }
133
134 #define FALLBACK_QSORT_SMALL_THRESH 10
135 #define FALLBACK_QSORT_STACK_SIZE 100
136
137
138 static
139 void fallbackQSort3 ( UInt32* fmap,
140 UInt32* eclass,
141 Int32 loSt,
142 Int32 hiSt )
143 {
144 Int32 unLo, unHi, ltLo, gtHi, n, m;
145 Int32 sp, lo, hi;
146 UInt32 med, r, r3;
147 Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
148 Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
149
150 r = 0;
151
152 sp = 0;
153 fpush ( loSt, hiSt );
154
155 while (sp > 0) {
156
157 AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
158
159 fpop ( lo, hi );
160 if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
161 fallbackSimpleSort ( fmap, eclass, lo, hi );
162 continue;
163 }
164
165 /* Random partitioning. Median of 3 sometimes fails to
166 avoid bad cases. Median of 9 seems to help but
167 looks rather expensive. This too seems to work but
168 is cheaper. Guidance for the magic constants
169 7621 and 32768 is taken from Sedgewick's algorithms
170 book, chapter 35.
171 */
172 r = ((r * 7621) + 1) % 32768;
173 r3 = r % 3;
174 if (r3 == 0) med = eclass[fmap[lo]]; else
175 if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
176 med = eclass[fmap[hi]];
177
178 unLo = ltLo = lo;
179 unHi = gtHi = hi;
180
181 while (1) {
182 while (1) {
183 if (unLo > unHi) break;
184 n = (Int32)eclass[fmap[unLo]] - (Int32)med;
185 if (n == 0) {
186 fswap(fmap[unLo], fmap[ltLo]);
187 ltLo++; unLo++;
188 continue;
189 };
190 if (n > 0) break;
191 unLo++;
192 }
193 while (1) {
194 if (unLo > unHi) break;
195 n = (Int32)eclass[fmap[unHi]] - (Int32)med;
196 if (n == 0) {
197 fswap(fmap[unHi], fmap[gtHi]);
198 gtHi--; unHi--;
199 continue;
200 };
201 if (n < 0) break;
202 unHi--;
203 }
204 if (unLo > unHi) break;
205 fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
206 }
207
208 AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
209
210 if (gtHi < ltLo) continue;
211
212 n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
213 m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
214
215 n = lo + unLo - ltLo - 1;
216 m = hi - (gtHi - unHi) + 1;
217
218 if (n - lo > hi - m) {
219 fpush ( lo, n );
220 fpush ( m, hi );
221 } else {
222 fpush ( m, hi );
223 fpush ( lo, n );
224 }
225 }
226 }
227
228 #undef fmin
229 #undef fpush
230 #undef fpop
231 #undef fswap
232 #undef fvswap
233 #undef FALLBACK_QSORT_SMALL_THRESH
234 #undef FALLBACK_QSORT_STACK_SIZE
235
236
237 /*---------------------------------------------*/
238 /* Pre:
239 nblock > 0
240 eclass exists for [0 .. nblock-1]
241 ((UChar*)eclass) [0 .. nblock-1] holds block
242 ptr exists for [0 .. nblock-1]
243
244 Post:
245 ((UChar*)eclass) [0 .. nblock-1] holds block
246 All other areas of eclass destroyed
247 fmap [0 .. nblock-1] holds sorted order
248 bhtab [ 0 .. 2+(nblock/32) ] destroyed
249 */
250
251 #define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
252 #define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
253 #define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
254 #define WORD_BH(zz) bhtab[(zz) >> 5]
255 #define UNALIGNED_BH(zz) ((zz) & 0x01f)
256
257 static
258 void fallbackSort ( UInt32* fmap,
259 UInt32* eclass,
260 UInt32* bhtab,
261 Int32 nblock,
262 Int32 verb )
263 {
264 Int32 ftab[257];
265 Int32 ftabCopy[256];
266 Int32 H, i, j, k, l, r, cc, cc1;
267 Int32 nNotDone;
268 Int32 nBhtab;
269 UChar* eclass8 = (UChar*)eclass;
270
271 /*--
272 Initial 1-char radix sort to generate
273 initial fmap and initial BH bits.
274 --*/
275 if (verb >= 4)
276 VPrintf0 ( " bucket sorting ...\n" );
277 for (i = 0; i < 257; i++) ftab[i] = 0;
278 for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
279 for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
280 for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
281
282 for (i = 0; i < nblock; i++) {
283 j = eclass8[i];
284 k = ftab[j] - 1;
285 ftab[j] = k;
286 fmap[k] = i;
287 }
288
289 nBhtab = 2 + (nblock / 32);
290 for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
291 for (i = 0; i < 256; i++) SET_BH(ftab[i]);
292
293 /*--
294 Inductively refine the buckets. Kind-of an
295 "exponential radix sort" (!), inspired by the
296 Manber-Myers suffix array construction algorithm.
297 --*/
298
299 /*-- set sentinel bits for block-end detection --*/
300 for (i = 0; i < 32; i++) {
301 SET_BH(nblock + 2*i);
302 CLEAR_BH(nblock + 2*i + 1);
303 }
304
305 /*-- the log(N) loop --*/
306 H = 1;
307 while (1) {
308
309 if (verb >= 4)
310 VPrintf1 ( " depth %6d has ", H );
311
312 j = 0;
313 for (i = 0; i < nblock; i++) {
314 if (ISSET_BH(i)) j = i;
315 k = fmap[i] - H; if (k < 0) k += nblock;
316 eclass[k] = j;
317 }
318
319 nNotDone = 0;
320 r = -1;
321 while (1) {
322
323 /*-- find the next non-singleton bucket --*/
324 k = r + 1;
325 while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
326 if (ISSET_BH(k)) {
327 while (WORD_BH(k) == 0xffffffff) k += 32;
328 while (ISSET_BH(k)) k++;
329 }
330 l = k - 1;
331 if (l >= nblock) break;
332 while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
333 if (!ISSET_BH(k)) {
334 while (WORD_BH(k) == 0x00000000) k += 32;
335 while (!ISSET_BH(k)) k++;
336 }
337 r = k - 1;
338 if (r >= nblock) break;
339
340 /*-- now [l, r] bracket current bucket --*/
341 if (r > l) {
342 nNotDone += (r - l + 1);
343 fallbackQSort3 ( fmap, eclass, l, r );
344
345 /*-- scan bucket and generate header bits-- */
346 cc = -1;
347 for (i = l; i <= r; i++) {
348 cc1 = eclass[fmap[i]];
349 if (cc != cc1) { SET_BH(i); cc = cc1; };
350 }
351 }
352 }
353
354 if (verb >= 4)
355 VPrintf1 ( "%6d unresolved strings\n", nNotDone );
356
357 H *= 2;
358 if (H > nblock || nNotDone == 0) break;
359 }
360
361 /*--
362 Reconstruct the original block in
363 eclass8 [0 .. nblock-1], since the
364 previous phase destroyed it.
365 --*/
366 if (verb >= 4)
367 VPrintf0 ( " reconstructing block ...\n" );
368 j = 0;
369 for (i = 0; i < nblock; i++) {
370 while (ftabCopy[j] == 0) j++;
371 ftabCopy[j]--;
372 eclass8[fmap[i]] = (UChar)j;
373 }
374 AssertH ( j < 256, 1005 );
375 }
376
377 #undef SET_BH
378 #undef CLEAR_BH
379 #undef ISSET_BH
380 #undef WORD_BH
381 #undef UNALIGNED_BH
382
383
384 /*---------------------------------------------*/
385 /*--- The main, O(N^2 log(N)) sorting ---*/
386 /*--- algorithm. Faster for "normal" ---*/
387 /*--- non-repetitive blocks. ---*/
388 /*---------------------------------------------*/
389
390 /*---------------------------------------------*/
391 static
392 __inline__
393 Bool mainGtU ( UInt32 i1,
394 UInt32 i2,
395 UChar* block,
396 UInt16* quadrant,
397 UInt32 nblock,
398 Int32* budget )
399 {
400 Int32 k;
401 UChar c1, c2;
402 UInt16 s1, s2;
403
404 AssertD ( i1 != i2, "mainGtU" );
405 /* 1 */
406 c1 = block[i1]; c2 = block[i2];
407 if (c1 != c2) return (c1 > c2);
408 i1++; i2++;
409 /* 2 */
410 c1 = block[i1]; c2 = block[i2];
411 if (c1 != c2) return (c1 > c2);
412 i1++; i2++;
413 /* 3 */
414 c1 = block[i1]; c2 = block[i2];
415 if (c1 != c2) return (c1 > c2);
416 i1++; i2++;
417 /* 4 */
418 c1 = block[i1]; c2 = block[i2];
419 if (c1 != c2) return (c1 > c2);
420 i1++; i2++;
421 /* 5 */
422 c1 = block[i1]; c2 = block[i2];
423 if (c1 != c2) return (c1 > c2);
424 i1++; i2++;
425 /* 6 */
426 c1 = block[i1]; c2 = block[i2];
427 if (c1 != c2) return (c1 > c2);
428 i1++; i2++;
429 /* 7 */
430 c1 = block[i1]; c2 = block[i2];
431 if (c1 != c2) return (c1 > c2);
432 i1++; i2++;
433 /* 8 */
434 c1 = block[i1]; c2 = block[i2];
435 if (c1 != c2) return (c1 > c2);
436 i1++; i2++;
437 /* 9 */
438 c1 = block[i1]; c2 = block[i2];
439 if (c1 != c2) return (c1 > c2);
440 i1++; i2++;
441 /* 10 */
442 c1 = block[i1]; c2 = block[i2];
443 if (c1 != c2) return (c1 > c2);
444 i1++; i2++;
445 /* 11 */
446 c1 = block[i1]; c2 = block[i2];
447 if (c1 != c2) return (c1 > c2);
448 i1++; i2++;
449 /* 12 */
450 c1 = block[i1]; c2 = block[i2];
451 if (c1 != c2) return (c1 > c2);
452 i1++; i2++;
453
454 k = nblock + 8;
455
456 do {
457 /* 1 */
458 c1 = block[i1]; c2 = block[i2];
459 if (c1 != c2) return (c1 > c2);
460 s1 = quadrant[i1]; s2 = quadrant[i2];
461 if (s1 != s2) return (s1 > s2);
462 i1++; i2++;
463 /* 2 */
464 c1 = block[i1]; c2 = block[i2];
465 if (c1 != c2) return (c1 > c2);
466 s1 = quadrant[i1]; s2 = quadrant[i2];
467 if (s1 != s2) return (s1 > s2);
468 i1++; i2++;
469 /* 3 */
470 c1 = block[i1]; c2 = block[i2];
471 if (c1 != c2) return (c1 > c2);
472 s1 = quadrant[i1]; s2 = quadrant[i2];
473 if (s1 != s2) return (s1 > s2);
474 i1++; i2++;
475 /* 4 */
476 c1 = block[i1]; c2 = block[i2];
477 if (c1 != c2) return (c1 > c2);
478 s1 = quadrant[i1]; s2 = quadrant[i2];
479 if (s1 != s2) return (s1 > s2);
480 i1++; i2++;
481 /* 5 */
482 c1 = block[i1]; c2 = block[i2];
483 if (c1 != c2) return (c1 > c2);
484 s1 = quadrant[i1]; s2 = quadrant[i2];
485 if (s1 != s2) return (s1 > s2);
486 i1++; i2++;
487 /* 6 */
488 c1 = block[i1]; c2 = block[i2];
489 if (c1 != c2) return (c1 > c2);
490 s1 = quadrant[i1]; s2 = quadrant[i2];
491 if (s1 != s2) return (s1 > s2);
492 i1++; i2++;
493 /* 7 */
494 c1 = block[i1]; c2 = block[i2];
495 if (c1 != c2) return (c1 > c2);
496 s1 = quadrant[i1]; s2 = quadrant[i2];
497 if (s1 != s2) return (s1 > s2);
498 i1++; i2++;
499 /* 8 */
500 c1 = block[i1]; c2 = block[i2];
501 if (c1 != c2) return (c1 > c2);
502 s1 = quadrant[i1]; s2 = quadrant[i2];
503 if (s1 != s2) return (s1 > s2);
504 i1++; i2++;
505
506 if (i1 >= nblock) i1 -= nblock;
507 if (i2 >= nblock) i2 -= nblock;
508
509 k -= 8;
510 (*budget)--;
511 }
512 while (k >= 0);
513
514 return False;
515 }
516
517
518 /*---------------------------------------------*/
519 /*--
520 Knuth's increments seem to work better
521 than Incerpi-Sedgewick here. Possibly
522 because the number of elems to sort is
523 usually small, typically <= 20.
524 --*/
525 static
526 Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
527 9841, 29524, 88573, 265720,
528 797161, 2391484 };
529
530 static
531 void mainSimpleSort ( UInt32* ptr,
532 UChar* block,
533 UInt16* quadrant,
534 Int32 nblock,
535 Int32 lo,
536 Int32 hi,
537 Int32 d,
538 Int32* budget )
539 {
540 Int32 i, j, h, bigN, hp;
541 UInt32 v;
542
543 bigN = hi - lo + 1;
544 if (bigN < 2) return;
545
546 hp = 0;
547 while (incs[hp] < bigN) hp++;
548 hp--;
549
550 for (; hp >= 0; hp--) {
551 h = incs[hp];
552
553 i = lo + h;
554 while (True) {
555
556 /*-- copy 1 --*/
557 if (i > hi) break;
558 v = ptr[i];
559 j = i;
560 while ( mainGtU (
561 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
562 ) ) {
563 ptr[j] = ptr[j-h];
564 j = j - h;
565 if (j <= (lo + h - 1)) break;
566 }
567 ptr[j] = v;
568 i++;
569
570 /*-- copy 2 --*/
571 if (i > hi) break;
572 v = ptr[i];
573 j = i;
574 while ( mainGtU (
575 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
576 ) ) {
577 ptr[j] = ptr[j-h];
578 j = j - h;
579 if (j <= (lo + h - 1)) break;
580 }
581 ptr[j] = v;
582 i++;
583
584 /*-- copy 3 --*/
585 if (i > hi) break;
586 v = ptr[i];
587 j = i;
588 while ( mainGtU (
589 ptr[j-h]+d, v+d, block, quadrant, nblock, budget
590 ) ) {
591 ptr[j] = ptr[j-h];
592 j = j - h;
593 if (j <= (lo + h - 1)) break;
594 }
595 ptr[j] = v;
596 i++;
597
598 if (*budget < 0) return;
599 }
600 }
601 }
602
603
604 /*---------------------------------------------*/
605 /*--
606 The following is an implementation of
607 an elegant 3-way quicksort for strings,
608 described in a paper "Fast Algorithms for
609 Sorting and Searching Strings", by Robert
610 Sedgewick and Jon L. Bentley.
611 --*/
612
613 #define mswap(zz1, zz2) \
614 { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
615
616 #define mvswap(zzp1, zzp2, zzn) \
617 { \
618 Int32 yyp1 = (zzp1); \
619 Int32 yyp2 = (zzp2); \
620 Int32 yyn = (zzn); \
621 while (yyn > 0) { \
622 mswap(ptr[yyp1], ptr[yyp2]); \
623 yyp1++; yyp2++; yyn--; \
624 } \
625 }
626
627 static
628 __inline__
629 UChar mmed3 ( UChar a, UChar b, UChar c )
630 {
631 UChar t;
632 if (a > b) { t = a; a = b; b = t; };
633 if (b > c) {
634 b = c;
635 if (a > b) b = a;
636 }
637 return b;
638 }
639
640 #define mmin(a,b) ((a) < (b)) ? (a) : (b)
641
642 #define mpush(lz,hz,dz) { stackLo[sp] = lz; \
643 stackHi[sp] = hz; \
644 stackD [sp] = dz; \
645 sp++; }
646
647 #define mpop(lz,hz,dz) { sp--; \
648 lz = stackLo[sp]; \
649 hz = stackHi[sp]; \
650 dz = stackD [sp]; }
651
652
653 #define mnextsize(az) (nextHi[az]-nextLo[az])
654
655 #define mnextswap(az,bz) \
656 { Int32 tz; \
657 tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
658 tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
659 tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
660
661
662 #define MAIN_QSORT_SMALL_THRESH 20
663 #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
664 #define MAIN_QSORT_STACK_SIZE 100
665
666 static
667 void mainQSort3 ( UInt32* ptr,
668 UChar* block,
669 UInt16* quadrant,
670 Int32 nblock,
671 Int32 loSt,
672 Int32 hiSt,
673 Int32 dSt,
674 Int32* budget )
675 {
676 Int32 unLo, unHi, ltLo, gtHi, n, m, med;
677 Int32 sp, lo, hi, d;
678
679 Int32 stackLo[MAIN_QSORT_STACK_SIZE];
680 Int32 stackHi[MAIN_QSORT_STACK_SIZE];
681 Int32 stackD [MAIN_QSORT_STACK_SIZE];
682
683 Int32 nextLo[3];
684 Int32 nextHi[3];
685 Int32 nextD [3];
686
687 sp = 0;
688 mpush ( loSt, hiSt, dSt );
689
690 while (sp > 0) {
691
692 AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
693
694 mpop ( lo, hi, d );
695 if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
696 d > MAIN_QSORT_DEPTH_THRESH) {
697 mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
698 if (*budget < 0) return;
699 continue;
700 }
701
702 med = (Int32)
703 mmed3 ( block[ptr[ lo ]+d],
704 block[ptr[ hi ]+d],
705 block[ptr[ (lo+hi)>>1 ]+d] );
706
707 unLo = ltLo = lo;
708 unHi = gtHi = hi;
709
710 while (True) {
711 while (True) {
712 if (unLo > unHi) break;
713 n = ((Int32)block[ptr[unLo]+d]) - med;
714 if (n == 0) {
715 mswap(ptr[unLo], ptr[ltLo]);
716 ltLo++; unLo++; continue;
717 };
718 if (n > 0) break;
719 unLo++;
720 }
721 while (True) {
722 if (unLo > unHi) break;
723 n = ((Int32)block[ptr[unHi]+d]) - med;
724 if (n == 0) {
725 mswap(ptr[unHi], ptr[gtHi]);
726 gtHi--; unHi--; continue;
727 };
728 if (n < 0) break;
729 unHi--;
730 }
731 if (unLo > unHi) break;
732 mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
733 }
734
735 AssertD ( unHi == unLo-1, "mainQSort3(2)" );
736
737 if (gtHi < ltLo) {
738 mpush(lo, hi, d+1 );
739 continue;
740 }
741
742 n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
743 m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
744
745 n = lo + unLo - ltLo - 1;
746 m = hi - (gtHi - unHi) + 1;
747
748 nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
749 nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
750 nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
751
752 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
753 if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
754 if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
755
756 AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
757 AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
758
759 mpush (nextLo[0], nextHi[0], nextD[0]);
760 mpush (nextLo[1], nextHi[1], nextD[1]);
761 mpush (nextLo[2], nextHi[2], nextD[2]);
762 }
763 }
764
765 #undef mswap
766 #undef mvswap
767 #undef mpush
768 #undef mpop
769 #undef mmin
770 #undef mnextsize
771 #undef mnextswap
772 #undef MAIN_QSORT_SMALL_THRESH
773 #undef MAIN_QSORT_DEPTH_THRESH
774 #undef MAIN_QSORT_STACK_SIZE
775
776
777 /*---------------------------------------------*/
778 /* Pre:
779 nblock > N_OVERSHOOT
780 block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
781 ((UChar*)block32) [0 .. nblock-1] holds block
782 ptr exists for [0 .. nblock-1]
783
784 Post:
785 ((UChar*)block32) [0 .. nblock-1] holds block
786 All other areas of block32 destroyed
787 ftab [0 .. 65536 ] destroyed
788 ptr [0 .. nblock-1] holds sorted order
789 if (*budget < 0), sorting was abandoned
790 */
791
792 #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
793 #define SETMASK (1 << 21)
794 #define CLEARMASK (~(SETMASK))
795
796 static
797 void mainSort ( UInt32* ptr,
798 UChar* block,
799 UInt16* quadrant,
800 UInt32* ftab,
801 Int32 nblock,
802 Int32 verb,
803 Int32* budget )
804 {
805 Int32 i, j, k, ss, sb;
806 Int32 runningOrder[256];
807 Bool bigDone[256];
808 Int32 copyStart[256];
809 Int32 copyEnd [256];
810 UChar c1;
811 Int32 numQSorted;
812 UInt16 s;
813 if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" );
814
815 /*-- set up the 2-byte frequency table --*/
816 for (i = 65536; i >= 0; i--) ftab[i] = 0;
817
818 j = block[0] << 8;
819 i = nblock-1;
820 for (; i >= 3; i -= 4) {
821 quadrant[i] = 0;
822 j = (j >> 8) | ( ((UInt16)block[i]) << 8);
823 ftab[j]++;
824 quadrant[i-1] = 0;
825 j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
826 ftab[j]++;
827 quadrant[i-2] = 0;
828 j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
829 ftab[j]++;
830 quadrant[i-3] = 0;
831 j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
832 ftab[j]++;
833 }
834 for (; i >= 0; i--) {
835 quadrant[i] = 0;
836 j = (j >> 8) | ( ((UInt16)block[i]) << 8);
837 ftab[j]++;
838 }
839
840 /*-- (emphasises close relationship of block & quadrant) --*/
841 for (i = 0; i < BZ_N_OVERSHOOT; i++) {
842 block [nblock+i] = block[i];
843 quadrant[nblock+i] = 0;
844 }
845
846 if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" );
847
848 /*-- Complete the initial radix sort --*/
849 for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
850
851 s = block[0] << 8;
852 i = nblock-1;
853 for (; i >= 3; i -= 4) {
854 s = (s >> 8) | (block[i] << 8);
855 j = ftab[s] -1;
856 ftab[s] = j;
857 ptr[j] = i;
858 s = (s >> 8) | (block[i-1] << 8);
859 j = ftab[s] -1;
860 ftab[s] = j;
861 ptr[j] = i-1;
862 s = (s >> 8) | (block[i-2] << 8);
863 j = ftab[s] -1;
864 ftab[s] = j;
865 ptr[j] = i-2;
866 s = (s >> 8) | (block[i-3] << 8);
867 j = ftab[s] -1;
868 ftab[s] = j;
869 ptr[j] = i-3;
870 }
871 for (; i >= 0; i--) {
872 s = (s >> 8) | (block[i] << 8);
873 j = ftab[s] -1;
874 ftab[s] = j;
875 ptr[j] = i;
876 }
877
878 /*--
879 Now ftab contains the first loc of every small bucket.
880 Calculate the running order, from smallest to largest
881 big bucket.
882 --*/
883 for (i = 0; i <= 255; i++) {
884 bigDone [i] = False;
885 runningOrder[i] = i;
886 }
887
888 {
889 Int32 vv;
890 Int32 h = 1;
891 do h = 3 * h + 1; while (h <= 256);
892 do {
893 h = h / 3;
894 for (i = h; i <= 255; i++) {
895 vv = runningOrder[i];
896 j = i;
897 while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
898 runningOrder[j] = runningOrder[j-h];
899 j = j - h;
900 if (j <= (h - 1)) goto zero;
901 }
902 zero:
903 runningOrder[j] = vv;
904 }
905 } while (h != 1);
906 }
907
908 /*--
909 The main sorting loop.
910 --*/
911
912 numQSorted = 0;
913
914 for (i = 0; i <= 255; i++) {
915
916 /*--
917 Process big buckets, starting with the least full.
918 Basically this is a 3-step process in which we call
919 mainQSort3 to sort the small buckets [ss, j], but
920 also make a big effort to avoid the calls if we can.
921 --*/
922 ss = runningOrder[i];
923
924 /*--
925 Step 1:
926 Complete the big bucket [ss] by quicksorting
927 any unsorted small buckets [ss, j], for j != ss.
928 Hopefully previous pointer-scanning phases have already
929 completed many of the small buckets [ss, j], so
930 we don't have to sort them at all.
931 --*/
932 for (j = 0; j <= 255; j++) {
933 if (j != ss) {
934 sb = (ss << 8) + j;
935 if ( ! (ftab[sb] & SETMASK) ) {
936 Int32 lo = ftab[sb] & CLEARMASK;
937 Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
938 if (hi > lo) {
939 if (verb >= 4)
940 VPrintf4 ( " qsort [0x%x, 0x%x] "
941 "done %d this %d\n",
942 ss, j, numQSorted, hi - lo + 1 );
943 mainQSort3 (
944 ptr, block, quadrant, nblock,
945 lo, hi, BZ_N_RADIX, budget
946 );
947 numQSorted += (hi - lo + 1);
948 if (*budget < 0) return;
949 }
950 }
951 ftab[sb] |= SETMASK;
952 }
953 }
954
955 AssertH ( !bigDone[ss], 1006 );
956
957 /*--
958 Step 2:
959 Now scan this big bucket [ss] so as to synthesise the
960 sorted order for small buckets [t, ss] for all t,
961 including, magically, the bucket [ss,ss] too.
962 This will avoid doing Real Work in subsequent Step 1's.
963 --*/
964 {
965 for (j = 0; j <= 255; j++) {
966 copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
967 copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
968 }
969 for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
970 k = ptr[j]-1; if (k < 0) k += nblock;
971 c1 = block[k];
972 if (!bigDone[c1])
973 ptr[ copyStart[c1]++ ] = k;
974 }
975 for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
976 k = ptr[j]-1; if (k < 0) k += nblock;
977 c1 = block[k];
978 if (!bigDone[c1])
979 ptr[ copyEnd[c1]-- ] = k;
980 }
981 }
982
983 AssertH ( (copyStart[ss]-1 == copyEnd[ss])
984 ||
985 /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
986 Necessity for this case is demonstrated by compressing
987 a sequence of approximately 48.5 million of character
988 251; 1.0.0/1.0.1 will then die here. */
989 (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
990 1007 )
991
992 for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
993
994 /*--
995 Step 3:
996 The [ss] big bucket is now done. Record this fact,
997 and update the quadrant descriptors. Remember to
998 update quadrants in the overshoot area too, if
999 necessary. The "if (i < 255)" test merely skips
1000 this updating for the last bucket processed, since
1001 updating for the last bucket is pointless.
1002
1003 The quadrant array provides a way to incrementally
1004 cache sort orderings, as they appear, so as to
1005 make subsequent comparisons in fullGtU() complete
1006 faster. For repetitive blocks this makes a big
1007 difference (but not big enough to be able to avoid
1008 the fallback sorting mechanism, exponential radix sort).
1009
1010 The precise meaning is: at all times:
1011
1012 for 0 <= i < nblock and 0 <= j <= nblock
1013
1014 if block[i] != block[j],
1015
1016 then the relative values of quadrant[i] and
1017 quadrant[j] are meaningless.
1018
1019 else {
1020 if quadrant[i] < quadrant[j]
1021 then the string starting at i lexicographically
1022 precedes the string starting at j
1023
1024 else if quadrant[i] > quadrant[j]
1025 then the string starting at j lexicographically
1026 precedes the string starting at i
1027
1028 else
1029 the relative ordering of the strings starting
1030 at i and j has not yet been determined.
1031 }
1032 --*/
1033 bigDone[ss] = True;
1034
1035 if (i < 255) {
1036 Int32 bbStart = ftab[ss << 8] & CLEARMASK;
1037 Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
1038 Int32 shifts = 0;
1039
1040 while ((bbSize >> shifts) > 65534) shifts++;
1041
1042 for (j = bbSize-1; j >= 0; j--) {
1043 Int32 a2update = ptr[bbStart + j];
1044 UInt16 qVal = (UInt16)(j >> shifts);
1045 quadrant[a2update] = qVal;
1046 if (a2update < BZ_N_OVERSHOOT)
1047 quadrant[a2update + nblock] = qVal;
1048 }
1049 AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
1050 }
1051
1052 }
1053
1054 if (verb >= 4)
1055 VPrintf3 ( " %d pointers, %d sorted, %d scanned\n",
1056 nblock, numQSorted, nblock - numQSorted );
1057 }
1058
1059 #undef BIGFREQ
1060 #undef SETMASK
1061 #undef CLEARMASK
1062
1063
1064 /*---------------------------------------------*/
1065 /* Pre:
1066 nblock > 0
1067 arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
1068 ((UChar*)arr2) [0 .. nblock-1] holds block
1069 arr1 exists for [0 .. nblock-1]
1070
1071 Post:
1072 ((UChar*)arr2) [0 .. nblock-1] holds block
1073 All other areas of block destroyed
1074 ftab [ 0 .. 65536 ] destroyed
1075 arr1 [0 .. nblock-1] holds sorted order
1076 */
1077 void BZ2_blockSort ( EState* s )
1078 {
1079 UInt32* ptr = s->ptr;
1080 UChar* block = s->block;
1081 UInt32* ftab = s->ftab;
1082 Int32 nblock = s->nblock;
1083 Int32 verb = s->verbosity;
1084 Int32 wfact = s->workFactor;
1085 UInt16* quadrant;
1086 Int32 budget;
1087 Int32 budgetInit;
1088 Int32 i;
1089
1090 if (nblock < 10000) {
1091 fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1092 } else {
1093 /* Calculate the location for quadrant, remembering to get
1094 the alignment right. Assumes that &(block[0]) is at least
1095 2-byte aligned -- this should be ok since block is really
1096 the first section of arr2.
1097 */
1098 i = nblock+BZ_N_OVERSHOOT;
1099 if (i & 1) i++;
1100 quadrant = (UInt16*)(&(block[i]));
1101
1102 /* (wfact-1) / 3 puts the default-factor-30
1103 transition point at very roughly the same place as
1104 with v0.1 and v0.9.0.
1105 Not that it particularly matters any more, since the
1106 resulting compressed stream is now the same regardless
1107 of whether or not we use the main sort or fallback sort.
1108 */
1109 if (wfact < 1 ) wfact = 1;
1110 if (wfact > 100) wfact = 100;
1111 budgetInit = nblock * ((wfact-1) / 3);
1112 budget = budgetInit;
1113
1114 mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
1115 if (verb >= 3)
1116 VPrintf3 ( " %d work, %d block, ratio %5.2f\n",
1117 budgetInit - budget,
1118 nblock,
1119 (float)(budgetInit - budget) /
1120 (float)(nblock==0 ? 1 : nblock) );
1121 if (budget < 0) {
1122 if (verb >= 2)
1123 VPrintf0 ( " too repetitive; using fallback"
1124 " sorting algorithm\n" );
1125 fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
1126 }
1127 }
1128
1129 s->origPtr = -1;
1130 for (i = 0; i < s->nblock; i++)
1131 if (ptr[i] == 0)
1132 { s->origPtr = i; break; };
1133
1134 AssertH( s->origPtr != -1, 1003 );
1135 }
1136
1137
1138 /*-------------------------------------------------------------*/
1139 /*--- end blocksort.c ---*/
1140 /*-------------------------------------------------------------*/
+0
-1597
lib/Support/bzip2/bzlib.c less more
None
1 /*-------------------------------------------------------------*/
2 /*--- Library top-level functions. ---*/
3 /*--- bzlib.c ---*/
4 /*-------------------------------------------------------------*/
5
6 /*--
7 This file is a part of bzip2 and/or libbzip2, a program and
8 library for lossless, block-sorting data compression.
9
10 Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. The origin of this software must not be misrepresented; you must
20 not claim that you wrote the original software. If you use this
21 software in a product, an acknowledgment in the product
22 documentation would be appreciated but is not required.
23
24 3. Altered source versions must be plainly marked as such, and must
25 not be misrepresented as being the original software.
26
27 4. The name of the author may not be used to endorse or promote
28 products derived from this software without specific prior written
29 permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
32 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
35 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
37 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
43 Julian Seward, Cambridge, UK.
44 jseward@acm.org
45 bzip2/libbzip2 version 1.0 of 21 March 2000
46
47 This program is based on (at least) the work of:
48 Mike Burrows
49 David Wheeler
50 Peter Fenwick
51 Alistair Moffat
52 Radford Neal
53 Ian H. Witten
54 Robert Sedgewick
55 Jon L. Bentley
56
57 For more information on these sources, see the manual.
58 --*/
59
60 /*--
61 CHANGES
62 ~~~~~~~
63 0.9.0 -- original version.
64
65 0.9.0a/b -- no changes in this file.
66
67 0.9.0c
68 * made zero-length BZ_FLUSH work correctly in bzCompress().
69 * fixed bzWrite/bzRead to ignore zero-length requests.
70 * fixed bzread to correctly handle read requests after EOF.
71 * wrong parameter order in call to bzDecompressInit in
72 bzBuffToBuffDecompress. Fixed.
73 --*/
74
75 #include "bzlib_private.h"
76
77
78 /*---------------------------------------------------*/
79 /*--- Compression stuff ---*/
80 /*---------------------------------------------------*/
81
82
83 /*---------------------------------------------------*/
84 #ifndef BZ_NO_STDIO
85 void BZ2_bz__AssertH__fail ( int errcode )
86 {
87 fprintf(stderr,
88 "\n\nbzip2/libbzip2: internal error number %d.\n"
89 "This is a bug in bzip2/libbzip2, %s.\n"
90 "Please report it to me at: jseward@acm.org. If this happened\n"
91 "when you were using some program which uses libbzip2 as a\n"
92 "component, you should also report this bug to the author(s)\n"
93 "of that program. Please make an effort to report this bug;\n"
94 "timely and accurate bug reports eventually lead to higher\n"
95 "quality software. Thanks. Julian Seward, 30 December 2001.\n\n",
96 errcode,
97 BZ2_bzlibVersion()
98 );
99
100 if (errcode == 1007) {
101 fprintf(stderr,
102 "\n*** A special note about internal error number 1007 ***\n"
103 "\n"
104 "Experience suggests that a common cause of i.e. 1007\n"
105 "is unreliable memory or other hardware. The 1007 assertion\n"
106 "just happens to cross-check the results of huge numbers of\n"
107 "memory reads/writes, and so acts (unintendedly) as a stress\n"
108 "test of your memory system.\n"
109 "\n"
110 );
111 fprintf(stderr,
112 "I suggest the following: try compressing the file again,\n"
113 "possibly monitoring progress in detail with the -vv flag.\n"
114 "\n"
115 "* If the error cannot be reproduced, and/or happens at different\n"
116 " points in compression, you may have a flaky memory system.\n"
117 " Try a memory-test program. I have used Memtest86\n"
118 " (www.memtest86.com). At the time of writing it is free (GPLd).\n"
119 " Memtest86 tests memory much more thorougly than your BIOSs\n"
120 " power-on test, and may find failures that the BIOS doesn't.\n"
121 "\n"
122 );
123 fprintf(stderr,
124 "* If the error can be repeatably reproduced, this is a bug in\n"
125 " bzip2, and I would very much like to hear about it. Please\n"
126 " let me know, and, ideally, save a copy of the file causing the\n"
127 " problem -- without which I will be unable to investigate it.\n"
128 "\n"
129 );
130 }
131
132 exit(3);
133 }
134 #endif
135
136
137 /*---------------------------------------------------*/
138 static
139 int bz_config_ok ( void )
140 {
141 if (sizeof(int) != 4) return 0;
142 if (sizeof(short) != 2) return 0;
143 if (sizeof(char) != 1) return 0;
144 return 1;
145 }
146
147
148 /*---------------------------------------------------*/
149 static
150 void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
151 {
152 void* v = malloc ( items * size );
153 return v;
154 }
155
156 static
157 void default_bzfree ( void* opaque, void* addr )
158 {
159 if (addr != NULL) free ( addr );
160 }
161
162
163 /*---------------------------------------------------*/
164 static
165 void prepare_new_block ( EState* s )
166 {
167 Int32 i;
168 s->nblock = 0;
169 s->numZ = 0;
170 s->state_out_pos = 0;
171 BZ_INITIALISE_CRC ( s->blockCRC );
172 for (i = 0; i < 256; i++) s->inUse[i] = False;
173 s->blockNo++;
174 }
175
176
177 /*---------------------------------------------------*/
178 static
179 void init_RL ( EState* s )
180 {
181 s->state_in_ch = 256;
182 s->state_in_len = 0;
183 }
184
185
186 static
187 Bool isempty_RL ( EState* s )
188 {
189 if (s->state_in_ch < 256 && s->state_in_len > 0)
190 return False; else
191 return True;
192 }
193
194
195 /*---------------------------------------------------*/
196 int BZ_API(BZ2_bzCompressInit)
197 ( bz_stream* strm,
198 int blockSize100k,
199 int verbosity,
200 int workFactor )
201 {
202 Int32 n;
203 EState* s;
204
205 if (!bz_config_ok()) return BZ_CONFIG_ERROR;
206
207 if (strm == NULL ||
208 blockSize100k < 1 || blockSize100k > 9 ||
209 workFactor < 0 || workFactor > 250)
210 return BZ_PARAM_ERROR;
211
212 if (workFactor == 0) workFactor = 30;
213 if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
214 if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
215
216 s = BZALLOC( sizeof(EState) );
217 if (s == NULL) return BZ_MEM_ERROR;
218 s->strm = strm;
219
220 s->arr1 = NULL;
221 s->arr2 = NULL;
222 s->ftab = NULL;
223
224 n = 100000 * blockSize100k;
225 s->arr1 = BZALLOC( n * sizeof(UInt32) );
226 s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
227 s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
228
229 if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
230 if (s->arr1 != NULL) BZFREE(s->arr1);
231 if (s->arr2 != NULL) BZFREE(s->arr2);
232 if (s->ftab != NULL) BZFREE(s->ftab);
233 if (s != NULL) BZFREE(s);
234 return BZ_MEM_ERROR;
235 }
236
237 s->blockNo = 0;
238 s->state = BZ_S_INPUT;
239 s->mode = BZ_M_RUNNING;
240 s->combinedCRC = 0;
241 s->blockSize100k = blockSize100k;
242 s->nblockMAX = 100000 * blockSize100k - 19;
243 s->verbosity = verbosity;
244 s->workFactor = workFactor;
245
246 s->block = (UChar*)s->arr2;
247 s->mtfv = (UInt16*)s->arr1;
248 s->zbits = NULL;
249 s->ptr = (UInt32*)s->arr1;
250
251 strm->state = s;
252 strm->total_in_lo32 = 0;
253 strm->total_in_hi32 = 0;
254 strm->total_out_lo32 = 0;
255 strm->total_out_hi32 = 0;
256 init_RL ( s );
257 prepare_new_block ( s );
258 return BZ_OK;
259 }
260
261
262 /*---------------------------------------------------*/
263 static
264 void add_pair_to_block ( EState* s )
265 {
266 Int32 i;
267 UChar ch = (UChar)(s->state_in_ch);
268 for (i = 0; i < s->state_in_len; i++) {
269 BZ_UPDATE_CRC( s->blockCRC, ch );
270 }
271 s->inUse[s->state_in_ch] = True;
272 switch (s->state_in_len) {
273 case 1:
274 s->block[s->nblock] = (UChar)ch; s->nblock++;
275 break;
276 case 2:
277 s->block[s->nblock] = (UChar)ch; s->nblock++;
278 s->block[s->nblock] = (UChar)ch; s->nblock++;
279 break;
280 case 3:
281 s->block[s->nblock] = (UChar)ch; s->nblock++;
282 s->block[s->nblock] = (UChar)ch; s->nblock++;
283 s->block[s->nblock] = (UChar)ch; s->nblock++;
284 break;
285 default:
286 s->inUse[s->state_in_len-4] = True;
287 s->block[s->nblock] = (UChar)ch; s->nblock++;
288 s->block[s->nblock] = (UChar)ch; s->nblock++;
289 s->block[s->nblock] = (UChar)ch; s->nblock++;
290 s->block[s->nblock] = (UChar)ch; s->nblock++;
291 s->block[s->nblock] = ((UChar)(s->state_in_len-4));
292 s->nblock++;
293 break;
294 }
295 }
296
297
298 /*---------------------------------------------------*/
299 static
300 void flush_RL ( EState* s )
301 {
302 if (s->state_in_ch < 256) add_pair_to_block ( s );
303 init_RL ( s );
304 }
305
306
307 /*---------------------------------------------------*/
308 #define ADD_CHAR_TO_BLOCK(zs,zchh0) \
309 { \
310 UInt32 zchh = (UInt32)(zchh0); \
311 /*-- fast track the common case --*/ \
312 if (zchh != zs->state_in_ch && \
313 zs->state_in_len == 1) { \
314 UChar ch = (UChar)(zs->state_in_ch); \
315 BZ_UPDATE_CRC( zs->blockCRC, ch ); \
316 zs->inUse[zs->state_in_ch] = True; \
317 zs->block[zs->nblock] = (UChar)ch; \
318 zs->nblock++; \
319 zs->state_in_ch = zchh; \
320 } \
321 else \
322 /*-- general, uncommon cases --*/ \
323 if (zchh != zs->state_in_ch || \
324 zs->state_in_len == 255) { \
325 if (zs->state_in_ch < 256) \
326 add_pair_to_block ( zs ); \
327 zs->state_in_ch = zchh; \
328 zs->state_in_len = 1; \
329 } else { \
330 zs->state_in_len++; \
331 } \
332 }
333
334
335 /*---------------------------------------------------*/
336 static
337 Bool copy_input_until_stop ( EState* s )
338 {
339 Bool progress_in = False;
340
341 if (s->mode == BZ_M_RUNNING) {
342
343 /*-- fast track the common case --*/
344 while (True) {
345 /*-- block full? --*/
346 if (s->nblock >= s->nblockMAX) break;
347 /*-- no input? --*/
348 if (s->strm->avail_in == 0) break;
349 progress_in = True;
350 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
351 s->strm->next_in++;
352 s->strm->avail_in--;
353 s->strm->total_in_lo32++;
354 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
355 }
356
357 } else {
358
359 /*-- general, uncommon case --*/
360 while (True) {
361 /*-- block full? --*/
362 if (s->nblock >= s->nblockMAX) break;
363 /*-- no input? --*/
364 if (s->strm->avail_in == 0) break;
365 /*-- flush/finish end? --*/
366 if (s->avail_in_expect == 0) break;
367 progress_in = True;
368 ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
369 s->strm->next_in++;
370 s->strm->avail_in--;
371 s->strm->total_in_lo32++;
372 if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
373 s->avail_in_expect--;
374 }
375 }
376 return progress_in;
377 }
378
379
380 /*---------------------------------------------------*/
381 static
382 Bool copy_output_until_stop ( EState* s )
383 {
384 Bool progress_out = False;
385
386 while (True) {
387
388 /*-- no output space? --*/
389 if (s->strm->avail_out == 0) break;
390
391 /*-- block done? --*/
392 if (s->state_out_pos >= s->numZ) break;
393
394 progress_out = True;
395 *(s->strm->next_out) = s->zbits[s->state_out_pos];
396 s->state_out_pos++;
397 s->strm->avail_out--;
398 s->strm->next_out++;
399 s->strm->total_out_lo32++;
400 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
401 }
402
403 return progress_out;
404 }
405
406
407 /*---------------------------------------------------*/
408 static
409 Bool handle_compress ( bz_stream* strm )
410 {
411 Bool progress_in = False;
412 Bool progress_out = False;
413 EState* s = strm->state;
414
415 while (True) {
416
417 if (s->state == BZ_S_OUTPUT) {
418 progress_out |= copy_output_until_stop ( s );
419 if (s->state_out_pos < s->numZ) break;
420 if (s->mode == BZ_M_FINISHING &&
421 s->avail_in_expect == 0 &&
422 isempty_RL(s)) break;
423 prepare_new_block ( s );
424 s->state = BZ_S_INPUT;
425 if (s->mode == BZ_M_FLUSHING &&
426 s->avail_in_expect == 0 &&
427 isempty_RL(s)) break;
428 }
429
430 if (s->state == BZ_S_INPUT) {
431 progress_in |= copy_input_until_stop ( s );
432 if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
433 flush_RL ( s );
434 BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
435 s->state = BZ_S_OUTPUT;
436 }
437 else
438 if (s->nblock >= s->nblockMAX) {
439 BZ2_compressBlock ( s, False );
440 s->state = BZ_S_OUTPUT;
441 }
442 else
443 if (s->strm->avail_in == 0) {
444 break;
445 }
446 }
447
448 }
449
450 return progress_in || progress_out;
451 }
452
453
454 /*---------------------------------------------------*/
455 int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
456 {
457 Bool progress;
458 EState* s;
459 if (strm == NULL) return BZ_PARAM_ERROR;
460 s = strm->state;
461 if (s == NULL) return BZ_PARAM_ERROR;
462 if (s->strm != strm) return BZ_PARAM_ERROR;
463
464 preswitch:
465 switch (s->mode) {
466
467 case BZ_M_IDLE:
468 return BZ_SEQUENCE_ERROR;
469
470 case BZ_M_RUNNING:
471 if (action == BZ_RUN) {
472 progress = handle_compress ( strm );
473 return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
474 }
475 else
476 if (action == BZ_FLUSH) {
477 s->avail_in_expect = strm->avail_in;
478 s->mode = BZ_M_FLUSHING;
479 goto preswitch;
480 }
481 else
482 if (action == BZ_FINISH) {
483 s->avail_in_expect = strm->avail_in;
484 s->mode = BZ_M_FINISHING;
485 goto preswitch;
486 }
487 else
488 return BZ_PARAM_ERROR;
489
490 case BZ_M_FLUSHING:
491 if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
492 if (s->avail_in_expect != s->strm->avail_in)
493 return BZ_SEQUENCE_ERROR;
494 progress = handle_compress ( strm );
495 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
496 s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
497 s->mode = BZ_M_RUNNING;
498 return BZ_RUN_OK;
499
500 case BZ_M_FINISHING:
501 if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
502 if (s->avail_in_expect != s->strm->avail_in)
503 return BZ_SEQUENCE_ERROR;
504 progress = handle_compress ( strm );
505 if (!progress) return BZ_SEQUENCE_ERROR;
506 if (s->avail_in_expect > 0 || !isempty_RL(s) ||
507 s->state_out_pos < s->numZ) return BZ_FINISH_OK;
508 s->mode = BZ_M_IDLE;
509 return BZ_STREAM_END;
510 }
511 return BZ_OK; /*--not reached--*/
512 }
513
514
515 /*---------------------------------------------------*/
516 int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
517 {
518 EState* s;
519 if (strm == NULL) return BZ_PARAM_ERROR;
520 s = strm->state;
521 if (s == NULL) return BZ_PARAM_ERROR;
522 if (s->strm != strm) return BZ_PARAM_ERROR;
523
524 if (s->arr1 != NULL) BZFREE(s->arr1);
525 if (s->arr2 != NULL) BZFREE(s->arr2);
526 if (s->ftab != NULL) BZFREE(s->ftab);
527 BZFREE(strm->state);
528
529 strm->state = NULL;
530
531 return BZ_OK;
532 }
533
534
535 /*---------------------------------------------------*/
536 /*--- Decompression stuff ---*/
537 /*---------------------------------------------------*/
538
539 /*---------------------------------------------------*/
540 int BZ_API(BZ2_bzDecompressInit)
541 ( bz_stream* strm,
542 int verbosity,
543 int small )
544 {
545 DState* s;
546
547 if (!bz_config_ok()) return BZ_CONFIG_ERROR;
548
549 if (strm == NULL) return BZ_PARAM_ERROR;
550 if (small != 0 && small != 1) return BZ_PARAM_ERROR;
551 if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
552
553 if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
554 if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
555
556 s = BZALLOC( sizeof(DState) );
557 if (s == NULL) return BZ_MEM_ERROR;
558 s->strm = strm;
559 strm->state = s;
560 s->state = BZ_X_MAGIC_1;
561 s->bsLive = 0;
562 s->bsBuff = 0;
563 s->calculatedCombinedCRC = 0;
564 strm->total_in_lo32 = 0;
565 strm->total_in_hi32 = 0;
566 strm->total_out_lo32 = 0;
567 strm->total_out_hi32 = 0;
568 s->smallDecompress = (Bool)small;
569 s->ll4 = NULL;
570 s->ll16 = NULL;
571 s->tt = NULL;
572 s->currBlockNo = 0;
573 s->verbosity = verbosity;
574
575 return BZ_OK;
576 }
577
578
579 /*---------------------------------------------------*/
580 static
581 void unRLE_obuf_to_output_FAST ( DState* s )
582 {
583 UChar k1;
584
585 if (s->blockRandomised) {
586
587 while (True) {
588 /* try to finish existing run */
589 while (True) {
590 if (s->strm->avail_out == 0) return;
591 if (s->state_out_len == 0) break;
592 *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
593 BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
594 s->state_out_len--;
595 s->strm->next_out++;
596 s->strm->avail_out--;
597 s->strm->total_out_lo32++;
598 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
599 }
600
601 /* can a new run be started? */
602 if (s->nblock_used == s->save_nblock+1) return;
603
604
605 s->state_out_len = 1;
606 s->state_out_ch = s->k0;
607 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
608 k1 ^= BZ_RAND_MASK; s->nblock_used++;
609 if (s->nblock_used == s->save_nblock+1) continue;
610 if (k1 != s->k0) { s->k0 = k1; continue; };
611
612 s->state_out_len = 2;
613 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
614 k1 ^= BZ_RAND_MASK; s->nblock_used++;
615 if (s->nblock_used == s->save_nblock+1) continue;
616 if (k1 != s->k0) { s->k0 = k1; continue; };
617
618 s->state_out_len = 3;
619 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
620 k1 ^= BZ_RAND_MASK; s->nblock_used++;
621 if (s->nblock_used == s->save_nblock+1) continue;
622 if (k1 != s->k0) { s->k0 = k1; continue; };
623
624 BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
625 k1 ^= BZ_RAND_MASK; s->nblock_used++;
626 s->state_out_len = ((Int32)k1) + 4;
627 BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
628 s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
629 }
630
631 } else {
632
633 /* restore */
634 UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
635 UChar c_state_out_ch = s->state_out_ch;
636 Int32 c_state_out_len = s->state_out_len;
637 Int32 c_nblock_used = s->nblock_used;
638 Int32 c_k0 = s->k0;
639 UInt32* c_tt = s->tt;
640 UInt32 c_tPos = s->tPos;
641 char* cs_next_out = s->strm->next_out;
642 unsigned int cs_avail_out = s->strm->avail_out;
643 /* end restore */
644
645 UInt32 avail_out_INIT = cs_avail_out;
646 Int32 s_save_nblockPP = s->save_nblock+1;
647 unsigned int total_out_lo32_old;
648
649 while (True) {
650
651 /* try to finish existing run */
652 if (c_state_out_len > 0) {
653 while (True) {
654 if (cs_avail_out == 0) goto return_notr;
655 if (c_state_out_len == 1) break;
656 *( (UChar*)(cs_next_out) ) = c_state_out_ch;
657 BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
658 c_state_out_len--;
659 cs_next_out++;
660 cs_avail_out--;
661 }
662 s_state_out_len_eq_one:
663 {
664 if (cs_avail_out == 0) {
665 c_state_out_len = 1; goto return_notr;
666 };
667 *( (UChar*)(cs_next_out) ) = c_state_out_ch;
668 BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
669 cs_next_out++;
670 cs_avail_out--;
671 }
672 }
673 /* can a new run be started? */
674 if (c_nblock_used == s_save_nblockPP) {
675 c_state_out_len = 0; goto return_notr;
676 };
677 c_state_out_ch = c_k0;
678 BZ_GET_FAST_C(k1); c_nblock_used++;
679 if (k1 != c_k0) {
680 c_k0 = k1; goto s_state_out_len_eq_one;
681 };
682 if (c_nblock_used == s_save_nblockPP)
683 goto s_state_out_len_eq_one;
684
685 c_state_out_len = 2;
686 BZ_GET_FAST_C(k1); c_nblock_used++;
687 if (c_nblock_used == s_save_nblockPP) continue;
688 if (k1 != c_k0) { c_k0 = k1; continue; };
689
690 c_state_out_len = 3;
691 BZ_GET_FAST_C(k1); c_nblock_used++;
692 if (c_nblock_used == s_save_nblockPP) continue;
693 if (k1 != c_k0) { c_k0 = k1; continue; };
694
695 BZ_GET_FAST_C(k1); c_nblock_used++;
696 c_state_out_len = ((Int32)k1) + 4;
697 BZ_GET_FAST_C(c_k0); c_nblock_used++;
698 }
699
700 return_notr:
701 total_out_lo32_old = s->strm->total_out_lo32;
702 s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
703 if (s->strm->total_out_lo32 < total_out_lo32_old)
704 s->strm->total_out_hi32++;
705
706 /* save */
707 s->calculatedBlockCRC = c_calculatedBlockCRC;
708 s->state_out_ch = c_state_out_ch;
709 s->state_out_len = c_state_out_len;
710 s->nblock_used = c_nblock_used;
711 s->k0 = c_k0;
712 s->tt = c_tt;
713 s->tPos = c_tPos;
714 s->strm->next_out = cs_next_out;
715 s->strm->avail_out = cs_avail_out;
716 /* end save */
717 }
718 }
719
720
721
722 /*---------------------------------------------------*/
723 __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
724 {
725 Int32 nb, na, mid;
726 nb = 0;
727 na = 256;
728 do {
729 mid = (nb + na) >> 1;
730 if (indx >= cftab[mid]) nb = mid; else na = mid;
731 }
732 while (na - nb != 1);
733 return nb;
734 }
735
736
737 /*---------------------------------------------------*/
738 static
739 void unRLE_obuf_to_output_SMALL ( DState* s )
740 {
741 UChar k1;
742
743 if (s->blockRandomised) {
744
745 while (True) {
746 /* try to finish existing run */
747 while (True) {
748 if (s->strm->avail_out == 0) return;
749 if (s->state_out_len == 0) break;
750 *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
751 BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
752 s->state_out_len--;
753 s->strm->next_out++;
754 s->strm->avail_out--;
755 s->strm->total_out_lo32++;
756 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
757 }
758
759 /* can a new run be started? */
760 if (s->nblock_used == s->save_nblock+1) return;
761
762
763 s->state_out_len = 1;
764 s->state_out_ch = s->k0;
765 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
766 k1 ^= BZ_RAND_MASK; s->nblock_used++;
767 if (s->nblock_used == s->save_nblock+1) continue;
768 if (k1 != s->k0) { s->k0 = k1; continue; };
769
770 s->state_out_len = 2;
771 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
772 k1 ^= BZ_RAND_MASK; s->nblock_used++;
773 if (s->nblock_used == s->save_nblock+1) continue;
774 if (k1 != s->k0) { s->k0 = k1; continue; };
775
776 s->state_out_len = 3;
777 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
778 k1 ^= BZ_RAND_MASK; s->nblock_used++;
779 if (s->nblock_used == s->save_nblock+1) continue;
780 if (k1 != s->k0) { s->k0 = k1; continue; };
781
782 BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
783 k1 ^= BZ_RAND_MASK; s->nblock_used++;
784 s->state_out_len = ((Int32)k1) + 4;
785 BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
786 s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
787 }
788
789 } else {
790
791 while (True) {
792 /* try to finish existing run */
793 while (True) {
794 if (s->strm->avail_out == 0) return;
795 if (s->state_out_len == 0) break;
796 *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
797 BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
798 s->state_out_len--;
799 s->strm->next_out++;
800 s->strm->avail_out--;
801 s->strm->total_out_lo32++;
802 if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
803 }
804
805 /* can a new run be started? */
806 if (s->nblock_used == s->save_nblock+1) return;
807
808 s->state_out_len = 1;
809 s->state_out_ch = s->k0;
810 BZ_GET_SMALL(k1); s->nblock_used++;
811 if (s->nblock_used == s->save_nblock+1) continue;
812 if (k1 != s->k0) { s->k0 = k1; continue; };
813
814 s->state_out_len = 2;
815 BZ_GET_SMALL(k1); s->nblock_used++;
816 if (s->nblock_used == s->save_nblock+1) continue;
817 if (k1 != s->k0) { s->k0 = k1; continue; };
818
819 s->state_out_len = 3;
820 BZ_GET_SMALL(k1); s->nblock_used++;
821 if (s->nblock_used == s->save_nblock+1) continue;
822 if (k1 != s->k0) { s->k0 = k1; continue; };
823
824 BZ_GET_SMALL(k1); s->nblock_used++;
825 s->state_out_len = ((Int32)k1) + 4;
826 BZ_GET_SMALL(s->k0); s->nblock_used++;
827 }
828
829 }
830 }
831
832
833 /*---------------------------------------------------*/
834 int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
835 {
836 DState* s;
837 if (strm == NULL) return BZ_PARAM_ERROR;
838 s = strm->state;
839 if (s == NULL) return BZ_PARAM_ERROR;
840 if (s->strm != strm) return BZ_PARAM_ERROR;
841
842 while (True) {
843 if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
844 if (s->state == BZ_X_OUTPUT) {
845 if (s->smallDecompress)
846 unRLE_obuf_to_output_SMALL ( s ); else
847 unRLE_obuf_to_output_FAST ( s );
848 if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
849 BZ_FINALISE_CRC ( s->calculatedBlockCRC );
850 if (s->verbosity >= 3)
851 VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC,
852 s->calculatedBlockCRC );
853 if (s->verbosity >= 2) VPrintf0 ( "]" );
854 if (s->calculatedBlockCRC != s->storedBlockCRC)
855 return BZ_DATA_ERROR;
856 s->calculatedCombinedCRC
857 = (s->calculatedCombinedCRC << 1) |
858 (s->calculatedCombinedCRC >> 31);
859 s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
860 s->state = BZ_X_BLKHDR_1;
861 } else {
862 return BZ_OK;
863 }
864 }
865 if (s->state >= BZ_X_MAGIC_1) {
866 Int32 r = BZ2_decompress ( s );
867 if (r == BZ_STREAM_END) {
868 if (s->verbosity >= 3)
869 VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
870 s->storedCombinedCRC, s->calculatedCombinedCRC );
871 if (s->calculatedCombinedCRC != s->storedCombinedCRC)
872 return BZ_DATA_ERROR;
873 return r;
874 }
875 if (s->state != BZ_X_OUTPUT) return r;
876 }
877 }
878
879 AssertH ( 0, 6001 );
880
881 return 0; /*NOTREACHED*/
882 }
883
884
885 /*---------------------------------------------------*/
886 int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
887 {
888 DState* s;
889 if (strm == NULL) return BZ_PARAM_ERROR;
890 s = strm->state;
891 if (s == NULL) return BZ_PARAM_ERROR;
892 if (s->strm != strm) return BZ_PARAM_ERROR;
893
894 if (s->tt != NULL) BZFREE(s->tt);
895 if (s->ll16 != NULL) BZFREE(s->ll16);
896 if (s->ll4 != NULL) BZFREE(s->ll4);
897
898 BZFREE(strm->state);
899 strm->state = NULL;
900
901 return BZ_OK;
902 }
903
904
905 #ifndef BZ_NO_STDIO
906 /*---------------------------------------------------*/
907 /*--- File I/O stuff ---*/
908 /*---------------------------------------------------*/
909
910 #define BZ_SETERR(eee) \
911 { \
912 if (bzerror != NULL) *bzerror = eee; \
913 if (bzf != NULL) bzf->lastErr = eee; \
914 }
915
916 typedef
917 struct {
918 FILE* handle;
919 Char buf[BZ_MAX_UNUSED];
920 Int32 bufN;
921 Bool writing;
922 bz_stream strm;
923 Int32 lastErr;
924 Bool initialisedOk;
925 }
926 bzFile;
927
928
929 /*---------------------------------------------*/
930 static Bool myfeof ( FILE* f )
931 {
932 Int32 c = fgetc ( f );
933 if (c == EOF) return True;
934 ungetc ( c, f );
935 return False;
936 }
937
938
939 /*---------------------------------------------------*/
940 BZFILE* BZ_API(BZ2_bzWriteOpen)
941 ( int* bzerror,
942 FILE* f,
943 int blockSize100k,
944 int verbosity,
945 int workFactor )
946 {
947 Int32 ret;
948 bzFile* bzf = NULL;
949
950 BZ_SETERR(BZ_OK);
951
952 if (f == NULL ||
953 (blockSize100k < 1 || blockSize100k > 9) ||
954 (workFactor < 0 || workFactor > 250) ||
955 (verbosity < 0 || verbosity > 4))
956 { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
957
958 if (ferror(f))
959 { BZ_SETERR(BZ_IO_ERROR); return NULL; };
960
961 bzf = malloc ( sizeof(bzFile) );
962 if (bzf == NULL)
963 { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
964
965 BZ_SETERR(BZ_OK);
966 bzf->initialisedOk = False;
967 bzf->bufN = 0;
968 bzf->handle = f;
969 bzf->writing = True;
970 bzf->strm.bzalloc = NULL;
971 bzf->strm.bzfree = NULL;
972 bzf->strm.opaque = NULL;
973
974 if (workFactor == 0) workFactor = 30;
975 ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
976 verbosity, workFactor );
977 if (ret != BZ_OK)
978 { BZ_SETERR(ret); free(bzf); return NULL; };
979
980 bzf->strm.avail_in = 0;
981 bzf->initialisedOk = True;
982 return bzf;
983 }
984
985
986
987 /*---------------------------------------------------*/
988 void BZ_API(BZ2_bzWrite)
989 ( int* bzerror,
990 BZFILE* b,
991 void* buf,
992 int len )
993 {
994 Int32 n, n2, ret;
995 bzFile* bzf = (bzFile*)b;
996
997 BZ_SETERR(BZ_OK);
998 if (bzf == NULL || buf == NULL || len < 0)
999 { BZ_SETERR(BZ_PARAM_ERROR); return; };
1000 if (!(bzf->writing))
1001 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1002 if (ferror(bzf->handle))
1003 { BZ_SETERR(BZ_IO_ERROR); return; };
1004
1005 if (len == 0)
1006 { BZ_SETERR(BZ_OK); return; };
1007
1008 bzf->strm.avail_in = len;
1009 bzf->strm.next_in = buf;
1010
1011 while (True) {
1012 bzf->strm.avail_out = BZ_MAX_UNUSED;
1013 bzf->strm.next_out = bzf->buf;
1014 ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
1015 if (ret != BZ_RUN_OK)
1016 { BZ_SETERR(ret); return; };
1017
1018 if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
1019 n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1020 n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
1021 n, bzf->handle );
1022 if (n != n2 || ferror(bzf->handle))
1023 { BZ_SETERR(BZ_IO_ERROR); return; };
1024 }
1025
1026 if (bzf->strm.avail_in == 0)
1027 { BZ_SETERR(BZ_OK); return; };
1028 }
1029 }
1030
1031
1032 /*---------------------------------------------------*/
1033 void BZ_API(BZ2_bzWriteClose)
1034 ( int* bzerror,
1035 BZFILE* b,
1036 int abandon,
1037 unsigned int* nbytes_in,
1038 unsigned int* nbytes_out )
1039 {
1040 BZ2_bzWriteClose64 ( bzerror, b, abandon,
1041 nbytes_in, NULL, nbytes_out, NULL );
1042 }
1043
1044
1045 void BZ_API(BZ2_bzWriteClose64)
1046 ( int* bzerror,
1047 BZFILE* b,
1048 int abandon,
1049 unsigned int* nbytes_in_lo32,
1050 unsigned int* nbytes_in_hi32,
1051 unsigned int* nbytes_out_lo32,
1052 unsigned int* nbytes_out_hi32 )
1053 {
1054 Int32 n, n2, ret;
1055 bzFile* bzf = (bzFile*)b;
1056
1057 if (bzf == NULL)
1058 { BZ_SETERR(BZ_OK); return; };
1059 if (!(bzf->writing))
1060 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1061 if (ferror(bzf->handle))
1062 { BZ_SETERR(BZ_IO_ERROR); return; };
1063
1064 if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
1065 if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
1066 if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
1067 if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
1068
1069 if ((!abandon) && bzf->lastErr == BZ_OK) {
1070 while (True) {
1071 bzf->strm.avail_out = BZ_MAX_UNUSED;
1072 bzf->strm.next_out = bzf->buf;
1073 ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
1074 if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
1075 { BZ_SETERR(ret); return; };
1076
1077 if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
1078 n = BZ_MAX_UNUSED - bzf->strm.avail_out;
1079 n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
1080 n, bzf->handle );
1081 if (n != n2 || ferror(bzf->handle))
1082 { BZ_SETERR(BZ_IO_ERROR); return; };
1083 }
1084
1085 if (ret == BZ_STREAM_END) break;
1086 }
1087 }
1088
1089 if ( !abandon && !ferror ( bzf->handle ) ) {
1090 fflush ( bzf->handle );
1091 if (ferror(bzf->handle))
1092 { BZ_SETERR(BZ_IO_ERROR); return; };
1093 }
1094
1095 if (nbytes_in_lo32 != NULL)
1096 *nbytes_in_lo32 = bzf->strm.total_in_lo32;
1097 if (nbytes_in_hi32 != NULL)
1098 *nbytes_in_hi32 = bzf->strm.total_in_hi32;
1099 if (nbytes_out_lo32 != NULL)
1100 *nbytes_out_lo32 = bzf->strm.total_out_lo32;
1101 if (nbytes_out_hi32 != NULL)
1102 *nbytes_out_hi32 = bzf->strm.total_out_hi32;
1103
1104 BZ_SETERR(BZ_OK);
1105 BZ2_bzCompressEnd ( &(bzf->strm) );
1106 free ( bzf );
1107 }
1108
1109
1110 /*---------------------------------------------------*/
1111 BZFILE* BZ_API(BZ2_bzReadOpen)
1112 ( int* bzerror,
1113 FILE* f,
1114 int verbosity,
1115 int small,
1116 void* unused,
1117 int nUnused )
1118 {
1119 bzFile* bzf = NULL;
1120 int ret;
1121
1122 BZ_SETERR(BZ_OK);
1123
1124 if (f == NULL ||
1125 (small != 0 && small != 1) ||
1126 (verbosity < 0 || verbosity > 4) ||
1127 (unused == NULL && nUnused != 0) ||
1128 (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
1129 { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
1130
1131 if (ferror(f))
1132 { BZ_SETERR(BZ_IO_ERROR); return NULL; };
1133
1134 bzf = malloc ( sizeof(bzFile) );
1135 if (bzf == NULL)
1136 { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
1137
1138 BZ_SETERR(BZ_OK);
1139
1140 bzf->initialisedOk = False;
1141 bzf->handle = f;
1142 bzf->bufN = 0;
1143 bzf->writing = False;
1144 bzf->strm.bzalloc = NULL;
1145 bzf->strm.bzfree = NULL;
1146 bzf->strm.opaque = NULL;
1147
1148 while (nUnused > 0) {
1149 bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
1150 unused = ((void*)( 1 + ((UChar*)(unused)) ));
1151 nUnused--;
1152 }
1153
1154 ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
1155 if (ret != BZ_OK)
1156 { BZ_SETERR(ret); free(bzf); return NULL; };
1157
1158 bzf->strm.avail_in = bzf->bufN;
1159 bzf->strm.next_in = bzf->buf;
1160
1161 bzf->initialisedOk = True;
1162 return bzf;
1163 }
1164
1165
1166 /*---------------------------------------------------*/
1167 void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
1168 {
1169 bzFile* bzf = (bzFile*)b;
1170
1171 BZ_SETERR(BZ_OK);
1172 if (bzf == NULL)
1173 { BZ_SETERR(BZ_OK); return; };
1174
1175 if (bzf->writing)
1176 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1177
1178 if (bzf->initialisedOk)
1179 (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
1180 free ( bzf );
1181 }
1182
1183
1184 /*---------------------------------------------------*/
1185 int BZ_API(BZ2_bzRead)
1186 ( int* bzerror,
1187 BZFILE* b,
1188 void* buf,
1189 int len )
1190 {
1191 Int32 n, ret;
1192 bzFile* bzf = (bzFile*)b;
1193
1194 BZ_SETERR(BZ_OK);
1195
1196 if (bzf == NULL || buf == NULL || len < 0)
1197 { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
1198
1199 if (bzf->writing)
1200 { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
1201
1202 if (len == 0)
1203 { BZ_SETERR(BZ_OK); return 0; };
1204
1205 bzf->strm.avail_out = len;
1206 bzf->strm.next_out = buf;
1207
1208 while (True) {
1209
1210 if (ferror(bzf->handle))
1211 { BZ_SETERR(BZ_IO_ERROR); return 0; };
1212
1213 if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
1214 n = fread ( bzf->buf, sizeof(UChar),
1215 BZ_MAX_UNUSED, bzf->handle );
1216 if (ferror(bzf->handle))
1217 { BZ_SETERR(BZ_IO_ERROR); return 0; };
1218 bzf->bufN = n;
1219 bzf->strm.avail_in = bzf->bufN;
1220 bzf->strm.next_in = bzf->buf;
1221 }
1222
1223 ret = BZ2_bzDecompress ( &(bzf->strm) );
1224
1225 if (ret != BZ_OK && ret != BZ_STREAM_END)
1226 { BZ_SETERR(ret); return 0; };
1227
1228 if (ret == BZ_OK && myfeof(bzf->handle) &&
1229 bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
1230 { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
1231
1232 if (ret == BZ_STREAM_END)
1233 { BZ_SETERR(BZ_STREAM_END);
1234 return len - bzf->strm.avail_out; };
1235 if (bzf->strm.avail_out == 0)
1236 { BZ_SETERR(BZ_OK); return len; };
1237
1238 }
1239
1240 return 0; /*not reached*/
1241 }
1242
1243
1244 /*---------------------------------------------------*/
1245 void BZ_API(BZ2_bzReadGetUnused)
1246 ( int* bzerror,
1247 BZFILE* b,
1248 void** unused,
1249 int* nUnused )
1250 {
1251 bzFile* bzf = (bzFile*)b;
1252 if (bzf == NULL)
1253 { BZ_SETERR(BZ_PARAM_ERROR); return; };
1254 if (bzf->lastErr != BZ_STREAM_END)
1255 { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
1256 if (unused == NULL || nUnused == NULL)
1257 { BZ_SETERR(BZ_PARAM_ERROR); return; };
1258
1259 BZ_SETERR(BZ_OK);
1260 *nUnused = bzf->strm.avail_in;
1261 *unused = bzf->strm.next_in;
1262 }
1263 #endif
1264
1265
1266 /*---------------------------------------------------*/
1267 /*--- Misc convenience stuff ---*/
1268 /*---------------------------------------------------*/
1269
1270 /*---------------------------------------------------*/
1271 int BZ_API(BZ2_bzBuffToBuffCompress)
1272 ( char* dest,
1273 unsigned int* destLen,
1274 char* source,
1275 unsigned int sourceLen,
1276 int blockSize100k,
1277 int verbosity,
1278 int workFactor )
1279 {
1280 bz_stream strm;
1281 int ret;
1282
1283 if (dest == NULL || destLen == NULL ||
1284 source == NULL ||
1285 blockSize100k < 1 || blockSize100k > 9 ||
1286 verbosity < 0 || verbosity > 4 ||
1287 workFactor < 0 || workFactor > 250)
1288 return BZ_PARAM_ERROR;
1289
1290 if (workFactor == 0) workFactor = 30;
1291 strm.bzalloc = NULL;
1292 strm.bzfree = NULL;
1293 strm.opaque = NULL;
1294 ret = BZ2_bzCompressInit ( &strm, blockSize100k,
1295 verbosity, workFactor );
1296 if (ret != BZ_OK) return ret;
1297
1298 strm.next_in = source;
1299 strm.next_out = dest;
1300 strm.avail_in = sourceLen;
1301 strm.avail_out = *destLen;
1302
1303 ret = BZ2_bzCompress ( &strm, BZ_FINISH );
1304 if (ret == BZ_FINISH_OK) goto output_overflow;
1305 if (ret != BZ_STREAM_END) goto errhandler;
1306
1307 /* normal termination */
1308 *destLen -= strm.avail_out;
1309 BZ2_bzCompressEnd ( &strm );
1310 return BZ_OK;
1311
1312 output_overflow:
1313 BZ2_bzCompressEnd ( &strm );
1314 return BZ_OUTBUFF_FULL;
1315
1316 errhandler:
1317 BZ2_bzCompressEnd ( &strm );
1318 return ret;
1319 }
1320
1321
1322 /*---------------------------------------------------*/
1323 int BZ_API(BZ2_bzBuffToBuffDecompress)
1324 ( char* dest,
1325 unsigned int* destLen,
1326 char* source,
1327 unsigned int sourceLen,
1328 int small,
1329 int verbosity )
1330 {
1331 bz_stream strm;
1332 int ret;
1333
1334 if (dest == NULL || destLen == NULL ||
1335 source == NULL ||
1336 (small != 0 && small != 1) ||
1337 verbosity < 0 || verbosity > 4)
1338 return BZ_PARAM_ERROR;
1339
1340 strm.bzalloc = NULL;
1341 strm.bzfree = NULL;
1342 strm.opaque = NULL;
1343 ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
1344 if (ret != BZ_OK) return ret;
1345
1346 strm.next_in = source;
1347 strm.next_out = dest;
1348 strm.avail_in = sourceLen;
1349 strm.avail_out = *destLen;
1350
1351 ret = BZ2_bzDecompress ( &strm );
1352 if (ret == BZ_OK) goto output_overflow_or_eof;
1353 if (ret != BZ_STREAM_END) goto errhandler;
1354
1355 /* normal termination */
1356 *destLen -= strm.avail_out;
1357 BZ2_bzDecompressEnd ( &strm );
1358 return BZ_OK;
1359
1360 output_overflow_or_eof:
1361 if (strm.avail_out > 0) {
1362 BZ2_bzDecompressEnd ( &strm );
1363 return BZ_UNEXPECTED_EOF;
1364 } else {
1365 BZ2_bzDecompressEnd ( &strm );
1366 return BZ_OUTBUFF_FULL;
1367 };
1368
1369 errhandler:
1370 BZ2_bzDecompressEnd ( &strm );
1371 return ret;
1372 }
1373
1374
1375 /*---------------------------------------------------*/
1376 /*--
1377 Code contributed by Yoshioka Tsuneo
1378 (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
1379 to support better zlib compatibility.
1380 This code is not _officially_ part of libbzip2 (yet);
1381 I haven't tested it, documented it, or considered the
1382 threading-safeness of it.
1383 If this code breaks, please contact both Yoshioka and me.
1384 --*/
1385 /*---------------------------------------------------*/
1386
1387 /*---------------------------------------------------*/
1388 /*--
1389 return version like "0.9.0c".
1390 --*/
1391 const char * BZ_API(BZ2_bzlibVersion)(void)
1392 {
1393 return BZ_VERSION;
1394 }
1395
1396
1397 #ifndef BZ_NO_STDIO
1398 /*---------------------------------------------------*/
1399
1400 #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
1401 # include
1402 # include
1403 # define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
1404 #else
1405 # define SET_BINARY_MODE(file)
1406 #endif
1407 static
1408 BZFILE * bzopen_or_bzdopen
1409 ( const char *path, /* no use when bzdopen */
1410 int fd, /* no use when bzdopen */
1411 const char *mode,
1412 int open_mode) /* bzopen: 0, bzdopen:1 */
1413 {
1414 int bzerr;
1415 char unused[BZ_MAX_UNUSED];
1416 int blockSize100k = 9;
1417 int writing = 0;
1418 char mode2[10] = "";
1419 FILE *fp = NULL;
1420 BZFILE *bzfp = NULL;
1421 int verbosity = 0;
1422 int workFactor = 30;
1423 int smallMode = 0;
1424 int nUnused = 0;
1425
1426 if (mode == NULL) return NULL;
1427 while (*mode) {
1428 switch (*mode) {
1429 case 'r':
1430 writing = 0; break;
1431 case 'w':
1432 writing = 1; break;
1433 case 's':
1434 smallMode = 1; break;
1435 default:
1436 if (isdigit((int)(*mode))) {
1437 blockSize100k = *mode-BZ_HDR_0;
1438 }
1439 }
1440 mode++;
1441 }
1442 strcat(mode2, writing ? "w" : "r" );
1443 strcat(mode2,"b"); /* binary mode */
1444
1445 if (open_mode==0) {
1446 if (path==NULL || strcmp(path,"")==0) {
1447 fp = (writing ? stdout : stdin);
1448 SET_BINARY_MODE(fp);
1449 } else {
1450 fp = fopen(path,mode2);
1451 }
1452 } else {
1453 #ifdef BZ_STRICT_ANSI
1454 fp = NULL;
1455 #else
1456 fp = fdopen(fd,mode2);
1457 #endif
1458 }
1459 if (fp == NULL) return NULL;
1460
1461 if (writing) {
1462 /* Guard against total chaos and anarchy -- JRS */
1463 if (blockSize100k < 1) blockSize100k = 1;
1464 if (blockSize100k > 9) blockSize100k = 9;
1465 bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
1466 verbosity,workFactor);
1467 } else {
1468 bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
1469 unused,nUnused);
1470 }
1471 if (bzfp == NULL) {
1472 if (fp != stdin && fp != stdout) fclose(fp);
1473 return NULL;
1474 }
1475 return bzfp;
1476 }
1477
1478
1479 /*---------------------------------------------------*/
1480 /*--
1481 open file for read or write.
1482 ex) bzopen("file","w9")
1483 case path="" or NULL => use stdin or stdout.
1484 --*/
1485 BZFILE * BZ_API(BZ2_bzopen)
1486 ( const char *path,
1487 const char *mode )
1488 {
1489 return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
1490 }
1491
1492
1493 /*---------------------------------------------------*/
1494 BZFILE * BZ_API(BZ2_bzdopen)
1495 ( int fd,
1496 const char *mode )
1497 {
1498 return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
1499 }
1500
1501
1502 /*---------------------------------------------------*/
1503 int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
1504 {
1505 int bzerr, nread;
1506 if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
1507 nread = BZ2_bzRead(&bzerr,b,buf,len);
1508 if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
1509 return nread;
1510 } else {
1511 return -1;
1512 }
1513 }
1514
1515
1516 /*---------------------------------------------------*/
1517 int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
1518 {
1519 int bzerr;
1520
1521 BZ2_bzWrite(&bzerr,b,buf,len);
1522 if(bzerr == BZ_OK){
1523 return len;
1524 }else{
1525 return -1;
1526 }
1527 }
1528
1529
1530 /*---------------------------------------------------*/
1531 int BZ_API(BZ2_bzflush) (BZFILE *b)
1532 {
1533 /* do nothing now... */
1534 return 0;
1535 }
1536
1537
1538 /*---------------------------------------------------*/
1539 void BZ_API(BZ2_bzclose) (BZFILE* b)
1540 {
1541 int bzerr;
1542 FILE *fp = ((bzFile *)b)->handle;
1543
1544 if (b==NULL) {return;}
1545 if(((bzFile*)b)->writing){
1546 BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
1547 if(bzerr != BZ_OK){
1548 BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
1549 }
1550 }else{
1551 BZ2_bzReadClose(&bzerr,b);
1552 }
1553 if(fp!=stdin && fp!=stdout){
1554 fclose(fp);
1555 }
1556 }
1557
1558
1559 /*---------------------------------------------------*/
1560 /*--
1561 return last error code
1562 --*/
1563 static const char *bzerrorstrings[] = {
1564 "OK"
1565 ,"SEQUENCE_ERROR"
1566 ,"PARAM_ERROR"
1567 ,"MEM_ERROR"
1568 ,"DATA_ERROR"
1569 ,"DATA_ERROR_MAGIC"
1570 ,"IO_ERROR"
1571 ,"UNEXPECTED_EOF"
1572 ,"OUTBUFF_FULL"
1573 ,"CONFIG_ERROR"
1574 ,"???" /* for future */
1575 ,"???" /* for future */
1576 ,"???" /* for future */
1577 ,"???" /* for future */
1578 ,"???" /* for future */
1579 ,"???" /* for future */
1580 };
1581
1582
1583 const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
1584 {
1585 int err = ((bzFile *)b)->lastErr;
1586
1587 if(err>0) err = 0;
1588 *errnum = err;
1589 return bzerrorstrings[err*-1];
1590 }
1591 #endif
1592
1593
1594 /*-------------------------------------------------------------*/
1595 /*--- end bzlib.c ---*/
1596 /*-------------------------------------------------------------*/
+0
-321
lib/Support/bzip2/bzlib.h less more
None
1 /*-------------------------------------------------------------*/
2 /*--- Public header file for the library. ---*/
3 /*--- bzlib.h ---*/
4 /*-------------------------------------------------------------*/
5
6 /*--
7 This file is a part of bzip2 and/or libbzip2, a program and
8 library for lossless, block-sorting data compression.
9
10 Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. The origin of this software must not be misrepresented; you must
20 not claim that you wrote the original software. If you use this
21 software in a product, an acknowledgment in the product
22 documentation would be appreciated but is not required.
23
24 3. Altered source versions must be plainly marked as such, and must
25 not be misrepresented as being the original software.
26
27 4. The name of the author may not be used to endorse or promote
28 products derived from this software without specific prior written
29 permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
32 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
35 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
37 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
43 Julian Seward, Cambridge, UK.
44 jseward@acm.org
45 bzip2/libbzip2 version 1.0 of 21 March 2000
46
47 This program is based on (at least) the work of:
48 Mike Burrows
49 David Wheeler
50 Peter Fenwick
51 Alistair Moffat
52 Radford Neal
53 Ian H. Witten
54 Robert Sedgewick
55 Jon L. Bentley
56
57 For more information on these sources, see the manual.
58 --*/
59
60
61 #ifndef _BZLIB_H
62 #define _BZLIB_H
63
64 #ifdef __cplusplus
65 extern "C" {
66 #endif
67
68 #define BZ_RUN 0
69 #define BZ_FLUSH 1
70 #define BZ_FINISH 2
71
72 #define BZ_OK 0
73 #define BZ_RUN_OK 1
74 #define BZ_FLUSH_OK 2
75 #define BZ_FINISH_OK 3
76 #define BZ_STREAM_END 4
77 #define BZ_SEQUENCE_ERROR (-1)
78 #define BZ_PARAM_ERROR (-2)
79 #define BZ_MEM_ERROR (-3)
80 #define BZ_DATA_ERROR (-4)
81 #define BZ_DATA_ERROR_MAGIC (-5)
82 #define BZ_IO_ERROR (-6)
83 #define BZ_UNEXPECTED_EOF (-7)
84 #define BZ_OUTBUFF_FULL (-8)
85 #define BZ_CONFIG_ERROR (-9)
86
87 typedef
88 struct {
89 char *next_in;
90 unsigned int avail_in;
91 unsigned int total_in_lo32;
92 unsigned int total_in_hi32;
93
94 char *next_out;
95 unsigned int avail_out;
96 unsigned int total_out_lo32;
97 unsigned int total_out_hi32;
98
99 void *state;
100
101 void *(*bzalloc)(void *,int,int);
102 void (*bzfree)(void *,void *);
103 void *opaque;
104 }
105 bz_stream;
106
107
108 #ifndef BZ_IMPORT
109 #define BZ_EXPORT
110 #endif
111
112 /* Need a definitition for FILE */
113 #include
114
115 #ifdef _WIN32
116 # include
117 # ifdef small
118 /* windows.h define small to char */
119 # undef small
120 # endif
121 # ifdef BZ_EXPORT
122 # define BZ_API(func) WINAPI func
123 # define BZ_EXTERN extern
124 # else
125 /* import windows dll dynamically */
126 # define BZ_API(func) (WINAPI * func)
127 # define BZ_EXTERN
128 # endif
129 #else
130 # define BZ_API(func) func
131 # define BZ_EXTERN extern
132 #endif
133
134
135 /*-- Core (low-level) library functions --*/
136
137 BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
138 bz_stream* strm,
139 int blockSize100k,
140 int verbosity,
141 int workFactor
142 );
143
144 BZ_EXTERN int BZ_API(BZ2_bzCompress) (
145 bz_stream* strm,
146 int action
147 );
148
149 BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
150 bz_stream* strm
151 );
152
153 BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
154 bz_stream *strm,
155 int verbosity,
156 int small
157 );
158
159 BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
160 bz_stream* strm
161 );
162
163 BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
164 bz_stream *strm
165 );
166
167
168
169 /*-- High(er) level library functions --*/
170
171 #ifndef BZ_NO_STDIO
172 #define BZ_MAX_UNUSED 5000
173
174 typedef void BZFILE;
175
176 BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
177 int* bzerror,
178 FILE* f,
179 int verbosity,
180 int small,
181 void* unused,
182 int nUnused
183 );
184
185 BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
186 int* bzerror,
187 BZFILE* b
188 );
189
190 BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
191 int* bzerror,
192 BZFILE* b,
193 void** unused,
194 int* nUnused
195 );
196
197 BZ_EXTERN int BZ_API(BZ2_bzRead) (
198 int* bzerror,
199 BZFILE* b,
200 void* buf,
201 int len
202 );
203
204 BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
205 int* bzerror,
206 FILE* f,
207 int blockSize100k,
208 int verbosity,
209 int workFactor
210 );
211
212 BZ_EXTERN void BZ_API(BZ2_bzWrite) (
213 int* bzerror,
214 BZFILE* b,
215 void* buf,
216 int len
217 );
218
219 BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
220 int* bzerror,
221 BZFILE* b,
222 int abandon,
223 unsigned int* nbytes_in,
224 unsigned int* nbytes_out
225 );
226
227 BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
228 int* bzerror,
229 BZFILE* b,
230 int abandon,
231 unsigned int* nbytes_in_lo32,
232 unsigned int* nbytes_in_hi32,
233 unsigned int* nbytes_out_lo32,
234 unsigned int* nbytes_out_hi32
235 );
236 #endif
237
238
239 /*-- Utility functions --*/
240
241 BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
242 char* dest,
243 unsigned int* destLen,
244 char* source,
245 unsigned int sourceLen,
246 int blockSize100k,
247 int verbosity,
248 int workFactor
249 );
250
251 BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
252 char* dest,
253 unsigned int* destLen,
254 char* source,
255 unsigned int sourceLen,
256 int small,
257 int verbosity
258 );
259
260
261 /*--
262 Code contributed by Yoshioka Tsuneo
263 (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
264 to support better zlib compatibility.
265 This code is not _officially_ part of libbzip2 (yet);
266 I haven't tested it, documented it, or considered the
267 threading-safeness of it.
268 If this code breaks, please contact both Yoshioka and me.
269 --*/
270
271 BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
272 void
273 );
274
275 #ifndef BZ_NO_STDIO
276 BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
277 const char *path,
278 const char *mode
279 );
280
281 BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
282 int fd,
283 const char *mode
284 );
285
286 BZ_EXTERN int BZ_API(BZ2_bzread) (
287 BZFILE* b,
288 void* buf,
289 int len
290 );
291
292 BZ_EXTERN int BZ_API(BZ2_bzwrite) (
293 BZFILE* b,
294 void* buf,
295 int len
296 );
297
298 BZ_EXTERN int BZ_API(BZ2_bzflush) (
299 BZFILE* b
300 );
301
302 BZ_EXTERN void BZ_API(BZ2_bzclose) (
303 BZFILE* b
304 );
305
306 BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
307 BZFILE *b,
308 int *errnum
309 );
310 #endif
311
312 #ifdef __cplusplus
313 }
314 #endif
315
316 #endif
317
318 /*-------------------------------------------------------------*/
319 /*--- end bzlib.h ---*/
320 /*-------------------------------------------------------------*/
+0
-537
lib/Support/bzip2/bzlib_private.h less more
None
1 /*-------------------------------------------------------------*/
2 /*--- Private header file for the library. ---*/
3 /*--- bzlib_private.h ---*/
4 /*-------------------------------------------------------------*/
5
6 /*--
7 This file is a part of bzip2 and/or libbzip2, a program and
8 library for lossless, block-sorting data compression.
9
10 Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. The origin of this software must not be misrepresented; you must
20 not claim that you wrote the original software. If you use this
21 software in a product, an acknowledgment in the product
22 documentation would be appreciated but is not required.
23
24 3. Altered source versions must be plainly marked as such, and must
25 not be misrepresented as being the original software.
26
27 4. The name of the author may not be used to endorse or promote
28 products derived from this software without specific prior written
29 permission.
30
31 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
32 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
35 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
37 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
43 Julian Seward, Cambridge, UK.
44 jseward@acm.org
45 bzip2/libbzip2 version 1.0 of 21 March 2000
46
47 This program is based on (at least) the work of:
48 Mike Burrows
49 David Wheeler
50 Peter Fenwick
51 Alistair Moffat