1b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Test the variable identification machinery in a non-toy sized
3b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   program.  Also, the croak() call in BZ2_decompress causes Valgrind
4b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   to try to describe a local variable (i) that has at least a dozen
5b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   independent live ranges (hence, is really that many independent
6b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   variables).  Hence it tests the machinery's ability to correctly
7b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   handle a variable which has multiple live ranges and hence multiple
8b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   non-overlapping areas in which it actually exists.
9b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
10b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
11b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Relevant compile flags are:
12b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
13b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   -Wall -g -I$prefix/include/valgrind
14b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   eg -Wall -g -I`pwd`/Inst/include/valgrind
16b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
17b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
18b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <stdio.h>
19b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <stdlib.h>
20b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <assert.h>
21b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "memcheck/memcheck.h"
22b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
23b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Cause memcheck to complain about the address "a" and so to print
24b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   its best guess as to what "a" actually is.  a must be
25b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   addressible. */
26b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
27b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid croak ( void* aV )
28b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
29b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  char* a = (char*)aV;
30b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  char* undefp = malloc(1);
31b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  char saved = *a;
32b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  assert(undefp);
33b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  *a = *undefp;
3406bc722457ffe12e056d2f40d0d2f5c8711b541fflorian  (void) VALGRIND_CHECK_MEM_IS_DEFINED(a, 1);
35b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  *a = saved;
36b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  free(undefp);
37b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
38b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// This benchmark is basically bzip2 (mashed to be a single file)
40b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// compressing and decompressing some data.  It tests Valgrind's handling of
41b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// realistic and "difficult" (ie. lots of branches and memory accesses)
42b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// integer code.  Execution is spread out over quite a few basic blocks;
43b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// --profile-flags indicates that to get to the top 90%th percentile of
44b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// dynamic BB counts requires considering the top 51 basic blocks
45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
46b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// This program can be used both as part of the performance test
47b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// suite, in which case we want it to run for quite a while,
48b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// and as part of the regression (correctness) test suite, in
49b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// which case we want it to run quickly and be verbose.
50b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// So it does the latter iff given a command line arg.
51b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// Licensing: the code within is mostly taken from bzip2, which has a BSD
53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// license.  There is a little code from VEX, which is licensed under GPLv2
54b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// And it's all written by Julian Seward.
55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
56b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_NO_STDIO
57b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
58b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
59b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
60b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Private header file for the library.                  ---*/
61b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                       bzlib_private.h ---*/
62b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
63b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
64b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
65b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
66b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
67b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
68b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
69b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
70b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
71b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
72b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
73b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
74b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
75b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
76b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
77b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
78b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
79b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
80b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
81b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
82b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
83b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
84b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
85b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
86b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
87b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
88b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
89b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
90b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
92b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
93b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
94b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
95b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
96b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
97b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
98b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef _BZLIB_PRIVATE_H
120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define _BZLIB_PRIVATE_H
121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <stdlib.h>
123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_NO_STDIO
125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <stdio.h>
126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <ctype.h>
127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <string.h>
128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Public header file for the library.                   ---*/
133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                               bzlib.h ---*/
134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef _BZLIB_H
192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define _BZLIB_H
193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifdef __cplusplus
195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern "C" {
196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RUN               0
199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_FLUSH             1
200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_FINISH            2
201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_OK                0
203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RUN_OK            1
204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_FLUSH_OK          2
205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_FINISH_OK         3
206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_STREAM_END        4
207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_SEQUENCE_ERROR    (-1)
208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_PARAM_ERROR       (-2)
209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_MEM_ERROR         (-3)
210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_DATA_ERROR        (-4)
211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_DATA_ERROR_MAGIC  (-5)
212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_IO_ERROR          (-6)
213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_UNEXPECTED_EOF    (-7)
214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_OUTBUFF_FULL      (-8)
215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_CONFIG_ERROR      (-9)
216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      char *next_in;
220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int avail_in;
221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int total_in_lo32;
222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int total_in_hi32;
223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      char *next_out;
225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int avail_out;
226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int total_out_lo32;
227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int total_out_hi32;
228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void *state;
230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void *(*bzalloc)(void *,int,int);
232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void (*bzfree)(void *,void *);
233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void *opaque;
234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bz_stream;
236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_IMPORT
239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_EXPORT
240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_NO_STDIO
243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Need a definitition for FILE */
244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <stdio.h>
245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifdef _WIN32
248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   include <windows.h>
249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   ifdef small
250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* windows.h define small to char */
251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#      undef small
252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   endif
253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   ifdef BZ_EXPORT
254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define BZ_API(func) WINAPI func
255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define BZ_EXTERN extern
256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   else
257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* import windows dll dynamically */
258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define BZ_API(func) (WINAPI * func)
259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define BZ_EXTERN
260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   endif
261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#else
262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define BZ_API(func) func
263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define BZ_EXTERN extern
264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Core (low-level) library functions --*/
268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream* strm,
271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int        blockSize100k,
272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int        verbosity,
273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int        workFactor
274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzCompress) (
277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream* strm,
278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int action
279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream* strm
283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream *strm,
287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int       verbosity,
288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int       small
289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzDecompress) (
292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream* strm
293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream *strm
297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- High(er) level library functions --*/
302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_NO_STDIO
304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_MAX_UNUSED 5000
305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef void BZFILE;
307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*  bzerror,
310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      FILE* f,
311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int   verbosity,
312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int   small,
313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void* unused,
314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int   nUnused
315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN void BZ_API(BZ2_bzReadClose) (
318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*    bzerror,
319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b
320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*    bzerror,
324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b,
325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void**  unused,
326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*    nUnused
327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzRead) (
330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*    bzerror,
331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b,
332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void*   buf,
333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int     len
334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*  bzerror,
338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      FILE* f,
339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int   blockSize100k,
340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int   verbosity,
341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int   workFactor
342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN void BZ_API(BZ2_bzWrite) (
345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*    bzerror,
346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b,
347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void*   buf,
348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int     len
349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*          bzerror,
353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE*       b,
354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int           abandon,
355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* nbytes_in,
356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* nbytes_out
357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int*          bzerror,
361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE*       b,
362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int           abandon,
363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* nbytes_in_lo32,
364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* nbytes_in_hi32,
365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* nbytes_out_lo32,
366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* nbytes_out_hi32
367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Utility functions --*/
372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      char*         dest,
375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* destLen,
376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      char*         source,
377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int  sourceLen,
378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int           blockSize100k,
379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int           verbosity,
380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int           workFactor
381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      char*         dest,
385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int* destLen,
386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      char*         source,
387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int  sourceLen,
388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int           small,
389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int           verbosity
390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Code contributed by Yoshioka Tsuneo
395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   to support better zlib compatibility.
397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This code is not _officially_ part of libbzip2 (yet);
398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   I haven't tested it, documented it, or considered the
399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   threading-safeness of it.
400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   If this code breaks, please contact both Yoshioka and me.
401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void
405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_NO_STDIO
408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      const char *path,
410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      const char *mode
411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int        fd,
415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      const char *mode
416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzread) (
419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b,
420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void* buf,
421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int len
422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzwrite) (
425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b,
426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      void*   buf,
427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int     len
428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN int BZ_API(BZ2_bzflush) (
431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b
432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN void BZ_API(BZ2_bzclose) (
435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE* b
436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ_EXTERN const char * BZ_API(BZ2_bzerror) (
439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZFILE *b,
440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      int    *errnum
441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   );
442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifdef __cplusplus
445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                           bzlib.h ---*/
452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- General stuff. --*/
458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_VERSION  "1.0.3, 17-Oct-2004"
460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef char            Char;
462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef unsigned char   Bool;
463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef unsigned char   UChar;
464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef int             Int32;
465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef unsigned int    UInt32;
466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef short           Int16;
467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef unsigned short  UInt16;
468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define True  ((Bool)1)
470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define False ((Bool)0)
471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef __GNUC__
473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define __inline__  /* */
474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_NO_STDIO
477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void BZ2_bz__AssertH__fail ( int errcode );
478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define AssertH(cond,errcode) \
479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if BZ_DEBUG
481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define AssertD(cond,msg) \
482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { if (!(cond)) {       \
483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fprintf ( stderr,   \
484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      exit(1); \
486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }}
487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#else
488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define AssertD(cond,msg) /* */
489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf0(zf) \
491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fprintf(stderr,zf)
492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf1(zf,za1) \
493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fprintf(stderr,zf,za1)
494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf2(zf,za1,za2) \
495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fprintf(stderr,zf,za1,za2)
496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf3(zf,za1,za2,za3) \
497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fprintf(stderr,zf,za1,za2,za3)
498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf4(zf,za1,za2,za3,za4) \
499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fprintf(stderr,zf,za1,za2,za3,za4)
500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fprintf(stderr,zf,za1,za2,za3,za4,za5)
502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#else
503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void bz_internal_error ( int errcode );
504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define AssertH(cond,errcode) \
505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { if (!(cond)) bz_internal_error ( errcode ); }
506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define AssertD(cond,msg) /* */
507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf0(zf) \
508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf(zf)
509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf1(zf,za1) \
510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf(zf,za1)
511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf2(zf,za1,za2) \
512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf(zf,za1,za2)
513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf3(zf,za1,za2,za3) \
514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf(zf,za1,za2,za3)
515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf4(zf,za1,za2,za3,za4) \
516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf(zf,za1,za2,za3,za4)
517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf(zf,za1,za2,za3,za4,za5)
519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Header bytes. --*/
527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_HDR_B 0x42   /* 'B' */
529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_HDR_Z 0x5a   /* 'Z' */
530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_HDR_h 0x68   /* 'h' */
531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_HDR_0 0x30   /* '0' */
532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Constants for the back end. --*/
534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_MAX_ALPHA_SIZE 258
536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_MAX_CODE_LEN    23
537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RUNA 0
539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RUNB 1
540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_N_GROUPS 6
542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_G_SIZE   50
543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_N_ITERS  4
544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Stuff for randomising repetitive blocks. --*/
550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern Int32 BZ2_rNums[512];
552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RAND_DECLS                          \
554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 rNToGo;                               \
555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 rTPos                                 \
556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RAND_INIT_MASK                      \
558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->rNToGo = 0;                              \
559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->rTPos  = 0                               \
560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_RAND_UPD_MASK                       \
564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->rNToGo == 0) {                       \
565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->rNToGo = BZ2_rNums[s->rTPos];         \
566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->rTPos++;                              \
567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->rTPos == 512) s->rTPos = 0;       \
568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                           \
569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->rNToGo--;
570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Stuff for doing CRCs. --*/
574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern UInt32 BZ2_crc32Table[256];
576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_INITIALISE_CRC(crcVar)              \
578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                              \
579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   crcVar = 0xffffffffL;                       \
580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_FINALISE_CRC(crcVar)                \
583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                              \
584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   crcVar = ~(crcVar);                         \
585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_UPDATE_CRC(crcVar,cha)              \
588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                              \
589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   crcVar = (crcVar << 8) ^                    \
590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ2_crc32Table[(crcVar >> 24) ^    \
591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           ((UChar)cha)];      \
592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- States and modes for compression. --*/
597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_M_IDLE      1
599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_M_RUNNING   2
600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_M_FLUSHING  3
601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_M_FINISHING 4
602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_S_OUTPUT    1
604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_S_INPUT     2
605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_N_RADIX 2
607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_N_QSORT 12
608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_N_SHELL 18
609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Structure holding all the compression-side stuff. --*/
615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* pointer back to the struct bz_stream */
619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream* strm;
620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* mode this stream is in, and whether inputting */
622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* or outputting data */
623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    mode;
624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    state;
625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* remembers avail_in when flush/finish requested */
627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   avail_in_expect;
628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* for doing the block sorting */
630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32*  arr1;
631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32*  arr2;
632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32*  ftab;
633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    origPtr;
634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* aliases for arr1 and arr2 */
636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32*  ptr;
637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar*   block;
638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt16*  mtfv;
639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar*   zbits;
640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* for deciding when to use the fallback sorting algorithm */
642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    workFactor;
643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* run-length-encoding of the input */
645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   state_in_ch;
646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    state_in_len;
647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ_RAND_DECLS;
648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* input and output limits and current posns */
650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    nblock;
651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    nblockMAX;
652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    numZ;
653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    state_out_pos;
654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* map of bytes used in block */
656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    nInUse;
657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool     inUse[256];
658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    unseqToSeq[256];
659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* the buffer for bit stream creation */
661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   bsBuff;
662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    bsLive;
663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* block and combined CRCs */
665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   blockCRC;
666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   combinedCRC;
667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* misc administratium */
669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    verbosity;
670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    blockNo;
671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    blockSize100k;
672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* stuff for coding the MTF values */
674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    nMTF;
675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    selector   [BZ_MAX_SELECTORS];
677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* second dimension: only 3 needed; 4 makes index calculations faster */
683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   EState;
687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- externs for compression. --*/
691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void
693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_blockSort ( EState* );
694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void
696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_compressBlock ( EState*, Bool );
697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void
699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_bsInitWrite ( EState* );
700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void
702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void
705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- states for decompression. --*/
710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_IDLE        1
712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_OUTPUT      2
713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MAGIC_1     10
715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MAGIC_2     11
716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MAGIC_3     12
717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MAGIC_4     13
718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BLKHDR_1    14
719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BLKHDR_2    15
720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BLKHDR_3    16
721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BLKHDR_4    17
722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BLKHDR_5    18
723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BLKHDR_6    19
724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BCRC_1      20
725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BCRC_2      21
726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BCRC_3      22
727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_BCRC_4      23
728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_RANDBIT     24
729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ORIGPTR_1   25
730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ORIGPTR_2   26
731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ORIGPTR_3   27
732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MAPPING_1   28
733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MAPPING_2   29
734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_SELECTOR_1  30
735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_SELECTOR_2  31
736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_SELECTOR_3  32
737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_CODING_1    33
738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_CODING_2    34
739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_CODING_3    35
740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MTF_1       36
741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MTF_2       37
742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MTF_3       38
743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MTF_4       39
744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MTF_5       40
745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_MTF_6       41
746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ENDHDR_2    42
747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ENDHDR_3    43
748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ENDHDR_4    44
749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ENDHDR_5    45
750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_ENDHDR_6    46
751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_CCRC_1      47
752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_CCRC_2      48
753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_CCRC_3      49
754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_X_CCRC_4      50
755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Constants for the fast MTF decoder. --*/
759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define MTFA_SIZE 4096
761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define MTFL_SIZE 16
762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Structure holding all the decompression-side stuff. --*/
766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* pointer back to the struct bz_stream */
770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream* strm;
771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* state indicator for this stream */
773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    state;
774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* for doing the final run-length decoding */
776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    state_out_ch;
777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    state_out_len;
778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool     blockRandomised;
779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ_RAND_DECLS;
780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* the buffer for bit stream reading */
782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   bsBuff;
783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    bsLive;
784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* misc administratium */
786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    blockSize100k;
787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool     smallDecompress;
788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    currBlockNo;
789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    verbosity;
790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* for undoing the Burrows-Wheeler transform */
792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    origPtr;
793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   tPos;
794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    k0;
795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    unzftab[256];
796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    nblock_used;
797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    cftab[257];
798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    cftabCopy[257];
799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* for undoing the Burrows-Wheeler transform (FAST) */
801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   *tt;
802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* for undoing the Burrows-Wheeler transform (SMALL) */
804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt16   *ll16;
805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    *ll4;
806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* stored and calculated CRCs */
808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   storedBlockCRC;
809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   storedCombinedCRC;
810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   calculatedBlockCRC;
811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32   calculatedCombinedCRC;
812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* map of bytes used in block */
814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    nInUse;
815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool     inUse[256];
816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool     inUse16[16];
817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    seqToUnseq[256];
818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* for decoding the MTF values */
820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    mtfa   [MTFA_SIZE];
821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    mtfbase[256 / MTFL_SIZE];
822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    selector   [BZ_MAX_SELECTORS];
823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    minLens[BZ_N_GROUPS];
830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* save area for scalars in the main decompress code */
832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_i;
833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_j;
834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_t;
835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_alphaSize;
836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_nGroups;
837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_nSelectors;
838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_EOB;
839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_groupNo;
840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_groupPos;
841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_nextSym;
842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_nblockMAX;
843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_nblock;
844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_es;
845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_N;
846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_curr;
847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_zt;
848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_zn;
849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_zvec;
850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_zj;
851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_gSel;
852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32    save_gMinlen;
853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32*   save_gLimit;
854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32*   save_gBase;
855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32*   save_gPerm;
856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DState;
859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- Macros for decompression. --*/
863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_GET_FAST(cccc)                     \
865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    s->tPos = s->tt[s->tPos];                 \
866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    cccc = (UChar)(s->tPos & 0xff);           \
867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    s->tPos >>= 8;
868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_GET_FAST_C(cccc)                   \
870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    c_tPos = c_tt[c_tPos];                    \
871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    cccc = (UChar)(c_tPos & 0xff);            \
872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    c_tPos >>= 8;
873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define SET_LL4(i,n)                                          \
875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { if (((i) & 0x1) == 0)                                    \
876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define GET_LL4(i)                             \
881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define SET_LL(i,n)                          \
884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     SET_LL4(i, n >> 16);                    \
886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define GET_LL(i) \
889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_GET_SMALL(cccc)                            \
892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->tPos = GET_LL(s->tPos);
894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- externs for decompression. --*/
897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern Int32
899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_indexIntoF ( Int32, Int32* );
900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern Int32
902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_decompress ( DState* );
903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjextern void
905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           Int32,  Int32, Int32 );
907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifdef BZ_NO_STDIO
915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef NULL
916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define NULL 0
917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                   bzlib_private.h ---*/
923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Something which has the same size as void* on the host.  That is,
927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   it is 32 bits on a 32-bit host and 64 bits on a 64-bit host, and so
928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   it can safely be coerced to and from a pointer type on the host
929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   machine. */
930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef  unsigned long HWord;
931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef  char          HChar;
932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef  signed int    Int;
933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef  unsigned int  UInt;
934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef    signed long long int   Long;
936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef  unsigned long long int   ULong;
937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic HWord (*serviceFn)(HWord,HWord) = 0;
943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic char* my_strcpy ( char* dest, const char* src )
946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   char* dest_orig = dest;
948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (*src) *dest++ = *src++;
949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *dest = 0;
950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return dest_orig;
951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void* my_memcpy ( void *dest, const void *src, int sz )
954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   const char *s = (const char *)src;
956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   char *d = (char *)dest;
957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (sz--)
959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *d++ = *s++;
960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return dest;
962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void* my_memmove( void *dst, const void *src, unsigned int len )
965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    register char *d;
967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    register char *s;
968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    if ( dst > src ) {
969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        d = (char *)dst + len - 1;
970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        s = (char *)src + len - 1;
971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        while ( len >= 4 ) {
972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d-- = *s--;
973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d-- = *s--;
974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d-- = *s--;
975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d-- = *s--;
976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            len -= 4;
977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        }
978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        while ( len-- ) {
979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d-- = *s--;
980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        }
981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    } else if ( dst < src ) {
982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        d = (char *)dst;
983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        s = (char *)src;
984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        while ( len >= 4 ) {
985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d++ = *s++;
986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d++ = *s++;
987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d++ = *s++;
988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d++ = *s++;
989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            len -= 4;
990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        }
991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        while ( len-- ) {
992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *d++ = *s++;
993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        }
994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    }
995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    return dst;
996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjchar* my_strcat ( char* dest, const char* src )
1000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   char* dest_orig = dest;
1002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (*dest) dest++;
1003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (*src) *dest++ = *src++;
1004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *dest = 0;
1005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return dest_orig;
1006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
1010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void vex_log_bytes ( char* p, int n )
1012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int i;
1014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < n; i++)
1015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (*serviceFn)( 1, (int)p[i] );
1016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------------*/
1019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- vex_printf                                        ---*/
1020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------------*/
1021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* This should be the only <...> include in the entire VEX library.
1023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   New code for vex_util.c should go above this point. */
1024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <stdarg.h>
1025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic HChar vex_toupper ( HChar c )
1027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c >= 'a' && c <= 'z')
1029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return c + ('A' - 'a');
1030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else
1031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return c;
1032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Int vex_strlen ( const HChar* str )
1035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int i = 0;
1037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (str[i] != 0) i++;
1038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return i;
1039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool vex_streq ( const HChar* s1, const HChar* s2 )
1042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
1044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (*s1 == 0 && *s2 == 0)
1045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return True;
1046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (*s1 != *s2)
1047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return False;
1048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1++;
1049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s2++;
1050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Some flags.  */
1054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VG_MSG_SIGNED    1 /* The value is signed. */
1055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VG_MSG_ZJUSTIFY  2 /* Must justify with '0'. */
1056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VG_MSG_LJUSTIFY  4 /* Must justify on the left. */
1057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VG_MSG_PAREN     8 /* Parenthesize if present (for %y) */
1058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define VG_MSG_COMMA    16 /* Add commas to numbers (for %d, %u) */
1059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Copy a string into the buffer. */
1061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UInt
1062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjmyvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
1063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                Bool capitalise )
1064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#  define MAYBE_TOUPPER(ch) (capitalise ? vex_toupper(ch) : (ch))
1066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt ret = 0;
1067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int i, extra;
1068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int len = vex_strlen(str);
1069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (width == 0) {
1071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ret += len;
1072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < len; i++)
1073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         send(MAYBE_TOUPPER(str[i]));
1074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return ret;
1075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (len > width) {
1078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ret += width;
1079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < width; i++)
1080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         send(MAYBE_TOUPPER(str[i]));
1081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return ret;
1082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   extra = width - len;
1085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (flags & VG_MSG_LJUSTIFY) {
1086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ret += extra;
1087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < extra; i++)
1088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         send(' ');
1089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret += len;
1091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < len; i++)
1092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      send(MAYBE_TOUPPER(str[i]));
1093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!(flags & VG_MSG_LJUSTIFY)) {
1094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ret += extra;
1095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < extra; i++)
1096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         send(' ');
1097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#  undef MAYBE_TOUPPER
1100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return ret;
1102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Write P into the buffer according to these args:
1105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *  If SIGN is true, p is a signed.
1106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *  BASE is the base.
1107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *  If WITH_ZERO is true, '0' must be added.
1108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj *  WIDTH is the width of the field.
1109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj */
1110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UInt
1111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjmyvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
1112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   HChar buf[40];
1114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int   ind = 0;
1115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int   i, nc = 0;
1116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool  neg = False;
1117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   HChar *digits = "0123456789ABCDEF";
1118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt  ret = 0;
1119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt  p = (UInt)pL;
1120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (base < 2 || base > 16)
1122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return ret;
1123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
1125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      p   = - (Int)p;
1126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      neg = True;
1127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (p == 0)
1130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      buf[ind++] = '0';
1131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else {
1132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (p > 0) {
1133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if ((flags & VG_MSG_COMMA) && 10 == base &&
1134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             0 == (ind-nc) % 3 && 0 != ind)
1135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         {
1136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            buf[ind++] = ',';
1137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            nc++;
1138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         buf[ind++] = digits[p % base];
1140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         p /= base;
1141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (neg)
1145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      buf[ind++] = '-';
1146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
1148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for(; ind < width; ind++) {
1149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	//vassert(ind < 39);
1150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         buf[ind] = ((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
1151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Reverse copy to buffer.  */
1155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret += ind;
1156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = ind -1; i >= 0; i--) {
1157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      send(buf[i]);
1158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
1160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for(; ind < width; ind++) {
1161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 ret++;
1162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         send(' ');  // Never pad with zeroes on RHS -- changes the value!
1163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return ret;
1166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* A simple vprintf().  */
1170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjUInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
1172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt ret = 0;
1174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int i;
1175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int flags;
1176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int width;
1177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool is_long;
1178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We assume that vargs has already been initialised by the
1180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      caller, using va_start, and that the caller will similarly
1181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      clean up with va_end.
1182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   */
1183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; format[i] != 0; i++) {
1185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (format[i] != '%') {
1186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         send(format[i]);
1187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 ret++;
1188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
1189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i++;
1191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* A '%' has been found.  Ignore a trailing %. */
1192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (format[i] == 0)
1193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (format[i] == '%') {
1195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* `%%' is replaced by `%'. */
1196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         send('%');
1197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 ret++;
1198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
1199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      flags = 0;
1201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      is_long = False;
1202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      width = 0; /* length of the field. */
1203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (format[i] == '(') {
1204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 flags |= VG_MSG_PAREN;
1205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 i++;
1206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* If ',' follows '%', commas will be inserted. */
1208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (format[i] == ',') {
1209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         flags |= VG_MSG_COMMA;
1210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i++;
1211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* If '-' follows '%', justify on the left. */
1213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (format[i] == '-') {
1214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         flags |= VG_MSG_LJUSTIFY;
1215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i++;
1216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* If '0' follows '%', pads will be inserted. */
1218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (format[i] == '0') {
1219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         flags |= VG_MSG_ZJUSTIFY;
1220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i++;
1221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Compute the field length. */
1223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (format[i] >= '0' && format[i] <= '9') {
1224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         width *= 10;
1225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         width += format[i++] - '0';
1226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (format[i] == 'l') {
1228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i++;
1229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         is_long = True;
1230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      switch (format[i]) {
1233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'd': /* %d */
1234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            flags |= VG_MSG_SIGNED;
1235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (is_long)
1236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ret += myvprintf_int64(send, flags, 10, width,
1237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj				      (ULong)(va_arg (vargs, Long)));
1238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            else
1239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ret += myvprintf_int64(send, flags, 10, width,
1240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj				      (ULong)(va_arg (vargs, Int)));
1241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
1242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'u': /* %u */
1243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (is_long)
1244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ret += myvprintf_int64(send, flags, 10, width,
1245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj				      (ULong)(va_arg (vargs, ULong)));
1246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            else
1247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ret += myvprintf_int64(send, flags, 10, width,
1248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj				      (ULong)(va_arg (vargs, UInt)));
1249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
1250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'p': /* %p */
1251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	    ret += 2;
1252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            send('0');
1253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            send('x');
1254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ret += myvprintf_int64(send, flags, 16, width,
1255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj				   (ULong)((HWord)va_arg (vargs, void *)));
1256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
1257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'x': /* %x */
1258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (is_long)
1259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ret += myvprintf_int64(send, flags, 16, width,
1260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj				      (ULong)(va_arg (vargs, ULong)));
1261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            else
1262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ret += myvprintf_int64(send, flags, 16, width,
1263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj				      (ULong)(va_arg (vargs, UInt)));
1264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
1265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'c': /* %c */
1266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	    ret++;
1267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            send((va_arg (vargs, int)));
1268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
1269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 's': case 'S': { /* %s */
1270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            char *str = va_arg (vargs, char *);
1271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (str == (char*) 0) str = "(null)";
1272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ret += myvprintf_str(send, flags, width, str,
1273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                 (format[i]=='S'));
1274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
1275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 }
1276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#        if 0
1277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 case 'y': { /* %y - print symbol */
1278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	    Addr a = va_arg(vargs, Addr);
1279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
128046cc04521acf2827eb33310fadc119bf2dc039e4florian
128146cc04521acf2827eb33310fadc119bf2dc039e4florian
128246cc04521acf2827eb33310fadc119bf2dc039e4florian            HChar *name;
128346cc04521acf2827eb33310fadc119bf2dc039e4florian	    if (VG_(get_fnname_w_offset)(a, &name)) {
128446cc04521acf2827eb33310fadc119bf2dc039e4florian               HChar buf[1 + VG_strlen(name) + 1 + 1];
1285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	       if (flags & VG_MSG_PAREN) {
128646cc04521acf2827eb33310fadc119bf2dc039e4florian                  VG_(sprintf)(str, "(%s)", name):
128746cc04521acf2827eb33310fadc119bf2dc039e4florian	       } else {
128846cc04521acf2827eb33310fadc119bf2dc039e4florian                  VG_(sprintf)(str, "%s", name):
128946cc04521acf2827eb33310fadc119bf2dc039e4florian               }
1290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	       ret += myvprintf_str(send, flags, width, buf, 0);
1291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	    }
1292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	    break;
1293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 }
1294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#        endif
1295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         default:
1296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
1297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return ret;
1300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* A general replacement for printf().  Note that only low-level
1304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   debugging info should be sent via here.  The official route is to
1305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   to use vg_message().  This interface is deprecated.
1306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
1307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic HChar myprintf_buf[1000];
1308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Int   n_myprintf_buf;
1309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void add_to_myprintf_buf ( HChar c )
1311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
1313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) );
1314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      n_myprintf_buf = 0;
1315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      myprintf_buf[n_myprintf_buf] = 0;
1316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   myprintf_buf[n_myprintf_buf++] = c;
1318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   myprintf_buf[n_myprintf_buf] = 0;
1319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UInt vex_printf ( const char *format, ... )
1322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt ret;
1324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   va_list vargs;
1325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   va_start(vargs,format);
1326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   n_myprintf_buf = 0;
1328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   myprintf_buf[n_myprintf_buf] = 0;
1329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
1330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (n_myprintf_buf > 0) {
1332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (*vex_log_bytes)( myprintf_buf, n_myprintf_buf );
1333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   va_end(vargs);
1336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return ret;
1338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------------------*/
1341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                          vex_util.c ---*/
1342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------------------*/
1343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
1346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
1347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
1348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
1349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
1352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Decompression machinery                               ---*/
1353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                          decompress.c ---*/
1354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
1355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
1357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
1358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
1359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
1361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
1363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
1364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
1365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
1367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
1368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
1370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
1371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
1372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
1373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
1375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
1376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
1378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
1379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
1380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
1394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
1395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
1396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
1398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
1399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
1400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
1401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
1402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
1403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
1404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
1405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
1406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
1408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
1409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
1414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid makeMaps_d ( DState* s )
1416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 i;
1418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->nInUse = 0;
1419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < 256; i++)
1420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->inUse[i]) {
1421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->seqToUnseq[s->nInUse] = i;
1422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->nInUse++;
1423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
1428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define RETURN(rrr)                               \
1429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { retVal = rrr; goto save_state_and_return; };
1430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define GET_BITS(lll,vvv,nnn)                     \
1432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   case lll: s->state = lll;                      \
1433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {                                 \
1434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->bsLive >= nnn) {                     \
1435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UInt32 v;                                \
1436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         v = (s->bsBuff >>                        \
1437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
1438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->bsLive -= nnn;                        \
1439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vvv = v;                                 \
1440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;                                   \
1441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }                                           \
1442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
1443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->bsBuff                                   \
1444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         = (s->bsBuff << 8) |                     \
1445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           ((UInt32)                              \
1446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              (*((UChar*)(s->strm->next_in))));   \
1447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->bsLive += 8;                             \
1448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->next_in++;                         \
1449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->avail_in--;                        \
1450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->total_in_lo32++;                   \
1451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->strm->total_in_lo32 == 0)            \
1452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->total_in_hi32++;                \
1453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define GET_UCHAR(lll,uuu)                        \
1456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GET_BITS(lll,uuu,8)
1457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define GET_BIT(lll,uuu)                          \
1459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GET_BITS(lll,uuu,1)
1460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
1462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define GET_MTF_VAL(label1,label2,lval)           \
1463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                                 \
1464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (groupPos == 0) {                           \
1465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      groupNo++;                                  \
1466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (groupNo >= nSelectors)                  \
1467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         RETURN(BZ_DATA_ERROR);                   \
1468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      groupPos = BZ_G_SIZE;                       \
1469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gSel = s->selector[groupNo];                \
1470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gMinlen = s->minLens[gSel];                 \
1471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gLimit = &(s->limit[gSel][0]);              \
1472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gPerm = &(s->perm[gSel][0]);                \
1473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gBase = &(s->base[gSel][0]);                \
1474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                              \
1475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   groupPos--;                                    \
1476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zn = gMinlen;                                  \
1477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GET_BITS(label1, zvec, zn);                    \
1478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (1) {                                    \
1479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (zn > 20 /* the longest code */)         \
1480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         RETURN(BZ_DATA_ERROR);                   \
1481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (zvec <= gLimit[zn]) break;              \
1482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zn++;                                       \
1483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_BIT(label2, zj);                        \
1484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zvec = (zvec << 1) | zj;                    \
1485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   };                                             \
1486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (zvec - gBase[zn] < 0                       \
1487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
1488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      RETURN(BZ_DATA_ERROR);                      \
1489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   lval = gPerm[zvec - gBase[zn]];                \
1490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
1495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjInt32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
1496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nb, na, mid;
1498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nb = 0;
1499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   na = 256;
1500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
1501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mid = (nb + na) >> 1;
1502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (indx >= cftab[mid]) nb = mid; else na = mid;
1503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (na - nb != 1);
1505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return nb;
1506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
1509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjInt32 BZ2_decompress ( DState* s )
1510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar      uc;
1512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32      retVal;
1513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32      minLen, maxLen;
1514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bz_stream* strm = s->strm;
1515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* stuff that needs to be saved/restored */
1517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  i;
1518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  j;
1519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  t;
1520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  alphaSize;
1521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  nGroups;
1522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  nSelectors;
1523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  EOB;
1524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  groupNo;
1525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  groupPos;
1526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  nextSym;
1527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  nblockMAX;
1528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  nblock;
1529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  es;
1530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  N;
1531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  curr;
1532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  zt;
1533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  zn;
1534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  zvec;
1535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  zj;
1536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  gSel;
1537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  gMinlen;
1538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32* gLimit;
1539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32* gBase;
1540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32* gPerm;
1541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->state == BZ_X_MAGIC_1) {
1543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*initialise the save area*/
1544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_i           = 0;
1545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_j           = 0;
1546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_t           = 0;
1547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_alphaSize   = 0;
1548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_nGroups     = 0;
1549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_nSelectors  = 0;
1550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_EOB         = 0;
1551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_groupNo     = 0;
1552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_groupPos    = 0;
1553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_nextSym     = 0;
1554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_nblockMAX   = 0;
1555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_nblock      = 0;
1556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_es          = 0;
1557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_N           = 0;
1558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_curr        = 0;
1559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_zt          = 0;
1560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_zn          = 0;
1561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_zvec        = 0;
1562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_zj          = 0;
1563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_gSel        = 0;
1564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_gMinlen     = 0;
1565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_gLimit      = NULL;
1566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_gBase       = NULL;
1567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->save_gPerm       = NULL;
1568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*restore from the save area*/
1571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i           = s->save_i;
1572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   j           = s->save_j;
1573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   t           = s->save_t;
1574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   alphaSize   = s->save_alphaSize;
1575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nGroups     = s->save_nGroups;
1576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nSelectors  = s->save_nSelectors;
1577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   EOB         = s->save_EOB;
1578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   groupNo     = s->save_groupNo;
1579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   groupPos    = s->save_groupPos;
1580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nextSym     = s->save_nextSym;
1581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nblockMAX   = s->save_nblockMAX;
1582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nblock      = s->save_nblock;
1583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   es          = s->save_es;
1584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   N           = s->save_N;
1585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   curr        = s->save_curr;
1586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zt          = s->save_zt;
1587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zn          = s->save_zn;
1588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zvec        = s->save_zvec;
1589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zj          = s->save_zj;
1590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   gSel        = s->save_gSel;
1591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   gMinlen     = s->save_gMinlen;
1592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   gLimit      = s->save_gLimit;
1593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   gBase       = s->save_gBase;
1594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   gPerm       = s->save_gPerm;
1595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   retVal = BZ_OK;
1597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   switch (s->state) {
1599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_MAGIC_1, uc);
1601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
1602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_MAGIC_2, uc);
1604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
1605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_MAGIC_3, uc)
1607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
1608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
1610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->blockSize100k < (BZ_HDR_0 + 1) ||
1611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
1612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->blockSize100k -= BZ_HDR_0;
1613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->smallDecompress) {
1615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
1616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->ll4  = BZALLOC(
1617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
1618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   );
1619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
1620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
1622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
1623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BLKHDR_1, uc);
1626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc == 0x17) goto endhdr_2;
1628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
1629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BLKHDR_2, uc);
1630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
1631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BLKHDR_3, uc);
1632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
1633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BLKHDR_4, uc);
1634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
1635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BLKHDR_5, uc);
1636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
1637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BLKHDR_6, uc);
1638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
1639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->currBlockNo++;
1641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->verbosity >= 2)
1642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
1643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedBlockCRC = 0;
1645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BCRC_1, uc);
1646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BCRC_2, uc);
1648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BCRC_3, uc);
1650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_BCRC_4, uc);
1652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
1655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->origPtr = 0;
1657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
1658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
1660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
1662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->origPtr < 0)
1665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         RETURN(BZ_DATA_ERROR);
1666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->origPtr > 10 + 100000*s->blockSize100k)
1667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         RETURN(BZ_DATA_ERROR);
1668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--- Receive the mapping table ---*/
1670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < 16; i++) {
1671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         GET_BIT(BZ_X_MAPPING_1, uc);
1672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (uc == 1)
1673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->inUse16[i] = True; else
1674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->inUse16[i] = False;
1675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < 256; i++) s->inUse[i] = False;
1678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < 16; i++)
1680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->inUse16[i])
1681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (j = 0; j < 16; j++) {
1682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               GET_BIT(BZ_X_MAPPING_2, uc);
1683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (uc == 1) s->inUse[i * 16 + j] = True;
1684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      makeMaps_d ( s );
1686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
1687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      alphaSize = s->nInUse+2;
1688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--- Now the selectors ---*/
1690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
1691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
1692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
1693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
1694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < nSelectors; i++) {
1695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = 0;
1696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
1697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            GET_BIT(BZ_X_SELECTOR_3, uc);
1698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (uc == 0) break;
1699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjcroak( 2 + (char*)&i );
1700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j++;
1701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
1702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->selectorMtf[i] = j;
1704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--- Undo the MTF values for the selectors. ---*/
1707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      {
1708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar pos[BZ_N_GROUPS], tmp, v;
1709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (v = 0; v < nGroups; v++) pos[v] = v;
1710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = 0; i < nSelectors; i++) {
1712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            v = s->selectorMtf[i];
1713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tmp = pos[v];
1714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (v > 0) { pos[v] = pos[v-1]; v--; }
1715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            pos[0] = tmp;
1716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->selector[i] = tmp;
1717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--- Now the coding tables ---*/
1721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (t = 0; t < nGroups; t++) {
1722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         GET_BITS(BZ_X_CODING_1, curr, 5);
1723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = 0; i < alphaSize; i++) {
1724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (True) {
1725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
1726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               GET_BIT(BZ_X_CODING_2, uc);
1727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (uc == 0) break;
1728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               GET_BIT(BZ_X_CODING_3, uc);
1729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (uc == 0) curr++; else curr--;
1730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->len[t][i] = curr;
1732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--- Create the Huffman decoding tables ---*/
1736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (t = 0; t < nGroups; t++) {
1737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         minLen = 32;
1738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         maxLen = 0;
1739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = 0; i < alphaSize; i++) {
1740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
1741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->len[t][i] < minLen) minLen = s->len[t][i];
1742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ2_hbCreateDecodeTables (
1744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            &(s->limit[t][0]),
1745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            &(s->base[t][0]),
1746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            &(s->perm[t][0]),
1747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            &(s->len[t][0]),
1748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            minLen, maxLen, alphaSize
1749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         );
1750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->minLens[t] = minLen;
1751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--- Now the MTF values ---*/
1754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      EOB      = s->nInUse+1;
1756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nblockMAX = 100000 * s->blockSize100k;
1757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      groupNo  = -1;
1758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      groupPos = 0;
1759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
1761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- MTF init --*/
1763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      {
1764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Int32 ii, jj, kk;
1765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         kk = MTFA_SIZE-1;
1766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
1767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
1768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
1769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               kk--;
1770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->mtfbase[ii] = kk + 1;
1772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- end MTF init --*/
1775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nblock = 0;
1777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
1778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nextSym == EOB) break;
1782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
1784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            es = -1;
1786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            N = 1;
1787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            do {
1788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
1789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
1790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               N = N * 2;
1791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
1792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
1794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            es++;
1796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
1797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->unzftab[uc] += es;
1798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->smallDecompress)
1800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               while (es > 0) {
1801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->ll16[nblock] = (UInt16)uc;
1803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  nblock++;
1804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  es--;
1805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
1806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            else
1807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               while (es > 0) {
1808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->tt[nblock] = (UInt32)uc;
1810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  nblock++;
1811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  es--;
1812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               };
1813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            continue;
1815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
1817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            /*-- uc = MTF ( nextSym-1 ) --*/
1821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            {
1822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               Int32 ii, jj, kk, pp, lno, off;
1823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               UInt32 nn;
1824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               nn = (UInt32)(nextSym - 1);
1825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (nn < MTFL_SIZE) {
1827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  /* avoid general-case expense */
1828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  pp = s->mtfbase[0];
1829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  uc = s->mtfa[pp+nn];
1830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  while (nn > 3) {
1831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     Int32 z = pp+nn;
1832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
1833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
1834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
1835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
1836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     nn -= 4;
1837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  }
1838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  while (nn > 0) {
1839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
1840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  };
1841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->mtfa[pp] = uc;
1842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               } else {
1843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  /* general case */
1844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  lno = nn / MTFL_SIZE;
1845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  off = nn % MTFL_SIZE;
1846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  pp = s->mtfbase[lno] + off;
1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  uc = s->mtfa[pp];
1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  while (pp > s->mtfbase[lno]) {
1849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfa[pp] = s->mtfa[pp-1]; pp--;
1850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  };
1851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->mtfbase[lno]++;
1852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  while (lno > 0) {
1853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfbase[lno]--;
1854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s->mtfa[s->mtfbase[lno]]
1855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
1856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     lno--;
1857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  }
1858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->mtfbase[0]--;
1859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->mtfa[s->mtfbase[0]] = uc;
1860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  if (s->mtfbase[0] == 0) {
1861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     kk = MTFA_SIZE-1;
1862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
1863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
1864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
1865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           kk--;
1866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        }
1867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        s->mtfbase[ii] = kk + 1;
1868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     }
1869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  }
1870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
1871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            /*-- end uc = MTF ( nextSym-1 ) --*/
1873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->unzftab[s->seqToUnseq[uc]]++;
1875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->smallDecompress)
1876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
1877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
1878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            nblock++;
1879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
1881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            continue;
1882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Now we know what nblock is, we can do a better sanity
1886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         check on s->origPtr.
1887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
1888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->origPtr < 0 || s->origPtr >= nblock)
1889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         RETURN(BZ_DATA_ERROR);
1890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- Set up cftab to facilitate generation of T^(-1) --*/
1892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->cftab[0] = 0;
1893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
1894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
1895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i <= 256; i++) {
1896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
1897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            /* s->cftab[i] can legitimately be == nblock */
1898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            RETURN(BZ_DATA_ERROR);
1899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->state_out_len = 0;
1903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->state_out_ch  = 0;
1904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
1905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->state = BZ_X_OUTPUT;
1906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
1907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->smallDecompress) {
1909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- Make a copy of cftab, used in generation of T --*/
1911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
1912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- compute the T vector --*/
1914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = 0; i < nblock; i++) {
1915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            uc = (UChar)(s->ll16[i]);
1916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            SET_LL(i, s->cftabCopy[uc]);
1917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->cftabCopy[uc]++;
1918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- Compute T^(-1) by pointer reversal on T --*/
1921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i = s->origPtr;
1922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = GET_LL(i);
1923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         do {
1924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Int32 tmp = GET_LL(j);
1925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            SET_LL(j, i);
1926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            i = j;
1927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j = tmp;
1928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (i != s->origPtr);
1930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->tPos = s->origPtr;
1932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->nblock_used = 0;
1933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->blockRandomised) {
1934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_RAND_INIT_MASK;
1935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
1936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
1937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
1938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
1939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- compute the T^(-1) vector --*/
1944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = 0; i < nblock; i++) {
1945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            uc = (UChar)(s->tt[i] & 0xff);
1946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->tt[s->cftab[uc]] |= (i << 8);
1947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->cftab[uc]++;
1948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->tPos = s->tt[s->origPtr] >> 8;
1951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->nblock_used = 0;
1952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->blockRandomised) {
1953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_RAND_INIT_MASK;
1954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
1955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
1956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
1957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
1958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      RETURN(BZ_OK);
1963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj    endhdr_2:
1967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ENDHDR_2, uc);
1969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
1970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ENDHDR_3, uc);
1971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
1972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ENDHDR_4, uc);
1973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
1974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ENDHDR_5, uc);
1975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
1976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_ENDHDR_6, uc);
1977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
1978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedCombinedCRC = 0;
1980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_CCRC_1, uc);
1981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_CCRC_2, uc);
1983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_CCRC_3, uc);
1985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GET_UCHAR(BZ_X_CCRC_4, uc);
1987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->state = BZ_X_IDLE;
1990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      RETURN(BZ_STREAM_END);
1991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      default: AssertH ( False, 4001 );
1993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH ( False, 4002 );
1996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   save_state_and_return:
1998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_i           = i;
2000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_j           = j;
2001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_t           = t;
2002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_alphaSize   = alphaSize;
2003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_nGroups     = nGroups;
2004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_nSelectors  = nSelectors;
2005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_EOB         = EOB;
2006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_groupNo     = groupNo;
2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_groupPos    = groupPos;
2008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_nextSym     = nextSym;
2009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_nblockMAX   = nblockMAX;
2010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_nblock      = nblock;
2011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_es          = es;
2012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_N           = N;
2013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_curr        = curr;
2014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_zt          = zt;
2015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_zn          = zn;
2016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_zvec        = zvec;
2017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_zj          = zj;
2018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_gSel        = gSel;
2019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_gMinlen     = gMinlen;
2020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_gLimit      = gLimit;
2021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_gBase       = gBase;
2022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->save_gPerm       = gPerm;
2023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return retVal;
2025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                      decompress.c ---*/
2030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
2033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Block sorting machinery                               ---*/
2034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                           blocksort.c ---*/
2035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
2036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
2038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
2039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
2040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
2042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
2044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
2045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
2046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
2048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
2049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
2051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
2052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
2053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
2054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
2056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
2057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
2059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
2060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
2061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
2063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
2075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
2076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
2077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
2079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
2080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
2081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
2082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
2083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
2084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
2085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
2086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
2087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
2089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  To get some idea how the block sorting algorithms in this file
2091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  work, read my paper
2092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     On the Performance of BWT Sorting Algorithms
2093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  in Proceedings of the IEEE Data Compression Conference 2000,
2094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
2095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  file implements the algorithm called  cache  in the paper.
2096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
2097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Fallback O(N log(N)^2) sorting        ---*/
2102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- algorithm, for repetitive blocks      ---*/
2103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid fallbackSimpleSort ( UInt32* fmap,
2108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          UInt32* eclass,
2109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          Int32   lo,
2110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          Int32   hi )
2111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 i, j, tmp;
2113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt32 ec_tmp;
2114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (lo == hi) return;
2116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (hi - lo > 3) {
2118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for ( i = hi-4; i >= lo; i-- ) {
2119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tmp = fmap[i];
2120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ec_tmp = eclass[tmp];
2121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            fmap[j-4] = fmap[j];
2123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fmap[j-4] = tmp;
2124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for ( i = hi-1; i >= lo; i-- ) {
2128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      tmp = fmap[i];
2129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ec_tmp = eclass[tmp];
2130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
2131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fmap[j-1] = fmap[j];
2132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fmap[j-1] = tmp;
2133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define fswap(zz1, zz2) \
2139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
2140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define fvswap(zzp1, zzp2, zzn)       \
2142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                     \
2143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 yyp1 = (zzp1);               \
2144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 yyp2 = (zzp2);               \
2145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 yyn  = (zzn);                \
2146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (yyn > 0) {                  \
2147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fswap(fmap[yyp1], fmap[yyp2]);  \
2148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      yyp1++; yyp2++; yyn--;          \
2149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                  \
2150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define fmin(a,b) ((a) < (b)) ? (a) : (b)
2154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define fpush(lz,hz) { stackLo[sp] = lz; \
2156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       stackHi[sp] = hz; \
2157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       sp++; }
2158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define fpop(lz,hz) { sp--;              \
2160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      lz = stackLo[sp];  \
2161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      hz = stackHi[sp]; }
2162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define FALLBACK_QSORT_SMALL_THRESH 10
2164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define FALLBACK_QSORT_STACK_SIZE   100
2165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid fallbackQSort3 ( UInt32* fmap,
2169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      UInt32* eclass,
2170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      Int32   loSt,
2171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      Int32   hiSt )
2172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 unLo, unHi, ltLo, gtHi, n, m;
2174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 sp, lo, hi;
2175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt32 med, r, r3;
2176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
2177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
2178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   r = 0;
2180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   sp = 0;
2182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fpush ( loSt, hiSt );
2183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (sp > 0) {
2185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
2187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fpop ( lo, hi );
2189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
2190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fallbackSimpleSort ( fmap, eclass, lo, hi );
2191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
2192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Random partitioning.  Median of 3 sometimes fails to
2195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         avoid bad cases.  Median of 9 seems to help but
2196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         looks rather expensive.  This too seems to work but
2197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         is cheaper.  Guidance for the magic constants
2198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         7621 and 32768 is taken from Sedgewick's algorithms
2199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         book, chapter 35.
2200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
2201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      r = ((r * 7621) + 1) % 32768;
2202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      r3 = r % 3;
2203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (r3 == 0) med = eclass[fmap[lo]]; else
2204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
2205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   med = eclass[fmap[hi]];
2206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unLo = ltLo = lo;
2208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unHi = gtHi = hi;
2209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (1) {
2211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (1) {
2212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (unLo > unHi) break;
2213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
2214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n == 0) {
2215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               fswap(fmap[unLo], fmap[ltLo]);
2216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ltLo++; unLo++;
2217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               continue;
2218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            };
2219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n > 0) break;
2220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            unLo++;
2221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (1) {
2223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (unLo > unHi) break;
2224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
2225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n == 0) {
2226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               fswap(fmap[unHi], fmap[gtHi]);
2227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               gtHi--; unHi--;
2228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               continue;
2229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            };
2230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n < 0) break;
2231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            unHi--;
2232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (unLo > unHi) break;
2234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
2235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
2238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (gtHi < ltLo) continue;
2240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
2242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
2243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      n = lo + unLo - ltLo - 1;
2245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      m = hi - (gtHi - unHi) + 1;
2246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (n - lo > hi - m) {
2248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fpush ( lo, n );
2249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fpush ( m, hi );
2250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
2251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fpush ( m, hi );
2252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fpush ( lo, n );
2253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef fmin
2258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef fpush
2259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef fpop
2260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef fswap
2261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef fvswap
2262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef FALLBACK_QSORT_SMALL_THRESH
2263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef FALLBACK_QSORT_STACK_SIZE
2264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Pre:
2268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nblock > 0
2269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      eclass exists for [0 .. nblock-1]
2270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
2271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr exists for [0 .. nblock-1]
2272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Post:
2274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
2275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      All other areas of eclass destroyed
2276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fmap [0 .. nblock-1] holds sorted order
2277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bhtab [ 0 .. 2+(nblock/32) ] destroyed
2278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
2279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
2281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
2282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
2283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define      WORD_BH(zz)  bhtab[(zz) >> 5]
2284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
2285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid fallbackSort ( UInt32* fmap,
2288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    UInt32* eclass,
2289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    UInt32* bhtab,
2290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    Int32   nblock,
2291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    Int32   verb )
2292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 ftab[257];
2294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 ftabCopy[256];
2295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 H, i, j, k, l, r, cc, cc1;
2296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nNotDone;
2297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nBhtab;
2298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar* eclass8 = (UChar*)eclass;
2299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--
2301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Initial 1-char radix sort to generate
2302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      initial fmap and initial BH bits.
2303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   --*/
2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (verb >= 4)
2305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VPrintf0 ( "        bucket sorting ...\n" );
2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < 257;    i++) ftab[i] = 0;
2307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < nblock; i++) {
2312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = eclass8[i];
2313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      k = ftab[j] - 1;
2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[j] = k;
2315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fmap[k] = i;
2316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nBhtab = 2 + (nblock / 32);
2319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
2320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
2321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--
2323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Inductively refine the buckets.  Kind-of an
2324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      "exponential radix sort" (!), inspired by the
2325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Manber-Myers suffix array construction algorithm.
2326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   --*/
2327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- set sentinel bits for block-end detection --*/
2329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < 32; i++) {
2330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      SET_BH(nblock + 2*i);
2331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      CLEAR_BH(nblock + 2*i + 1);
2332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- the log(N) loop --*/
2335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   H = 1;
2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (1) {
2337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (verb >= 4)
2339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf1 ( "        depth %6d has ", H );
2340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = 0;
2342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < nblock; i++) {
2343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ISSET_BH(i)) j = i;
2344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k = fmap[i] - H; if (k < 0) k += nblock;
2345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         eclass[k] = j;
2346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nNotDone = 0;
2349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      r = -1;
2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (1) {
2351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 /*-- find the next non-singleton bucket --*/
2353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k = r + 1;
2354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
2355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ISSET_BH(k)) {
2356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (WORD_BH(k) == 0xffffffff) k += 32;
2357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (ISSET_BH(k)) k++;
2358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         l = k - 1;
2360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (l >= nblock) break;
2361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
2362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (!ISSET_BH(k)) {
2363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (WORD_BH(k) == 0x00000000) k += 32;
2364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (!ISSET_BH(k)) k++;
2365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         r = k - 1;
2367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (r >= nblock) break;
2368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- now [l, r] bracket current bucket --*/
2370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (r > l) {
2371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            nNotDone += (r - l + 1);
2372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            fallbackQSort3 ( fmap, eclass, l, r );
2373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            /*-- scan bucket and generate header bits-- */
2375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            cc = -1;
2376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (i = l; i <= r; i++) {
2377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cc1 = eclass[fmap[i]];
2378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (cc != cc1) { SET_BH(i); cc = cc1; };
2379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (verb >= 4)
2384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
2385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      H *= 2;
2387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (H > nblock || nNotDone == 0) break;
2388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--
2391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Reconstruct the original block in
2392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      eclass8 [0 .. nblock-1], since the
2393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      previous phase destroyed it.
2394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   --*/
2395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (verb >= 4)
2396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VPrintf0 ( "        reconstructing block ...\n" );
2397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   j = 0;
2398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < nblock; i++) {
2399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (ftabCopy[j] == 0) j++;
2400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftabCopy[j]--;
2401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      eclass8[fmap[i]] = (UChar)j;
2402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH ( j < 256, 1005 );
2404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef       SET_BH
2407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef     CLEAR_BH
2408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef     ISSET_BH
2409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef      WORD_BH
2410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef UNALIGNED_BH
2411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- The main, O(N^2 log(N)) sorting       ---*/
2415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- algorithm.  Faster for "normal"       ---*/
2416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- non-repetitive blocks.                ---*/
2417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool mainGtU ( UInt32  i1,
2422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               UInt32  i2,
2423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               UChar*  block,
2424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               UInt16* quadrant,
2425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               UInt32  nblock,
2426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               Int32*  budget )
2427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  k;
2429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  c1, c2;
2430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt16 s1, s2;
2431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertD ( i1 != i2, "mainGtU" );
2433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 1 */
2434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 2 */
2438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 3 */
2442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 4 */
2446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 5 */
2450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 6 */
2454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 7 */
2458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 8 */
2462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 9 */
2466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 10 */
2470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 11 */
2474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* 12 */
2478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c1 = block[i1]; c2 = block[i2];
2479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c1 != c2) return (c1 > c2);
2480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i1++; i2++;
2481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   k = nblock + 8;
2483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
2485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 1 */
2486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 2 */
2492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 3 */
2498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 4 */
2504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 5 */
2510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 6 */
2516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 7 */
2522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 8 */
2528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c1 = block[i1]; c2 = block[i2];
2529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (c1 != c2) return (c1 > c2);
2530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s1 != s2) return (s1 > s2);
2532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i1++; i2++;
2533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (i1 >= nblock) i1 -= nblock;
2535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (i2 >= nblock) i2 -= nblock;
2536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      k -= 8;
2538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (*budget)--;
2539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (k >= 0);
2541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return False;
2543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
2548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Knuth's increments seem to work better
2549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   than Incerpi-Sedgewick here.  Possibly
2550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   because the number of elems to sort is
2551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   usually small, typically <= 20.
2552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
2553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjInt32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
2555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   9841, 29524, 88573, 265720,
2556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   797161, 2391484 };
2557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid mainSimpleSort ( UInt32* ptr,
2560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      UChar*  block,
2561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      UInt16* quadrant,
2562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      Int32   nblock,
2563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      Int32   lo,
2564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      Int32   hi,
2565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      Int32   d,
2566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      Int32*  budget )
2567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 i, j, h, bigN, hp;
2569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt32 v;
2570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bigN = hi - lo + 1;
2572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bigN < 2) return;
2573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   hp = 0;
2575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (incs[hp] < bigN) hp++;
2576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   hp--;
2577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (; hp >= 0; hp--) {
2579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      h = incs[hp];
2580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i = lo + h;
2582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- copy 1 --*/
2585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (i > hi) break;
2586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         v = ptr[i];
2587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = i;
2588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while ( mainGtU (
2589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 ) ) {
2591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ptr[j] = ptr[j-h];
2592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j = j - h;
2593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (j <= (lo + h - 1)) break;
2594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ptr[j] = v;
2596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i++;
2597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- copy 2 --*/
2599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (i > hi) break;
2600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         v = ptr[i];
2601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = i;
2602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while ( mainGtU (
2603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 ) ) {
2605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ptr[j] = ptr[j-h];
2606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j = j - h;
2607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (j <= (lo + h - 1)) break;
2608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ptr[j] = v;
2610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i++;
2611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- copy 3 --*/
2613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (i > hi) break;
2614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         v = ptr[i];
2615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = i;
2616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while ( mainGtU (
2617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 ) ) {
2619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ptr[j] = ptr[j-h];
2620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j = j - h;
2621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (j <= (lo + h - 1)) break;
2622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ptr[j] = v;
2624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         i++;
2625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (*budget < 0) return;
2627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
2634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The following is an implementation of
2635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   an elegant 3-way quicksort for strings,
2636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   described in a paper "Fast Algorithms for
2637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Sorting and Searching Strings", by Robert
2638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Sedgewick and Jon L. Bentley.
2639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
2640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define mswap(zz1, zz2) \
2642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
2643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define mvswap(zzp1, zzp2, zzn)       \
2645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                     \
2646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 yyp1 = (zzp1);               \
2647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 yyp2 = (zzp2);               \
2648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 yyn  = (zzn);                \
2649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (yyn > 0) {                  \
2650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mswap(ptr[yyp1], ptr[yyp2]);    \
2651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      yyp1++; yyp2++; yyn--;          \
2652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                  \
2653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjUChar mmed3 ( UChar a, UChar b, UChar c )
2657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar t;
2659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (a > b) { t = a; a = b; b = t; };
2660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (b > c) {
2661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      b = c;
2662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (a > b) b = a;
2663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return b;
2665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define mmin(a,b) ((a) < (b)) ? (a) : (b)
2668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
2670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          stackHi[sp] = hz; \
2671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          stackD [sp] = dz; \
2672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          sp++; }
2673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define mpop(lz,hz,dz) { sp--;             \
2675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         lz = stackLo[sp]; \
2676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         hz = stackHi[sp]; \
2677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         dz = stackD [sp]; }
2678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define mnextsize(az) (nextHi[az]-nextLo[az])
2681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define mnextswap(az,bz)                                        \
2683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { Int32 tz;                                                  \
2684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
2685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
2686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
2687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define MAIN_QSORT_SMALL_THRESH 20
2690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
2691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define MAIN_QSORT_STACK_SIZE 100
2692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid mainQSort3 ( UInt32* ptr,
2695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  UChar*  block,
2696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  UInt16* quadrant,
2697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  Int32   nblock,
2698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  Int32   loSt,
2699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  Int32   hiSt,
2700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  Int32   dSt,
2701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  Int32*  budget )
2702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
2704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 sp, lo, hi, d;
2705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
2707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
2708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 stackD [MAIN_QSORT_STACK_SIZE];
2709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nextLo[3];
2711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nextHi[3];
2712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nextD [3];
2713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   sp = 0;
2715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   mpush ( loSt, hiSt, dSt );
2716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (sp > 0) {
2718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
2720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mpop ( lo, hi, d );
2722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
2723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          d > MAIN_QSORT_DEPTH_THRESH) {
2724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
2725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (*budget < 0) return;
2726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
2727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      med = (Int32)
2730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            mmed3 ( block[ptr[ lo         ]+d],
2731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    block[ptr[ hi         ]+d],
2732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    block[ptr[ (lo+hi)>>1 ]+d] );
2733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unLo = ltLo = lo;
2735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unHi = gtHi = hi;
2736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
2739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (unLo > unHi) break;
2740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            n = ((Int32)block[ptr[unLo]+d]) - med;
2741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n == 0) {
2742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               mswap(ptr[unLo], ptr[ltLo]);
2743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ltLo++; unLo++; continue;
2744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            };
2745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n >  0) break;
2746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            unLo++;
2747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
2749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (unLo > unHi) break;
2750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            n = ((Int32)block[ptr[unHi]+d]) - med;
2751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n == 0) {
2752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               mswap(ptr[unHi], ptr[gtHi]);
2753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               gtHi--; unHi--; continue;
2754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            };
2755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n <  0) break;
2756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            unHi--;
2757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (unLo > unHi) break;
2759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
2760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
2763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (gtHi < ltLo) {
2765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         mpush(lo, hi, d+1 );
2766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
2767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
2770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
2771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      n = lo + unLo - ltLo - 1;
2773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      m = hi - (gtHi - unHi) + 1;
2774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
2776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
2777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
2778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
2780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
2781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
2782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
2784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
2785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mpush (nextLo[0], nextHi[0], nextD[0]);
2787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mpush (nextLo[1], nextHi[1], nextD[1]);
2788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mpush (nextLo[2], nextHi[2], nextD[2]);
2789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef mswap
2793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef mvswap
2794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef mpush
2795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef mpop
2796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef mmin
2797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef mnextsize
2798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef mnextswap
2799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef MAIN_QSORT_SMALL_THRESH
2800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef MAIN_QSORT_DEPTH_THRESH
2801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef MAIN_QSORT_STACK_SIZE
2802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
2805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Pre:
2806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nblock > N_OVERSHOOT
2807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
2808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ((UChar*)block32) [0 .. nblock-1] holds block
2809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr exists for [0 .. nblock-1]
2810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Post:
2812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ((UChar*)block32) [0 .. nblock-1] holds block
2813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      All other areas of block32 destroyed
2814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab [0 .. 65536 ] destroyed
2815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr [0 .. nblock-1] holds sorted order
2816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (*budget < 0), sorting was abandoned
2817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
2818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
2820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define SETMASK (1 << 21)
2821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define CLEARMASK (~(SETMASK))
2822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*static*/ __attribute__((noinline))
2824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid mainSort ( UInt32* ptr,
2825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                UChar*  block,
2826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                UInt16* quadrant,
2827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                UInt32* ftab,
2828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                Int32   nblock,
2829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                Int32   verb,
2830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                Int32*  budget )
2831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  i, j, k, ss, sb;
2833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  runningOrder[256];
2834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool   bigDone[256];
2835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  copyStart[256];
2836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  copyEnd  [256];
2837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  c1;
2838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  numQSorted;
2839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt16 s;
2840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
2841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- set up the 2-byte frequency table --*/
2843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 65536; i >= 0; i--) ftab[i] = 0;
2844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   j = block[0] << 8;
2846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i = nblock-1;
2847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (; i >= 3; i -= 4) {
2848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      quadrant[i] = 0;
2849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
2850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[j]++;
2851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      quadrant[i-1] = 0;
2852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
2853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[j]++;
2854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      quadrant[i-2] = 0;
2855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
2856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[j]++;
2857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      quadrant[i-3] = 0;
2858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
2859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[j]++;
2860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (; i >= 0; i--) {
2862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      quadrant[i] = 0;
2863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
2864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[j]++;
2865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- (emphasises close relationship of block & quadrant) --*/
2868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
2869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      block   [nblock+i] = block[i];
2870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      quadrant[nblock+i] = 0;
2871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
2874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- Complete the initial radix sort --*/
2876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
2877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s = block[0] << 8;
2879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   i = nblock-1;
2880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (; i >= 3; i -= 4) {
2881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s = (s >> 8) | (block[i] << 8);
2882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = ftab[s] -1;
2883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[s] = j;
2884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr[j] = i;
2885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s = (s >> 8) | (block[i-1] << 8);
2886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = ftab[s] -1;
2887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[s] = j;
2888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr[j] = i-1;
2889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s = (s >> 8) | (block[i-2] << 8);
2890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = ftab[s] -1;
2891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[s] = j;
2892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr[j] = i-2;
2893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s = (s >> 8) | (block[i-3] << 8);
2894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = ftab[s] -1;
2895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[s] = j;
2896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr[j] = i-3;
2897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (; i >= 0; i--) {
2899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s = (s >> 8) | (block[i] << 8);
2900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = ftab[s] -1;
2901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab[s] = j;
2902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ptr[j] = i;
2903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--
2906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Now ftab contains the first loc of every small bucket.
2907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Calculate the running order, from smallest to largest
2908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      big bucket.
2909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   --*/
2910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= 255; i++) {
2911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bigDone     [i] = False;
2912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      runningOrder[i] = i;
2913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   {
2916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32 vv;
2917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32 h = 1;
2918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      do h = 3 * h + 1; while (h <= 256);
2919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      do {
2920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         h = h / 3;
2921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = h; i <= 255; i++) {
2922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vv = runningOrder[i];
2923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j = i;
2924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
2925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               runningOrder[j] = runningOrder[j-h];
2926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               j = j - h;
2927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (j <= (h - 1)) goto zero;
2928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            zero:
2930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            runningOrder[j] = vv;
2931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } while (h != 1);
2933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--
2936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      The main sorting loop.
2937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   --*/
2938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   numQSorted = 0;
2940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= 255; i++) {
2942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--
2944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Process big buckets, starting with the least full.
2945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Basically this is a 3-step process in which we call
2946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         mainQSort3 to sort the small buckets [ss, j], but
2947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         also make a big effort to avoid the calls if we can.
2948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      --*/
2949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ss = runningOrder[i];
2950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--
2952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Step 1:
2953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Complete the big bucket [ss] by quicksorting
2954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         any unsorted small buckets [ss, j], for j != ss.
2955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Hopefully previous pointer-scanning phases have already
2956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         completed many of the small buckets [ss, j], so
2957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         we don't have to sort them at all.
2958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      --*/
2959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (j = 0; j <= 255; j++) {
2960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (j != ss) {
2961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            sb = (ss << 8) + j;
2962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if ( ! (ftab[sb] & SETMASK) ) {
2963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               Int32 lo = ftab[sb]   & CLEARMASK;
2964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
2965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (hi > lo) {
2966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  if (verb >= 4)
2967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
2968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                "done %d   this %d\n",
2969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                ss, j, numQSorted, hi - lo + 1 );
2970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  mainQSort3 (
2971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     ptr, block, quadrant, nblock,
2972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     lo, hi, BZ_N_RADIX, budget
2973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  );
2974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  numQSorted += (hi - lo + 1);
2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  if (*budget < 0) return;
2976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
2977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ftab[sb] |= SETMASK;
2979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH ( !bigDone[ss], 1006 );
2983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--
2985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Step 2:
2986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Now scan this big bucket [ss] so as to synthesise the
2987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         sorted order for small buckets [t, ss] for all t,
2988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         including, magically, the bucket [ss,ss] too.
2989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         This will avoid doing Real Work in subsequent Step 1's.
2990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      --*/
2991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      {
2992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (j = 0; j <= 255; j++) {
2993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
2994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
2995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
2997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            k = ptr[j]-1; if (k < 0) k += nblock;
2998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            c1 = block[k];
2999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjcroak( 2 + (char*)budget ); /* should identify decl in calling frame */
3000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (!bigDone[c1])
3001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ptr[ copyStart[c1]++ ] = k;
3002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
3004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            k = ptr[j]-1; if (k < 0) k += nblock;
3005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            c1 = block[k];
3006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (!bigDone[c1])
3007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ptr[ copyEnd[c1]-- ] = k;
3008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
3012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                ||
3013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
3014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   Necessity for this case is demonstrated by compressing
3015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   a sequence of approximately 48.5 million of character
3016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   251; 1.0.0/1.0.1 will then die here. */
3017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
3018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                1007 )
3019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
3021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--
3023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Step 3:
3024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         The [ss] big bucket is now done.  Record this fact,
3025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         and update the quadrant descriptors.  Remember to
3026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         update quadrants in the overshoot area too, if
3027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         necessary.  The "if (i < 255)" test merely skips
3028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         this updating for the last bucket processed, since
3029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         updating for the last bucket is pointless.
3030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         The quadrant array provides a way to incrementally
3032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cache sort orderings, as they appear, so as to
3033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         make subsequent comparisons in fullGtU() complete
3034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         faster.  For repetitive blocks this makes a big
3035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         difference (but not big enough to be able to avoid
3036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the fallback sorting mechanism, exponential radix sort).
3037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         The precise meaning is: at all times:
3039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for 0 <= i < nblock and 0 <= j <= nblock
3041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if block[i] != block[j],
3043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               then the relative values of quadrant[i] and
3045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    quadrant[j] are meaningless.
3046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               else {
3048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  if quadrant[i] < quadrant[j]
3049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     then the string starting at i lexicographically
3050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     precedes the string starting at j
3051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  else if quadrant[i] > quadrant[j]
3053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     then the string starting at j lexicographically
3054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     precedes the string starting at i
3055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  else
3057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     the relative ordering of the strings starting
3058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     at i and j has not yet been determined.
3059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
3060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      --*/
3061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bigDone[ss] = True;
3062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (i < 255) {
3064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
3065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
3066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Int32 shifts   = 0;
3067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while ((bbSize >> shifts) > 65534) shifts++;
3069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (j = bbSize-1; j >= 0; j--) {
3071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Int32 a2update     = ptr[bbStart + j];
3072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            UInt16 qVal        = (UInt16)(j >> shifts);
3073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            quadrant[a2update] = qVal;
3074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (a2update < BZ_N_OVERSHOOT)
3075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               quadrant[a2update + nblock] = qVal;
3076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
3078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (verb >= 4)
3083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
3084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 nblock, numQSorted, nblock - numQSorted );
3085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef BIGFREQ
3088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef SETMASK
3089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#undef CLEARMASK
3090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
3093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Pre:
3094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nblock > 0
3095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
3096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ((UChar*)arr2)  [0 .. nblock-1] holds block
3097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      arr1 exists for [0 .. nblock-1]
3098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Post:
3100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ((UChar*)arr2) [0 .. nblock-1] holds block
3101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      All other areas of block destroyed
3102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ftab [ 0 .. 65536 ] destroyed
3103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      arr1 [0 .. nblock-1] holds sorted order
3104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
3105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
3106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ2_blockSort ( EState* s )
3107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt32* ptr    = s->ptr;
3109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar*  block  = s->block;
3110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt32* ftab   = s->ftab;
3111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   nblock = s->nblock;
3112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   verb   = s->verbosity;
3113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   wfact  = s->workFactor;
3114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt16* quadrant;
3115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   budget;
3116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   budgetInit;
3117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   i;
3118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nblock < /* 10000 */1000 ) {
3120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
3121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
3122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Calculate the location for quadrant, remembering to get
3123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the alignment right.  Assumes that &(block[0]) is at least
3124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         2-byte aligned -- this should be ok since block is really
3125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the first section of arr2.
3126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
3127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      i = nblock+BZ_N_OVERSHOOT;
3128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (i & 1) i++;
3129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      quadrant = (UInt16*)(&(block[i]));
3130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* (wfact-1) / 3 puts the default-factor-30
3132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         transition point at very roughly the same place as
3133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         with v0.1 and v0.9.0.
3134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Not that it particularly matters any more, since the
3135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         resulting compressed stream is now the same regardless
3136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         of whether or not we use the main sort or fallback sort.
3137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
3138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (wfact < 1  ) wfact = 1;
3139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (wfact > 100) wfact = 100;
3140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      budgetInit = nblock * ((wfact-1) / 3);
3141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      budget = budgetInit;
3142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
3144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0 && verb >= 3)
3145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
3146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    budgetInit - budget,
3147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    nblock,
3148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    (float)(budgetInit - budget) /
3149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    (float)(nblock==0 ? 1 : nblock) );
3150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (budget < 0) {
3151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (verb >= 2)
3152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VPrintf0 ( "    too repetitive; using fallback"
3153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       " sorting algorithm\n" );
3154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
3155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->origPtr = -1;
3159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < s->nblock; i++)
3160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ptr[i] == 0)
3161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { s->origPtr = i; break; };
3162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH( s->origPtr != -1, 1003 );
3164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                       blocksort.c ---*/
3169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Huffman coding low-level stuff                        ---*/
3173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                             huffman.c ---*/
3174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
3177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
3178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
3179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
3181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
3183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
3184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
3185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
3187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
3188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
3190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
3191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
3192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
3193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
3195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
3196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
3198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
3199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
3200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
3202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
3207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
3214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
3215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
3216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
3218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
3219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
3220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
3221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
3222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
3223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
3224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
3225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
3226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
3228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
3229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
3234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
3235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
3236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define ADDWEIGHTS(zw1,zw2)                           \
3238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
3239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
3240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define UPHEAP(z)                                     \
3242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                                     \
3243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 zz, tmp;                                     \
3244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zz = z; tmp = heap[zz];                            \
3245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
3246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      heap[zz] = heap[zz >> 1];                       \
3247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zz >>= 1;                                       \
3248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                                  \
3249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   heap[zz] = tmp;                                    \
3250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define DOWNHEAP(z)                                   \
3253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                                     \
3254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 zz, yy, tmp;                                 \
3255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zz = z; tmp = heap[zz];                            \
3256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {                                     \
3257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      yy = zz << 1;                                   \
3258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (yy > nHeap) break;                          \
3259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (yy < nHeap &&                               \
3260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          weight[heap[yy+1]] < weight[heap[yy]])      \
3261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         yy++;                                        \
3262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (weight[tmp] < weight[heap[yy]]) break;      \
3263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      heap[zz] = heap[yy];                            \
3264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zz = yy;                                        \
3265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                                  \
3266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   heap[zz] = tmp;                                    \
3267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ2_hbMakeCodeLengths ( UChar *len,
3272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Int32 *freq,
3273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Int32 alphaSize,
3274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Int32 maxLen )
3275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--
3277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Nodes and heap entries run from 1.  Entry 0
3278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for both the heap and nodes is a sentinel.
3279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   --*/
3280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nNodes, nHeap, n1, n2, i, j, k;
3281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool  tooLong;
3282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
3284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
3285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
3286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < alphaSize; i++)
3288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
3289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
3291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nNodes = alphaSize;
3293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nHeap = 0;
3294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      heap[0] = 0;
3296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      weight[0] = 0;
3297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parent[0] = -2;
3298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 1; i <= alphaSize; i++) {
3300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         parent[i] = -1;
3301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nHeap++;
3302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         heap[nHeap] = i;
3303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UPHEAP(nHeap);
3304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
3307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (nHeap > 1) {
3309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
3310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
3311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nNodes++;
3312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         parent[n1] = parent[n2] = nNodes;
3313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
3314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         parent[nNodes] = -1;
3315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nHeap++;
3316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         heap[nHeap] = nNodes;
3317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UPHEAP(nHeap);
3318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
3321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      tooLong = False;
3323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 1; i <= alphaSize; i++) {
3324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = 0;
3325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k = i;
3326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (parent[k] >= 0) { k = parent[k]; j++; }
3327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         len[i-1] = j;
3328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (j > maxLen) tooLong = True;
3329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (! tooLong) break;
3332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* 17 Oct 04: keep-going condition for the following loop used
3334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         to be 'i < alphaSize', which missed the last element,
3335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         theoretically leading to the possibility of the compressor
3336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         looping.  However, this count-scaling step is only needed if
3337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         one of the generated Huffman code words is longer than
3338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         maxLen, which up to and including version 1.0.2 was 20 bits,
3339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         which is extremely unlikely.  In version 1.0.3 maxLen was
3340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         changed to 17 bits, which has minimal effect on compression
3341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ratio, but does mean this scaling step is used from time to
3342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         time, enough to verify that it works.
3343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         This means that bzip2-1.0.3 and later will only produce
3345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Huffman codes with a maximum length of 17 bits.  However, in
3346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         order to preserve backwards compatibility with bitstreams
3347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         produced by versions pre-1.0.3, the decompressor must still
3348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         handle lengths of up to 20. */
3349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 1; i <= alphaSize; i++) {
3351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = weight[i] >> 8;
3352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = 1 + (j / 2);
3353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         weight[i] = j << 8;
3354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ2_hbAssignCodes ( Int32 *code,
3361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         UChar *length,
3362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         Int32 minLen,
3363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         Int32 maxLen,
3364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         Int32 alphaSize )
3365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 n, vec, i;
3367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vec = 0;
3369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (n = minLen; n <= maxLen; n++) {
3370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < alphaSize; i++)
3371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (length[i] == n) { code[i] = vec; vec++; };
3372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vec <<= 1;
3373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ2_hbCreateDecodeTables ( Int32 *limit,
3379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Int32 *base,
3380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Int32 *perm,
3381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                UChar *length,
3382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Int32 minLen,
3383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Int32 maxLen,
3384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Int32 alphaSize )
3385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 pp, i, j, vec;
3387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pp = 0;
3389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = minLen; i <= maxLen; i++)
3390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (j = 0; j < alphaSize; j++)
3391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (length[j] == i) { perm[pp] = j; pp++; };
3392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
3394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
3395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
3397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
3399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vec = 0;
3400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = minLen; i <= maxLen; i++) {
3402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vec += (base[i+1] - base[i]);
3403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      limit[i] = vec-1;
3404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vec <<= 1;
3405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = minLen + 1; i <= maxLen; i++)
3407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      base[i] = ((limit[i-1] + 1) << 1) - base[i];
3408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                         huffman.c ---*/
3413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Compression machinery (not incl block sorting)        ---*/
3417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                            compress.c ---*/
3418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
3419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
3421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
3422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
3423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
3425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
3427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
3428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
3429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
3431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
3432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
3434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
3435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
3436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
3437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
3439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
3440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
3442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
3443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
3444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
3446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
3451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
3458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
3459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
3460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
3462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
3463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
3464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
3465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
3466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
3467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
3468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
3469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
3470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
3472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
3473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
3475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   CHANGES
3476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ~~~~~~~
3477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0.9.0 -- original version.
3478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0.9.0a/b -- no changes in this file.
3480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0.9.0c
3482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      * changed setting of nGroups in sendMTFValues() so as to
3483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        do a bit better on small files
3484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
3485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Bit stream I/O                              ---*/
3490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ2_bsInitWrite ( EState* s )
3494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->bsLive = 0;
3496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->bsBuff = 0;
3497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid bsFinishWrite ( EState* s )
3503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (s->bsLive > 0) {
3505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
3506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->numZ++;
3507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->bsBuff <<= 8;
3508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->bsLive -= 8;
3509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define bsNEEDW(nz)                           \
3515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                             \
3516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (s->bsLive >= 8) {                   \
3517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->zbits[s->numZ]                       \
3518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         = (UChar)(s->bsBuff >> 24);          \
3519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->numZ++;                              \
3520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->bsBuff <<= 8;                        \
3521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->bsLive -= 8;                         \
3522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                          \
3523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid bsW ( EState* s, Int32 n, UInt32 v )
3529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsNEEDW ( n );
3531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->bsBuff |= (v << (32 - s->bsLive - n));
3532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->bsLive += n;
3533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid bsPutUInt32 ( EState* s, UInt32 u )
3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsW ( s, 8, (u >> 24) & 0xffL );
3541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsW ( s, 8, (u >> 16) & 0xffL );
3542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsW ( s, 8, (u >>  8) & 0xffL );
3543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsW ( s, 8,  u        & 0xffL );
3544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid bsPutUChar ( EState* s, UChar c )
3550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsW( s, 8, (UInt32)c );
3552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- The back end proper                         ---*/
3557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid makeMaps_e ( EState* s )
3562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 i;
3564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->nInUse = 0;
3565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < 256; i++)
3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->inUse[i]) {
3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->unseqToSeq[i] = s->nInUse;
3568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->nInUse++;
3569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid generateMTFValues ( EState* s )
3576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar   yy[256];
3578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   i, j;
3579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   zPend;
3580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   wr;
3581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   EOB;
3582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*
3584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      After sorting (eg, here),
3585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
3586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         and
3587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
3588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         holds the original block data.
3589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      The first thing to do is generate the MTF values,
3591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      and put them in
3592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
3593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Because there are strictly fewer or equal MTF values
3594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      than block values, ptr values in this area are overwritten
3595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      with MTF values only when they are no longer needed.
3596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      The final compressed bitstream is generated into the
3598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      area starting at
3599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (UChar*) (&((UChar*)s->arr2)[s->nblock])
3600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      These storage aliases are set up in bzCompressInit(),
3602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      except for the last one, which is arranged in
3603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      compressBlock().
3604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   */
3605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt32* ptr   = s->ptr;
3606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar* block  = s->block;
3607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt16* mtfv  = s->mtfv;
3608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   makeMaps_e ( s );
3610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   EOB = s->nInUse+1;
3611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
3613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   wr = 0;
3615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zPend = 0;
3616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
3617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < s->nblock; i++) {
3619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar ll_i;
3620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertD ( wr <= i, "generateMTFValues(1)" );
3621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      j = ptr[i]-1; if (j < 0) j += s->nblock;
3622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ll_i = s->unseqToSeq[block[j]];
3623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
3624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (yy[0] == ll_i) {
3626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         zPend++;
3627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
3628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (zPend > 0) {
3630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            zPend--;
3631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (True) {
3632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (zPend & 1) {
3633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  mtfv[wr] = BZ_RUNB; wr++;
3634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->mtfFreq[BZ_RUNB]++;
3635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               } else {
3636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  mtfv[wr] = BZ_RUNA; wr++;
3637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->mtfFreq[BZ_RUNA]++;
3638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
3639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (zPend < 2) break;
3640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               zPend = (zPend - 2) / 2;
3641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            };
3642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            zPend = 0;
3643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         {
3645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            register UChar  rtmp;
3646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            register UChar* ryy_j;
3647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            register UChar  rll_i;
3648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            rtmp  = yy[1];
3649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            yy[1] = yy[0];
3650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ryy_j = &(yy[1]);
3651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            rll_i = ll_i;
3652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while ( rll_i != rtmp ) {
3653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               register UChar rtmp2;
3654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ryy_j++;
3655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               rtmp2  = rtmp;
3656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               rtmp   = *ryy_j;
3657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               *ryy_j = rtmp2;
3658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            };
3659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            yy[0] = rtmp;
3660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j = ryy_j - &(yy[0]);
3661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
3662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (zPend > 0) {
3668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zPend--;
3669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (zPend & 1) {
3671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            mtfv[wr] = BZ_RUNB; wr++;
3672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->mtfFreq[BZ_RUNB]++;
3673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
3674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            mtfv[wr] = BZ_RUNA; wr++;
3675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->mtfFreq[BZ_RUNA]++;
3676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (zPend < 2) break;
3678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         zPend = (zPend - 2) / 2;
3679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      };
3680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zPend = 0;
3681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
3684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->nMTF = wr;
3686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
3690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_LESSER_ICOST  0
3691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_GREATER_ICOST 15
3692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid sendMTFValues ( EState* s )
3695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
3697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
3698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 nGroups, nBytes;
3699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--
3701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   is a global since the decoder also needs it.
3703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   are also globals only used in this proc.
3707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Made global to keep stack frame size small.
3708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   --*/
3709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt16 cost[BZ_N_GROUPS];
3712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32  fave[BZ_N_GROUPS];
3713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt16* mtfv = s->mtfv;
3715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->verbosity >= 3)
3717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
3718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "%d+2 syms in use\n",
3719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                s->nblock, s->nMTF, s->nInUse );
3720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   alphaSize = s->nInUse+2;
3722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (t = 0; t < BZ_N_GROUPS; t++)
3723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (v = 0; v < alphaSize; v++)
3724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->len[t][v] = BZ_GREATER_ICOST;
3725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- Decide how many coding tables to use ---*/
3727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH ( s->nMTF > 0, 3001 );
3728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->nMTF < 200)  nGroups = 2; else
3729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->nMTF < 600)  nGroups = 3; else
3730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->nMTF < 1200) nGroups = 4; else
3731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->nMTF < 2400) nGroups = 5; else
3732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       nGroups = 6;
3733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- Generate an initial set of coding tables ---*/
3735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   {
3736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32 nPart, remF, tFreq, aFreq;
3737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nPart = nGroups;
3739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      remF  = s->nMTF;
3740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gs = 0;
3741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (nPart > 0) {
3742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tFreq = remF / nPart;
3743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ge = gs-1;
3744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         aFreq = 0;
3745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (aFreq < tFreq && ge < alphaSize-1) {
3746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ge++;
3747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            aFreq += s->mtfFreq[ge];
3748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ge > gs
3751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             && nPart != nGroups && nPart != 1
3752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             && ((nGroups-nPart) % 2 == 1)) {
3753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            aFreq -= s->mtfFreq[ge];
3754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ge--;
3755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (0 && s->verbosity >= 3)
3758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VPrintf5( "      initial group %d, [%d .. %d], "
3759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      "has %d syms (%4.1f%%)\n",
3760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      nPart, gs, ge, aFreq,
3761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
3762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (v = 0; v < alphaSize; v++)
3764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (v >= gs && v <= ge)
3765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
3766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               s->len[nPart-1][v] = BZ_GREATER_ICOST;
3767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nPart--;
3769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         gs = ge+1;
3770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         remF -= aFreq;
3771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*---
3775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Iterate up to BZ_N_ITERS times to improve the tables.
3776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ---*/
3777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (iter = 0; iter < BZ_N_ITERS; iter++) {
3778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (t = 0; t < nGroups; t++) fave[t] = 0;
3780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (t = 0; t < nGroups; t++)
3782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (v = 0; v < alphaSize; v++)
3783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->rfreq[t][v] = 0;
3784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*---
3786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        Set up an auxiliary length table which is used to fast-track
3787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	the common case (nGroups == 6).
3788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ---*/
3789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (nGroups == 6) {
3790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (v = 0; v < alphaSize; v++) {
3791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
3792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
3793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
3794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 }
3795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nSelectors = 0;
3798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      totc = 0;
3799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gs = 0;
3800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*--- Set group start & end marks. --*/
3803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (gs >= s->nMTF) break;
3804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ge = gs + BZ_G_SIZE - 1;
3805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ge >= s->nMTF) ge = s->nMTF-1;
3806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*--
3808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Calculate the cost of this group as coded
3809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            by each of the coding tables.
3810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         --*/
3811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (t = 0; t < nGroups; t++) cost[t] = 0;
3812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nGroups == 6 && 50 == ge-gs+1) {
3814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            /*--- fast track the common case ---*/
3815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            register UInt32 cost01, cost23, cost45;
3816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            register UInt16 icv;
3817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            cost01 = cost23 = cost45 = 0;
3818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#           define BZ_ITER(nn)                \
3820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               icv = mtfv[gs+(nn)];           \
3821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cost01 += s->len_pack[icv][0]; \
3822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cost23 += s->len_pack[icv][1]; \
3823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cost45 += s->len_pack[icv][2]; \
3824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
3826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
3827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
3828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
3829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
3830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
3831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
3832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
3833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
3834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
3835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#           undef BZ_ITER
3837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
3839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
3840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
3841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
3843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	    /*--- slow version which correctly handles all situations ---*/
3844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (i = gs; i <= ge; i++) {
3845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               UInt16 icv = mtfv[i];
3846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
3847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
3848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*--
3851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Find the coding table which is best for this group,
3852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            and record its identity in the selector table.
3853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         --*/
3854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         bc = 999999999; bt = -1;
3855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (t = 0; t < nGroups; t++)
3856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (cost[t] < bc) { bc = cost[t]; bt = t; };
3857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         totc += bc;
3858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         fave[bt]++;
3859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->selector[nSelectors] = bt;
3860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nSelectors++;
3861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*--
3863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Increment the symbol frequencies for the selected table.
3864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          --*/
3865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nGroups == 6 && 50 == ge-gs+1) {
3866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            /*--- fast track the common case ---*/
3867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
3869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
3871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
3872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
3873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
3874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
3875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
3876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
3877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
3878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
3879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
3880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#           undef BZ_ITUR
3882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
3884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	    /*--- slow version which correctly handles all situations ---*/
3885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (i = gs; i <= ge; i++)
3886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               s->rfreq[bt][ mtfv[i] ]++;
3887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         gs = ge+1;
3890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->verbosity >= 3) {
3892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf2 ( "      pass %d: size is %d, grp uses are ",
3893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   iter+1, totc/8 );
3894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (t = 0; t < nGroups; t++)
3895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VPrintf1 ( "%d ", fave[t] );
3896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf0 ( "\n" );
3897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--
3900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        Recompute the tables based on the accumulated frequencies.
3901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      --*/
3902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
3903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         comment in huffman.c for details. */
3904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (t = 0; t < nGroups; t++)
3905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
3906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                 alphaSize, 17 /*20*/ );
3907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH( nGroups < 8, 3002 );
3911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH( nSelectors < 32768 &&
3912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
3913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            3003 );
3914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- Compute MTF values for the selectors. ---*/
3917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   {
3918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
3919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < nGroups; i++) pos[i] = i;
3920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < nSelectors; i++) {
3921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ll_i = s->selector[i];
3922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         j = 0;
3923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tmp = pos[j];
3924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while ( ll_i != tmp ) {
3925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            j++;
3926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tmp2 = tmp;
3927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tmp = pos[j];
3928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            pos[j] = tmp2;
3929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         };
3930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         pos[0] = tmp;
3931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->selectorMtf[i] = j;
3932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   };
3934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- Assign actual codes for the tables. --*/
3936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (t = 0; t < nGroups; t++) {
3937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      minLen = 32;
3938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      maxLen = 0;
3939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < alphaSize; i++) {
3940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
3941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->len[t][i] < minLen) minLen = s->len[t][i];
3942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
3944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH ( !(minLen < 1),  3005 );
3945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
3946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          minLen, maxLen, alphaSize );
3947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- Transmit the mapping table. ---*/
3950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   {
3951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool inUse16[16];
3952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < 16; i++) {
3953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          inUse16[i] = False;
3954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          for (j = 0; j < 16; j++)
3955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             if (s->inUse[i * 16 + j]) inUse16[i] = True;
3956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nBytes = s->numZ;
3959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < 16; i++)
3960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
3961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < 16; i++)
3963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (inUse16[i])
3964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (j = 0; j < 16; j++) {
3965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
3966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
3967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->verbosity >= 3)
3969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
3970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- Now the selectors. ---*/
3973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nBytes = s->numZ;
3974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsW ( s, 3, nGroups );
3975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bsW ( s, 15, nSelectors );
3976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < nSelectors; i++) {
3977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
3978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsW(s,1,0);
3979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->verbosity >= 3)
3981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VPrintf1( "selectors %d, ", s->numZ-nBytes );
3982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- Now the coding tables. ---*/
3984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nBytes = s->numZ;
3985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (t = 0; t < nGroups; t++) {
3987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32 curr = s->len[t][0];
3988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsW ( s, 5, curr );
3989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      for (i = 0; i < alphaSize; i++) {
3990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
3991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
3992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         bsW ( s, 1, 0 );
3993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->verbosity >= 3)
3997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
3998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*--- And finally, the block data proper ---*/
4000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nBytes = s->numZ;
4001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   selCtr = 0;
4002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   gs = 0;
4003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
4004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (gs >= s->nMTF) break;
4005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ge = gs + BZ_G_SIZE - 1;
4006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ge >= s->nMTF) ge = s->nMTF-1;
4007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      AssertH ( s->selector[selCtr] < nGroups, 3006 );
4008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (nGroups == 6 && 50 == ge-gs+1) {
4010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            /*--- fast track the common case ---*/
4011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            UInt16 mtfv_i;
4012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            UChar* s_len_sel_selCtr
4013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               = &(s->len[s->selector[selCtr]][0]);
4014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Int32* s_code_sel_selCtr
4015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               = &(s->code[s->selector[selCtr]][0]);
4016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#           define BZ_ITAH(nn)                      \
4018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               mtfv_i = mtfv[gs+(nn)];              \
4019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               bsW ( s,                             \
4020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s_len_sel_selCtr[mtfv_i],      \
4021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     s_code_sel_selCtr[mtfv_i] )
4022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
4024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
4025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
4026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
4027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
4028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
4029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
4030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
4031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
4032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
4033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#           undef BZ_ITAH
4035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
4037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 /*--- slow version which correctly handles all situations ---*/
4038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (i = gs; i <= ge; i++) {
4039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            bsW ( s,
4040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->len  [s->selector[selCtr]] [mtfv[i]],
4041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  s->code [s->selector[selCtr]] [mtfv[i]] );
4042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      gs = ge+1;
4047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      selCtr++;
4048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH( selCtr == nSelectors, 3007 );
4050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->verbosity >= 3)
4052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VPrintf1( "codes %d\n", s->numZ-nBytes );
4053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
4058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ2_compressBlock ( EState* s, Bool is_last_block )
4059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->nblock > 0) {
4061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ_FINALISE_CRC ( s->blockCRC );
4063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
4064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->combinedCRC ^= s->blockCRC;
4065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->blockNo > 1) s->numZ = 0;
4066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->verbosity >= 2)
4068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf4( "    block %d: crc = 0x%08x, "
4069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   "combined CRC = 0x%08x, size = %d\n",
4070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
4071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ2_blockSort ( s );
4073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
4076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- If this is the first block, create the stream header. --*/
4078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->blockNo == 1) {
4079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ2_bsInitWrite ( s );
4080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, BZ_HDR_B );
4081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, BZ_HDR_Z );
4082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, BZ_HDR_h );
4083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
4084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->nblock > 0) {
4087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
4089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
4090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
4091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- Now the block's CRC, so it is in a known place. --*/
4093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUInt32 ( s, s->blockCRC );
4094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*--
4096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Now a single bit indicating (non-)randomisation.
4097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         As of version 0.9.5, we use a better sorting algorithm
4098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         which makes randomisation unnecessary.  So always set
4099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the randomised bit to 'no'.  Of course, the decoder
4100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         still needs to be able to handle randomised blocks
4101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         so as to maintain backwards compatibility with
4102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         older versions of bzip2.
4103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      --*/
4104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsW(s,1,0);
4105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsW ( s, 24, s->origPtr );
4107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      generateMTFValues ( s );
4108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      sendMTFValues ( s );
4109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- If this is the last block, add the stream trailer. --*/
4113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (is_last_block) {
4114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
4116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
4117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
4118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsPutUInt32 ( s, s->combinedCRC );
4119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->verbosity >= 2)
4120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
4121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bsFinishWrite ( s );
4122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                        compress.c ---*/
4128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Table for randomising repetitive blocks               ---*/
4133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                           randtable.c ---*/
4134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
4137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
4138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
4139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
4143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
4144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
4145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
4147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
4148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
4150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
4151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
4152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
4153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
4155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
4156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
4158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
4159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
4160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
4174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
4175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
4176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
4178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
4179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
4180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
4181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
4182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
4183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
4184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
4185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
4186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
4188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
4189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
4194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjInt32 BZ2_rNums[512] = {
4195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
4196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
4197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
4198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
4199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
4200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
4201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
4202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
4203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
4204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
4205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
4206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
4207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
4208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
4209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
4210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
4211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
4212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
4213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
4214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
4215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
4216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
4217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
4218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
4219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
4220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
4221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
4222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
4223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
4224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
4225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
4226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
4227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
4228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
4229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
4230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
4231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
4232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
4233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
4234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
4235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
4236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
4237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
4238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
4239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
4240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
4241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
4242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
4243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
4244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
4245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
4246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   936, 638
4247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj};
4248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                       randtable.c ---*/
4252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Table for doing CRCs                                  ---*/
4256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                            crctable.c ---*/
4257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
4260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
4261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
4262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
4266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
4267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
4268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
4270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
4271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
4273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
4274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
4275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
4276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
4278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
4279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
4281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
4282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
4283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
4297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
4298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
4299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
4301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
4302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
4303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
4304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
4305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
4306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
4307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
4308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
4309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
4311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
4312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
4318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  I think this is an implementation of the AUTODIN-II,
4319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
4320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  from code by Rob Warnock, in Section 51 of the
4321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  comp.compression FAQ.
4322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
4323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjUInt32 BZ2_crc32Table[256] = {
4325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- Ugly, innit? --*/
4327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
4329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
4330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
4331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
4332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
4333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
4334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
4335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
4336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
4337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
4338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
4339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
4340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
4341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
4342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
4343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
4344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
4345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
4346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
4347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
4348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
4349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
4350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
4351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
4352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
4353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
4354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
4355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
4356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
4357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
4358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
4359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
4360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
4361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
4362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
4363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
4364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
4365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
4366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
4367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
4368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
4369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
4370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
4371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
4372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
4373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
4374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
4375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
4376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
4377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
4378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
4379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
4380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
4381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
4382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
4383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
4384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
4385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
4386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
4387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
4388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
4389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
4390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
4391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
4392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj};
4393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                        crctable.c ---*/
4397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Library top-level functions.                          ---*/
4401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                               bzlib.c ---*/
4402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
4403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
4405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This file is a part of bzip2 and/or libbzip2, a program and
4406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  library for lossless, block-sorting data compression.
4407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Redistribution and use in source and binary forms, with or without
4411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  modification, are permitted provided that the following conditions
4412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  are met:
4413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  1. Redistributions of source code must retain the above copyright
4415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     notice, this list of conditions and the following disclaimer.
4416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  2. The origin of this software must not be misrepresented; you must
4418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not claim that you wrote the original software.  If you use this
4419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     software in a product, an acknowledgment in the product
4420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     documentation would be appreciated but is not required.
4421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  3. Altered source versions must be plainly marked as such, and must
4423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     not be misrepresented as being the original software.
4424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  4. The name of the author may not be used to endorse or promote
4426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     products derived from this software without specific prior written
4427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     permission.
4428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  Julian Seward, Cambridge, UK.
4442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  jseward@bzip.org
4443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
4444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  This program is based on (at least) the work of:
4446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Mike Burrows
4447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     David Wheeler
4448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Peter Fenwick
4449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Alistair Moffat
4450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Radford Neal
4451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Ian H. Witten
4452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Robert Sedgewick
4453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     Jon L. Bentley
4454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  For more information on these sources, see the manual.
4456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
4457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
4459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   CHANGES
4460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ~~~~~~~
4461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0.9.0 -- original version.
4462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0.9.0a/b -- no changes in this file.
4464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   0.9.0c
4466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      * made zero-length BZ_FLUSH work correctly in bzCompress().
4467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      * fixed bzWrite/bzRead to ignore zero-length requests.
4468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      * fixed bzread to correctly handle read requests after EOF.
4469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      * wrong parameter order in call to bzDecompressInit in
4470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        bzBuffToBuffDecompress.  Fixed.
4471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
4472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Compression stuff                           ---*/
4477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ2_bz__AssertH__fail ( int errcode )
4482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf("BZ2_bz__AssertH__fail(%d) called, exiting\n", errcode);
4484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (*serviceFn)(0,0);
4485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid bz_internal_error ( int errcode )
4488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf("bz_internal_error called, exiting\n", errcode);
4490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (*serviceFn)(0,0);
4491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint bz_config_ok ( void )
4496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(int)   != 4) return 0;
4498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(short) != 2) return 0;
4499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(char)  != 1) return 0;
4500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 1;
4501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid* default_bzalloc ( void* opaque, Int32 items, Int32 size )
4507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   void* v = (void*) (*serviceFn)(2, items * size );
4509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return v;
4510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid default_bzfree ( void* opaque, void* addr )
4514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (addr != NULL) (*serviceFn)( 3, (HWord)addr );
4516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid prepare_new_block ( EState* s )
4522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 i;
4524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->nblock = 0;
4525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->numZ = 0;
4526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->state_out_pos = 0;
4527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_INITIALISE_CRC ( s->blockCRC );
4528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < 256; i++) s->inUse[i] = False;
4529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->blockNo++;
4530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid init_RL ( EState* s )
4536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->state_in_ch  = 256;
4538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->state_in_len = 0;
4539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool isempty_RL ( EState* s )
4544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->state_in_ch < 256 && s->state_in_len > 0)
4546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return False; else
4547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return True;
4548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzCompressInit)
4553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    ( bz_stream* strm,
4554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     int        blockSize100k,
4555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     int        verbosity,
4556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     int        workFactor )
4557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   n;
4559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   EState* s;
4560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
4562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm == NULL ||
4564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       blockSize100k < 1 || blockSize100k > 9 ||
4565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       workFactor < 0 || workFactor > 250)
4566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     return BZ_PARAM_ERROR;
4567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (workFactor == 0) workFactor = 30;
4569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
4570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
4571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s = BZALLOC( sizeof(EState) );
4573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s == NULL) return BZ_MEM_ERROR;
4574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->strm = strm;
4575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->arr1 = NULL;
4577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->arr2 = NULL;
4578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->ftab = NULL;
4579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   n       = 100000 * blockSize100k;
4581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
4582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
4583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
4584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
4586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->arr1 != NULL) BZFREE(s->arr1);
4587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->arr2 != NULL) BZFREE(s->arr2);
4588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->ftab != NULL) BZFREE(s->ftab);
4589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s       != NULL) BZFREE(s);
4590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return BZ_MEM_ERROR;
4591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->blockNo           = 0;
4594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->state             = BZ_S_INPUT;
4595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->mode              = BZ_M_RUNNING;
4596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->combinedCRC       = 0;
4597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->blockSize100k     = blockSize100k;
4598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->nblockMAX         = 100000 * blockSize100k - 19;
4599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->verbosity         = verbosity;
4600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->workFactor        = workFactor;
4601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->block             = (UChar*)s->arr2;
4603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->mtfv              = (UInt16*)s->arr1;
4604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->zbits             = NULL;
4605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->ptr               = (UInt32*)s->arr1;
4606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->state          = s;
4608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_in_lo32  = 0;
4609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_in_hi32  = 0;
4610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_out_lo32 = 0;
4611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_out_hi32 = 0;
4612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   init_RL ( s );
4613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   prepare_new_block ( s );
4614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OK;
4615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid add_pair_to_block ( EState* s )
4621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 i;
4623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar ch = (UChar)(s->state_in_ch);
4624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < s->state_in_len; i++) {
4625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ_UPDATE_CRC( s->blockCRC, ch );
4626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->inUse[s->state_in_ch] = True;
4628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   switch (s->state_in_len) {
4629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 1:
4630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
4632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 2:
4633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
4636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 3:
4637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
4641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      default:
4642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->inUse[s->state_in_len-4] = True;
4643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
4648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->nblock++;
4649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
4650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid flush_RL ( EState* s )
4657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->state_in_ch < 256) add_pair_to_block ( s );
4659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   init_RL ( s );
4660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
4665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                                 \
4666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt32 zchh = (UInt32)(zchh0);                 \
4667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- fast track the common case --*/           \
4668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (zchh != zs->state_in_ch &&                 \
4669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       zs->state_in_len == 1) {                   \
4670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar ch = (UChar)(zs->state_in_ch);        \
4671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
4672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->inUse[zs->state_in_ch] = True;          \
4673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->block[zs->nblock] = (UChar)ch;          \
4674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->nblock++;                               \
4675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->state_in_ch = zchh;                     \
4676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                              \
4677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else                                           \
4678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*-- general, uncommon cases --*/              \
4679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (zchh != zs->state_in_ch ||                 \
4680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->state_in_len == 255) {                  \
4681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (zs->state_in_ch < 256)                  \
4682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         add_pair_to_block ( zs );                \
4683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->state_in_ch = zchh;                     \
4684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->state_in_len = 1;                       \
4685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {                                       \
4686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      zs->state_in_len++;                         \
4687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }                                              \
4688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool copy_input_until_stop ( EState* s )
4694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool progress_in = False;
4696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->mode == BZ_M_RUNNING) {
4698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- fast track the common case --*/
4700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
4701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- block full? --*/
4702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock >= s->nblockMAX) break;
4703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- no input? --*/
4704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->strm->avail_in == 0) break;
4705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         progress_in = True;
4706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
4707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->next_in++;
4708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->avail_in--;
4709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->total_in_lo32++;
4710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
4711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
4714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- general, uncommon case --*/
4716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
4717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- block full? --*/
4718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock >= s->nblockMAX) break;
4719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- no input? --*/
4720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->strm->avail_in == 0) break;
4721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /*-- flush/finish end? --*/
4722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->avail_in_expect == 0) break;
4723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         progress_in = True;
4724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
4725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->next_in++;
4726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->avail_in--;
4727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->total_in_lo32++;
4728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
4729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->avail_in_expect--;
4730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return progress_in;
4733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool copy_output_until_stop ( EState* s )
4739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool progress_out = False;
4741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
4743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- no output space? --*/
4745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->strm->avail_out == 0) break;
4746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*-- block done? --*/
4748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->state_out_pos >= s->numZ) break;
4749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      progress_out = True;
4751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *(s->strm->next_out) = s->zbits[s->state_out_pos];
4752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->state_out_pos++;
4753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->avail_out--;
4754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->next_out++;
4755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->total_out_lo32++;
4756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
4757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return progress_out;
4760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool handle_compress ( bz_stream* strm )
4766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool progress_in  = False;
4768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool progress_out = False;
4769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   EState* s = strm->state;
4770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
4772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->state == BZ_S_OUTPUT) {
4774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         progress_out |= copy_output_until_stop ( s );
4775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->state_out_pos < s->numZ) break;
4776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->mode == BZ_M_FINISHING &&
4777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             s->avail_in_expect == 0 &&
4778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             isempty_RL(s)) break;
4779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         prepare_new_block ( s );
4780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state = BZ_S_INPUT;
4781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->mode == BZ_M_FLUSHING &&
4782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             s->avail_in_expect == 0 &&
4783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             isempty_RL(s)) break;
4784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->state == BZ_S_INPUT) {
4787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         progress_in |= copy_input_until_stop ( s );
4788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
4789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            flush_RL ( s );
4790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
4791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->state = BZ_S_OUTPUT;
4792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else
4794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock >= s->nblockMAX) {
4795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ2_compressBlock ( s, False );
4796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->state = BZ_S_OUTPUT;
4797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else
4799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->strm->avail_in == 0) {
4800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            break;
4801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return progress_in || progress_out;
4807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
4812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool progress;
4814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   EState* s;
4815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
4816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s = strm->state;
4817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s == NULL) return BZ_PARAM_ERROR;
4818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
4819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   preswitch:
4821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   switch (s->mode) {
4822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case BZ_M_IDLE:
4824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return BZ_SEQUENCE_ERROR;
4825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case BZ_M_RUNNING:
4827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (action == BZ_RUN) {
4828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            progress = handle_compress ( strm );
4829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
4830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else
4832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 if (action == BZ_FLUSH) {
4833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->avail_in_expect = strm->avail_in;
4834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->mode = BZ_M_FLUSHING;
4835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            goto preswitch;
4836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else
4838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (action == BZ_FINISH) {
4839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->avail_in_expect = strm->avail_in;
4840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->mode = BZ_M_FINISHING;
4841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            goto preswitch;
4842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else
4844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return BZ_PARAM_ERROR;
4845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case BZ_M_FLUSHING:
4847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
4848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->avail_in_expect != s->strm->avail_in)
4849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return BZ_SEQUENCE_ERROR;
4850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         progress = handle_compress ( strm );
4851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
4852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
4853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->mode = BZ_M_RUNNING;
4854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return BZ_RUN_OK;
4855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case BZ_M_FINISHING:
4857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
4858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->avail_in_expect != s->strm->avail_in)
4859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return BZ_SEQUENCE_ERROR;
4860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         progress = handle_compress ( strm );
4861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (!progress) return BZ_SEQUENCE_ERROR;
4862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
4863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
4864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->mode = BZ_M_IDLE;
4865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return BZ_STREAM_END;
4866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OK; /*--not reached--*/
4868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
4873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   EState* s;
4875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
4876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s = strm->state;
4877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s == NULL) return BZ_PARAM_ERROR;
4878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
4879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->arr1 != NULL) BZFREE(s->arr1);
4881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->arr2 != NULL) BZFREE(s->arr2);
4882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->ftab != NULL) BZFREE(s->ftab);
4883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZFREE(strm->state);
4884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->state = NULL;
4886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OK;
4888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Decompression stuff                         ---*/
4893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzDecompressInit)
4897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     ( bz_stream* strm,
4898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       int        verbosity,
4899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       int        small )
4900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DState* s;
4902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
4904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
4906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
4907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
4908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
4910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
4911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s = BZALLOC( sizeof(DState) );
4913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s == NULL) return BZ_MEM_ERROR;
4914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->strm                  = strm;
4915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->state              = s;
4916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->state                 = BZ_X_MAGIC_1;
4917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->bsLive                = 0;
4918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->bsBuff                = 0;
4919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->calculatedCombinedCRC = 0;
4920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_in_lo32      = 0;
4921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_in_hi32      = 0;
4922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_out_lo32     = 0;
4923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->total_out_hi32     = 0;
4924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->smallDecompress       = (Bool)small;
4925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->ll4                   = NULL;
4926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->ll16                  = NULL;
4927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->tt                    = NULL;
4928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->currBlockNo           = 0;
4929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s->verbosity             = verbosity;
4930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OK;
4932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
4936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Return  True iff data corruption is discovered.
4937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Returns False if there is no problem.
4938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
4939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
4940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool unRLE_obuf_to_output_FAST ( DState* s )
4941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar k1;
4943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->blockRandomised) {
4945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
4947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* try to finish existing run */
4948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
4949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->strm->avail_out == 0) return False;
4950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->state_out_len == 0) break;
4951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
4952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
4953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->state_out_len--;
4954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->next_out++;
4955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->avail_out--;
4956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->total_out_lo32++;
4957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
4958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* can a new run be started? */
4961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) return False;
4962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Only caused by corrupt data stream? */
4964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used > s->save_nblock+1)
4965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return True;
4966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 1;
4968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_ch = s->k0;
4969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
4972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
4973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 2;
4975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
4978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
4979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 3;
4981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
4984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
4985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = ((Int32)k1) + 4;
4989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
4990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
4991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
4994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* restore */
4996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
4997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar         c_state_out_ch       = s->state_out_ch;
4998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32         c_state_out_len      = s->state_out_len;
4999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32         c_nblock_used        = s->nblock_used;
5000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32         c_k0                 = s->k0;
5001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32*       c_tt                 = s->tt;
5002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32        c_tPos               = s->tPos;
5003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      char*         cs_next_out          = s->strm->next_out;
5004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int  cs_avail_out         = s->strm->avail_out;
5005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* end restore */
5006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UInt32       avail_out_INIT = cs_avail_out;
5008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32        s_save_nblockPP = s->save_nblock+1;
5009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unsigned int total_out_lo32_old;
5010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
5012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* try to finish existing run */
5014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (c_state_out_len > 0) {
5015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            while (True) {
5016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (cs_avail_out == 0) goto return_notr;
5017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (c_state_out_len == 1) break;
5018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
5019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
5020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               c_state_out_len--;
5021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cs_next_out++;
5022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cs_avail_out--;
5023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
5024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s_state_out_len_eq_one:
5025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            {
5026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (cs_avail_out == 0) {
5027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  c_state_out_len = 1; goto return_notr;
5028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               };
5029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
5030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
5031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cs_next_out++;
5032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               cs_avail_out--;
5033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
5034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
5035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Only caused by corrupt data stream? */
5036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (c_nblock_used > s_save_nblockPP)
5037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return True;
5038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* can a new run be started? */
5040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (c_nblock_used == s_save_nblockPP) {
5041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            c_state_out_len = 0; goto return_notr;
5042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         };
5043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c_state_out_ch = c_k0;
5044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != c_k0) {
5046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            c_k0 = k1; goto s_state_out_len_eq_one;
5047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         };
5048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (c_nblock_used == s_save_nblockPP)
5049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            goto s_state_out_len_eq_one;
5050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c_state_out_len = 2;
5052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (c_nblock_used == s_save_nblockPP) continue;
5054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
5055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c_state_out_len = 3;
5057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (c_nblock_used == s_save_nblockPP) continue;
5059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
5060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c_state_out_len = ((Int32)k1) + 4;
5063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_FAST_C(c_k0); c_nblock_used++;
5064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return_notr:
5067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      total_out_lo32_old = s->strm->total_out_lo32;
5068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
5069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->strm->total_out_lo32 < total_out_lo32_old)
5070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->strm->total_out_hi32++;
5071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* save */
5073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->calculatedBlockCRC = c_calculatedBlockCRC;
5074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->state_out_ch       = c_state_out_ch;
5075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->state_out_len      = c_state_out_len;
5076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->nblock_used        = c_nblock_used;
5077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->k0                 = c_k0;
5078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->tt                 = c_tt;
5079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->tPos               = c_tPos;
5080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->next_out     = cs_next_out;
5081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      s->strm->avail_out    = cs_avail_out;
5082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* end save */
5083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return False;
5085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Return  True iff data corruption is discovered.
5091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Returns False if there is no problem.
5092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
5093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
5094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool unRLE_obuf_to_output_SMALL ( DState* s )
5095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar k1;
5097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->blockRandomised) {
5099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
5101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* try to finish existing run */
5102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
5103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->strm->avail_out == 0) return False;
5104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->state_out_len == 0) break;
5105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
5106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
5107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->state_out_len--;
5108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->next_out++;
5109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->avail_out--;
5110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->total_out_lo32++;
5111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
5112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
5113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* can a new run be started? */
5115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) return False;
5116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Only caused by corrupt data stream? */
5118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used > s->save_nblock+1)
5119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return True;
5120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 1;
5122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_ch = s->k0;
5123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 2;
5129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 3;
5135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = ((Int32)k1) + 4;
5143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
5144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
5145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
5148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
5150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* try to finish existing run */
5151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
5152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->strm->avail_out == 0) return False;
5153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->state_out_len == 0) break;
5154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
5155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
5156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->state_out_len--;
5157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->next_out++;
5158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->avail_out--;
5159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->strm->total_out_lo32++;
5160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
5161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
5162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* can a new run be started? */
5164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) return False;
5165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Only caused by corrupt data stream? */
5167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used > s->save_nblock+1)
5168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return True;
5169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 1;
5171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_ch = s->k0;
5172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 2;
5177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = 3;
5182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s->state_out_len = ((Int32)k1) + 4;
5188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ_GET_SMALL(s->k0); s->nblock_used++;
5189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
5197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool    corrupt;
5199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DState* s;
5200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
5201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s = strm->state;
5202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s == NULL) return BZ_PARAM_ERROR;
5203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
5204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
5206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
5207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->state == BZ_X_OUTPUT) {
5208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->smallDecompress)
5209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
5210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            corrupt = unRLE_obuf_to_output_FAST  ( s );
5211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (corrupt) return BZ_DATA_ERROR;
5212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
5213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
5214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->verbosity >= 3)
5215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
5216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          s->calculatedBlockCRC );
5217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->verbosity >= 2) VPrintf0 ( "]" );
5218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->calculatedBlockCRC != s->storedBlockCRC)
5219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               return BZ_DATA_ERROR;
5220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->calculatedCombinedCRC
5221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               = (s->calculatedCombinedCRC << 1) |
5222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    (s->calculatedCombinedCRC >> 31);
5223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
5224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            s->state = BZ_X_BLKHDR_1;
5225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
5226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return BZ_OK;
5227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
5228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (s->state >= BZ_X_MAGIC_1) {
5230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Int32 r = BZ2_decompress ( s );
5231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (r == BZ_STREAM_END) {
5232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->verbosity >= 3)
5233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
5234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          s->storedCombinedCRC, s->calculatedCombinedCRC );
5235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
5236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               return BZ_DATA_ERROR;
5237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            return r;
5238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
5239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (s->state != BZ_X_OUTPUT) return r;
5240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AssertH ( 0, 6001 );
5244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0;  /*NOTREACHED*/
5246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
5251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DState* s;
5253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
5254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   s = strm->state;
5255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s == NULL) return BZ_PARAM_ERROR;
5256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
5257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->tt   != NULL) BZFREE(s->tt);
5259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->ll16 != NULL) BZFREE(s->ll16);
5260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (s->ll4  != NULL) BZFREE(s->ll4);
5261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZFREE(strm->state);
5263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm->state = NULL;
5264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OK;
5266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_NO_STDIO
5270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- File I/O stuff                              ---*/
5272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define BZ_SETERR(eee)                    \
5275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{                                         \
5276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzerror != NULL) *bzerror = eee;   \
5277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf != NULL) bzf->lastErr = eee;   \
5278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
5281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
5282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      FILE*     handle;
5283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Char      buf[BZ_MAX_UNUSED];
5284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32     bufN;
5285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool      writing;
5286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bz_stream strm;
5287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int32     lastErr;
5288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool      initialisedOk;
5289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile;
5291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------*/
5294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool myfeof ( FILE* f )
5295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 c = fgetc ( f );
5297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (c == EOF) return True;
5298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ungetc ( c, f );
5299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return False;
5300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZFILE* BZ_API(BZ2_bzWriteOpen)
5305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    ( int*  bzerror,
5306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      FILE* f,
5307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      int   blockSize100k,
5308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      int   verbosity,
5309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      int   workFactor )
5310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   ret;
5312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile* bzf = NULL;
5313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (f == NULL ||
5317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (blockSize100k < 1 || blockSize100k > 9) ||
5318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (workFactor < 0 || workFactor > 250) ||
5319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (verbosity < 0 || verbosity > 4))
5320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
5321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ferror(f))
5323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
5324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf = malloc ( sizeof(bzFile) );
5326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf == NULL)
5327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
5328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->initialisedOk = False;
5331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->bufN          = 0;
5332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->handle        = f;
5333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->writing       = True;
5334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.bzalloc  = NULL;
5335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.bzfree   = NULL;
5336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.opaque   = NULL;
5337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (workFactor == 0) workFactor = 30;
5339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
5340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                              verbosity, workFactor );
5341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret != BZ_OK)
5342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
5343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.avail_in = 0;
5345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->initialisedOk = True;
5346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return bzf;
5347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ_API(BZ2_bzWrite)
5353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             ( int*    bzerror,
5354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               BZFILE* b,
5355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               void*   buf,
5356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               int     len )
5357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32 n, n2, ret;
5359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile* bzf = (bzFile*)b;
5360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf == NULL || buf == NULL || len < 0)
5363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
5364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!(bzf->writing))
5365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ferror(bzf->handle))
5367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
5368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (len == 0)
5370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_OK); return; };
5371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.avail_in = len;
5373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.next_in  = buf;
5374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
5376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bzf->strm.avail_out = BZ_MAX_UNUSED;
5377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bzf->strm.next_out = bzf->buf;
5378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
5379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ret != BZ_RUN_OK)
5380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(ret); return; };
5381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
5383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
5384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
5385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       n, bzf->handle );
5386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (n != n2 || ferror(bzf->handle))
5387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            { BZ_SETERR(BZ_IO_ERROR); return; };
5388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (bzf->strm.avail_in == 0)
5391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(BZ_OK); return; };
5392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ_API(BZ2_bzWriteClose)
5398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  ( int*          bzerror,
5399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    BZFILE*       b,
5400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    int           abandon,
5401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    unsigned int* nbytes_in,
5402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    unsigned int* nbytes_out )
5403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzWriteClose64 ( bzerror, b, abandon,
5405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        nbytes_in, NULL, nbytes_out, NULL );
5406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ_API(BZ2_bzWriteClose64)
5410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  ( int*          bzerror,
5411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    BZFILE*       b,
5412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    int           abandon,
5413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    unsigned int* nbytes_in_lo32,
5414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    unsigned int* nbytes_in_hi32,
5415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    unsigned int* nbytes_out_lo32,
5416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    unsigned int* nbytes_out_hi32 )
5417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   n, n2, ret;
5419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile* bzf = (bzFile*)b;
5420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf == NULL)
5422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_OK); return; };
5423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!(bzf->writing))
5424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ferror(bzf->handle))
5426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
5427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
5429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
5430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
5431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
5432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if ((!abandon) && bzf->lastErr == BZ_OK) {
5434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
5435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         bzf->strm.avail_out = BZ_MAX_UNUSED;
5436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         bzf->strm.next_out = bzf->buf;
5437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
5438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
5439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            { BZ_SETERR(ret); return; };
5440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
5442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
5443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
5444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          n, bzf->handle );
5445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (n != n2 || ferror(bzf->handle))
5446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               { BZ_SETERR(BZ_IO_ERROR); return; };
5447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
5448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ret == BZ_STREAM_END) break;
5450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if ( !abandon && !ferror ( bzf->handle ) ) {
5454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fflush ( bzf->handle );
5455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ferror(bzf->handle))
5456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(BZ_IO_ERROR); return; };
5457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_in_lo32 != NULL)
5460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
5461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_in_hi32 != NULL)
5462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
5463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_out_lo32 != NULL)
5464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
5465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (nbytes_out_hi32 != NULL)
5466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
5467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzCompressEnd ( &(bzf->strm) );
5470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   free ( bzf );
5471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZFILE* BZ_API(BZ2_bzReadOpen)
5476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   ( int*  bzerror,
5477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     FILE* f,
5478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     int   verbosity,
5479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     int   small,
5480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     void* unused,
5481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     int   nUnused )
5482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile* bzf = NULL;
5484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int     ret;
5485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (f == NULL ||
5489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (small != 0 && small != 1) ||
5490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (verbosity < 0 || verbosity > 4) ||
5491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (unused == NULL && nUnused != 0) ||
5492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
5493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
5494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ferror(f))
5496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
5497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf = malloc ( sizeof(bzFile) );
5499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf == NULL)
5500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
5501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->initialisedOk = False;
5505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->handle        = f;
5506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->bufN          = 0;
5507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->writing       = False;
5508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.bzalloc  = NULL;
5509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.bzfree   = NULL;
5510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.opaque   = NULL;
5511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (nUnused > 0) {
5513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
5514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      unused = ((void*)( 1 + ((UChar*)(unused))  ));
5515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nUnused--;
5516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
5519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret != BZ_OK)
5520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
5521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.avail_in = bzf->bufN;
5523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.next_in  = bzf->buf;
5524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->initialisedOk = True;
5526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return bzf;
5527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
5532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile* bzf = (bzFile*)b;
5534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf == NULL)
5537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_OK); return; };
5538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf->writing)
5540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf->initialisedOk)
5543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
5544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   free ( bzf );
5545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzRead)
5550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           ( int*    bzerror,
5551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             BZFILE* b,
5552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             void*   buf,
5553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             int     len )
5554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int32   n, ret;
5556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile* bzf = (bzFile*)b;
5557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf == NULL || buf == NULL || len < 0)
5561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
5562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf->writing)
5564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
5565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (len == 0)
5567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_OK); return 0; };
5568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.avail_out = len;
5570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzf->strm.next_out = buf;
5571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
5573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ferror(bzf->handle))
5575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(BZ_IO_ERROR); return 0; };
5576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
5578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n = fread ( bzf->buf, sizeof(UChar),
5579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     BZ_MAX_UNUSED, bzf->handle );
5580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ferror(bzf->handle))
5581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            { BZ_SETERR(BZ_IO_ERROR); return 0; };
5582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         bzf->bufN = n;
5583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         bzf->strm.avail_in = bzf->bufN;
5584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         bzf->strm.next_in = bzf->buf;
5585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ret = BZ2_bzDecompress ( &(bzf->strm) );
5588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ret != BZ_OK && ret != BZ_STREAM_END)
5590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(ret); return 0; };
5591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ret == BZ_OK && myfeof(bzf->handle) &&
5593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
5594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
5595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (ret == BZ_STREAM_END)
5597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(BZ_STREAM_END);
5598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           return len - bzf->strm.avail_out; };
5599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (bzf->strm.avail_out == 0)
5600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         { BZ_SETERR(BZ_OK); return len; };
5601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0; /*not reached*/
5605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ_API(BZ2_bzReadGetUnused)
5610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     ( int*    bzerror,
5611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       BZFILE* b,
5612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       void**  unused,
5613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       int*    nUnused )
5614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bzFile* bzf = (bzFile*)b;
5616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf == NULL)
5617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
5618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzf->lastErr != BZ_STREAM_END)
5619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (unused == NULL || nUnused == NULL)
5621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
5622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ_SETERR(BZ_OK);
5624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *nUnused = bzf->strm.avail_in;
5625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *unused = bzf->strm.next_in;
5626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
5628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Misc convenience stuff                      ---*/
5632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzBuffToBuffCompress)
5636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         ( char*         dest,
5637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unsigned int* destLen,
5638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           char*         source,
5639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unsigned int  sourceLen,
5640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           int           blockSize100k,
5641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           int           verbosity,
5642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           int           workFactor )
5643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bz_stream strm;
5645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int ret;
5646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dest == NULL || destLen == NULL ||
5648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       source == NULL ||
5649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       blockSize100k < 1 || blockSize100k > 9 ||
5650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       verbosity < 0 || verbosity > 4 ||
5651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       workFactor < 0 || workFactor > 250)
5652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return BZ_PARAM_ERROR;
5653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (workFactor == 0) workFactor = 30;
5655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.bzalloc = NULL;
5656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.bzfree = NULL;
5657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.opaque = NULL;
5658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret = BZ2_bzCompressInit ( &strm, blockSize100k,
5659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                              verbosity, workFactor );
5660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret != BZ_OK) return ret;
5661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.next_in = source;
5663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.next_out = dest;
5664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.avail_in = sourceLen;
5665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.avail_out = *destLen;
5666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
5668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret == BZ_FINISH_OK) goto output_overflow;
5669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret != BZ_STREAM_END) goto errhandler;
5670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* normal termination */
5672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *destLen -= strm.avail_out;
5673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzCompressEnd ( &strm );
5674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OK;
5675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   output_overflow:
5677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzCompressEnd ( &strm );
5678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OUTBUFF_FULL;
5679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   errhandler:
5681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzCompressEnd ( &strm );
5682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return ret;
5683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzBuffToBuffDecompress)
5688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           ( char*         dest,
5689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             unsigned int* destLen,
5690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             char*         source,
5691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             unsigned int  sourceLen,
5692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             int           small,
5693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             int           verbosity )
5694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bz_stream strm;
5696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int ret;
5697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dest == NULL || destLen == NULL ||
5699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       source == NULL ||
5700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       (small != 0 && small != 1) ||
5701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       verbosity < 0 || verbosity > 4)
5702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          return BZ_PARAM_ERROR;
5703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.bzalloc = NULL;
5705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.bzfree = NULL;
5706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.opaque = NULL;
5707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
5708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret != BZ_OK) return ret;
5709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.next_in = source;
5711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.next_out = dest;
5712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.avail_in = sourceLen;
5713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strm.avail_out = *destLen;
5714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ret = BZ2_bzDecompress ( &strm );
5716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret == BZ_OK) goto output_overflow_or_eof;
5717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (ret != BZ_STREAM_END) goto errhandler;
5718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* normal termination */
5720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *destLen -= strm.avail_out;
5721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzDecompressEnd ( &strm );
5722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_OK;
5723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   output_overflow_or_eof:
5725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (strm.avail_out > 0) {
5726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ2_bzDecompressEnd ( &strm );
5727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return BZ_UNEXPECTED_EOF;
5728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
5729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ2_bzDecompressEnd ( &strm );
5730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return BZ_OUTBUFF_FULL;
5731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   };
5732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   errhandler:
5734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzDecompressEnd ( &strm );
5735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return ret;
5736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
5741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Code contributed by Yoshioka Tsuneo
5742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
5743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   to support better zlib compatibility.
5744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This code is not _officially_ part of libbzip2 (yet);
5745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   I haven't tested it, documented it, or considered the
5746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   threading-safeness of it.
5747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   If this code breaks, please contact both Yoshioka and me.
5748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
5749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
5753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return version like "0.9.0c".
5754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
5755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst char * BZ_API(BZ2_bzlibVersion)(void)
5756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return BZ_VERSION;
5758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifndef BZ_NO_STDIO
5762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
5765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   include <fcntl.h>
5766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   include <io.h>
5767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
5768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#else
5769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#   define SET_BINARY_MODE(file)
5770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
5771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
5772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZFILE * bzopen_or_bzdopen
5773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ( const char *path,   /* no use when bzdopen */
5774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 int fd,             /* no use when bzdopen */
5775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 const char *mode,
5776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 int open_mode)      /* bzopen: 0, bzdopen:1 */
5777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int    bzerr;
5779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   char   unused[BZ_MAX_UNUSED];
5780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int    blockSize100k = 9;
5781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int    writing       = 0;
5782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   char   mode2[10]     = "";
5783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   FILE   *fp           = NULL;
5784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZFILE *bzfp         = NULL;
5785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int    verbosity     = 0;
5786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int    workFactor    = 30;
5787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int    smallMode     = 0;
5788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int    nUnused       = 0;
5789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (mode == NULL) return NULL;
5791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (*mode) {
5792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      switch (*mode) {
5793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 'r':
5794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         writing = 0; break;
5795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 'w':
5796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         writing = 1; break;
5797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 's':
5798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         smallMode = 1; break;
5799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      default:
5800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (isdigit((int)(*mode))) {
5801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            blockSize100k = *mode-BZ_HDR_0;
5802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
5803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      mode++;
5805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strcat(mode2, writing ? "w" : "r" );
5807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   strcat(mode2,"b");   /* binary mode */
5808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (open_mode==0) {
5810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (path==NULL || strcmp(path,"")==0) {
5811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        fp = (writing ? stdout : stdin);
5812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        SET_BINARY_MODE(fp);
5813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
5814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        fp = fopen(path,mode2);
5815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
5817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#ifdef BZ_STRICT_ANSI
5818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fp = NULL;
5819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#else
5820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fp = fdopen(fd,mode2);
5821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
5822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (fp == NULL) return NULL;
5824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (writing) {
5826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Guard against total chaos and anarchy -- JRS */
5827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (blockSize100k < 1) blockSize100k = 1;
5828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (blockSize100k > 9) blockSize100k = 9;
5829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
5830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             verbosity,workFactor);
5831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
5832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
5833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            unused,nUnused);
5834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzfp == NULL) {
5836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (fp != stdin && fp != stdout) fclose(fp);
5837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return NULL;
5838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return bzfp;
5840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
5845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   open file for read or write.
5846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ex) bzopen("file","w9")
5847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case path="" or NULL => use stdin or stdout.
5848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
5849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZFILE * BZ_API(BZ2_bzopen)
5850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ( const char *path,
5851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 const char *mode )
5852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
5854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBZFILE * BZ_API(BZ2_bzdopen)
5859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               ( int fd,
5860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 const char *mode )
5861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
5863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
5868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int bzerr, nread;
5870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
5871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nread = BZ2_bzRead(&bzerr,b,buf,len);
5872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
5873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return nread;
5874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
5875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return -1;
5876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
5882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int bzerr;
5884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   BZ2_bzWrite(&bzerr,b,buf,len);
5886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if(bzerr == BZ_OK){
5887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return len;
5888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }else{
5889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return -1;
5890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint BZ_API(BZ2_bzflush) (BZFILE *b)
5896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* do nothing now... */
5898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0;
5899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid BZ_API(BZ2_bzclose) (BZFILE* b)
5904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int bzerr;
5906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   FILE *fp = ((bzFile *)b)->handle;
5907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (b==NULL) {return;}
5909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if(((bzFile*)b)->writing){
5910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
5911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if(bzerr != BZ_OK){
5912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
5913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }else{
5915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      BZ2_bzReadClose(&bzerr,b);
5916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if(fp!=stdin && fp!=stdout){
5918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      fclose(fp);
5919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---------------------------------------------------*/
5924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--
5925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return last error code
5926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj--*/
5927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic char *bzerrorstrings[] = {
5928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       "OK"
5929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"SEQUENCE_ERROR"
5930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"PARAM_ERROR"
5931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"MEM_ERROR"
5932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"DATA_ERROR"
5933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"DATA_ERROR_MAGIC"
5934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"IO_ERROR"
5935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"UNEXPECTED_EOF"
5936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"OUTBUFF_FULL"
5937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"CONFIG_ERROR"
5938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
5939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
5940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
5941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
5942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
5943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
5944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj};
5945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjconst char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
5948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int err = ((bzFile *)b)->lastErr;
5950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if(err>0) err = 0;
5952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *errnum = err;
5953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return bzerrorstrings[err*-1];
5954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
5956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
5959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- end                                           bzlib.c ---*/
5960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*-------------------------------------------------------------*/
5961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
5964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/////////////////////////////////////////////////////////////////////
5965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* A test program written to test robustness to decompression of
5968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   corrupted data.  Usage is
5969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       unzcrash filename
5970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   and the program will read the specified file, compress it (in memory),
5971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   and then repeatedly decompress it, each time with a different bit of
5972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   the compressed data inverted, so as to test all possible one-bit errors.
5973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This should not cause any invalid memory accesses.  If it does,
5974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   I want to know about it!
5975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   p.s.  As you can see from the above description, the process is
5977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   incredibly slow.  A file of size eg 5KB will cause it to run for
5978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   many hours.
5979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
5980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj//#include <stdio.h>
5982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj//#include <assert.h>
5983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj//#include "bzlib.h"
5984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define M_BLOCK 1000000
5986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define M_BLOCK_OUT (M_BLOCK + 1000000)
5989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj char inbuf[M_BLOCK];
5990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj char outbuf[M_BLOCK_OUT];
5991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj char zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
5992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint nIn;
5994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjunsigned int nOut;
5995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjunsigned int nZ;
5996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
5998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic char *bzerrorstrings[] = {
5999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       "OK"
6000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"SEQUENCE_ERROR"
6001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"PARAM_ERROR"
6002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"MEM_ERROR"
6003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"DATA_ERROR"
6004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"DATA_ERROR_MAGIC"
6005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"IO_ERROR"
6006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"UNEXPECTED_EOF"
6007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"OUTBUFF_FULL"
6008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
6009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
6010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
6011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
6012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
6013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ,"???"   /* for future */
6014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj};
6015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
6016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid flip_bit ( int bit )
6018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
6019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int byteno = bit / 8;
6020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int bitno  = bit % 8;
6021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar mask = 1 << bitno;
6022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
6023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   //          byteno, bitno, (int)mask );
6024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zbuf[byteno] ^= mask;
6025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
6026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid set_inbuf ( void )
6028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
6029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  inbuf[0] = 0;
6030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "At her sixtieth birthday party, Margaret Thatcher ");
6031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "blew on the cake to light the candles.\n");
6032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "This program, bzip2, the associated library libbzip2, and all\n");
6033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "documentation, are copyright (C) 1996-2004 Julian R Seward.  All\n");
6034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "rights reserved.\n");
6035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Redistribution and use in source and binary forms, with or without\n");
6037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "modification, are permitted provided that the following conditions\n");
6038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "are met:\n");
6039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "1. Redistributions of source code must retain the above copyright\n");
6041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   notice, this list of conditions and the following disclaimer.\n");
6042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "2. The origin of this software must not be misrepresented; you must\n");
6044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   not claim that you wrote the original software.  If you use this\n");
6045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   software in a product, an acknowledgment in the product\n");
6046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   documentation would be appreciated but is not required.\n");
6047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "3. Altered source versions must be plainly marked as such, and must\n");
6049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   not be misrepresented as being the original software.\n");
6050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "4. The name of the author may not be used to endorse or promote\n");
6052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   products derived from this software without specific prior written\n");
6053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   permission.\n");
6054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n");
6056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n");
6057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n");
6058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n");
6059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n");
6060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n");
6061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n");
6062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n");
6063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n");
6064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n");
6065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n");
6066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "		    GNU GENERAL PUBLIC LICENSE\n");
6109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "		       Version 2, June 1991\n");
6110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n");
6112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n");
6113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, " Everyone is permitted to copy and distribute verbatim copies\n");
6114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, " of this license document, but changing it is not allowed.\n");
6115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "			    Preamble\n");
6117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  The licenses for most software are designed to take away your\n");
6119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "freedom to share and change it.  By contrast, the GNU General Public\n");
6120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "License is intended to guarantee your freedom to share and change free\n");
6121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "software--to make sure the software is free for all its users.  This\n");
6122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "General Public License applies to most of the Free Software\n");
6123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Foundation's software and to any other program whose authors commit to\n");
6124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "using it.  (Some other Free Software Foundation software is covered by\n");
6125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "the GNU Library General Public License instead.)  You can apply it to\n");
6126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "your programs, too.\n");
6127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  When we speak of free software, we are referring to freedom, not\n");
6129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "price.  Our General Public Licenses are designed to make sure that you\n");
6130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "have the freedom to distribute copies of free software (and charge for\n");
6131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "this service if you wish), that you receive source code or can get it\n");
6132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "if you want it, that you can change the software or use pieces of it\n");
6133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "in new free programs; and that you know you can do these things.\n");
6134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  To protect your rights, we need to make restrictions that forbid\n");
6136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "anyone to deny you these rights or to ask you to surrender the rights.\n");
6137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "These restrictions translate to certain responsibilities for you if you\n");
6138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "distribute copies of the software, or if you modify it.\n");
6139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  For example, if you distribute copies of such a program, whether\n");
6141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "gratis or for a fee, you must give the recipients all the rights that\n");
6142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "you have.  You must make sure that they, too, receive or can get the\n");
6143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "source code.  And you must show them these terms so they know their\n");
6144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "rights.\n");
6145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  We protect your rights with two steps: (1) copyright the software, and\n");
6147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "(2) offer you this license which gives you legal permission to copy,\n");
6148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "distribute and/or modify the software.\n");
6149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  Also, for each author's protection and ours, we want to make certain\n");
6151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "that everyone understands that there is no warranty for this free\n");
6152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "software.  If the software is modified by someone else and passed on, we\n");
6153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "want its recipients to know that what they have is not the original, so\n");
6154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "that any problems introduced by others will not reflect on the original\n");
6155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "authors' reputations.\n");
6156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  Finally, any free program is threatened constantly by software\n");
6158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "patents.  We wish to avoid the danger that redistributors of a free\n");
6159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "program will individually obtain patent licenses, in effect making the\n");
6160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "program proprietary.  To prevent this, we have made it clear that any\n");
6161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "patent must be licensed for everyone's free use or not licensed at all.\n");
6162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  The precise terms and conditions for copying, distribution and\n");
6164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "modification follow.\n");
6165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "		    GNU GENERAL PUBLIC LICENSE\n");
6167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n");
6168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  0. This License applies to any program or other work which contains\n");
6170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "a notice placed by the copyright holder saying it may be distributed\n");
6171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "under the terms of this General Public License.  The Program, below,\n");
6172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "refers to any such program or work, and a work based on the Program\n");
6173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "means either the Program or any derivative work under copyright law:\n");
6174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "that is to say, a work containing the Program or a portion of it,\n");
6175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "either verbatim or with modifications and/or translated into another\n");
6176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "language.  (Hereinafter, translation is included without limitation in\n");
6177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "the term modification.)  Each licensee is addressed as you.\n");
6178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Activities other than copying, distribution and modification are not\n");
6180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "covered by this License; they are outside its scope.  The act of\n");
6181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "running the Program is not restricted, and the output from the Program\n");
6182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "is covered only if its contents constitute a work based on the\n");
6183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Program (independent of having been made by running the Program).\n");
6184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Whether that is true depends on what the Program does.\n");
6185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  1. You may copy and distribute verbatim copies of the Program's\n");
6187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "source code as you receive it, in any medium, provided that you\n");
6188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "conspicuously and appropriately publish on each copy an appropriate\n");
6189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "copyright notice and disclaimer of warranty; keep intact all the\n");
6190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "notices that refer to this License and to the absence of any warranty;\n");
6191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "and give any other recipients of the Program a copy of this License\n");
6192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "along with the Program.\n");
6193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "You may charge a fee for the physical act of transferring a copy, and\n");
6195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "you may at your option offer warranty protection in exchange for a fee.\n");
6196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  2. You may modify your copy or copies of the Program or any portion\n");
6198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "of it, thus forming a work based on the Program, and copy and\n");
6199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "distribute such modifications or work under the terms of Section 1\n");
6200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "above, provided that you also meet all of these conditions:\n");
6201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    a) You must cause the modified files to carry prominent notices\n");
6203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    stating that you changed the files and the date of any change.\n");
6204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    b) You must cause any work that you distribute or publish, that in\n");
6206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    whole or in part contains or is derived from the Program or any\n");
6207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    part thereof, to be licensed as a whole at no charge to all third\n");
6208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    parties under the terms of this License.\n");
6209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    c) If the modified program normally reads commands interactively\n");
6211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    when run, you must cause it, when started running for such\n");
6212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    interactive use in the most ordinary way, to print or display an\n");
6213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    announcement including an appropriate copyright notice and a\n");
6214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    notice that there is no warranty (or else, saying that you provide\n");
6215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    a warranty) and that users may redistribute the program under\n");
6216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    these conditions, and telling the user how to view a copy of this\n");
6217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    License.  (Exception: if the Program itself is interactive but\n");
6218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    does not normally print such an announcement, your work based on\n");
6219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    the Program is not required to print an announcement.)\n");
6220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "These requirements apply to the modified work as a whole.  If\n");
6222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "identifiable sections of that work are not derived from the Program,\n");
6223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "and can be reasonably considered independent and separate works in\n");
6224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "themselves, then this License, and its terms, do not apply to those\n");
6225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "sections when you distribute them as separate works.  But when you\n");
6226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "distribute the same sections as part of a whole which is a work based\n");
6227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "on the Program, the distribution of the whole must be on the terms of\n");
6228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "this License, whose permissions for other licensees extend to the\n");
6229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "entire whole, and thus to each and every part regardless of who wrote it.\n");
6230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Thus, it is not the intent of this section to claim rights or contest\n");
6232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "your rights to work written entirely by you; rather, the intent is to\n");
6233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "exercise the right to control the distribution of derivative or\n");
6234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "collective works based on the Program.\n");
6235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "In addition, mere aggregation of another work not based on the Program\n");
6237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "with the Program (or with a work based on the Program) on a volume of\n");
6238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "a storage or distribution medium does not bring the other work under\n");
6239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "the scope of this License.\n");
6240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  3. You may copy and distribute the Program (or a work based on it,\n");
6242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "under Section 2) in object code or executable form under the terms of\n");
6243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Sections 1 and 2 above provided that you also do one of the following:\n");
6244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    a) Accompany it with the complete corresponding machine-readable\n");
6246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    source code, which must be distributed under the terms of Sections\n");
6247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    1 and 2 above on a medium customarily used for software interchange; or,\n");
6248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    b) Accompany it with a written offer, valid for at least three\n");
6250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    years, to give any third party, for a charge no more than your\n");
6251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    cost of physically performing source distribution, a complete\n");
6252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    machine-readable copy of the corresponding source code, to be\n");
6253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    distributed under the terms of Sections 1 and 2 above on a medium\n");
6254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    customarily used for software interchange; or,\n");
6255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    c) Accompany it with the information you received as to the offer\n");
6257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    to distribute corresponding source code.  (This alternative is\n");
6258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    allowed only for noncommercial distribution and only if you\n");
6259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    received the program in object code or executable form with such\n");
6260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    an offer, in accord with Subsection b above.)\n");
6261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "The source code for a work means the preferred form of the work for\n");
6263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "making modifications to it.  For an executable work, complete source\n");
6264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "code means all the source code for all modules it contains, plus any\n");
6265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "associated interface definition files, plus the scripts used to\n");
6266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "control compilation and installation of the executable.  However, as a\n");
6267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "special exception, the source code distributed need not include\n");
6268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "anything that is normally distributed (in either source or binary\n");
6269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "form) with the major components (compiler, kernel, and so on) of the\n");
6270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "operating system on which the executable runs, unless that component\n");
6271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "itself accompanies the executable.\n");
6272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "If distribution of executable or object code is made by offering\n");
6274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "access to copy from a designated place, then offering equivalent\n");
6275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "access to copy the source code from the same place counts as\n");
6276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "distribution of the source code, even though third parties are not\n");
6277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "compelled to copy the source along with the object code.\n");
6278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  4. You may not copy, modify, sublicense, or distribute the Program\n");
6280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "except as expressly provided under this License.  Any attempt\n");
6281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "otherwise to copy, modify, sublicense or distribute the Program is\n");
6282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "void, and will automatically terminate your rights under this License.\n");
6283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "However, parties who have received copies, or rights, from you under\n");
6284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "this License will not have their licenses terminated so long as such\n");
6285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "parties remain in full compliance.\n");
6286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  5. You are not required to accept this License, since you have not\n");
6288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "signed it.  However, nothing else grants you permission to modify or\n");
6289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "distribute the Program or its derivative works.  These actions are\n");
6290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "prohibited by law if you do not accept this License.  Therefore, by\n");
6291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "modifying or distributing the Program (or any work based on the\n");
6292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Program), you indicate your acceptance of this License to do so, and\n");
6293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "all its terms and conditions for copying, distributing or modifying\n");
6294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "the Program or works based on it.\n");
6295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  6. Each time you redistribute the Program (or any work based on the\n");
6297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Program), the recipient automatically receives a license from the\n");
6298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "original licensor to copy, distribute or modify the Program subject to\n");
6299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "these terms and conditions.  You may not impose any further\n");
6300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "restrictions on the recipients' exercise of the rights granted herein.\n");
6301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "You are not responsible for enforcing compliance by third parties to\n");
6302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "this License.\n");
6303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  7. If, as a consequence of a court judgment or allegation of patent\n");
6305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "infringement or for any other reason (not limited to patent issues),\n");
6306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "conditions are imposed on you (whether by court order, agreement or\n");
6307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "otherwise) that contradict the conditions of this License, they do not\n");
6308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "excuse you from the conditions of this License.  If you cannot\n");
6309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "distribute so as to satisfy simultaneously your obligations under this\n");
6310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "License and any other pertinent obligations, then as a consequence you\n");
6311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "may not distribute the Program at all.  For example, if a patent\n");
6312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "license would not permit royalty-free redistribution of the Program by\n");
6313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "all those who receive copies directly or indirectly through you, then\n");
6314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "the only way you could satisfy both it and this License would be to\n");
6315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "refrain entirely from distribution of the Program.\n");
6316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "If any portion of this section is held invalid or unenforceable under\n");
6318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "any particular circumstance, the balance of the section is intended to\n");
6319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "apply and the section as a whole is intended to apply in other\n");
6320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "circumstances.\n");
6321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "It is not the purpose of this section to induce you to infringe any\n");
6323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "patents or other property right claims or to contest validity of any\n");
6324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "such claims; this section has the sole purpose of protecting the\n");
6325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "integrity of the free software distribution system, which is\n");
6326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "implemented by public license practices.  Many people have made\n");
6327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "generous contributions to the wide range of software distributed\n");
6328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "through that system in reliance on consistent application of that\n");
6329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "system; it is up to the author/donor to decide if he or she is willing\n");
6330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "to distribute software through any other system and a licensee cannot\n");
6331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "impose that choice.\n");
6332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "This section is intended to make thoroughly clear what is believed to\n");
6334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "be a consequence of the rest of this License.\n");
6335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  8. If the distribution and/or use of the Program is restricted in\n");
6337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "certain countries either by patents or by copyrighted interfaces, the\n");
6338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "original copyright holder who places the Program under this License\n");
6339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "may add an explicit geographical distribution limitation excluding\n");
6340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "those countries, so that distribution is permitted only in or among\n");
6341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "countries not thus excluded.  In such case, this License incorporates\n");
6342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "the limitation as if written in the body of this License.\n");
6343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  9. The Free Software Foundation may publish revised and/or new versions\n");
6345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "of the General Public License from time to time.  Such new versions will\n");
6346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "be similar in spirit to the present version, but may differ in detail to\n");
6347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "address new problems or concerns.\n");
6348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Each version is given a distinguishing version number.  If the Program\n");
6350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "specifies a version number of this License which applies to it and any\n");
6351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "later version, you have the option of following the terms and conditions\n");
6352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "either of that version or of any later version published by the Free\n");
6353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Software Foundation.  If the Program does not specify a version number of\n");
6354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "this License, you may choose any version ever published by the Free Software\n");
6355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Foundation.\n");
6356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  10. If you wish to incorporate parts of the Program into other free\n");
6358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "programs whose distribution conditions are different, write to the author\n");
6359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "to ask for permission.  For software which is copyrighted by the Free\n");
6360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Software Foundation, write to the Free Software Foundation; we sometimes\n");
6361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "make exceptions for this.  Our decision will be guided by the two goals\n");
6362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "of preserving the free status of all derivatives of our free software and\n");
6363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "of promoting the sharing and reuse of software generally.\n");
6364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "			    NO WARRANTY\n");
6366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n");
6368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n");
6369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n");
6370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "PROVIDE THE PROGRAM AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n");
6371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n");
6372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n");
6373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n");
6374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n");
6375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "REPAIR OR CORRECTION.\n");
6376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n");
6378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n");
6379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n");
6380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n");
6381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n");
6382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n");
6383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n");
6384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n");
6385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "POSSIBILITY OF SUCH DAMAGES.\n");
6386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "		     END OF TERMS AND CONDITIONS\n");
6388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "	    How to Apply These Terms to Your New Programs\n");
6390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  If you develop a new program, and you want it to be of the greatest\n");
6392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "possible use to the public, the best way to achieve this is to make it\n");
6393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "free software which everyone can redistribute and change under these terms.\n");
6394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  To do so, attach the following notices to the program.  It is safest\n");
6396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "to attach them to the start of each source file to most effectively\n");
6397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "convey the exclusion of warranty; and each file should have at least\n");
6398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "the copyright line and a pointer to where the full notice is found.\n");
6399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    <one line to give the program's name and a brief idea of what it does.>\n");
6401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    Copyright (C) <year>  <name of author>\n");
6402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    This program is free software; you can redistribute it and/or modify\n");
6404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    it under the terms of the GNU General Public License as published by\n");
6405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    the Free Software Foundation; either version 2 of the License, or\n");
6406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    (at your option) any later version.\n");
6407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    This program is distributed in the hope that it will be useful,\n");
6409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
6410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
6411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    GNU General Public License for more details.\n");
6412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    You should have received a copy of the GNU General Public License\n");
6414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    along with this program; if not, write to the Free Software\n");
6415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n");
6416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Also add information on how to contact you by electronic and paper mail.\n");
6419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "If the program is interactive, make it output a short notice like this\n");
6421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "when it starts in an interactive mode:\n");
6422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    Gnomovision version 69, Copyright (C) year  name of author\n");
6424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n");
6425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    This is free software, and you are welcome to redistribute it\n");
6426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "    under certain conditions; type `show c' for details.\n");
6427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "The hypothetical commands `show w' and `show c' should show the appropriate\n");
6429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "parts of the General Public License.  Of course, the commands you use may\n");
6430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "be called something other than `show w' and `show c'; they could even be\n");
6431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "mouse-clicks or menu items--whatever suits your program.\n");
6432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "You should also get your employer (if you work as a programmer) or your\n");
6434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "school, if any, to sign a copyright disclaimer for the program, if\n");
6435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "necessary.  Here is a sample; alter the names:\n");
6436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n");
6438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n");
6439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  <signature of Ty Coon>, 1 April 1989\n");
6441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "  Ty Coon, President of Vice\n");
6442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "This General Public License does not permit incorporating your program into\n");
6444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "proprietary programs.  If your program is a subroutine library, you may\n");
6445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "consider it more useful to permit linking proprietary applications with the\n");
6446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "library.  If this is what you want to do, use the GNU Library General\n");
6447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "Public License instead of this License.\n");
6448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  my_strcat(inbuf, "\n");
6450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
6451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6452d3e4dd9f322e1746ee90fb9363d11654c5101502njn
6453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <stdio.h>
6454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include <assert.h>
6455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* For providing services. */
6457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic HWord g_serviceFn ( HWord arg1, HWord arg2 )
6458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
6459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   switch (arg1) {
6460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 0: /* EXIT */
6461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         exit(0);
6462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 1: /* PUTC */
6463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         putchar(arg2);
6464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return 0;
6465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 2: /* MALLOC */
6466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return (HWord)malloc(arg2);
6467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case 3: /* FREE */
6468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         free((void*)arg2);
6469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         return 0;
6470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      default:
6471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         assert(0);
6472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
6473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0;
6474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
6475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic char *bzerrorstrings[] = {
6476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       "OK"
6477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"SEQUENCE_ERROR"
6478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"PARAM_ERROR"
6479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"MEM_ERROR"
6480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"DATA_ERROR"
6481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"DATA_ERROR_MAGIC"
6482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"IO_ERROR"
6483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"UNEXPECTED_EOF"
6484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"OUTBUFF_FULL"
6485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"CONFIG_ERROR"
6486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"???"   /* for future */
6487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"???"   /* for future */
6488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"???"   /* for future */
6489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"???"   /* for future */
6490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"???"   /* for future */
6491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       ,"???"   /* for future */
6492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj};
6493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// If given a cmd line arg, behave as a correctness regtest
6495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// (run fast and be verbose).  If not, run for a long time
6496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj// which is what is needed for the performance suite.
6497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjint main ( int argc, char** argv )
6498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
6499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int   r;
6500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int   bit;
6501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int   i;
6502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   int regtest;
6504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   assert(argc == 1 || argc == 2);
6505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   regtest = argc==2;
6506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* hardwire one particular behaviour */
6508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   regtest = 1;
6509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   serviceFn = g_serviceFn;
6511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_inbuf();
6513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nIn = vex_strlen(inbuf)+1;
6514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf( "%d bytes read\n", nIn );
6515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nZ = M_BLOCK;
6517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   r = BZ2_bzBuffToBuffCompress (
6518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          zbuf, &nZ, inbuf, nIn, 9, 3/*verb*/, 30 );
6519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (r != BZ_OK) {
6521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     vex_printf("initial compress failed!\n");
6522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     (*serviceFn)(0,0);
6523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
6524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf( "%d after compression\n", nZ );
6525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (bit = 0; bit < nZ*8; bit += (bit < 35 ? 3 : (regtest?2377:137))) {
6527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     if (bit >= 11920) break;
6528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (regtest)
6529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vex_printf( "bit %d  ", bit );
6530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      flip_bit ( bit );
6531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      nOut = M_BLOCK_OUT;
6532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      r = BZ2_bzBuffToBuffDecompress (
6533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             outbuf, &nOut, zbuf, nZ, 1/*small*/, 0 );
6534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (regtest)
6535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vex_printf( " %d  %s ", r, bzerrorstrings[-r] );
6536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (r != BZ_OK) {
6538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 if (regtest)
6539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vex_printf( "\n" );
6540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
6541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nOut != nIn) {
6542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vex_printf(  "nIn/nOut mismatch %d %d\n", nIn, nOut );
6543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           (*serviceFn)(0,0);
6544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
6545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           for (i = 0; i < nOut; i++)
6546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             if (inbuf[i] != outbuf[i]) {
6547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                vex_printf(  "mismatch at %d\n", i );
6548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                (*serviceFn)(0,0);
6549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           }
6550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           if (i == nOut) vex_printf( "really ok!\n" );
6551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
6552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
6553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      flip_bit ( bit );
6555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
6556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
6558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   assert (nOut == nIn);
6559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < nOut; i++) {
6560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     if (inbuf[i] != outbuf[i]) {
6561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        vex_printf( "difference at %d !\n", i );
6562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        return 1;
6563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     }
6564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
6565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
6566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vex_printf( "all ok\n" );
6568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (*serviceFn)(0,0);
6569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
6570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0;
6571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
6572