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