1024598e40c84666cc311a42c256bbf880db3ac99sewardj
2024598e40c84666cc311a42c256bbf880db3ac99sewardj/* This is a very slightly modified version of perf/bz2.c, with a
3024598e40c84666cc311a42c256bbf880db3ac99sewardj   single change that causes it to overrun a global array by one byte.
4024598e40c84666cc311a42c256bbf880db3ac99sewardj   The change in question is a change of the size of myprintf_buf from
5024598e40c84666cc311a42c256bbf880db3ac99sewardj   1000 to 70, at line 1278.  ptrcheck should report exactly one
6024598e40c84666cc311a42c256bbf880db3ac99sewardj   error, resulting from an out of range access to this array. */
7024598e40c84666cc311a42c256bbf880db3ac99sewardj
8024598e40c84666cc311a42c256bbf880db3ac99sewardj// This benchmark is basically bzip2 (mashed to be a single file)
9024598e40c84666cc311a42c256bbf880db3ac99sewardj// compressing and decompressing some data.  It tests Valgrind's handling of
10024598e40c84666cc311a42c256bbf880db3ac99sewardj// realistic and "difficult" (ie. lots of branches and memory accesses)
11024598e40c84666cc311a42c256bbf880db3ac99sewardj// integer code.  Execution is spread out over quite a few basic blocks;
12024598e40c84666cc311a42c256bbf880db3ac99sewardj// --profile-flags indicates that to get to the top 90%th percentile of
13024598e40c84666cc311a42c256bbf880db3ac99sewardj// dynamic BB counts requires considering the top 51 basic blocks
14024598e40c84666cc311a42c256bbf880db3ac99sewardj
15024598e40c84666cc311a42c256bbf880db3ac99sewardj// This program can be used both as part of the performance test
16024598e40c84666cc311a42c256bbf880db3ac99sewardj// suite, in which case we want it to run for quite a while,
17024598e40c84666cc311a42c256bbf880db3ac99sewardj// and as part of the regression (correctness) test suite, in
18024598e40c84666cc311a42c256bbf880db3ac99sewardj// which case we want it to run quickly and be verbose.
19024598e40c84666cc311a42c256bbf880db3ac99sewardj// So it does the latter iff given a command line arg.
20024598e40c84666cc311a42c256bbf880db3ac99sewardj
21024598e40c84666cc311a42c256bbf880db3ac99sewardj// Licensing: the code within is mostly taken from bzip2, which has a BSD
22024598e40c84666cc311a42c256bbf880db3ac99sewardj// license.  There is a little code from VEX, which is licensed under GPLv2
23024598e40c84666cc311a42c256bbf880db3ac99sewardj// And it's all written by Julian Seward.
24024598e40c84666cc311a42c256bbf880db3ac99sewardj
25024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_NO_STDIO
26024598e40c84666cc311a42c256bbf880db3ac99sewardj
27024598e40c84666cc311a42c256bbf880db3ac99sewardj
28024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
29024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Private header file for the library.                  ---*/
30024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                       bzlib_private.h ---*/
31024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
32024598e40c84666cc311a42c256bbf880db3ac99sewardj
33024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
34024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
35024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
36024598e40c84666cc311a42c256bbf880db3ac99sewardj
37024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
38024598e40c84666cc311a42c256bbf880db3ac99sewardj
39024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
40024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
41024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
42024598e40c84666cc311a42c256bbf880db3ac99sewardj
43024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
44024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
45024598e40c84666cc311a42c256bbf880db3ac99sewardj
46024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
47024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
48024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
49024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
50024598e40c84666cc311a42c256bbf880db3ac99sewardj
51024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
52024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
53024598e40c84666cc311a42c256bbf880db3ac99sewardj
54024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
55024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
56024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
57024598e40c84666cc311a42c256bbf880db3ac99sewardj
58024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
59024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
62024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
64024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
65024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
66024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
67024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
68024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69024598e40c84666cc311a42c256bbf880db3ac99sewardj
70024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
71024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
72024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
73024598e40c84666cc311a42c256bbf880db3ac99sewardj
74024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
75024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
76024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
77024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
78024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
79024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
80024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
81024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
82024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
83024598e40c84666cc311a42c256bbf880db3ac99sewardj
84024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
85024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
86024598e40c84666cc311a42c256bbf880db3ac99sewardj
87024598e40c84666cc311a42c256bbf880db3ac99sewardj
88024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef _BZLIB_PRIVATE_H
89024598e40c84666cc311a42c256bbf880db3ac99sewardj#define _BZLIB_PRIVATE_H
90024598e40c84666cc311a42c256bbf880db3ac99sewardj
91024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <stdlib.h>
92024598e40c84666cc311a42c256bbf880db3ac99sewardj
93024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_NO_STDIO
94024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <stdio.h>
95024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <ctype.h>
96024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <string.h>
97024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
98024598e40c84666cc311a42c256bbf880db3ac99sewardj
99024598e40c84666cc311a42c256bbf880db3ac99sewardj
100024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
101024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Public header file for the library.                   ---*/
102024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                               bzlib.h ---*/
103024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
104024598e40c84666cc311a42c256bbf880db3ac99sewardj
105024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
106024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
107024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
108024598e40c84666cc311a42c256bbf880db3ac99sewardj
109024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
110024598e40c84666cc311a42c256bbf880db3ac99sewardj
111024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
112024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
113024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
114024598e40c84666cc311a42c256bbf880db3ac99sewardj
115024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
116024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
117024598e40c84666cc311a42c256bbf880db3ac99sewardj
118024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
119024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
120024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
121024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
122024598e40c84666cc311a42c256bbf880db3ac99sewardj
123024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
124024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
125024598e40c84666cc311a42c256bbf880db3ac99sewardj
126024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
127024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
128024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
129024598e40c84666cc311a42c256bbf880db3ac99sewardj
130024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
131024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
133024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
134024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
135024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
136024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
137024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
138024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
139024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
140024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
141024598e40c84666cc311a42c256bbf880db3ac99sewardj
142024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
143024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
144024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
145024598e40c84666cc311a42c256bbf880db3ac99sewardj
146024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
147024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
148024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
149024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
150024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
151024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
152024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
153024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
154024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
155024598e40c84666cc311a42c256bbf880db3ac99sewardj
156024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
157024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
158024598e40c84666cc311a42c256bbf880db3ac99sewardj
159024598e40c84666cc311a42c256bbf880db3ac99sewardj
160024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef _BZLIB_H
161024598e40c84666cc311a42c256bbf880db3ac99sewardj#define _BZLIB_H
162024598e40c84666cc311a42c256bbf880db3ac99sewardj
163024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifdef __cplusplus
164024598e40c84666cc311a42c256bbf880db3ac99sewardjextern "C" {
165024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
166024598e40c84666cc311a42c256bbf880db3ac99sewardj
167024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RUN               0
168024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_FLUSH             1
169024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_FINISH            2
170024598e40c84666cc311a42c256bbf880db3ac99sewardj
171024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_OK                0
172024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RUN_OK            1
173024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_FLUSH_OK          2
174024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_FINISH_OK         3
175024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_STREAM_END        4
176024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_SEQUENCE_ERROR    (-1)
177024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_PARAM_ERROR       (-2)
178024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_MEM_ERROR         (-3)
179024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_DATA_ERROR        (-4)
180024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_DATA_ERROR_MAGIC  (-5)
181024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_IO_ERROR          (-6)
182024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_UNEXPECTED_EOF    (-7)
183024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_OUTBUFF_FULL      (-8)
184024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_CONFIG_ERROR      (-9)
185024598e40c84666cc311a42c256bbf880db3ac99sewardj
186024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef
187024598e40c84666cc311a42c256bbf880db3ac99sewardj   struct {
188024598e40c84666cc311a42c256bbf880db3ac99sewardj      char *next_in;
189024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int avail_in;
190024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int total_in_lo32;
191024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int total_in_hi32;
192024598e40c84666cc311a42c256bbf880db3ac99sewardj
193024598e40c84666cc311a42c256bbf880db3ac99sewardj      char *next_out;
194024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int avail_out;
195024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int total_out_lo32;
196024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int total_out_hi32;
197024598e40c84666cc311a42c256bbf880db3ac99sewardj
198024598e40c84666cc311a42c256bbf880db3ac99sewardj      void *state;
199024598e40c84666cc311a42c256bbf880db3ac99sewardj
200024598e40c84666cc311a42c256bbf880db3ac99sewardj      void *(*bzalloc)(void *,int,int);
201024598e40c84666cc311a42c256bbf880db3ac99sewardj      void (*bzfree)(void *,void *);
202024598e40c84666cc311a42c256bbf880db3ac99sewardj      void *opaque;
203024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
204024598e40c84666cc311a42c256bbf880db3ac99sewardj   bz_stream;
205024598e40c84666cc311a42c256bbf880db3ac99sewardj
206024598e40c84666cc311a42c256bbf880db3ac99sewardj
207024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_IMPORT
208024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_EXPORT
209024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
210024598e40c84666cc311a42c256bbf880db3ac99sewardj
211024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_NO_STDIO
212024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Need a definitition for FILE */
213024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <stdio.h>
214024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
215024598e40c84666cc311a42c256bbf880db3ac99sewardj
216024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifdef _WIN32
217024598e40c84666cc311a42c256bbf880db3ac99sewardj#   include <windows.h>
218024598e40c84666cc311a42c256bbf880db3ac99sewardj#   ifdef small
219024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* windows.h define small to char */
220024598e40c84666cc311a42c256bbf880db3ac99sewardj#      undef small
221024598e40c84666cc311a42c256bbf880db3ac99sewardj#   endif
222024598e40c84666cc311a42c256bbf880db3ac99sewardj#   ifdef BZ_EXPORT
223024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define BZ_API(func) WINAPI func
224024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define BZ_EXTERN extern
225024598e40c84666cc311a42c256bbf880db3ac99sewardj#   else
226024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* import windows dll dynamically */
227024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define BZ_API(func) (WINAPI * func)
228024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define BZ_EXTERN
229024598e40c84666cc311a42c256bbf880db3ac99sewardj#   endif
230024598e40c84666cc311a42c256bbf880db3ac99sewardj#else
231024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define BZ_API(func) func
232024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define BZ_EXTERN extern
233024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
234024598e40c84666cc311a42c256bbf880db3ac99sewardj
235024598e40c84666cc311a42c256bbf880db3ac99sewardj
236024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Core (low-level) library functions --*/
237024598e40c84666cc311a42c256bbf880db3ac99sewardj
238024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
239024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream* strm,
240024598e40c84666cc311a42c256bbf880db3ac99sewardj      int        blockSize100k,
241024598e40c84666cc311a42c256bbf880db3ac99sewardj      int        verbosity,
242024598e40c84666cc311a42c256bbf880db3ac99sewardj      int        workFactor
243024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
244024598e40c84666cc311a42c256bbf880db3ac99sewardj
245024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzCompress) (
246024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream* strm,
247024598e40c84666cc311a42c256bbf880db3ac99sewardj      int action
248024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
249024598e40c84666cc311a42c256bbf880db3ac99sewardj
250024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
251024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream* strm
252024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
253024598e40c84666cc311a42c256bbf880db3ac99sewardj
254024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
255024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream *strm,
256024598e40c84666cc311a42c256bbf880db3ac99sewardj      int       verbosity,
257024598e40c84666cc311a42c256bbf880db3ac99sewardj      int       small
258024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
259024598e40c84666cc311a42c256bbf880db3ac99sewardj
260024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzDecompress) (
261024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream* strm
262024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
263024598e40c84666cc311a42c256bbf880db3ac99sewardj
264024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
265024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream *strm
266024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
267024598e40c84666cc311a42c256bbf880db3ac99sewardj
268024598e40c84666cc311a42c256bbf880db3ac99sewardj
269024598e40c84666cc311a42c256bbf880db3ac99sewardj
270024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- High(er) level library functions --*/
271024598e40c84666cc311a42c256bbf880db3ac99sewardj
272024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_NO_STDIO
273024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_MAX_UNUSED 5000
274024598e40c84666cc311a42c256bbf880db3ac99sewardj
275024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef void BZFILE;
276024598e40c84666cc311a42c256bbf880db3ac99sewardj
277024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
278024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*  bzerror,
279024598e40c84666cc311a42c256bbf880db3ac99sewardj      FILE* f,
280024598e40c84666cc311a42c256bbf880db3ac99sewardj      int   verbosity,
281024598e40c84666cc311a42c256bbf880db3ac99sewardj      int   small,
282024598e40c84666cc311a42c256bbf880db3ac99sewardj      void* unused,
283024598e40c84666cc311a42c256bbf880db3ac99sewardj      int   nUnused
284024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
285024598e40c84666cc311a42c256bbf880db3ac99sewardj
286024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN void BZ_API(BZ2_bzReadClose) (
287024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*    bzerror,
288024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b
289024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
290024598e40c84666cc311a42c256bbf880db3ac99sewardj
291024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
292024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*    bzerror,
293024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b,
294024598e40c84666cc311a42c256bbf880db3ac99sewardj      void**  unused,
295024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*    nUnused
296024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
297024598e40c84666cc311a42c256bbf880db3ac99sewardj
298024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzRead) (
299024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*    bzerror,
300024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b,
301024598e40c84666cc311a42c256bbf880db3ac99sewardj      void*   buf,
302024598e40c84666cc311a42c256bbf880db3ac99sewardj      int     len
303024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
304024598e40c84666cc311a42c256bbf880db3ac99sewardj
305024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
306024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*  bzerror,
307024598e40c84666cc311a42c256bbf880db3ac99sewardj      FILE* f,
308024598e40c84666cc311a42c256bbf880db3ac99sewardj      int   blockSize100k,
309024598e40c84666cc311a42c256bbf880db3ac99sewardj      int   verbosity,
310024598e40c84666cc311a42c256bbf880db3ac99sewardj      int   workFactor
311024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
312024598e40c84666cc311a42c256bbf880db3ac99sewardj
313024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN void BZ_API(BZ2_bzWrite) (
314024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*    bzerror,
315024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b,
316024598e40c84666cc311a42c256bbf880db3ac99sewardj      void*   buf,
317024598e40c84666cc311a42c256bbf880db3ac99sewardj      int     len
318024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
319024598e40c84666cc311a42c256bbf880db3ac99sewardj
320024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
321024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*          bzerror,
322024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE*       b,
323024598e40c84666cc311a42c256bbf880db3ac99sewardj      int           abandon,
324024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* nbytes_in,
325024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* nbytes_out
326024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
327024598e40c84666cc311a42c256bbf880db3ac99sewardj
328024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
329024598e40c84666cc311a42c256bbf880db3ac99sewardj      int*          bzerror,
330024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE*       b,
331024598e40c84666cc311a42c256bbf880db3ac99sewardj      int           abandon,
332024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* nbytes_in_lo32,
333024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* nbytes_in_hi32,
334024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* nbytes_out_lo32,
335024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* nbytes_out_hi32
336024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
337024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
338024598e40c84666cc311a42c256bbf880db3ac99sewardj
339024598e40c84666cc311a42c256bbf880db3ac99sewardj
340024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Utility functions --*/
341024598e40c84666cc311a42c256bbf880db3ac99sewardj
342024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
343024598e40c84666cc311a42c256bbf880db3ac99sewardj      char*         dest,
344024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* destLen,
345024598e40c84666cc311a42c256bbf880db3ac99sewardj      char*         source,
346024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int  sourceLen,
347024598e40c84666cc311a42c256bbf880db3ac99sewardj      int           blockSize100k,
348024598e40c84666cc311a42c256bbf880db3ac99sewardj      int           verbosity,
349024598e40c84666cc311a42c256bbf880db3ac99sewardj      int           workFactor
350024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
351024598e40c84666cc311a42c256bbf880db3ac99sewardj
352024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
353024598e40c84666cc311a42c256bbf880db3ac99sewardj      char*         dest,
354024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int* destLen,
355024598e40c84666cc311a42c256bbf880db3ac99sewardj      char*         source,
356024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int  sourceLen,
357024598e40c84666cc311a42c256bbf880db3ac99sewardj      int           small,
358024598e40c84666cc311a42c256bbf880db3ac99sewardj      int           verbosity
359024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
360024598e40c84666cc311a42c256bbf880db3ac99sewardj
361024598e40c84666cc311a42c256bbf880db3ac99sewardj
362024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
363024598e40c84666cc311a42c256bbf880db3ac99sewardj   Code contributed by Yoshioka Tsuneo
364024598e40c84666cc311a42c256bbf880db3ac99sewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
365024598e40c84666cc311a42c256bbf880db3ac99sewardj   to support better zlib compatibility.
366024598e40c84666cc311a42c256bbf880db3ac99sewardj   This code is not _officially_ part of libbzip2 (yet);
367024598e40c84666cc311a42c256bbf880db3ac99sewardj   I haven't tested it, documented it, or considered the
368024598e40c84666cc311a42c256bbf880db3ac99sewardj   threading-safeness of it.
369024598e40c84666cc311a42c256bbf880db3ac99sewardj   If this code breaks, please contact both Yoshioka and me.
370024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
371024598e40c84666cc311a42c256bbf880db3ac99sewardj
372024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
373024598e40c84666cc311a42c256bbf880db3ac99sewardj      void
374024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
375024598e40c84666cc311a42c256bbf880db3ac99sewardj
376024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_NO_STDIO
377024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
378024598e40c84666cc311a42c256bbf880db3ac99sewardj      const char *path,
379024598e40c84666cc311a42c256bbf880db3ac99sewardj      const char *mode
380024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
381024598e40c84666cc311a42c256bbf880db3ac99sewardj
382024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
383024598e40c84666cc311a42c256bbf880db3ac99sewardj      int        fd,
384024598e40c84666cc311a42c256bbf880db3ac99sewardj      const char *mode
385024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
386024598e40c84666cc311a42c256bbf880db3ac99sewardj
387024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzread) (
388024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b,
389024598e40c84666cc311a42c256bbf880db3ac99sewardj      void* buf,
390024598e40c84666cc311a42c256bbf880db3ac99sewardj      int len
391024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
392024598e40c84666cc311a42c256bbf880db3ac99sewardj
393024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzwrite) (
394024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b,
395024598e40c84666cc311a42c256bbf880db3ac99sewardj      void*   buf,
396024598e40c84666cc311a42c256bbf880db3ac99sewardj      int     len
397024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
398024598e40c84666cc311a42c256bbf880db3ac99sewardj
399024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN int BZ_API(BZ2_bzflush) (
400024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b
401024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
402024598e40c84666cc311a42c256bbf880db3ac99sewardj
403024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN void BZ_API(BZ2_bzclose) (
404024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE* b
405024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
406024598e40c84666cc311a42c256bbf880db3ac99sewardj
407024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ_EXTERN const char * BZ_API(BZ2_bzerror) (
408024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZFILE *b,
409024598e40c84666cc311a42c256bbf880db3ac99sewardj      int    *errnum
410024598e40c84666cc311a42c256bbf880db3ac99sewardj   );
411024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
412024598e40c84666cc311a42c256bbf880db3ac99sewardj
413024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifdef __cplusplus
414024598e40c84666cc311a42c256bbf880db3ac99sewardj}
415024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
416024598e40c84666cc311a42c256bbf880db3ac99sewardj
417024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
418024598e40c84666cc311a42c256bbf880db3ac99sewardj
419024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
420024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                           bzlib.h ---*/
421024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
422024598e40c84666cc311a42c256bbf880db3ac99sewardj
423024598e40c84666cc311a42c256bbf880db3ac99sewardj
424024598e40c84666cc311a42c256bbf880db3ac99sewardj
425024598e40c84666cc311a42c256bbf880db3ac99sewardj
426024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- General stuff. --*/
427024598e40c84666cc311a42c256bbf880db3ac99sewardj
428024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_VERSION  "1.0.3, 17-Oct-2004"
429024598e40c84666cc311a42c256bbf880db3ac99sewardj
430024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef char            Char;
431024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef unsigned char   Bool;
432024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef unsigned char   UChar;
433024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef int             Int32;
434024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef unsigned int    UInt32;
435024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef short           Int16;
436024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef unsigned short  UInt16;
437024598e40c84666cc311a42c256bbf880db3ac99sewardj
438024598e40c84666cc311a42c256bbf880db3ac99sewardj#define True  ((Bool)1)
439024598e40c84666cc311a42c256bbf880db3ac99sewardj#define False ((Bool)0)
440024598e40c84666cc311a42c256bbf880db3ac99sewardj
441024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef __GNUC__
442024598e40c84666cc311a42c256bbf880db3ac99sewardj#define __inline__  /* */
443024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
444024598e40c84666cc311a42c256bbf880db3ac99sewardj
445024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_NO_STDIO
446024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void BZ2_bz__AssertH__fail ( int errcode );
447024598e40c84666cc311a42c256bbf880db3ac99sewardj#define AssertH(cond,errcode) \
448024598e40c84666cc311a42c256bbf880db3ac99sewardj   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
449024598e40c84666cc311a42c256bbf880db3ac99sewardj#if BZ_DEBUG
450024598e40c84666cc311a42c256bbf880db3ac99sewardj#define AssertD(cond,msg) \
451024598e40c84666cc311a42c256bbf880db3ac99sewardj   { if (!(cond)) {       \
452024598e40c84666cc311a42c256bbf880db3ac99sewardj      fprintf ( stderr,   \
453024598e40c84666cc311a42c256bbf880db3ac99sewardj        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
454024598e40c84666cc311a42c256bbf880db3ac99sewardj      exit(1); \
455024598e40c84666cc311a42c256bbf880db3ac99sewardj   }}
456024598e40c84666cc311a42c256bbf880db3ac99sewardj#else
457024598e40c84666cc311a42c256bbf880db3ac99sewardj#define AssertD(cond,msg) /* */
458024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
459024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf0(zf) \
460024598e40c84666cc311a42c256bbf880db3ac99sewardj   fprintf(stderr,zf)
461024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf1(zf,za1) \
462024598e40c84666cc311a42c256bbf880db3ac99sewardj   fprintf(stderr,zf,za1)
463024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf2(zf,za1,za2) \
464024598e40c84666cc311a42c256bbf880db3ac99sewardj   fprintf(stderr,zf,za1,za2)
465024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf3(zf,za1,za2,za3) \
466024598e40c84666cc311a42c256bbf880db3ac99sewardj   fprintf(stderr,zf,za1,za2,za3)
467024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf4(zf,za1,za2,za3,za4) \
468024598e40c84666cc311a42c256bbf880db3ac99sewardj   fprintf(stderr,zf,za1,za2,za3,za4)
469024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
470024598e40c84666cc311a42c256bbf880db3ac99sewardj   fprintf(stderr,zf,za1,za2,za3,za4,za5)
471024598e40c84666cc311a42c256bbf880db3ac99sewardj#else
472024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void bz_internal_error ( int errcode );
473024598e40c84666cc311a42c256bbf880db3ac99sewardj#define AssertH(cond,errcode) \
474024598e40c84666cc311a42c256bbf880db3ac99sewardj   { if (!(cond)) bz_internal_error ( errcode ); }
475024598e40c84666cc311a42c256bbf880db3ac99sewardj#define AssertD(cond,msg) /* */
476024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf0(zf) \
477024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf(zf)
478024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf1(zf,za1) \
479024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf(zf,za1)
480024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf2(zf,za1,za2) \
481024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf(zf,za1,za2)
482024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf3(zf,za1,za2,za3) \
483024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf(zf,za1,za2,za3)
484024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf4(zf,za1,za2,za3,za4) \
485024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf(zf,za1,za2,za3,za4)
486024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
487024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf(zf,za1,za2,za3,za4,za5)
488024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
489024598e40c84666cc311a42c256bbf880db3ac99sewardj
490024598e40c84666cc311a42c256bbf880db3ac99sewardj
491024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
492024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
493024598e40c84666cc311a42c256bbf880db3ac99sewardj
494024598e40c84666cc311a42c256bbf880db3ac99sewardj
495024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Header bytes. --*/
496024598e40c84666cc311a42c256bbf880db3ac99sewardj
497024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_HDR_B 0x42   /* 'B' */
498024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_HDR_Z 0x5a   /* 'Z' */
499024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_HDR_h 0x68   /* 'h' */
500024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_HDR_0 0x30   /* '0' */
501024598e40c84666cc311a42c256bbf880db3ac99sewardj
502024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Constants for the back end. --*/
503024598e40c84666cc311a42c256bbf880db3ac99sewardj
504024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_MAX_ALPHA_SIZE 258
505024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_MAX_CODE_LEN    23
506024598e40c84666cc311a42c256bbf880db3ac99sewardj
507024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RUNA 0
508024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RUNB 1
509024598e40c84666cc311a42c256bbf880db3ac99sewardj
510024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_N_GROUPS 6
511024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_G_SIZE   50
512024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_N_ITERS  4
513024598e40c84666cc311a42c256bbf880db3ac99sewardj
514024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
515024598e40c84666cc311a42c256bbf880db3ac99sewardj
516024598e40c84666cc311a42c256bbf880db3ac99sewardj
517024598e40c84666cc311a42c256bbf880db3ac99sewardj
518024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Stuff for randomising repetitive blocks. --*/
519024598e40c84666cc311a42c256bbf880db3ac99sewardj
520024598e40c84666cc311a42c256bbf880db3ac99sewardjextern Int32 BZ2_rNums[512];
521024598e40c84666cc311a42c256bbf880db3ac99sewardj
522024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RAND_DECLS                          \
523024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 rNToGo;                               \
524024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 rTPos                                 \
525024598e40c84666cc311a42c256bbf880db3ac99sewardj
526024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RAND_INIT_MASK                      \
527024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->rNToGo = 0;                              \
528024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->rTPos  = 0                               \
529024598e40c84666cc311a42c256bbf880db3ac99sewardj
530024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
531024598e40c84666cc311a42c256bbf880db3ac99sewardj
532024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_RAND_UPD_MASK                       \
533024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->rNToGo == 0) {                       \
534024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->rNToGo = BZ2_rNums[s->rTPos];         \
535024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->rTPos++;                              \
536024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->rTPos == 512) s->rTPos = 0;       \
537024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                           \
538024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->rNToGo--;
539024598e40c84666cc311a42c256bbf880db3ac99sewardj
540024598e40c84666cc311a42c256bbf880db3ac99sewardj
541024598e40c84666cc311a42c256bbf880db3ac99sewardj
542024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Stuff for doing CRCs. --*/
543024598e40c84666cc311a42c256bbf880db3ac99sewardj
544024598e40c84666cc311a42c256bbf880db3ac99sewardjextern UInt32 BZ2_crc32Table[256];
545024598e40c84666cc311a42c256bbf880db3ac99sewardj
546024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_INITIALISE_CRC(crcVar)              \
547024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                              \
548024598e40c84666cc311a42c256bbf880db3ac99sewardj   crcVar = 0xffffffffL;                       \
549024598e40c84666cc311a42c256bbf880db3ac99sewardj}
550024598e40c84666cc311a42c256bbf880db3ac99sewardj
551024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_FINALISE_CRC(crcVar)                \
552024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                              \
553024598e40c84666cc311a42c256bbf880db3ac99sewardj   crcVar = ~(crcVar);                         \
554024598e40c84666cc311a42c256bbf880db3ac99sewardj}
555024598e40c84666cc311a42c256bbf880db3ac99sewardj
556024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_UPDATE_CRC(crcVar,cha)              \
557024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                              \
558024598e40c84666cc311a42c256bbf880db3ac99sewardj   crcVar = (crcVar << 8) ^                    \
559024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ2_crc32Table[(crcVar >> 24) ^    \
560024598e40c84666cc311a42c256bbf880db3ac99sewardj                           ((UChar)cha)];      \
561024598e40c84666cc311a42c256bbf880db3ac99sewardj}
562024598e40c84666cc311a42c256bbf880db3ac99sewardj
563024598e40c84666cc311a42c256bbf880db3ac99sewardj
564024598e40c84666cc311a42c256bbf880db3ac99sewardj
565024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- States and modes for compression. --*/
566024598e40c84666cc311a42c256bbf880db3ac99sewardj
567024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_M_IDLE      1
568024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_M_RUNNING   2
569024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_M_FLUSHING  3
570024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_M_FINISHING 4
571024598e40c84666cc311a42c256bbf880db3ac99sewardj
572024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_S_OUTPUT    1
573024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_S_INPUT     2
574024598e40c84666cc311a42c256bbf880db3ac99sewardj
575024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_N_RADIX 2
576024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_N_QSORT 12
577024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_N_SHELL 18
578024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
579024598e40c84666cc311a42c256bbf880db3ac99sewardj
580024598e40c84666cc311a42c256bbf880db3ac99sewardj
581024598e40c84666cc311a42c256bbf880db3ac99sewardj
582024598e40c84666cc311a42c256bbf880db3ac99sewardj
583024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Structure holding all the compression-side stuff. --*/
584024598e40c84666cc311a42c256bbf880db3ac99sewardj
585024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef
586024598e40c84666cc311a42c256bbf880db3ac99sewardj   struct {
587024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* pointer back to the struct bz_stream */
588024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream* strm;
589024598e40c84666cc311a42c256bbf880db3ac99sewardj
590024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* mode this stream is in, and whether inputting */
591024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* or outputting data */
592024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    mode;
593024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    state;
594024598e40c84666cc311a42c256bbf880db3ac99sewardj
595024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* remembers avail_in when flush/finish requested */
596024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   avail_in_expect;
597024598e40c84666cc311a42c256bbf880db3ac99sewardj
598024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* for doing the block sorting */
599024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32*  arr1;
600024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32*  arr2;
601024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32*  ftab;
602024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    origPtr;
603024598e40c84666cc311a42c256bbf880db3ac99sewardj
604024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* aliases for arr1 and arr2 */
605024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32*  ptr;
606024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar*   block;
607024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt16*  mtfv;
608024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar*   zbits;
609024598e40c84666cc311a42c256bbf880db3ac99sewardj
610024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* for deciding when to use the fallback sorting algorithm */
611024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    workFactor;
612024598e40c84666cc311a42c256bbf880db3ac99sewardj
613024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* run-length-encoding of the input */
614024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   state_in_ch;
615024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    state_in_len;
616024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ_RAND_DECLS;
617024598e40c84666cc311a42c256bbf880db3ac99sewardj
618024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* input and output limits and current posns */
619024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    nblock;
620024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    nblockMAX;
621024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    numZ;
622024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    state_out_pos;
623024598e40c84666cc311a42c256bbf880db3ac99sewardj
624024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* map of bytes used in block */
625024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    nInUse;
626024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool     inUse[256];
627024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    unseqToSeq[256];
628024598e40c84666cc311a42c256bbf880db3ac99sewardj
629024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* the buffer for bit stream creation */
630024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   bsBuff;
631024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    bsLive;
632024598e40c84666cc311a42c256bbf880db3ac99sewardj
633024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* block and combined CRCs */
634024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   blockCRC;
635024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   combinedCRC;
636024598e40c84666cc311a42c256bbf880db3ac99sewardj
637024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* misc administratium */
638024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    verbosity;
639024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    blockNo;
640024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    blockSize100k;
641024598e40c84666cc311a42c256bbf880db3ac99sewardj
642024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* stuff for coding the MTF values */
643024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    nMTF;
644024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
645024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    selector   [BZ_MAX_SELECTORS];
646024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
647024598e40c84666cc311a42c256bbf880db3ac99sewardj
648024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
649024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
650024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
651024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* second dimension: only 3 needed; 4 makes index calculations faster */
652024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
653024598e40c84666cc311a42c256bbf880db3ac99sewardj
654024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
655024598e40c84666cc311a42c256bbf880db3ac99sewardj   EState;
656024598e40c84666cc311a42c256bbf880db3ac99sewardj
657024598e40c84666cc311a42c256bbf880db3ac99sewardj
658024598e40c84666cc311a42c256bbf880db3ac99sewardj
659024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- externs for compression. --*/
660024598e40c84666cc311a42c256bbf880db3ac99sewardj
661024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void
662024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_blockSort ( EState* );
663024598e40c84666cc311a42c256bbf880db3ac99sewardj
664024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void
665024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_compressBlock ( EState*, Bool );
666024598e40c84666cc311a42c256bbf880db3ac99sewardj
667024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void
668024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_bsInitWrite ( EState* );
669024598e40c84666cc311a42c256bbf880db3ac99sewardj
670024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void
671024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
672024598e40c84666cc311a42c256bbf880db3ac99sewardj
673024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void
674024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
675024598e40c84666cc311a42c256bbf880db3ac99sewardj
676024598e40c84666cc311a42c256bbf880db3ac99sewardj
677024598e40c84666cc311a42c256bbf880db3ac99sewardj
678024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- states for decompression. --*/
679024598e40c84666cc311a42c256bbf880db3ac99sewardj
680024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_IDLE        1
681024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_OUTPUT      2
682024598e40c84666cc311a42c256bbf880db3ac99sewardj
683024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MAGIC_1     10
684024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MAGIC_2     11
685024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MAGIC_3     12
686024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MAGIC_4     13
687024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BLKHDR_1    14
688024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BLKHDR_2    15
689024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BLKHDR_3    16
690024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BLKHDR_4    17
691024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BLKHDR_5    18
692024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BLKHDR_6    19
693024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BCRC_1      20
694024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BCRC_2      21
695024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BCRC_3      22
696024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_BCRC_4      23
697024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_RANDBIT     24
698024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ORIGPTR_1   25
699024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ORIGPTR_2   26
700024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ORIGPTR_3   27
701024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MAPPING_1   28
702024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MAPPING_2   29
703024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_SELECTOR_1  30
704024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_SELECTOR_2  31
705024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_SELECTOR_3  32
706024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_CODING_1    33
707024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_CODING_2    34
708024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_CODING_3    35
709024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MTF_1       36
710024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MTF_2       37
711024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MTF_3       38
712024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MTF_4       39
713024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MTF_5       40
714024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_MTF_6       41
715024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ENDHDR_2    42
716024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ENDHDR_3    43
717024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ENDHDR_4    44
718024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ENDHDR_5    45
719024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_ENDHDR_6    46
720024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_CCRC_1      47
721024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_CCRC_2      48
722024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_CCRC_3      49
723024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_X_CCRC_4      50
724024598e40c84666cc311a42c256bbf880db3ac99sewardj
725024598e40c84666cc311a42c256bbf880db3ac99sewardj
726024598e40c84666cc311a42c256bbf880db3ac99sewardj
727024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Constants for the fast MTF decoder. --*/
728024598e40c84666cc311a42c256bbf880db3ac99sewardj
729024598e40c84666cc311a42c256bbf880db3ac99sewardj#define MTFA_SIZE 4096
730024598e40c84666cc311a42c256bbf880db3ac99sewardj#define MTFL_SIZE 16
731024598e40c84666cc311a42c256bbf880db3ac99sewardj
732024598e40c84666cc311a42c256bbf880db3ac99sewardj
733024598e40c84666cc311a42c256bbf880db3ac99sewardj
734024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Structure holding all the decompression-side stuff. --*/
735024598e40c84666cc311a42c256bbf880db3ac99sewardj
736024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef
737024598e40c84666cc311a42c256bbf880db3ac99sewardj   struct {
738024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* pointer back to the struct bz_stream */
739024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream* strm;
740024598e40c84666cc311a42c256bbf880db3ac99sewardj
741024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* state indicator for this stream */
742024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    state;
743024598e40c84666cc311a42c256bbf880db3ac99sewardj
744024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* for doing the final run-length decoding */
745024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    state_out_ch;
746024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    state_out_len;
747024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool     blockRandomised;
748024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ_RAND_DECLS;
749024598e40c84666cc311a42c256bbf880db3ac99sewardj
750024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* the buffer for bit stream reading */
751024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   bsBuff;
752024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    bsLive;
753024598e40c84666cc311a42c256bbf880db3ac99sewardj
754024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* misc administratium */
755024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    blockSize100k;
756024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool     smallDecompress;
757024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    currBlockNo;
758024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    verbosity;
759024598e40c84666cc311a42c256bbf880db3ac99sewardj
760024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* for undoing the Burrows-Wheeler transform */
761024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    origPtr;
762024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   tPos;
763024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    k0;
764024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    unzftab[256];
765024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    nblock_used;
766024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    cftab[257];
767024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    cftabCopy[257];
768024598e40c84666cc311a42c256bbf880db3ac99sewardj
769024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* for undoing the Burrows-Wheeler transform (FAST) */
770024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   *tt;
771024598e40c84666cc311a42c256bbf880db3ac99sewardj
772024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* for undoing the Burrows-Wheeler transform (SMALL) */
773024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt16   *ll16;
774024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    *ll4;
775024598e40c84666cc311a42c256bbf880db3ac99sewardj
776024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* stored and calculated CRCs */
777024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   storedBlockCRC;
778024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   storedCombinedCRC;
779024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   calculatedBlockCRC;
780024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32   calculatedCombinedCRC;
781024598e40c84666cc311a42c256bbf880db3ac99sewardj
782024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* map of bytes used in block */
783024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    nInUse;
784024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool     inUse[256];
785024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool     inUse16[16];
786024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    seqToUnseq[256];
787024598e40c84666cc311a42c256bbf880db3ac99sewardj
788024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* for decoding the MTF values */
789024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    mtfa   [MTFA_SIZE];
790024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    mtfbase[256 / MTFL_SIZE];
791024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    selector   [BZ_MAX_SELECTORS];
792024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
793024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
794024598e40c84666cc311a42c256bbf880db3ac99sewardj
795024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
796024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
797024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
798024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    minLens[BZ_N_GROUPS];
799024598e40c84666cc311a42c256bbf880db3ac99sewardj
800024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* save area for scalars in the main decompress code */
801024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_i;
802024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_j;
803024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_t;
804024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_alphaSize;
805024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_nGroups;
806024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_nSelectors;
807024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_EOB;
808024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_groupNo;
809024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_groupPos;
810024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_nextSym;
811024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_nblockMAX;
812024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_nblock;
813024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_es;
814024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_N;
815024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_curr;
816024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_zt;
817024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_zn;
818024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_zvec;
819024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_zj;
820024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_gSel;
821024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32    save_gMinlen;
822024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32*   save_gLimit;
823024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32*   save_gBase;
824024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32*   save_gPerm;
825024598e40c84666cc311a42c256bbf880db3ac99sewardj
826024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
827024598e40c84666cc311a42c256bbf880db3ac99sewardj   DState;
828024598e40c84666cc311a42c256bbf880db3ac99sewardj
829024598e40c84666cc311a42c256bbf880db3ac99sewardj
830024598e40c84666cc311a42c256bbf880db3ac99sewardj
831024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- Macros for decompression. --*/
832024598e40c84666cc311a42c256bbf880db3ac99sewardj
833024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_GET_FAST(cccc)                     \
834024598e40c84666cc311a42c256bbf880db3ac99sewardj    s->tPos = s->tt[s->tPos];                 \
835024598e40c84666cc311a42c256bbf880db3ac99sewardj    cccc = (UChar)(s->tPos & 0xff);           \
836024598e40c84666cc311a42c256bbf880db3ac99sewardj    s->tPos >>= 8;
837024598e40c84666cc311a42c256bbf880db3ac99sewardj
838024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_GET_FAST_C(cccc)                   \
839024598e40c84666cc311a42c256bbf880db3ac99sewardj    c_tPos = c_tt[c_tPos];                    \
840024598e40c84666cc311a42c256bbf880db3ac99sewardj    cccc = (UChar)(c_tPos & 0xff);            \
841024598e40c84666cc311a42c256bbf880db3ac99sewardj    c_tPos >>= 8;
842024598e40c84666cc311a42c256bbf880db3ac99sewardj
843024598e40c84666cc311a42c256bbf880db3ac99sewardj#define SET_LL4(i,n)                                          \
844024598e40c84666cc311a42c256bbf880db3ac99sewardj   { if (((i) & 0x1) == 0)                                    \
845024598e40c84666cc311a42c256bbf880db3ac99sewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
846024598e40c84666cc311a42c256bbf880db3ac99sewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
847024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
848024598e40c84666cc311a42c256bbf880db3ac99sewardj
849024598e40c84666cc311a42c256bbf880db3ac99sewardj#define GET_LL4(i)                             \
850024598e40c84666cc311a42c256bbf880db3ac99sewardj   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
851024598e40c84666cc311a42c256bbf880db3ac99sewardj
852024598e40c84666cc311a42c256bbf880db3ac99sewardj#define SET_LL(i,n)                          \
853024598e40c84666cc311a42c256bbf880db3ac99sewardj   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
854024598e40c84666cc311a42c256bbf880db3ac99sewardj     SET_LL4(i, n >> 16);                    \
855024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
856024598e40c84666cc311a42c256bbf880db3ac99sewardj
857024598e40c84666cc311a42c256bbf880db3ac99sewardj#define GET_LL(i) \
858024598e40c84666cc311a42c256bbf880db3ac99sewardj   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
859024598e40c84666cc311a42c256bbf880db3ac99sewardj
860024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_GET_SMALL(cccc)                            \
861024598e40c84666cc311a42c256bbf880db3ac99sewardj      cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
862024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->tPos = GET_LL(s->tPos);
863024598e40c84666cc311a42c256bbf880db3ac99sewardj
864024598e40c84666cc311a42c256bbf880db3ac99sewardj
865024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- externs for decompression. --*/
866024598e40c84666cc311a42c256bbf880db3ac99sewardj
867024598e40c84666cc311a42c256bbf880db3ac99sewardjextern Int32
868024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_indexIntoF ( Int32, Int32* );
869024598e40c84666cc311a42c256bbf880db3ac99sewardj
870024598e40c84666cc311a42c256bbf880db3ac99sewardjextern Int32
871024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_decompress ( DState* );
872024598e40c84666cc311a42c256bbf880db3ac99sewardj
873024598e40c84666cc311a42c256bbf880db3ac99sewardjextern void
874024598e40c84666cc311a42c256bbf880db3ac99sewardjBZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
875024598e40c84666cc311a42c256bbf880db3ac99sewardj                           Int32,  Int32, Int32 );
876024598e40c84666cc311a42c256bbf880db3ac99sewardj
877024598e40c84666cc311a42c256bbf880db3ac99sewardj
878024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
879024598e40c84666cc311a42c256bbf880db3ac99sewardj
880024598e40c84666cc311a42c256bbf880db3ac99sewardj
881024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
882024598e40c84666cc311a42c256bbf880db3ac99sewardj
883024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifdef BZ_NO_STDIO
884024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef NULL
885024598e40c84666cc311a42c256bbf880db3ac99sewardj#define NULL 0
886024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
887024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
888024598e40c84666cc311a42c256bbf880db3ac99sewardj
889024598e40c84666cc311a42c256bbf880db3ac99sewardj
890024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
891024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                   bzlib_private.h ---*/
892024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
893024598e40c84666cc311a42c256bbf880db3ac99sewardj
894024598e40c84666cc311a42c256bbf880db3ac99sewardj
895024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Something which has the same size as void* on the host.  That is,
896024598e40c84666cc311a42c256bbf880db3ac99sewardj   it is 32 bits on a 32-bit host and 64 bits on a 64-bit host, and so
897024598e40c84666cc311a42c256bbf880db3ac99sewardj   it can safely be coerced to and from a pointer type on the host
898024598e40c84666cc311a42c256bbf880db3ac99sewardj   machine. */
899024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef  unsigned long HWord;
900024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef  char          HChar;
901024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef  signed int    Int;
902024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef  unsigned int  UInt;
903024598e40c84666cc311a42c256bbf880db3ac99sewardj
904024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef    signed long long int   Long;
905024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef  unsigned long long int   ULong;
906024598e40c84666cc311a42c256bbf880db3ac99sewardj
907024598e40c84666cc311a42c256bbf880db3ac99sewardj
908024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
909024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
910024598e40c84666cc311a42c256bbf880db3ac99sewardj
911024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic HWord (*serviceFn)(HWord,HWord) = 0;
912024598e40c84666cc311a42c256bbf880db3ac99sewardj
913024598e40c84666cc311a42c256bbf880db3ac99sewardj#if 0
914024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic char* my_strcpy ( char* dest, const char* src )
915024598e40c84666cc311a42c256bbf880db3ac99sewardj{
916024598e40c84666cc311a42c256bbf880db3ac99sewardj   char* dest_orig = dest;
917024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (*src) *dest++ = *src++;
918024598e40c84666cc311a42c256bbf880db3ac99sewardj   *dest = 0;
919024598e40c84666cc311a42c256bbf880db3ac99sewardj   return dest_orig;
920024598e40c84666cc311a42c256bbf880db3ac99sewardj}
921024598e40c84666cc311a42c256bbf880db3ac99sewardj
922024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic void* my_memcpy ( void *dest, const void *src, int sz )
923024598e40c84666cc311a42c256bbf880db3ac99sewardj{
924024598e40c84666cc311a42c256bbf880db3ac99sewardj   const char *s = (const char *)src;
925024598e40c84666cc311a42c256bbf880db3ac99sewardj   char *d = (char *)dest;
926024598e40c84666cc311a42c256bbf880db3ac99sewardj
927024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (sz--)
928024598e40c84666cc311a42c256bbf880db3ac99sewardj      *d++ = *s++;
929024598e40c84666cc311a42c256bbf880db3ac99sewardj
930024598e40c84666cc311a42c256bbf880db3ac99sewardj   return dest;
931024598e40c84666cc311a42c256bbf880db3ac99sewardj}
932024598e40c84666cc311a42c256bbf880db3ac99sewardj
933024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic void* my_memmove( void *dst, const void *src, unsigned int len )
934024598e40c84666cc311a42c256bbf880db3ac99sewardj{
935024598e40c84666cc311a42c256bbf880db3ac99sewardj    register char *d;
936024598e40c84666cc311a42c256bbf880db3ac99sewardj    register char *s;
937024598e40c84666cc311a42c256bbf880db3ac99sewardj    if ( dst > src ) {
938024598e40c84666cc311a42c256bbf880db3ac99sewardj        d = (char *)dst + len - 1;
939024598e40c84666cc311a42c256bbf880db3ac99sewardj        s = (char *)src + len - 1;
940024598e40c84666cc311a42c256bbf880db3ac99sewardj        while ( len >= 4 ) {
941024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d-- = *s--;
942024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d-- = *s--;
943024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d-- = *s--;
944024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d-- = *s--;
945024598e40c84666cc311a42c256bbf880db3ac99sewardj            len -= 4;
946024598e40c84666cc311a42c256bbf880db3ac99sewardj        }
947024598e40c84666cc311a42c256bbf880db3ac99sewardj        while ( len-- ) {
948024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d-- = *s--;
949024598e40c84666cc311a42c256bbf880db3ac99sewardj        }
950024598e40c84666cc311a42c256bbf880db3ac99sewardj    } else if ( dst < src ) {
951024598e40c84666cc311a42c256bbf880db3ac99sewardj        d = (char *)dst;
952024598e40c84666cc311a42c256bbf880db3ac99sewardj        s = (char *)src;
953024598e40c84666cc311a42c256bbf880db3ac99sewardj        while ( len >= 4 ) {
954024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d++ = *s++;
955024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d++ = *s++;
956024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d++ = *s++;
957024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d++ = *s++;
958024598e40c84666cc311a42c256bbf880db3ac99sewardj            len -= 4;
959024598e40c84666cc311a42c256bbf880db3ac99sewardj        }
960024598e40c84666cc311a42c256bbf880db3ac99sewardj        while ( len-- ) {
961024598e40c84666cc311a42c256bbf880db3ac99sewardj            *d++ = *s++;
962024598e40c84666cc311a42c256bbf880db3ac99sewardj        }
963024598e40c84666cc311a42c256bbf880db3ac99sewardj    }
964024598e40c84666cc311a42c256bbf880db3ac99sewardj    return dst;
965024598e40c84666cc311a42c256bbf880db3ac99sewardj}
966024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
967024598e40c84666cc311a42c256bbf880db3ac99sewardj
968024598e40c84666cc311a42c256bbf880db3ac99sewardjchar* my_strcat ( char* dest, const char* src )
969024598e40c84666cc311a42c256bbf880db3ac99sewardj{
970024598e40c84666cc311a42c256bbf880db3ac99sewardj   char* dest_orig = dest;
971024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (*dest) dest++;
972024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (*src) *dest++ = *src++;
973024598e40c84666cc311a42c256bbf880db3ac99sewardj   *dest = 0;
974024598e40c84666cc311a42c256bbf880db3ac99sewardj   return dest_orig;
975024598e40c84666cc311a42c256bbf880db3ac99sewardj}
976024598e40c84666cc311a42c256bbf880db3ac99sewardj
977024598e40c84666cc311a42c256bbf880db3ac99sewardj
978024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
979024598e40c84666cc311a42c256bbf880db3ac99sewardj
980024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic void vex_log_bytes ( char* p, int n )
981024598e40c84666cc311a42c256bbf880db3ac99sewardj{
982024598e40c84666cc311a42c256bbf880db3ac99sewardj   int i;
983024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < n; i++)
984024598e40c84666cc311a42c256bbf880db3ac99sewardj      (*serviceFn)( 1, (int)p[i] );
985024598e40c84666cc311a42c256bbf880db3ac99sewardj}
986024598e40c84666cc311a42c256bbf880db3ac99sewardj
987024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------------*/
988024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- vex_printf                                        ---*/
989024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------------*/
990024598e40c84666cc311a42c256bbf880db3ac99sewardj
991024598e40c84666cc311a42c256bbf880db3ac99sewardj/* This should be the only <...> include in the entire VEX library.
992024598e40c84666cc311a42c256bbf880db3ac99sewardj   New code for vex_util.c should go above this point. */
993024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <stdarg.h>
994024598e40c84666cc311a42c256bbf880db3ac99sewardj
995024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic HChar vex_toupper ( HChar c )
996024598e40c84666cc311a42c256bbf880db3ac99sewardj{
997024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c >= 'a' && c <= 'z')
998024598e40c84666cc311a42c256bbf880db3ac99sewardj      return c + ('A' - 'a');
999024598e40c84666cc311a42c256bbf880db3ac99sewardj   else
1000024598e40c84666cc311a42c256bbf880db3ac99sewardj      return c;
1001024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1002e25d54b2a995a492c3014bc12cb491ddc7503ef3mjw/* Explicitly set noinline so the test can check it is in the backtrace. */
1003e25d54b2a995a492c3014bc12cb491ddc7503ef3mjwstatic __attribute__(( noinline)) Int vex_strlen ( const HChar* str )
1004024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1005024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int i = 0;
1006024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (str[i] != 0) i++;
1007024598e40c84666cc311a42c256bbf880db3ac99sewardj   return i;
1008024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1009024598e40c84666cc311a42c256bbf880db3ac99sewardj
1010024598e40c84666cc311a42c256bbf880db3ac99sewardjBool vex_streq ( const HChar* s1, const HChar* s2 )
1011024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1012024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
1013024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (*s1 == 0 && *s2 == 0)
1014024598e40c84666cc311a42c256bbf880db3ac99sewardj         return True;
1015024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (*s1 != *s2)
1016024598e40c84666cc311a42c256bbf880db3ac99sewardj         return False;
1017024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1++;
1018024598e40c84666cc311a42c256bbf880db3ac99sewardj      s2++;
1019024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1020024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1021024598e40c84666cc311a42c256bbf880db3ac99sewardj
1022024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Some flags.  */
1023024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VG_MSG_SIGNED    1 /* The value is signed. */
1024024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VG_MSG_ZJUSTIFY  2 /* Must justify with '0'. */
1025024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VG_MSG_LJUSTIFY  4 /* Must justify on the left. */
1026024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VG_MSG_PAREN     8 /* Parenthesize if present (for %y) */
1027024598e40c84666cc311a42c256bbf880db3ac99sewardj#define VG_MSG_COMMA    16 /* Add commas to numbers (for %d, %u) */
1028024598e40c84666cc311a42c256bbf880db3ac99sewardj
1029024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Copy a string into the buffer. */
1030024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic UInt
1031024598e40c84666cc311a42c256bbf880db3ac99sewardjmyvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
1032024598e40c84666cc311a42c256bbf880db3ac99sewardj                Bool capitalise )
1033024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1034024598e40c84666cc311a42c256bbf880db3ac99sewardj#  define MAYBE_TOUPPER(ch) (capitalise ? vex_toupper(ch) : (ch))
1035024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt ret = 0;
1036024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int i, extra;
1037024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int len = vex_strlen(str);
1038024598e40c84666cc311a42c256bbf880db3ac99sewardj
1039024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (width == 0) {
1040024598e40c84666cc311a42c256bbf880db3ac99sewardj      ret += len;
1041024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < len; i++)
1042024598e40c84666cc311a42c256bbf880db3ac99sewardj         send(MAYBE_TOUPPER(str[i]));
1043024598e40c84666cc311a42c256bbf880db3ac99sewardj      return ret;
1044024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1045024598e40c84666cc311a42c256bbf880db3ac99sewardj
1046024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (len > width) {
1047024598e40c84666cc311a42c256bbf880db3ac99sewardj      ret += width;
1048024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < width; i++)
1049024598e40c84666cc311a42c256bbf880db3ac99sewardj         send(MAYBE_TOUPPER(str[i]));
1050024598e40c84666cc311a42c256bbf880db3ac99sewardj      return ret;
1051024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1052024598e40c84666cc311a42c256bbf880db3ac99sewardj
1053024598e40c84666cc311a42c256bbf880db3ac99sewardj   extra = width - len;
1054024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (flags & VG_MSG_LJUSTIFY) {
1055024598e40c84666cc311a42c256bbf880db3ac99sewardj      ret += extra;
1056024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < extra; i++)
1057024598e40c84666cc311a42c256bbf880db3ac99sewardj         send(' ');
1058024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1059024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret += len;
1060024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < len; i++)
1061024598e40c84666cc311a42c256bbf880db3ac99sewardj      send(MAYBE_TOUPPER(str[i]));
1062024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (!(flags & VG_MSG_LJUSTIFY)) {
1063024598e40c84666cc311a42c256bbf880db3ac99sewardj      ret += extra;
1064024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < extra; i++)
1065024598e40c84666cc311a42c256bbf880db3ac99sewardj         send(' ');
1066024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1067024598e40c84666cc311a42c256bbf880db3ac99sewardj
1068024598e40c84666cc311a42c256bbf880db3ac99sewardj#  undef MAYBE_TOUPPER
1069024598e40c84666cc311a42c256bbf880db3ac99sewardj
1070024598e40c84666cc311a42c256bbf880db3ac99sewardj   return ret;
1071024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1072024598e40c84666cc311a42c256bbf880db3ac99sewardj
1073024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Write P into the buffer according to these args:
1074024598e40c84666cc311a42c256bbf880db3ac99sewardj *  If SIGN is true, p is a signed.
1075024598e40c84666cc311a42c256bbf880db3ac99sewardj *  BASE is the base.
1076024598e40c84666cc311a42c256bbf880db3ac99sewardj *  If WITH_ZERO is true, '0' must be added.
1077024598e40c84666cc311a42c256bbf880db3ac99sewardj *  WIDTH is the width of the field.
1078024598e40c84666cc311a42c256bbf880db3ac99sewardj */
1079024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic UInt
1080024598e40c84666cc311a42c256bbf880db3ac99sewardjmyvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
1081024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1082024598e40c84666cc311a42c256bbf880db3ac99sewardj   HChar buf[40];
1083024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int   ind = 0;
1084024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int   i, nc = 0;
1085024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool  neg = False;
1086024598e40c84666cc311a42c256bbf880db3ac99sewardj   HChar *digits = "0123456789ABCDEF";
1087024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt  ret = 0;
1088024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt  p = (UInt)pL;
1089024598e40c84666cc311a42c256bbf880db3ac99sewardj
1090024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (base < 2 || base > 16)
1091024598e40c84666cc311a42c256bbf880db3ac99sewardj      return ret;
1092024598e40c84666cc311a42c256bbf880db3ac99sewardj
1093024598e40c84666cc311a42c256bbf880db3ac99sewardj   if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
1094024598e40c84666cc311a42c256bbf880db3ac99sewardj      p   = - (Int)p;
1095024598e40c84666cc311a42c256bbf880db3ac99sewardj      neg = True;
1096024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1097024598e40c84666cc311a42c256bbf880db3ac99sewardj
1098024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (p == 0)
1099024598e40c84666cc311a42c256bbf880db3ac99sewardj      buf[ind++] = '0';
1100024598e40c84666cc311a42c256bbf880db3ac99sewardj   else {
1101024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (p > 0) {
1102024598e40c84666cc311a42c256bbf880db3ac99sewardj         if ((flags & VG_MSG_COMMA) && 10 == base &&
1103024598e40c84666cc311a42c256bbf880db3ac99sewardj             0 == (ind-nc) % 3 && 0 != ind)
1104024598e40c84666cc311a42c256bbf880db3ac99sewardj         {
1105024598e40c84666cc311a42c256bbf880db3ac99sewardj            buf[ind++] = ',';
1106024598e40c84666cc311a42c256bbf880db3ac99sewardj            nc++;
1107024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1108024598e40c84666cc311a42c256bbf880db3ac99sewardj         buf[ind++] = digits[p % base];
1109024598e40c84666cc311a42c256bbf880db3ac99sewardj         p /= base;
1110024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1111024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1112024598e40c84666cc311a42c256bbf880db3ac99sewardj
1113024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (neg)
1114024598e40c84666cc311a42c256bbf880db3ac99sewardj      buf[ind++] = '-';
1115024598e40c84666cc311a42c256bbf880db3ac99sewardj
1116024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
1117024598e40c84666cc311a42c256bbf880db3ac99sewardj      for(; ind < width; ind++) {
1118024598e40c84666cc311a42c256bbf880db3ac99sewardj	//vassert(ind < 39);
1119024598e40c84666cc311a42c256bbf880db3ac99sewardj         buf[ind] = ((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
1120024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1121024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1122024598e40c84666cc311a42c256bbf880db3ac99sewardj
1123024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* Reverse copy to buffer.  */
1124024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret += ind;
1125024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = ind -1; i >= 0; i--) {
1126024598e40c84666cc311a42c256bbf880db3ac99sewardj      send(buf[i]);
1127024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1128024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
1129024598e40c84666cc311a42c256bbf880db3ac99sewardj      for(; ind < width; ind++) {
1130024598e40c84666cc311a42c256bbf880db3ac99sewardj	 ret++;
1131024598e40c84666cc311a42c256bbf880db3ac99sewardj         send(' ');  // Never pad with zeroes on RHS -- changes the value!
1132024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1133024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1134024598e40c84666cc311a42c256bbf880db3ac99sewardj   return ret;
1135024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1136024598e40c84666cc311a42c256bbf880db3ac99sewardj
1137024598e40c84666cc311a42c256bbf880db3ac99sewardj
1138024598e40c84666cc311a42c256bbf880db3ac99sewardj/* A simple vprintf().  */
1139024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
1140024598e40c84666cc311a42c256bbf880db3ac99sewardjUInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
1141024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1142024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt ret = 0;
1143024598e40c84666cc311a42c256bbf880db3ac99sewardj   int i;
1144024598e40c84666cc311a42c256bbf880db3ac99sewardj   int flags;
1145024598e40c84666cc311a42c256bbf880db3ac99sewardj   int width;
1146024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool is_long;
1147024598e40c84666cc311a42c256bbf880db3ac99sewardj
1148024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* We assume that vargs has already been initialised by the
1149024598e40c84666cc311a42c256bbf880db3ac99sewardj      caller, using va_start, and that the caller will similarly
1150024598e40c84666cc311a42c256bbf880db3ac99sewardj      clean up with va_end.
1151024598e40c84666cc311a42c256bbf880db3ac99sewardj   */
1152024598e40c84666cc311a42c256bbf880db3ac99sewardj
1153024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; format[i] != 0; i++) {
1154024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (format[i] != '%') {
1155024598e40c84666cc311a42c256bbf880db3ac99sewardj         send(format[i]);
1156024598e40c84666cc311a42c256bbf880db3ac99sewardj	 ret++;
1157024598e40c84666cc311a42c256bbf880db3ac99sewardj         continue;
1158024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1159024598e40c84666cc311a42c256bbf880db3ac99sewardj      i++;
1160024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* A '%' has been found.  Ignore a trailing %. */
1161024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (format[i] == 0)
1162024598e40c84666cc311a42c256bbf880db3ac99sewardj         break;
1163024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (format[i] == '%') {
1164024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* `%%' is replaced by `%'. */
1165024598e40c84666cc311a42c256bbf880db3ac99sewardj         send('%');
1166024598e40c84666cc311a42c256bbf880db3ac99sewardj	 ret++;
1167024598e40c84666cc311a42c256bbf880db3ac99sewardj         continue;
1168024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1169024598e40c84666cc311a42c256bbf880db3ac99sewardj      flags = 0;
1170024598e40c84666cc311a42c256bbf880db3ac99sewardj      is_long = False;
1171024598e40c84666cc311a42c256bbf880db3ac99sewardj      width = 0; /* length of the field. */
1172024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (format[i] == '(') {
1173024598e40c84666cc311a42c256bbf880db3ac99sewardj	 flags |= VG_MSG_PAREN;
1174024598e40c84666cc311a42c256bbf880db3ac99sewardj	 i++;
1175024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1176024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* If ',' follows '%', commas will be inserted. */
1177024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (format[i] == ',') {
1178024598e40c84666cc311a42c256bbf880db3ac99sewardj         flags |= VG_MSG_COMMA;
1179024598e40c84666cc311a42c256bbf880db3ac99sewardj         i++;
1180024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1181024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* If '-' follows '%', justify on the left. */
1182024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (format[i] == '-') {
1183024598e40c84666cc311a42c256bbf880db3ac99sewardj         flags |= VG_MSG_LJUSTIFY;
1184024598e40c84666cc311a42c256bbf880db3ac99sewardj         i++;
1185024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1186024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* If '0' follows '%', pads will be inserted. */
1187024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (format[i] == '0') {
1188024598e40c84666cc311a42c256bbf880db3ac99sewardj         flags |= VG_MSG_ZJUSTIFY;
1189024598e40c84666cc311a42c256bbf880db3ac99sewardj         i++;
1190024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1191024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* Compute the field length. */
1192024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (format[i] >= '0' && format[i] <= '9') {
1193024598e40c84666cc311a42c256bbf880db3ac99sewardj         width *= 10;
1194024598e40c84666cc311a42c256bbf880db3ac99sewardj         width += format[i++] - '0';
1195024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1196024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (format[i] == 'l') {
1197024598e40c84666cc311a42c256bbf880db3ac99sewardj         i++;
1198024598e40c84666cc311a42c256bbf880db3ac99sewardj         is_long = True;
1199024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1200024598e40c84666cc311a42c256bbf880db3ac99sewardj
1201024598e40c84666cc311a42c256bbf880db3ac99sewardj      switch (format[i]) {
1202024598e40c84666cc311a42c256bbf880db3ac99sewardj         case 'd': /* %d */
1203024598e40c84666cc311a42c256bbf880db3ac99sewardj            flags |= VG_MSG_SIGNED;
1204024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (is_long)
1205024598e40c84666cc311a42c256bbf880db3ac99sewardj               ret += myvprintf_int64(send, flags, 10, width,
1206024598e40c84666cc311a42c256bbf880db3ac99sewardj				      (ULong)(va_arg (vargs, Long)));
1207024598e40c84666cc311a42c256bbf880db3ac99sewardj            else
1208024598e40c84666cc311a42c256bbf880db3ac99sewardj               ret += myvprintf_int64(send, flags, 10, width,
1209024598e40c84666cc311a42c256bbf880db3ac99sewardj				      (ULong)(va_arg (vargs, Int)));
1210024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
1211024598e40c84666cc311a42c256bbf880db3ac99sewardj         case 'u': /* %u */
1212024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (is_long)
1213024598e40c84666cc311a42c256bbf880db3ac99sewardj               ret += myvprintf_int64(send, flags, 10, width,
1214024598e40c84666cc311a42c256bbf880db3ac99sewardj				      (ULong)(va_arg (vargs, ULong)));
1215024598e40c84666cc311a42c256bbf880db3ac99sewardj            else
1216024598e40c84666cc311a42c256bbf880db3ac99sewardj               ret += myvprintf_int64(send, flags, 10, width,
1217024598e40c84666cc311a42c256bbf880db3ac99sewardj				      (ULong)(va_arg (vargs, UInt)));
1218024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
1219024598e40c84666cc311a42c256bbf880db3ac99sewardj         case 'p': /* %p */
1220024598e40c84666cc311a42c256bbf880db3ac99sewardj	    ret += 2;
1221024598e40c84666cc311a42c256bbf880db3ac99sewardj            send('0');
1222024598e40c84666cc311a42c256bbf880db3ac99sewardj            send('x');
1223024598e40c84666cc311a42c256bbf880db3ac99sewardj            ret += myvprintf_int64(send, flags, 16, width,
1224024598e40c84666cc311a42c256bbf880db3ac99sewardj				   (ULong)((HWord)va_arg (vargs, void *)));
1225024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
1226024598e40c84666cc311a42c256bbf880db3ac99sewardj         case 'x': /* %x */
1227024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (is_long)
1228024598e40c84666cc311a42c256bbf880db3ac99sewardj               ret += myvprintf_int64(send, flags, 16, width,
1229024598e40c84666cc311a42c256bbf880db3ac99sewardj				      (ULong)(va_arg (vargs, ULong)));
1230024598e40c84666cc311a42c256bbf880db3ac99sewardj            else
1231024598e40c84666cc311a42c256bbf880db3ac99sewardj               ret += myvprintf_int64(send, flags, 16, width,
1232024598e40c84666cc311a42c256bbf880db3ac99sewardj				      (ULong)(va_arg (vargs, UInt)));
1233024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
1234024598e40c84666cc311a42c256bbf880db3ac99sewardj         case 'c': /* %c */
1235024598e40c84666cc311a42c256bbf880db3ac99sewardj	    ret++;
1236024598e40c84666cc311a42c256bbf880db3ac99sewardj            send((va_arg (vargs, int)));
1237024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
1238024598e40c84666cc311a42c256bbf880db3ac99sewardj         case 's': case 'S': { /* %s */
1239024598e40c84666cc311a42c256bbf880db3ac99sewardj            char *str = va_arg (vargs, char *);
1240024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (str == (char*) 0) str = "(null)";
1241024598e40c84666cc311a42c256bbf880db3ac99sewardj            ret += myvprintf_str(send, flags, width, str,
1242024598e40c84666cc311a42c256bbf880db3ac99sewardj                                 (format[i]=='S'));
1243024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
1244024598e40c84666cc311a42c256bbf880db3ac99sewardj	 }
1245024598e40c84666cc311a42c256bbf880db3ac99sewardj#        if 0
1246024598e40c84666cc311a42c256bbf880db3ac99sewardj	 case 'y': { /* %y - print symbol */
1247024598e40c84666cc311a42c256bbf880db3ac99sewardj	    Addr a = va_arg(vargs, Addr);
1248024598e40c84666cc311a42c256bbf880db3ac99sewardj
124946cc04521acf2827eb33310fadc119bf2dc039e4florian
125046cc04521acf2827eb33310fadc119bf2dc039e4florian
125146cc04521acf2827eb33310fadc119bf2dc039e4florian            HChar *name;
125246cc04521acf2827eb33310fadc119bf2dc039e4florian	    if (VG_(get_fnname_w_offset)(a, &name)) {
125346cc04521acf2827eb33310fadc119bf2dc039e4florian               HChar buf[1 + VG_strlen(name) + 1 + 1];
1254024598e40c84666cc311a42c256bbf880db3ac99sewardj	       if (flags & VG_MSG_PAREN) {
125546cc04521acf2827eb33310fadc119bf2dc039e4florian                  VG_(sprintf)(str, "(%s)", name):
125646cc04521acf2827eb33310fadc119bf2dc039e4florian	       } else {
125746cc04521acf2827eb33310fadc119bf2dc039e4florian                  VG_(sprintf)(str, "%s", name):
125846cc04521acf2827eb33310fadc119bf2dc039e4florian               }
1259024598e40c84666cc311a42c256bbf880db3ac99sewardj	       ret += myvprintf_str(send, flags, width, buf, 0);
1260024598e40c84666cc311a42c256bbf880db3ac99sewardj	    }
1261024598e40c84666cc311a42c256bbf880db3ac99sewardj	    break;
1262024598e40c84666cc311a42c256bbf880db3ac99sewardj	 }
1263024598e40c84666cc311a42c256bbf880db3ac99sewardj#        endif
1264024598e40c84666cc311a42c256bbf880db3ac99sewardj         default:
1265024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
1266024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1267024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1268024598e40c84666cc311a42c256bbf880db3ac99sewardj   return ret;
1269024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1270024598e40c84666cc311a42c256bbf880db3ac99sewardj
1271024598e40c84666cc311a42c256bbf880db3ac99sewardj
1272024598e40c84666cc311a42c256bbf880db3ac99sewardj/* A general replacement for printf().  Note that only low-level
1273024598e40c84666cc311a42c256bbf880db3ac99sewardj   debugging info should be sent via here.  The official route is to
1274024598e40c84666cc311a42c256bbf880db3ac99sewardj   to use vg_message().  This interface is deprecated.
1275024598e40c84666cc311a42c256bbf880db3ac99sewardj*/
1276024598e40c84666cc311a42c256bbf880db3ac99sewardj/* XXX re 930: make the buffer just to small (by 1 byte) to be OK
1277024598e40c84666cc311a42c256bbf880db3ac99sewardj   for this particular run. */
1278024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic HChar myprintf_buf[1000   -930];
1279024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic Int   n_myprintf_buf;
1280024598e40c84666cc311a42c256bbf880db3ac99sewardj
1281024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic void add_to_myprintf_buf ( HChar c )
1282024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1283024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
1284024598e40c84666cc311a42c256bbf880db3ac99sewardj      (*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) );
1285024598e40c84666cc311a42c256bbf880db3ac99sewardj      n_myprintf_buf = 0;
1286024598e40c84666cc311a42c256bbf880db3ac99sewardj      myprintf_buf[n_myprintf_buf] = 0;
1287024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1288024598e40c84666cc311a42c256bbf880db3ac99sewardj   myprintf_buf[n_myprintf_buf++] = c;
1289024598e40c84666cc311a42c256bbf880db3ac99sewardj   myprintf_buf[n_myprintf_buf] = 0;
1290024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1291024598e40c84666cc311a42c256bbf880db3ac99sewardj
1292024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic UInt vex_printf ( const char *format, ... )
1293024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1294024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt ret;
1295024598e40c84666cc311a42c256bbf880db3ac99sewardj   va_list vargs;
1296024598e40c84666cc311a42c256bbf880db3ac99sewardj   va_start(vargs,format);
1297024598e40c84666cc311a42c256bbf880db3ac99sewardj
1298024598e40c84666cc311a42c256bbf880db3ac99sewardj   n_myprintf_buf = 0;
1299024598e40c84666cc311a42c256bbf880db3ac99sewardj   myprintf_buf[n_myprintf_buf] = 0;
1300024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
1301024598e40c84666cc311a42c256bbf880db3ac99sewardj
1302024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (n_myprintf_buf > 0) {
1303024598e40c84666cc311a42c256bbf880db3ac99sewardj      (*vex_log_bytes)( myprintf_buf, n_myprintf_buf );
1304024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1305024598e40c84666cc311a42c256bbf880db3ac99sewardj
1306024598e40c84666cc311a42c256bbf880db3ac99sewardj   va_end(vargs);
1307024598e40c84666cc311a42c256bbf880db3ac99sewardj
1308024598e40c84666cc311a42c256bbf880db3ac99sewardj   return ret;
1309024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1310024598e40c84666cc311a42c256bbf880db3ac99sewardj
1311024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------------------*/
1312024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                          vex_util.c ---*/
1313024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------------------*/
1314024598e40c84666cc311a42c256bbf880db3ac99sewardj
1315024598e40c84666cc311a42c256bbf880db3ac99sewardj
1316024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
1317024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
1318024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
1319024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
1320024598e40c84666cc311a42c256bbf880db3ac99sewardj
1321024598e40c84666cc311a42c256bbf880db3ac99sewardj
1322024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
1323024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Decompression machinery                               ---*/
1324024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                          decompress.c ---*/
1325024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
1326024598e40c84666cc311a42c256bbf880db3ac99sewardj
1327024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
1328024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
1329024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
1330024598e40c84666cc311a42c256bbf880db3ac99sewardj
1331024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
1332024598e40c84666cc311a42c256bbf880db3ac99sewardj
1333024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
1334024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
1335024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
1336024598e40c84666cc311a42c256bbf880db3ac99sewardj
1337024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
1338024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
1339024598e40c84666cc311a42c256bbf880db3ac99sewardj
1340024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
1341024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
1342024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
1343024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
1344024598e40c84666cc311a42c256bbf880db3ac99sewardj
1345024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
1346024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
1347024598e40c84666cc311a42c256bbf880db3ac99sewardj
1348024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
1349024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
1350024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
1351024598e40c84666cc311a42c256bbf880db3ac99sewardj
1352024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1353024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1354024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1355024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1356024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1357024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1358024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1359024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1360024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1361024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1362024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1363024598e40c84666cc311a42c256bbf880db3ac99sewardj
1364024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
1365024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
1366024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
1367024598e40c84666cc311a42c256bbf880db3ac99sewardj
1368024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
1369024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
1370024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
1371024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
1372024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
1373024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
1374024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
1375024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
1376024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
1377024598e40c84666cc311a42c256bbf880db3ac99sewardj
1378024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
1379024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
1380024598e40c84666cc311a42c256bbf880db3ac99sewardj
1381024598e40c84666cc311a42c256bbf880db3ac99sewardj
1382024598e40c84666cc311a42c256bbf880db3ac99sewardj
1383024598e40c84666cc311a42c256bbf880db3ac99sewardj
1384024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
1385024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
1386024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid makeMaps_d ( DState* s )
1387024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1388024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 i;
1389024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->nInUse = 0;
1390024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < 256; i++)
1391024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->inUse[i]) {
1392024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->seqToUnseq[s->nInUse] = i;
1393024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->nInUse++;
1394024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1395024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1396024598e40c84666cc311a42c256bbf880db3ac99sewardj
1397024598e40c84666cc311a42c256bbf880db3ac99sewardj
1398024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
1399024598e40c84666cc311a42c256bbf880db3ac99sewardj#define RETURN(rrr)                               \
1400024598e40c84666cc311a42c256bbf880db3ac99sewardj   { retVal = rrr; goto save_state_and_return; };
1401024598e40c84666cc311a42c256bbf880db3ac99sewardj
1402024598e40c84666cc311a42c256bbf880db3ac99sewardj#define GET_BITS(lll,vvv,nnn)                     \
1403024598e40c84666cc311a42c256bbf880db3ac99sewardj   case lll: s->state = lll;                      \
1404024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {                                 \
1405024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->bsLive >= nnn) {                     \
1406024598e40c84666cc311a42c256bbf880db3ac99sewardj         UInt32 v;                                \
1407024598e40c84666cc311a42c256bbf880db3ac99sewardj         v = (s->bsBuff >>                        \
1408024598e40c84666cc311a42c256bbf880db3ac99sewardj             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
1409024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->bsLive -= nnn;                        \
1410024598e40c84666cc311a42c256bbf880db3ac99sewardj         vvv = v;                                 \
1411024598e40c84666cc311a42c256bbf880db3ac99sewardj         break;                                   \
1412024598e40c84666cc311a42c256bbf880db3ac99sewardj      }                                           \
1413024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
1414024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->bsBuff                                   \
1415024598e40c84666cc311a42c256bbf880db3ac99sewardj         = (s->bsBuff << 8) |                     \
1416024598e40c84666cc311a42c256bbf880db3ac99sewardj           ((UInt32)                              \
1417024598e40c84666cc311a42c256bbf880db3ac99sewardj              (*((UChar*)(s->strm->next_in))));   \
1418024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->bsLive += 8;                             \
1419024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->next_in++;                         \
1420024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->avail_in--;                        \
1421024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->total_in_lo32++;                   \
1422024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->strm->total_in_lo32 == 0)            \
1423024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->total_in_hi32++;                \
1424024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1425024598e40c84666cc311a42c256bbf880db3ac99sewardj
1426024598e40c84666cc311a42c256bbf880db3ac99sewardj#define GET_UCHAR(lll,uuu)                        \
1427024598e40c84666cc311a42c256bbf880db3ac99sewardj   GET_BITS(lll,uuu,8)
1428024598e40c84666cc311a42c256bbf880db3ac99sewardj
1429024598e40c84666cc311a42c256bbf880db3ac99sewardj#define GET_BIT(lll,uuu)                          \
1430024598e40c84666cc311a42c256bbf880db3ac99sewardj   GET_BITS(lll,uuu,1)
1431024598e40c84666cc311a42c256bbf880db3ac99sewardj
1432024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
1433024598e40c84666cc311a42c256bbf880db3ac99sewardj#define GET_MTF_VAL(label1,label2,lval)           \
1434024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                                 \
1435024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (groupPos == 0) {                           \
1436024598e40c84666cc311a42c256bbf880db3ac99sewardj      groupNo++;                                  \
1437024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (groupNo >= nSelectors)                  \
1438024598e40c84666cc311a42c256bbf880db3ac99sewardj         RETURN(BZ_DATA_ERROR);                   \
1439024598e40c84666cc311a42c256bbf880db3ac99sewardj      groupPos = BZ_G_SIZE;                       \
1440024598e40c84666cc311a42c256bbf880db3ac99sewardj      gSel = s->selector[groupNo];                \
1441024598e40c84666cc311a42c256bbf880db3ac99sewardj      gMinlen = s->minLens[gSel];                 \
1442024598e40c84666cc311a42c256bbf880db3ac99sewardj      gLimit = &(s->limit[gSel][0]);              \
1443024598e40c84666cc311a42c256bbf880db3ac99sewardj      gPerm = &(s->perm[gSel][0]);                \
1444024598e40c84666cc311a42c256bbf880db3ac99sewardj      gBase = &(s->base[gSel][0]);                \
1445024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                              \
1446024598e40c84666cc311a42c256bbf880db3ac99sewardj   groupPos--;                                    \
1447024598e40c84666cc311a42c256bbf880db3ac99sewardj   zn = gMinlen;                                  \
1448024598e40c84666cc311a42c256bbf880db3ac99sewardj   GET_BITS(label1, zvec, zn);                    \
1449024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (1) {                                    \
1450024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (zn > 20 /* the longest code */)         \
1451024598e40c84666cc311a42c256bbf880db3ac99sewardj         RETURN(BZ_DATA_ERROR);                   \
1452024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (zvec <= gLimit[zn]) break;              \
1453024598e40c84666cc311a42c256bbf880db3ac99sewardj      zn++;                                       \
1454024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_BIT(label2, zj);                        \
1455024598e40c84666cc311a42c256bbf880db3ac99sewardj      zvec = (zvec << 1) | zj;                    \
1456024598e40c84666cc311a42c256bbf880db3ac99sewardj   };                                             \
1457024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (zvec - gBase[zn] < 0                       \
1458024598e40c84666cc311a42c256bbf880db3ac99sewardj       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
1459024598e40c84666cc311a42c256bbf880db3ac99sewardj      RETURN(BZ_DATA_ERROR);                      \
1460024598e40c84666cc311a42c256bbf880db3ac99sewardj   lval = gPerm[zvec - gBase[zn]];                \
1461024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1462024598e40c84666cc311a42c256bbf880db3ac99sewardj
1463024598e40c84666cc311a42c256bbf880db3ac99sewardj
1464024598e40c84666cc311a42c256bbf880db3ac99sewardj
1465024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
1466024598e40c84666cc311a42c256bbf880db3ac99sewardj__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
1467024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1468024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nb, na, mid;
1469024598e40c84666cc311a42c256bbf880db3ac99sewardj   nb = 0;
1470024598e40c84666cc311a42c256bbf880db3ac99sewardj   na = 256;
1471024598e40c84666cc311a42c256bbf880db3ac99sewardj   do {
1472024598e40c84666cc311a42c256bbf880db3ac99sewardj      mid = (nb + na) >> 1;
1473024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (indx >= cftab[mid]) nb = mid; else na = mid;
1474024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1475024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (na - nb != 1);
1476024598e40c84666cc311a42c256bbf880db3ac99sewardj   return nb;
1477024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1478024598e40c84666cc311a42c256bbf880db3ac99sewardj
1479024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
1480024598e40c84666cc311a42c256bbf880db3ac99sewardjInt32 BZ2_decompress ( DState* s )
1481024598e40c84666cc311a42c256bbf880db3ac99sewardj{
1482024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar      uc;
1483024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32      retVal;
1484024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32      minLen, maxLen;
1485024598e40c84666cc311a42c256bbf880db3ac99sewardj   bz_stream* strm = s->strm;
1486024598e40c84666cc311a42c256bbf880db3ac99sewardj
1487024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* stuff that needs to be saved/restored */
1488024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  i;
1489024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  j;
1490024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  t;
1491024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  alphaSize;
1492024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  nGroups;
1493024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  nSelectors;
1494024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  EOB;
1495024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  groupNo;
1496024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  groupPos;
1497024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  nextSym;
1498024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  nblockMAX;
1499024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  nblock;
1500024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  es;
1501024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  N;
1502024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  curr;
1503024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  zt;
1504024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  zn;
1505024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  zvec;
1506024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  zj;
1507024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  gSel;
1508024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  gMinlen;
1509024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32* gLimit;
1510024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32* gBase;
1511024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32* gPerm;
1512024598e40c84666cc311a42c256bbf880db3ac99sewardj
1513024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->state == BZ_X_MAGIC_1) {
1514024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*initialise the save area*/
1515024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_i           = 0;
1516024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_j           = 0;
1517024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_t           = 0;
1518024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_alphaSize   = 0;
1519024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_nGroups     = 0;
1520024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_nSelectors  = 0;
1521024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_EOB         = 0;
1522024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_groupNo     = 0;
1523024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_groupPos    = 0;
1524024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_nextSym     = 0;
1525024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_nblockMAX   = 0;
1526024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_nblock      = 0;
1527024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_es          = 0;
1528024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_N           = 0;
1529024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_curr        = 0;
1530024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_zt          = 0;
1531024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_zn          = 0;
1532024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_zvec        = 0;
1533024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_zj          = 0;
1534024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_gSel        = 0;
1535024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_gMinlen     = 0;
1536024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_gLimit      = NULL;
1537024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_gBase       = NULL;
1538024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->save_gPerm       = NULL;
1539024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1540024598e40c84666cc311a42c256bbf880db3ac99sewardj
1541024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*restore from the save area*/
1542024598e40c84666cc311a42c256bbf880db3ac99sewardj   i           = s->save_i;
1543024598e40c84666cc311a42c256bbf880db3ac99sewardj   j           = s->save_j;
1544024598e40c84666cc311a42c256bbf880db3ac99sewardj   t           = s->save_t;
1545024598e40c84666cc311a42c256bbf880db3ac99sewardj   alphaSize   = s->save_alphaSize;
1546024598e40c84666cc311a42c256bbf880db3ac99sewardj   nGroups     = s->save_nGroups;
1547024598e40c84666cc311a42c256bbf880db3ac99sewardj   nSelectors  = s->save_nSelectors;
1548024598e40c84666cc311a42c256bbf880db3ac99sewardj   EOB         = s->save_EOB;
1549024598e40c84666cc311a42c256bbf880db3ac99sewardj   groupNo     = s->save_groupNo;
1550024598e40c84666cc311a42c256bbf880db3ac99sewardj   groupPos    = s->save_groupPos;
1551024598e40c84666cc311a42c256bbf880db3ac99sewardj   nextSym     = s->save_nextSym;
1552024598e40c84666cc311a42c256bbf880db3ac99sewardj   nblockMAX   = s->save_nblockMAX;
1553024598e40c84666cc311a42c256bbf880db3ac99sewardj   nblock      = s->save_nblock;
1554024598e40c84666cc311a42c256bbf880db3ac99sewardj   es          = s->save_es;
1555024598e40c84666cc311a42c256bbf880db3ac99sewardj   N           = s->save_N;
1556024598e40c84666cc311a42c256bbf880db3ac99sewardj   curr        = s->save_curr;
1557024598e40c84666cc311a42c256bbf880db3ac99sewardj   zt          = s->save_zt;
1558024598e40c84666cc311a42c256bbf880db3ac99sewardj   zn          = s->save_zn;
1559024598e40c84666cc311a42c256bbf880db3ac99sewardj   zvec        = s->save_zvec;
1560024598e40c84666cc311a42c256bbf880db3ac99sewardj   zj          = s->save_zj;
1561024598e40c84666cc311a42c256bbf880db3ac99sewardj   gSel        = s->save_gSel;
1562024598e40c84666cc311a42c256bbf880db3ac99sewardj   gMinlen     = s->save_gMinlen;
1563024598e40c84666cc311a42c256bbf880db3ac99sewardj   gLimit      = s->save_gLimit;
1564024598e40c84666cc311a42c256bbf880db3ac99sewardj   gBase       = s->save_gBase;
1565024598e40c84666cc311a42c256bbf880db3ac99sewardj   gPerm       = s->save_gPerm;
1566024598e40c84666cc311a42c256bbf880db3ac99sewardj
1567024598e40c84666cc311a42c256bbf880db3ac99sewardj   retVal = BZ_OK;
1568024598e40c84666cc311a42c256bbf880db3ac99sewardj
1569024598e40c84666cc311a42c256bbf880db3ac99sewardj   switch (s->state) {
1570024598e40c84666cc311a42c256bbf880db3ac99sewardj
1571024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_MAGIC_1, uc);
1572024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
1573024598e40c84666cc311a42c256bbf880db3ac99sewardj
1574024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_MAGIC_2, uc);
1575024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
1576024598e40c84666cc311a42c256bbf880db3ac99sewardj
1577024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_MAGIC_3, uc)
1578024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
1579024598e40c84666cc311a42c256bbf880db3ac99sewardj
1580024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
1581024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->blockSize100k < (BZ_HDR_0 + 1) ||
1582024598e40c84666cc311a42c256bbf880db3ac99sewardj          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
1583024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->blockSize100k -= BZ_HDR_0;
1584024598e40c84666cc311a42c256bbf880db3ac99sewardj
1585024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->smallDecompress) {
1586024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
1587024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->ll4  = BZALLOC(
1588024598e40c84666cc311a42c256bbf880db3ac99sewardj                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
1589024598e40c84666cc311a42c256bbf880db3ac99sewardj                   );
1590024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
1591024598e40c84666cc311a42c256bbf880db3ac99sewardj      } else {
1592024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
1593024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
1594024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1595024598e40c84666cc311a42c256bbf880db3ac99sewardj
1596024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BLKHDR_1, uc);
1597024598e40c84666cc311a42c256bbf880db3ac99sewardj
1598024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc == 0x17) goto endhdr_2;
1599024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
1600024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BLKHDR_2, uc);
1601024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
1602024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BLKHDR_3, uc);
1603024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
1604024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BLKHDR_4, uc);
1605024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
1606024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BLKHDR_5, uc);
1607024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
1608024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BLKHDR_6, uc);
1609024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
1610024598e40c84666cc311a42c256bbf880db3ac99sewardj
1611024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->currBlockNo++;
1612024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->verbosity >= 2)
1613024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
1614024598e40c84666cc311a42c256bbf880db3ac99sewardj
1615024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedBlockCRC = 0;
1616024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BCRC_1, uc);
1617024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1618024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BCRC_2, uc);
1619024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1620024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BCRC_3, uc);
1621024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1622024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_BCRC_4, uc);
1623024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1624024598e40c84666cc311a42c256bbf880db3ac99sewardj
1625024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
1626024598e40c84666cc311a42c256bbf880db3ac99sewardj
1627024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->origPtr = 0;
1628024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
1629024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1630024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
1631024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1632024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
1633024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1634024598e40c84666cc311a42c256bbf880db3ac99sewardj
1635024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->origPtr < 0)
1636024598e40c84666cc311a42c256bbf880db3ac99sewardj         RETURN(BZ_DATA_ERROR);
1637024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->origPtr > 10 + 100000*s->blockSize100k)
1638024598e40c84666cc311a42c256bbf880db3ac99sewardj         RETURN(BZ_DATA_ERROR);
1639024598e40c84666cc311a42c256bbf880db3ac99sewardj
1640024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--- Receive the mapping table ---*/
1641024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < 16; i++) {
1642024598e40c84666cc311a42c256bbf880db3ac99sewardj         GET_BIT(BZ_X_MAPPING_1, uc);
1643024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (uc == 1)
1644024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->inUse16[i] = True; else
1645024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->inUse16[i] = False;
1646024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1647024598e40c84666cc311a42c256bbf880db3ac99sewardj
1648024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < 256; i++) s->inUse[i] = False;
1649024598e40c84666cc311a42c256bbf880db3ac99sewardj
1650024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < 16; i++)
1651024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->inUse16[i])
1652024598e40c84666cc311a42c256bbf880db3ac99sewardj            for (j = 0; j < 16; j++) {
1653024598e40c84666cc311a42c256bbf880db3ac99sewardj               GET_BIT(BZ_X_MAPPING_2, uc);
1654024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (uc == 1) s->inUse[i * 16 + j] = True;
1655024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
1656024598e40c84666cc311a42c256bbf880db3ac99sewardj      makeMaps_d ( s );
1657024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
1658024598e40c84666cc311a42c256bbf880db3ac99sewardj      alphaSize = s->nInUse+2;
1659024598e40c84666cc311a42c256bbf880db3ac99sewardj
1660024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--- Now the selectors ---*/
1661024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
1662024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
1663024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
1664024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
1665024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < nSelectors; i++) {
1666024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = 0;
1667024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (True) {
1668024598e40c84666cc311a42c256bbf880db3ac99sewardj            GET_BIT(BZ_X_SELECTOR_3, uc);
1669024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (uc == 0) break;
1670024598e40c84666cc311a42c256bbf880db3ac99sewardj            j++;
1671024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
1672024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1673024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->selectorMtf[i] = j;
1674024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1675024598e40c84666cc311a42c256bbf880db3ac99sewardj
1676024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--- Undo the MTF values for the selectors. ---*/
1677024598e40c84666cc311a42c256bbf880db3ac99sewardj      {
1678024598e40c84666cc311a42c256bbf880db3ac99sewardj         UChar pos[BZ_N_GROUPS], tmp, v;
1679024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (v = 0; v < nGroups; v++) pos[v] = v;
1680024598e40c84666cc311a42c256bbf880db3ac99sewardj
1681024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = 0; i < nSelectors; i++) {
1682024598e40c84666cc311a42c256bbf880db3ac99sewardj            v = s->selectorMtf[i];
1683024598e40c84666cc311a42c256bbf880db3ac99sewardj            tmp = pos[v];
1684024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (v > 0) { pos[v] = pos[v-1]; v--; }
1685024598e40c84666cc311a42c256bbf880db3ac99sewardj            pos[0] = tmp;
1686024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->selector[i] = tmp;
1687024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1688024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1689024598e40c84666cc311a42c256bbf880db3ac99sewardj
1690024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--- Now the coding tables ---*/
1691024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (t = 0; t < nGroups; t++) {
1692024598e40c84666cc311a42c256bbf880db3ac99sewardj         GET_BITS(BZ_X_CODING_1, curr, 5);
1693024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = 0; i < alphaSize; i++) {
1694024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (True) {
1695024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
1696024598e40c84666cc311a42c256bbf880db3ac99sewardj               GET_BIT(BZ_X_CODING_2, uc);
1697024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (uc == 0) break;
1698024598e40c84666cc311a42c256bbf880db3ac99sewardj               GET_BIT(BZ_X_CODING_3, uc);
1699024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (uc == 0) curr++; else curr--;
1700024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
1701024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->len[t][i] = curr;
1702024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1703024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1704024598e40c84666cc311a42c256bbf880db3ac99sewardj
1705024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--- Create the Huffman decoding tables ---*/
1706024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (t = 0; t < nGroups; t++) {
1707024598e40c84666cc311a42c256bbf880db3ac99sewardj         minLen = 32;
1708024598e40c84666cc311a42c256bbf880db3ac99sewardj         maxLen = 0;
1709024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = 0; i < alphaSize; i++) {
1710024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
1711024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->len[t][i] < minLen) minLen = s->len[t][i];
1712024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1713024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ2_hbCreateDecodeTables (
1714024598e40c84666cc311a42c256bbf880db3ac99sewardj            &(s->limit[t][0]),
1715024598e40c84666cc311a42c256bbf880db3ac99sewardj            &(s->base[t][0]),
1716024598e40c84666cc311a42c256bbf880db3ac99sewardj            &(s->perm[t][0]),
1717024598e40c84666cc311a42c256bbf880db3ac99sewardj            &(s->len[t][0]),
1718024598e40c84666cc311a42c256bbf880db3ac99sewardj            minLen, maxLen, alphaSize
1719024598e40c84666cc311a42c256bbf880db3ac99sewardj         );
1720024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->minLens[t] = minLen;
1721024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1722024598e40c84666cc311a42c256bbf880db3ac99sewardj
1723024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--- Now the MTF values ---*/
1724024598e40c84666cc311a42c256bbf880db3ac99sewardj
1725024598e40c84666cc311a42c256bbf880db3ac99sewardj      EOB      = s->nInUse+1;
1726024598e40c84666cc311a42c256bbf880db3ac99sewardj      nblockMAX = 100000 * s->blockSize100k;
1727024598e40c84666cc311a42c256bbf880db3ac99sewardj      groupNo  = -1;
1728024598e40c84666cc311a42c256bbf880db3ac99sewardj      groupPos = 0;
1729024598e40c84666cc311a42c256bbf880db3ac99sewardj
1730024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
1731024598e40c84666cc311a42c256bbf880db3ac99sewardj
1732024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- MTF init --*/
1733024598e40c84666cc311a42c256bbf880db3ac99sewardj      {
1734024598e40c84666cc311a42c256bbf880db3ac99sewardj         Int32 ii, jj, kk;
1735024598e40c84666cc311a42c256bbf880db3ac99sewardj         kk = MTFA_SIZE-1;
1736024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
1737024598e40c84666cc311a42c256bbf880db3ac99sewardj            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
1738024598e40c84666cc311a42c256bbf880db3ac99sewardj               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
1739024598e40c84666cc311a42c256bbf880db3ac99sewardj               kk--;
1740024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
1741024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->mtfbase[ii] = kk + 1;
1742024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1743024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1744024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- end MTF init --*/
1745024598e40c84666cc311a42c256bbf880db3ac99sewardj
1746024598e40c84666cc311a42c256bbf880db3ac99sewardj      nblock = 0;
1747024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
1748024598e40c84666cc311a42c256bbf880db3ac99sewardj
1749024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
1750024598e40c84666cc311a42c256bbf880db3ac99sewardj
1751024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (nextSym == EOB) break;
1752024598e40c84666cc311a42c256bbf880db3ac99sewardj
1753024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
1754024598e40c84666cc311a42c256bbf880db3ac99sewardj
1755024598e40c84666cc311a42c256bbf880db3ac99sewardj            es = -1;
1756024598e40c84666cc311a42c256bbf880db3ac99sewardj            N = 1;
1757024598e40c84666cc311a42c256bbf880db3ac99sewardj            do {
1758024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
1759024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
1760024598e40c84666cc311a42c256bbf880db3ac99sewardj               N = N * 2;
1761024598e40c84666cc311a42c256bbf880db3ac99sewardj               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
1762024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
1763024598e40c84666cc311a42c256bbf880db3ac99sewardj               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
1764024598e40c84666cc311a42c256bbf880db3ac99sewardj
1765024598e40c84666cc311a42c256bbf880db3ac99sewardj            es++;
1766024598e40c84666cc311a42c256bbf880db3ac99sewardj            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
1767024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->unzftab[uc] += es;
1768024598e40c84666cc311a42c256bbf880db3ac99sewardj
1769024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->smallDecompress)
1770024598e40c84666cc311a42c256bbf880db3ac99sewardj               while (es > 0) {
1771024598e40c84666cc311a42c256bbf880db3ac99sewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1772024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->ll16[nblock] = (UInt16)uc;
1773024598e40c84666cc311a42c256bbf880db3ac99sewardj                  nblock++;
1774024598e40c84666cc311a42c256bbf880db3ac99sewardj                  es--;
1775024598e40c84666cc311a42c256bbf880db3ac99sewardj               }
1776024598e40c84666cc311a42c256bbf880db3ac99sewardj            else
1777024598e40c84666cc311a42c256bbf880db3ac99sewardj               while (es > 0) {
1778024598e40c84666cc311a42c256bbf880db3ac99sewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1779024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->tt[nblock] = (UInt32)uc;
1780024598e40c84666cc311a42c256bbf880db3ac99sewardj                  nblock++;
1781024598e40c84666cc311a42c256bbf880db3ac99sewardj                  es--;
1782024598e40c84666cc311a42c256bbf880db3ac99sewardj               };
1783024598e40c84666cc311a42c256bbf880db3ac99sewardj
1784024598e40c84666cc311a42c256bbf880db3ac99sewardj            continue;
1785024598e40c84666cc311a42c256bbf880db3ac99sewardj
1786024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
1787024598e40c84666cc311a42c256bbf880db3ac99sewardj
1788024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1789024598e40c84666cc311a42c256bbf880db3ac99sewardj
1790024598e40c84666cc311a42c256bbf880db3ac99sewardj            /*-- uc = MTF ( nextSym-1 ) --*/
1791024598e40c84666cc311a42c256bbf880db3ac99sewardj            {
1792024598e40c84666cc311a42c256bbf880db3ac99sewardj               Int32 ii, jj, kk, pp, lno, off;
1793024598e40c84666cc311a42c256bbf880db3ac99sewardj               UInt32 nn;
1794024598e40c84666cc311a42c256bbf880db3ac99sewardj               nn = (UInt32)(nextSym - 1);
1795024598e40c84666cc311a42c256bbf880db3ac99sewardj
1796024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (nn < MTFL_SIZE) {
1797024598e40c84666cc311a42c256bbf880db3ac99sewardj                  /* avoid general-case expense */
1798024598e40c84666cc311a42c256bbf880db3ac99sewardj                  pp = s->mtfbase[0];
1799024598e40c84666cc311a42c256bbf880db3ac99sewardj                  uc = s->mtfa[pp+nn];
1800024598e40c84666cc311a42c256bbf880db3ac99sewardj                  while (nn > 3) {
1801024598e40c84666cc311a42c256bbf880db3ac99sewardj                     Int32 z = pp+nn;
1802024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
1803024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
1804024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
1805024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
1806024598e40c84666cc311a42c256bbf880db3ac99sewardj                     nn -= 4;
1807024598e40c84666cc311a42c256bbf880db3ac99sewardj                  }
1808024598e40c84666cc311a42c256bbf880db3ac99sewardj                  while (nn > 0) {
1809024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
1810024598e40c84666cc311a42c256bbf880db3ac99sewardj                  };
1811024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->mtfa[pp] = uc;
1812024598e40c84666cc311a42c256bbf880db3ac99sewardj               } else {
1813024598e40c84666cc311a42c256bbf880db3ac99sewardj                  /* general case */
1814024598e40c84666cc311a42c256bbf880db3ac99sewardj                  lno = nn / MTFL_SIZE;
1815024598e40c84666cc311a42c256bbf880db3ac99sewardj                  off = nn % MTFL_SIZE;
1816024598e40c84666cc311a42c256bbf880db3ac99sewardj                  pp = s->mtfbase[lno] + off;
1817024598e40c84666cc311a42c256bbf880db3ac99sewardj                  uc = s->mtfa[pp];
1818024598e40c84666cc311a42c256bbf880db3ac99sewardj                  while (pp > s->mtfbase[lno]) {
1819024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfa[pp] = s->mtfa[pp-1]; pp--;
1820024598e40c84666cc311a42c256bbf880db3ac99sewardj                  };
1821024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->mtfbase[lno]++;
1822024598e40c84666cc311a42c256bbf880db3ac99sewardj                  while (lno > 0) {
1823024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfbase[lno]--;
1824024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s->mtfa[s->mtfbase[lno]]
1825024598e40c84666cc311a42c256bbf880db3ac99sewardj                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
1826024598e40c84666cc311a42c256bbf880db3ac99sewardj                     lno--;
1827024598e40c84666cc311a42c256bbf880db3ac99sewardj                  }
1828024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->mtfbase[0]--;
1829024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->mtfa[s->mtfbase[0]] = uc;
1830024598e40c84666cc311a42c256bbf880db3ac99sewardj                  if (s->mtfbase[0] == 0) {
1831024598e40c84666cc311a42c256bbf880db3ac99sewardj                     kk = MTFA_SIZE-1;
1832024598e40c84666cc311a42c256bbf880db3ac99sewardj                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
1833024598e40c84666cc311a42c256bbf880db3ac99sewardj                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
1834024598e40c84666cc311a42c256bbf880db3ac99sewardj                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
1835024598e40c84666cc311a42c256bbf880db3ac99sewardj                           kk--;
1836024598e40c84666cc311a42c256bbf880db3ac99sewardj                        }
1837024598e40c84666cc311a42c256bbf880db3ac99sewardj                        s->mtfbase[ii] = kk + 1;
1838024598e40c84666cc311a42c256bbf880db3ac99sewardj                     }
1839024598e40c84666cc311a42c256bbf880db3ac99sewardj                  }
1840024598e40c84666cc311a42c256bbf880db3ac99sewardj               }
1841024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
1842024598e40c84666cc311a42c256bbf880db3ac99sewardj            /*-- end uc = MTF ( nextSym-1 ) --*/
1843024598e40c84666cc311a42c256bbf880db3ac99sewardj
1844024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->unzftab[s->seqToUnseq[uc]]++;
1845024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->smallDecompress)
1846024598e40c84666cc311a42c256bbf880db3ac99sewardj               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
1847024598e40c84666cc311a42c256bbf880db3ac99sewardj               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
1848024598e40c84666cc311a42c256bbf880db3ac99sewardj            nblock++;
1849024598e40c84666cc311a42c256bbf880db3ac99sewardj
1850024598e40c84666cc311a42c256bbf880db3ac99sewardj            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
1851024598e40c84666cc311a42c256bbf880db3ac99sewardj            continue;
1852024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1853024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1854024598e40c84666cc311a42c256bbf880db3ac99sewardj
1855024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* Now we know what nblock is, we can do a better sanity
1856024598e40c84666cc311a42c256bbf880db3ac99sewardj         check on s->origPtr.
1857024598e40c84666cc311a42c256bbf880db3ac99sewardj      */
1858024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->origPtr < 0 || s->origPtr >= nblock)
1859024598e40c84666cc311a42c256bbf880db3ac99sewardj         RETURN(BZ_DATA_ERROR);
1860024598e40c84666cc311a42c256bbf880db3ac99sewardj
1861024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- Set up cftab to facilitate generation of T^(-1) --*/
1862024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->cftab[0] = 0;
1863024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
1864024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
1865024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i <= 256; i++) {
1866024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
1867024598e40c84666cc311a42c256bbf880db3ac99sewardj            /* s->cftab[i] can legitimately be == nblock */
1868024598e40c84666cc311a42c256bbf880db3ac99sewardj            RETURN(BZ_DATA_ERROR);
1869024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1870024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1871024598e40c84666cc311a42c256bbf880db3ac99sewardj
1872024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->state_out_len = 0;
1873024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->state_out_ch  = 0;
1874024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
1875024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->state = BZ_X_OUTPUT;
1876024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
1877024598e40c84666cc311a42c256bbf880db3ac99sewardj
1878024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->smallDecompress) {
1879024598e40c84666cc311a42c256bbf880db3ac99sewardj
1880024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- Make a copy of cftab, used in generation of T --*/
1881024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
1882024598e40c84666cc311a42c256bbf880db3ac99sewardj
1883024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- compute the T vector --*/
1884024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = 0; i < nblock; i++) {
1885024598e40c84666cc311a42c256bbf880db3ac99sewardj            uc = (UChar)(s->ll16[i]);
1886024598e40c84666cc311a42c256bbf880db3ac99sewardj            SET_LL(i, s->cftabCopy[uc]);
1887024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->cftabCopy[uc]++;
1888024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1889024598e40c84666cc311a42c256bbf880db3ac99sewardj
1890024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- Compute T^(-1) by pointer reversal on T --*/
1891024598e40c84666cc311a42c256bbf880db3ac99sewardj         i = s->origPtr;
1892024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = GET_LL(i);
1893024598e40c84666cc311a42c256bbf880db3ac99sewardj         do {
1894024598e40c84666cc311a42c256bbf880db3ac99sewardj            Int32 tmp = GET_LL(j);
1895024598e40c84666cc311a42c256bbf880db3ac99sewardj            SET_LL(j, i);
1896024598e40c84666cc311a42c256bbf880db3ac99sewardj            i = j;
1897024598e40c84666cc311a42c256bbf880db3ac99sewardj            j = tmp;
1898024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1899024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (i != s->origPtr);
1900024598e40c84666cc311a42c256bbf880db3ac99sewardj
1901024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->tPos = s->origPtr;
1902024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->nblock_used = 0;
1903024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->blockRandomised) {
1904024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_RAND_INIT_MASK;
1905024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
1906024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
1907024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
1908024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
1909024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1910024598e40c84666cc311a42c256bbf880db3ac99sewardj
1911024598e40c84666cc311a42c256bbf880db3ac99sewardj      } else {
1912024598e40c84666cc311a42c256bbf880db3ac99sewardj
1913024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- compute the T^(-1) vector --*/
1914024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = 0; i < nblock; i++) {
1915024598e40c84666cc311a42c256bbf880db3ac99sewardj            uc = (UChar)(s->tt[i] & 0xff);
1916024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->tt[s->cftab[uc]] |= (i << 8);
1917024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->cftab[uc]++;
1918024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1919024598e40c84666cc311a42c256bbf880db3ac99sewardj
1920024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->tPos = s->tt[s->origPtr] >> 8;
1921024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->nblock_used = 0;
1922024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->blockRandomised) {
1923024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_RAND_INIT_MASK;
1924024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
1925024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
1926024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
1927024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
1928024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
1929024598e40c84666cc311a42c256bbf880db3ac99sewardj
1930024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
1931024598e40c84666cc311a42c256bbf880db3ac99sewardj
1932024598e40c84666cc311a42c256bbf880db3ac99sewardj      RETURN(BZ_OK);
1933024598e40c84666cc311a42c256bbf880db3ac99sewardj
1934024598e40c84666cc311a42c256bbf880db3ac99sewardj
1935024598e40c84666cc311a42c256bbf880db3ac99sewardj
1936024598e40c84666cc311a42c256bbf880db3ac99sewardj    endhdr_2:
1937024598e40c84666cc311a42c256bbf880db3ac99sewardj
1938024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ENDHDR_2, uc);
1939024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
1940024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ENDHDR_3, uc);
1941024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
1942024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ENDHDR_4, uc);
1943024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
1944024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ENDHDR_5, uc);
1945024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
1946024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_ENDHDR_6, uc);
1947024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
1948024598e40c84666cc311a42c256bbf880db3ac99sewardj
1949024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedCombinedCRC = 0;
1950024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_CCRC_1, uc);
1951024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1952024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_CCRC_2, uc);
1953024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1954024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_CCRC_3, uc);
1955024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1956024598e40c84666cc311a42c256bbf880db3ac99sewardj      GET_UCHAR(BZ_X_CCRC_4, uc);
1957024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1958024598e40c84666cc311a42c256bbf880db3ac99sewardj
1959024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->state = BZ_X_IDLE;
1960024598e40c84666cc311a42c256bbf880db3ac99sewardj      RETURN(BZ_STREAM_END);
1961024598e40c84666cc311a42c256bbf880db3ac99sewardj
1962024598e40c84666cc311a42c256bbf880db3ac99sewardj      default: AssertH ( False, 4001 );
1963024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
1964024598e40c84666cc311a42c256bbf880db3ac99sewardj
1965024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH ( False, 4002 );
1966024598e40c84666cc311a42c256bbf880db3ac99sewardj
1967024598e40c84666cc311a42c256bbf880db3ac99sewardj   save_state_and_return:
1968024598e40c84666cc311a42c256bbf880db3ac99sewardj
1969024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_i           = i;
1970024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_j           = j;
1971024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_t           = t;
1972024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_alphaSize   = alphaSize;
1973024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_nGroups     = nGroups;
1974024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_nSelectors  = nSelectors;
1975024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_EOB         = EOB;
1976024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_groupNo     = groupNo;
1977024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_groupPos    = groupPos;
1978024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_nextSym     = nextSym;
1979024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_nblockMAX   = nblockMAX;
1980024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_nblock      = nblock;
1981024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_es          = es;
1982024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_N           = N;
1983024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_curr        = curr;
1984024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_zt          = zt;
1985024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_zn          = zn;
1986024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_zvec        = zvec;
1987024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_zj          = zj;
1988024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_gSel        = gSel;
1989024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_gMinlen     = gMinlen;
1990024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_gLimit      = gLimit;
1991024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_gBase       = gBase;
1992024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->save_gPerm       = gPerm;
1993024598e40c84666cc311a42c256bbf880db3ac99sewardj
1994024598e40c84666cc311a42c256bbf880db3ac99sewardj   return retVal;
1995024598e40c84666cc311a42c256bbf880db3ac99sewardj}
1996024598e40c84666cc311a42c256bbf880db3ac99sewardj
1997024598e40c84666cc311a42c256bbf880db3ac99sewardj
1998024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
1999024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                      decompress.c ---*/
2000024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
2001024598e40c84666cc311a42c256bbf880db3ac99sewardj
2002024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
2003024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Block sorting machinery                               ---*/
2004024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                           blocksort.c ---*/
2005024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
2006024598e40c84666cc311a42c256bbf880db3ac99sewardj
2007024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
2008024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
2009024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
2010024598e40c84666cc311a42c256bbf880db3ac99sewardj
2011024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
2012024598e40c84666cc311a42c256bbf880db3ac99sewardj
2013024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
2014024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
2015024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
2016024598e40c84666cc311a42c256bbf880db3ac99sewardj
2017024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
2018024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
2019024598e40c84666cc311a42c256bbf880db3ac99sewardj
2020024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
2021024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
2022024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
2023024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
2024024598e40c84666cc311a42c256bbf880db3ac99sewardj
2025024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
2026024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
2027024598e40c84666cc311a42c256bbf880db3ac99sewardj
2028024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
2029024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
2030024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
2031024598e40c84666cc311a42c256bbf880db3ac99sewardj
2032024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
2033024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2034024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2035024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2036024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2037024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2038024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2039024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2040024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2041024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2042024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2043024598e40c84666cc311a42c256bbf880db3ac99sewardj
2044024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
2045024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
2046024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
2047024598e40c84666cc311a42c256bbf880db3ac99sewardj
2048024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
2049024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
2050024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
2051024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
2052024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
2053024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
2054024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
2055024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
2056024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
2057024598e40c84666cc311a42c256bbf880db3ac99sewardj
2058024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
2059024598e40c84666cc311a42c256bbf880db3ac99sewardj
2060024598e40c84666cc311a42c256bbf880db3ac99sewardj  To get some idea how the block sorting algorithms in this file
2061024598e40c84666cc311a42c256bbf880db3ac99sewardj  work, read my paper
2062024598e40c84666cc311a42c256bbf880db3ac99sewardj     On the Performance of BWT Sorting Algorithms
2063024598e40c84666cc311a42c256bbf880db3ac99sewardj  in Proceedings of the IEEE Data Compression Conference 2000,
2064024598e40c84666cc311a42c256bbf880db3ac99sewardj  Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
2065024598e40c84666cc311a42c256bbf880db3ac99sewardj  file implements the algorithm called  cache  in the paper.
2066024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
2067024598e40c84666cc311a42c256bbf880db3ac99sewardj
2068024598e40c84666cc311a42c256bbf880db3ac99sewardj
2069024598e40c84666cc311a42c256bbf880db3ac99sewardj
2070024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2071024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Fallback O(N log(N)^2) sorting        ---*/
2072024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- algorithm, for repetitive blocks      ---*/
2073024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2074024598e40c84666cc311a42c256bbf880db3ac99sewardj
2075024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2076024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2077024598e40c84666cc311a42c256bbf880db3ac99sewardj__inline__
2078024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid fallbackSimpleSort ( UInt32* fmap,
2079024598e40c84666cc311a42c256bbf880db3ac99sewardj                          UInt32* eclass,
2080024598e40c84666cc311a42c256bbf880db3ac99sewardj                          Int32   lo,
2081024598e40c84666cc311a42c256bbf880db3ac99sewardj                          Int32   hi )
2082024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2083024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 i, j, tmp;
2084024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt32 ec_tmp;
2085024598e40c84666cc311a42c256bbf880db3ac99sewardj
2086024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (lo == hi) return;
2087024598e40c84666cc311a42c256bbf880db3ac99sewardj
2088024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (hi - lo > 3) {
2089024598e40c84666cc311a42c256bbf880db3ac99sewardj      for ( i = hi-4; i >= lo; i-- ) {
2090024598e40c84666cc311a42c256bbf880db3ac99sewardj         tmp = fmap[i];
2091024598e40c84666cc311a42c256bbf880db3ac99sewardj         ec_tmp = eclass[tmp];
2092024598e40c84666cc311a42c256bbf880db3ac99sewardj         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
2093024598e40c84666cc311a42c256bbf880db3ac99sewardj            fmap[j-4] = fmap[j];
2094024598e40c84666cc311a42c256bbf880db3ac99sewardj         fmap[j-4] = tmp;
2095024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2096024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2097024598e40c84666cc311a42c256bbf880db3ac99sewardj
2098024598e40c84666cc311a42c256bbf880db3ac99sewardj   for ( i = hi-1; i >= lo; i-- ) {
2099024598e40c84666cc311a42c256bbf880db3ac99sewardj      tmp = fmap[i];
2100024598e40c84666cc311a42c256bbf880db3ac99sewardj      ec_tmp = eclass[tmp];
2101024598e40c84666cc311a42c256bbf880db3ac99sewardj      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
2102024598e40c84666cc311a42c256bbf880db3ac99sewardj         fmap[j-1] = fmap[j];
2103024598e40c84666cc311a42c256bbf880db3ac99sewardj      fmap[j-1] = tmp;
2104024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2105024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2106024598e40c84666cc311a42c256bbf880db3ac99sewardj
2107024598e40c84666cc311a42c256bbf880db3ac99sewardj
2108024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2109024598e40c84666cc311a42c256bbf880db3ac99sewardj#define fswap(zz1, zz2) \
2110024598e40c84666cc311a42c256bbf880db3ac99sewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
2111024598e40c84666cc311a42c256bbf880db3ac99sewardj
2112024598e40c84666cc311a42c256bbf880db3ac99sewardj#define fvswap(zzp1, zzp2, zzn)       \
2113024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                     \
2114024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 yyp1 = (zzp1);               \
2115024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 yyp2 = (zzp2);               \
2116024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 yyn  = (zzn);                \
2117024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (yyn > 0) {                  \
2118024598e40c84666cc311a42c256bbf880db3ac99sewardj      fswap(fmap[yyp1], fmap[yyp2]);  \
2119024598e40c84666cc311a42c256bbf880db3ac99sewardj      yyp1++; yyp2++; yyn--;          \
2120024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                  \
2121024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2122024598e40c84666cc311a42c256bbf880db3ac99sewardj
2123024598e40c84666cc311a42c256bbf880db3ac99sewardj
2124024598e40c84666cc311a42c256bbf880db3ac99sewardj#define fmin(a,b) ((a) < (b)) ? (a) : (b)
2125024598e40c84666cc311a42c256bbf880db3ac99sewardj
2126024598e40c84666cc311a42c256bbf880db3ac99sewardj#define fpush(lz,hz) { stackLo[sp] = lz; \
2127024598e40c84666cc311a42c256bbf880db3ac99sewardj                       stackHi[sp] = hz; \
2128024598e40c84666cc311a42c256bbf880db3ac99sewardj                       sp++; }
2129024598e40c84666cc311a42c256bbf880db3ac99sewardj
2130024598e40c84666cc311a42c256bbf880db3ac99sewardj#define fpop(lz,hz) { sp--;              \
2131024598e40c84666cc311a42c256bbf880db3ac99sewardj                      lz = stackLo[sp];  \
2132024598e40c84666cc311a42c256bbf880db3ac99sewardj                      hz = stackHi[sp]; }
2133024598e40c84666cc311a42c256bbf880db3ac99sewardj
2134024598e40c84666cc311a42c256bbf880db3ac99sewardj#define FALLBACK_QSORT_SMALL_THRESH 10
2135024598e40c84666cc311a42c256bbf880db3ac99sewardj#define FALLBACK_QSORT_STACK_SIZE   100
2136024598e40c84666cc311a42c256bbf880db3ac99sewardj
2137024598e40c84666cc311a42c256bbf880db3ac99sewardj
2138024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2139024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid fallbackQSort3 ( UInt32* fmap,
2140024598e40c84666cc311a42c256bbf880db3ac99sewardj                      UInt32* eclass,
2141024598e40c84666cc311a42c256bbf880db3ac99sewardj                      Int32   loSt,
2142024598e40c84666cc311a42c256bbf880db3ac99sewardj                      Int32   hiSt )
2143024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2144024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 unLo, unHi, ltLo, gtHi, n, m;
2145024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 sp, lo, hi;
2146024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt32 med, r, r3;
2147024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
2148024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
2149024598e40c84666cc311a42c256bbf880db3ac99sewardj
2150024598e40c84666cc311a42c256bbf880db3ac99sewardj   r = 0;
2151024598e40c84666cc311a42c256bbf880db3ac99sewardj
2152024598e40c84666cc311a42c256bbf880db3ac99sewardj   sp = 0;
2153024598e40c84666cc311a42c256bbf880db3ac99sewardj   fpush ( loSt, hiSt );
2154024598e40c84666cc311a42c256bbf880db3ac99sewardj
2155024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (sp > 0) {
2156024598e40c84666cc311a42c256bbf880db3ac99sewardj
2157024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
2158024598e40c84666cc311a42c256bbf880db3ac99sewardj
2159024598e40c84666cc311a42c256bbf880db3ac99sewardj      fpop ( lo, hi );
2160024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
2161024598e40c84666cc311a42c256bbf880db3ac99sewardj         fallbackSimpleSort ( fmap, eclass, lo, hi );
2162024598e40c84666cc311a42c256bbf880db3ac99sewardj         continue;
2163024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2164024598e40c84666cc311a42c256bbf880db3ac99sewardj
2165024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* Random partitioning.  Median of 3 sometimes fails to
2166024598e40c84666cc311a42c256bbf880db3ac99sewardj         avoid bad cases.  Median of 9 seems to help but
2167024598e40c84666cc311a42c256bbf880db3ac99sewardj         looks rather expensive.  This too seems to work but
2168024598e40c84666cc311a42c256bbf880db3ac99sewardj         is cheaper.  Guidance for the magic constants
2169024598e40c84666cc311a42c256bbf880db3ac99sewardj         7621 and 32768 is taken from Sedgewick's algorithms
2170024598e40c84666cc311a42c256bbf880db3ac99sewardj         book, chapter 35.
2171024598e40c84666cc311a42c256bbf880db3ac99sewardj      */
2172024598e40c84666cc311a42c256bbf880db3ac99sewardj      r = ((r * 7621) + 1) % 32768;
2173024598e40c84666cc311a42c256bbf880db3ac99sewardj      r3 = r % 3;
2174024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (r3 == 0) med = eclass[fmap[lo]]; else
2175024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
2176024598e40c84666cc311a42c256bbf880db3ac99sewardj                   med = eclass[fmap[hi]];
2177024598e40c84666cc311a42c256bbf880db3ac99sewardj
2178024598e40c84666cc311a42c256bbf880db3ac99sewardj      unLo = ltLo = lo;
2179024598e40c84666cc311a42c256bbf880db3ac99sewardj      unHi = gtHi = hi;
2180024598e40c84666cc311a42c256bbf880db3ac99sewardj
2181024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (1) {
2182024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (1) {
2183024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (unLo > unHi) break;
2184024598e40c84666cc311a42c256bbf880db3ac99sewardj            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
2185024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n == 0) {
2186024598e40c84666cc311a42c256bbf880db3ac99sewardj               fswap(fmap[unLo], fmap[ltLo]);
2187024598e40c84666cc311a42c256bbf880db3ac99sewardj               ltLo++; unLo++;
2188024598e40c84666cc311a42c256bbf880db3ac99sewardj               continue;
2189024598e40c84666cc311a42c256bbf880db3ac99sewardj            };
2190024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n > 0) break;
2191024598e40c84666cc311a42c256bbf880db3ac99sewardj            unLo++;
2192024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2193024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (1) {
2194024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (unLo > unHi) break;
2195024598e40c84666cc311a42c256bbf880db3ac99sewardj            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
2196024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n == 0) {
2197024598e40c84666cc311a42c256bbf880db3ac99sewardj               fswap(fmap[unHi], fmap[gtHi]);
2198024598e40c84666cc311a42c256bbf880db3ac99sewardj               gtHi--; unHi--;
2199024598e40c84666cc311a42c256bbf880db3ac99sewardj               continue;
2200024598e40c84666cc311a42c256bbf880db3ac99sewardj            };
2201024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n < 0) break;
2202024598e40c84666cc311a42c256bbf880db3ac99sewardj            unHi--;
2203024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2204024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (unLo > unHi) break;
2205024598e40c84666cc311a42c256bbf880db3ac99sewardj         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
2206024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2207024598e40c84666cc311a42c256bbf880db3ac99sewardj
2208024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
2209024598e40c84666cc311a42c256bbf880db3ac99sewardj
2210024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (gtHi < ltLo) continue;
2211024598e40c84666cc311a42c256bbf880db3ac99sewardj
2212024598e40c84666cc311a42c256bbf880db3ac99sewardj      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
2213024598e40c84666cc311a42c256bbf880db3ac99sewardj      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
2214024598e40c84666cc311a42c256bbf880db3ac99sewardj
2215024598e40c84666cc311a42c256bbf880db3ac99sewardj      n = lo + unLo - ltLo - 1;
2216024598e40c84666cc311a42c256bbf880db3ac99sewardj      m = hi - (gtHi - unHi) + 1;
2217024598e40c84666cc311a42c256bbf880db3ac99sewardj
2218024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (n - lo > hi - m) {
2219024598e40c84666cc311a42c256bbf880db3ac99sewardj         fpush ( lo, n );
2220024598e40c84666cc311a42c256bbf880db3ac99sewardj         fpush ( m, hi );
2221024598e40c84666cc311a42c256bbf880db3ac99sewardj      } else {
2222024598e40c84666cc311a42c256bbf880db3ac99sewardj         fpush ( m, hi );
2223024598e40c84666cc311a42c256bbf880db3ac99sewardj         fpush ( lo, n );
2224024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2225024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2226024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2227024598e40c84666cc311a42c256bbf880db3ac99sewardj
2228024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef fmin
2229024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef fpush
2230024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef fpop
2231024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef fswap
2232024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef fvswap
2233024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef FALLBACK_QSORT_SMALL_THRESH
2234024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef FALLBACK_QSORT_STACK_SIZE
2235024598e40c84666cc311a42c256bbf880db3ac99sewardj
2236024598e40c84666cc311a42c256bbf880db3ac99sewardj
2237024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2238024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Pre:
2239024598e40c84666cc311a42c256bbf880db3ac99sewardj      nblock > 0
2240024598e40c84666cc311a42c256bbf880db3ac99sewardj      eclass exists for [0 .. nblock-1]
2241024598e40c84666cc311a42c256bbf880db3ac99sewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
2242024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr exists for [0 .. nblock-1]
2243024598e40c84666cc311a42c256bbf880db3ac99sewardj
2244024598e40c84666cc311a42c256bbf880db3ac99sewardj   Post:
2245024598e40c84666cc311a42c256bbf880db3ac99sewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
2246024598e40c84666cc311a42c256bbf880db3ac99sewardj      All other areas of eclass destroyed
2247024598e40c84666cc311a42c256bbf880db3ac99sewardj      fmap [0 .. nblock-1] holds sorted order
2248024598e40c84666cc311a42c256bbf880db3ac99sewardj      bhtab [ 0 .. 2+(nblock/32) ] destroyed
2249024598e40c84666cc311a42c256bbf880db3ac99sewardj*/
2250024598e40c84666cc311a42c256bbf880db3ac99sewardj
2251024598e40c84666cc311a42c256bbf880db3ac99sewardj#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
2252024598e40c84666cc311a42c256bbf880db3ac99sewardj#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
2253024598e40c84666cc311a42c256bbf880db3ac99sewardj#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
2254024598e40c84666cc311a42c256bbf880db3ac99sewardj#define      WORD_BH(zz)  bhtab[(zz) >> 5]
2255024598e40c84666cc311a42c256bbf880db3ac99sewardj#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
2256024598e40c84666cc311a42c256bbf880db3ac99sewardj
2257024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2258024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid fallbackSort ( UInt32* fmap,
2259024598e40c84666cc311a42c256bbf880db3ac99sewardj                    UInt32* eclass,
2260024598e40c84666cc311a42c256bbf880db3ac99sewardj                    UInt32* bhtab,
2261024598e40c84666cc311a42c256bbf880db3ac99sewardj                    Int32   nblock,
2262024598e40c84666cc311a42c256bbf880db3ac99sewardj                    Int32   verb )
2263024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2264024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 ftab[257];
2265024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 ftabCopy[256];
2266024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 H, i, j, k, l, r, cc, cc1;
2267024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nNotDone;
2268024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nBhtab;
2269024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar* eclass8 = (UChar*)eclass;
2270024598e40c84666cc311a42c256bbf880db3ac99sewardj
2271024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--
2272024598e40c84666cc311a42c256bbf880db3ac99sewardj      Initial 1-char radix sort to generate
2273024598e40c84666cc311a42c256bbf880db3ac99sewardj      initial fmap and initial BH bits.
2274024598e40c84666cc311a42c256bbf880db3ac99sewardj   --*/
2275024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (verb >= 4)
2276024598e40c84666cc311a42c256bbf880db3ac99sewardj      VPrintf0 ( "        bucket sorting ...\n" );
2277024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < 257;    i++) ftab[i] = 0;
2278024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
2279024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
2280024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
2281024598e40c84666cc311a42c256bbf880db3ac99sewardj
2282024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < nblock; i++) {
2283024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = eclass8[i];
2284024598e40c84666cc311a42c256bbf880db3ac99sewardj      k = ftab[j] - 1;
2285024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[j] = k;
2286024598e40c84666cc311a42c256bbf880db3ac99sewardj      fmap[k] = i;
2287024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2288024598e40c84666cc311a42c256bbf880db3ac99sewardj
2289024598e40c84666cc311a42c256bbf880db3ac99sewardj   nBhtab = 2 + (nblock / 32);
2290024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
2291024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
2292024598e40c84666cc311a42c256bbf880db3ac99sewardj
2293024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--
2294024598e40c84666cc311a42c256bbf880db3ac99sewardj      Inductively refine the buckets.  Kind-of an
2295024598e40c84666cc311a42c256bbf880db3ac99sewardj      "exponential radix sort" (!), inspired by the
2296024598e40c84666cc311a42c256bbf880db3ac99sewardj      Manber-Myers suffix array construction algorithm.
2297024598e40c84666cc311a42c256bbf880db3ac99sewardj   --*/
2298024598e40c84666cc311a42c256bbf880db3ac99sewardj
2299024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- set sentinel bits for block-end detection --*/
2300024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < 32; i++) {
2301024598e40c84666cc311a42c256bbf880db3ac99sewardj      SET_BH(nblock + 2*i);
2302024598e40c84666cc311a42c256bbf880db3ac99sewardj      CLEAR_BH(nblock + 2*i + 1);
2303024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2304024598e40c84666cc311a42c256bbf880db3ac99sewardj
2305024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- the log(N) loop --*/
2306024598e40c84666cc311a42c256bbf880db3ac99sewardj   H = 1;
2307024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (1) {
2308024598e40c84666cc311a42c256bbf880db3ac99sewardj
2309024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (verb >= 4)
2310024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf1 ( "        depth %6d has ", H );
2311024598e40c84666cc311a42c256bbf880db3ac99sewardj
2312024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = 0;
2313024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < nblock; i++) {
2314024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (ISSET_BH(i)) j = i;
2315024598e40c84666cc311a42c256bbf880db3ac99sewardj         k = fmap[i] - H; if (k < 0) k += nblock;
2316024598e40c84666cc311a42c256bbf880db3ac99sewardj         eclass[k] = j;
2317024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2318024598e40c84666cc311a42c256bbf880db3ac99sewardj
2319024598e40c84666cc311a42c256bbf880db3ac99sewardj      nNotDone = 0;
2320024598e40c84666cc311a42c256bbf880db3ac99sewardj      r = -1;
2321024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (1) {
2322024598e40c84666cc311a42c256bbf880db3ac99sewardj
2323024598e40c84666cc311a42c256bbf880db3ac99sewardj	 /*-- find the next non-singleton bucket --*/
2324024598e40c84666cc311a42c256bbf880db3ac99sewardj         k = r + 1;
2325024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
2326024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (ISSET_BH(k)) {
2327024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (WORD_BH(k) == 0xffffffff) k += 32;
2328024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (ISSET_BH(k)) k++;
2329024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2330024598e40c84666cc311a42c256bbf880db3ac99sewardj         l = k - 1;
2331024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (l >= nblock) break;
2332024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
2333024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (!ISSET_BH(k)) {
2334024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (WORD_BH(k) == 0x00000000) k += 32;
2335024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (!ISSET_BH(k)) k++;
2336024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2337024598e40c84666cc311a42c256bbf880db3ac99sewardj         r = k - 1;
2338024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (r >= nblock) break;
2339024598e40c84666cc311a42c256bbf880db3ac99sewardj
2340024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- now [l, r] bracket current bucket --*/
2341024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (r > l) {
2342024598e40c84666cc311a42c256bbf880db3ac99sewardj            nNotDone += (r - l + 1);
2343024598e40c84666cc311a42c256bbf880db3ac99sewardj            fallbackQSort3 ( fmap, eclass, l, r );
2344024598e40c84666cc311a42c256bbf880db3ac99sewardj
2345024598e40c84666cc311a42c256bbf880db3ac99sewardj            /*-- scan bucket and generate header bits-- */
2346024598e40c84666cc311a42c256bbf880db3ac99sewardj            cc = -1;
2347024598e40c84666cc311a42c256bbf880db3ac99sewardj            for (i = l; i <= r; i++) {
2348024598e40c84666cc311a42c256bbf880db3ac99sewardj               cc1 = eclass[fmap[i]];
2349024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (cc != cc1) { SET_BH(i); cc = cc1; };
2350024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
2351024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2352024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2353024598e40c84666cc311a42c256bbf880db3ac99sewardj
2354024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (verb >= 4)
2355024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
2356024598e40c84666cc311a42c256bbf880db3ac99sewardj
2357024598e40c84666cc311a42c256bbf880db3ac99sewardj      H *= 2;
2358024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (H > nblock || nNotDone == 0) break;
2359024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2360024598e40c84666cc311a42c256bbf880db3ac99sewardj
2361024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--
2362024598e40c84666cc311a42c256bbf880db3ac99sewardj      Reconstruct the original block in
2363024598e40c84666cc311a42c256bbf880db3ac99sewardj      eclass8 [0 .. nblock-1], since the
2364024598e40c84666cc311a42c256bbf880db3ac99sewardj      previous phase destroyed it.
2365024598e40c84666cc311a42c256bbf880db3ac99sewardj   --*/
2366024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (verb >= 4)
2367024598e40c84666cc311a42c256bbf880db3ac99sewardj      VPrintf0 ( "        reconstructing block ...\n" );
2368024598e40c84666cc311a42c256bbf880db3ac99sewardj   j = 0;
2369024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < nblock; i++) {
2370024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (ftabCopy[j] == 0) j++;
2371024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftabCopy[j]--;
2372024598e40c84666cc311a42c256bbf880db3ac99sewardj      eclass8[fmap[i]] = (UChar)j;
2373024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2374024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH ( j < 256, 1005 );
2375024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2376024598e40c84666cc311a42c256bbf880db3ac99sewardj
2377024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef       SET_BH
2378024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef     CLEAR_BH
2379024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef     ISSET_BH
2380024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef      WORD_BH
2381024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef UNALIGNED_BH
2382024598e40c84666cc311a42c256bbf880db3ac99sewardj
2383024598e40c84666cc311a42c256bbf880db3ac99sewardj
2384024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2385024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- The main, O(N^2 log(N)) sorting       ---*/
2386024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- algorithm.  Faster for "normal"       ---*/
2387024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- non-repetitive blocks.                ---*/
2388024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2389024598e40c84666cc311a42c256bbf880db3ac99sewardj
2390024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2391024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2392024598e40c84666cc311a42c256bbf880db3ac99sewardj__inline__
2393024598e40c84666cc311a42c256bbf880db3ac99sewardjBool mainGtU ( UInt32  i1,
2394024598e40c84666cc311a42c256bbf880db3ac99sewardj               UInt32  i2,
2395024598e40c84666cc311a42c256bbf880db3ac99sewardj               UChar*  block,
2396024598e40c84666cc311a42c256bbf880db3ac99sewardj               UInt16* quadrant,
2397024598e40c84666cc311a42c256bbf880db3ac99sewardj               UInt32  nblock,
2398024598e40c84666cc311a42c256bbf880db3ac99sewardj               Int32*  budget )
2399024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2400024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  k;
2401024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar  c1, c2;
2402024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt16 s1, s2;
2403024598e40c84666cc311a42c256bbf880db3ac99sewardj
2404024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertD ( i1 != i2, "mainGtU" );
2405024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 1 */
2406024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2407024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2408024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2409024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 2 */
2410024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2411024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2412024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2413024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 3 */
2414024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2415024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2416024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2417024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 4 */
2418024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2419024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2420024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2421024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 5 */
2422024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2423024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2424024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2425024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 6 */
2426024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2427024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2428024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2429024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 7 */
2430024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2431024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2432024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2433024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 8 */
2434024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2435024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2436024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2437024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 9 */
2438024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2439024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2440024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2441024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 10 */
2442024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2443024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2444024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2445024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 11 */
2446024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2447024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2448024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2449024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* 12 */
2450024598e40c84666cc311a42c256bbf880db3ac99sewardj   c1 = block[i1]; c2 = block[i2];
2451024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c1 != c2) return (c1 > c2);
2452024598e40c84666cc311a42c256bbf880db3ac99sewardj   i1++; i2++;
2453024598e40c84666cc311a42c256bbf880db3ac99sewardj
2454024598e40c84666cc311a42c256bbf880db3ac99sewardj   k = nblock + 8;
2455024598e40c84666cc311a42c256bbf880db3ac99sewardj
2456024598e40c84666cc311a42c256bbf880db3ac99sewardj   do {
2457024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 1 */
2458024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2459024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2460024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2461024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2462024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2463024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 2 */
2464024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2465024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2466024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2467024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2468024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2469024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 3 */
2470024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2471024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2472024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2473024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2474024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2475024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 4 */
2476024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2477024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2478024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2479024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2480024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2481024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 5 */
2482024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2483024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2484024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2485024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2486024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2487024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 6 */
2488024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2489024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2490024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2491024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2492024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2493024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 7 */
2494024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2495024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2496024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2497024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2498024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2499024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 8 */
2500024598e40c84666cc311a42c256bbf880db3ac99sewardj      c1 = block[i1]; c2 = block[i2];
2501024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (c1 != c2) return (c1 > c2);
2502024598e40c84666cc311a42c256bbf880db3ac99sewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
2503024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s1 != s2) return (s1 > s2);
2504024598e40c84666cc311a42c256bbf880db3ac99sewardj      i1++; i2++;
2505024598e40c84666cc311a42c256bbf880db3ac99sewardj
2506024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (i1 >= nblock) i1 -= nblock;
2507024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (i2 >= nblock) i2 -= nblock;
2508024598e40c84666cc311a42c256bbf880db3ac99sewardj
2509024598e40c84666cc311a42c256bbf880db3ac99sewardj      k -= 8;
2510024598e40c84666cc311a42c256bbf880db3ac99sewardj      (*budget)--;
2511024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2512024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (k >= 0);
2513024598e40c84666cc311a42c256bbf880db3ac99sewardj
2514024598e40c84666cc311a42c256bbf880db3ac99sewardj   return False;
2515024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2516024598e40c84666cc311a42c256bbf880db3ac99sewardj
2517024598e40c84666cc311a42c256bbf880db3ac99sewardj
2518024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2519024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
2520024598e40c84666cc311a42c256bbf880db3ac99sewardj   Knuth's increments seem to work better
2521024598e40c84666cc311a42c256bbf880db3ac99sewardj   than Incerpi-Sedgewick here.  Possibly
2522024598e40c84666cc311a42c256bbf880db3ac99sewardj   because the number of elems to sort is
2523024598e40c84666cc311a42c256bbf880db3ac99sewardj   usually small, typically <= 20.
2524024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
2525024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2526024598e40c84666cc311a42c256bbf880db3ac99sewardjInt32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
2527024598e40c84666cc311a42c256bbf880db3ac99sewardj                   9841, 29524, 88573, 265720,
2528024598e40c84666cc311a42c256bbf880db3ac99sewardj                   797161, 2391484 };
2529024598e40c84666cc311a42c256bbf880db3ac99sewardj
2530024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2531024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid mainSimpleSort ( UInt32* ptr,
2532024598e40c84666cc311a42c256bbf880db3ac99sewardj                      UChar*  block,
2533024598e40c84666cc311a42c256bbf880db3ac99sewardj                      UInt16* quadrant,
2534024598e40c84666cc311a42c256bbf880db3ac99sewardj                      Int32   nblock,
2535024598e40c84666cc311a42c256bbf880db3ac99sewardj                      Int32   lo,
2536024598e40c84666cc311a42c256bbf880db3ac99sewardj                      Int32   hi,
2537024598e40c84666cc311a42c256bbf880db3ac99sewardj                      Int32   d,
2538024598e40c84666cc311a42c256bbf880db3ac99sewardj                      Int32*  budget )
2539024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2540024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 i, j, h, bigN, hp;
2541024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt32 v;
2542024598e40c84666cc311a42c256bbf880db3ac99sewardj
2543024598e40c84666cc311a42c256bbf880db3ac99sewardj   bigN = hi - lo + 1;
2544024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bigN < 2) return;
2545024598e40c84666cc311a42c256bbf880db3ac99sewardj
2546024598e40c84666cc311a42c256bbf880db3ac99sewardj   hp = 0;
2547024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (incs[hp] < bigN) hp++;
2548024598e40c84666cc311a42c256bbf880db3ac99sewardj   hp--;
2549024598e40c84666cc311a42c256bbf880db3ac99sewardj
2550024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (; hp >= 0; hp--) {
2551024598e40c84666cc311a42c256bbf880db3ac99sewardj      h = incs[hp];
2552024598e40c84666cc311a42c256bbf880db3ac99sewardj
2553024598e40c84666cc311a42c256bbf880db3ac99sewardj      i = lo + h;
2554024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
2555024598e40c84666cc311a42c256bbf880db3ac99sewardj
2556024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- copy 1 --*/
2557024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (i > hi) break;
2558024598e40c84666cc311a42c256bbf880db3ac99sewardj         v = ptr[i];
2559024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = i;
2560024598e40c84666cc311a42c256bbf880db3ac99sewardj         while ( mainGtU (
2561024598e40c84666cc311a42c256bbf880db3ac99sewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2562024598e40c84666cc311a42c256bbf880db3ac99sewardj                 ) ) {
2563024598e40c84666cc311a42c256bbf880db3ac99sewardj            ptr[j] = ptr[j-h];
2564024598e40c84666cc311a42c256bbf880db3ac99sewardj            j = j - h;
2565024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (j <= (lo + h - 1)) break;
2566024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2567024598e40c84666cc311a42c256bbf880db3ac99sewardj         ptr[j] = v;
2568024598e40c84666cc311a42c256bbf880db3ac99sewardj         i++;
2569024598e40c84666cc311a42c256bbf880db3ac99sewardj
2570024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- copy 2 --*/
2571024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (i > hi) break;
2572024598e40c84666cc311a42c256bbf880db3ac99sewardj         v = ptr[i];
2573024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = i;
2574024598e40c84666cc311a42c256bbf880db3ac99sewardj         while ( mainGtU (
2575024598e40c84666cc311a42c256bbf880db3ac99sewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2576024598e40c84666cc311a42c256bbf880db3ac99sewardj                 ) ) {
2577024598e40c84666cc311a42c256bbf880db3ac99sewardj            ptr[j] = ptr[j-h];
2578024598e40c84666cc311a42c256bbf880db3ac99sewardj            j = j - h;
2579024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (j <= (lo + h - 1)) break;
2580024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2581024598e40c84666cc311a42c256bbf880db3ac99sewardj         ptr[j] = v;
2582024598e40c84666cc311a42c256bbf880db3ac99sewardj         i++;
2583024598e40c84666cc311a42c256bbf880db3ac99sewardj
2584024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- copy 3 --*/
2585024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (i > hi) break;
2586024598e40c84666cc311a42c256bbf880db3ac99sewardj         v = ptr[i];
2587024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = i;
2588024598e40c84666cc311a42c256bbf880db3ac99sewardj         while ( mainGtU (
2589024598e40c84666cc311a42c256bbf880db3ac99sewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2590024598e40c84666cc311a42c256bbf880db3ac99sewardj                 ) ) {
2591024598e40c84666cc311a42c256bbf880db3ac99sewardj            ptr[j] = ptr[j-h];
2592024598e40c84666cc311a42c256bbf880db3ac99sewardj            j = j - h;
2593024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (j <= (lo + h - 1)) break;
2594024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2595024598e40c84666cc311a42c256bbf880db3ac99sewardj         ptr[j] = v;
2596024598e40c84666cc311a42c256bbf880db3ac99sewardj         i++;
2597024598e40c84666cc311a42c256bbf880db3ac99sewardj
2598024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (*budget < 0) return;
2599024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2600024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2601024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2602024598e40c84666cc311a42c256bbf880db3ac99sewardj
2603024598e40c84666cc311a42c256bbf880db3ac99sewardj
2604024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2605024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
2606024598e40c84666cc311a42c256bbf880db3ac99sewardj   The following is an implementation of
2607024598e40c84666cc311a42c256bbf880db3ac99sewardj   an elegant 3-way quicksort for strings,
2608024598e40c84666cc311a42c256bbf880db3ac99sewardj   described in a paper "Fast Algorithms for
2609024598e40c84666cc311a42c256bbf880db3ac99sewardj   Sorting and Searching Strings", by Robert
2610024598e40c84666cc311a42c256bbf880db3ac99sewardj   Sedgewick and Jon L. Bentley.
2611024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
2612024598e40c84666cc311a42c256bbf880db3ac99sewardj
2613024598e40c84666cc311a42c256bbf880db3ac99sewardj#define mswap(zz1, zz2) \
2614024598e40c84666cc311a42c256bbf880db3ac99sewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
2615024598e40c84666cc311a42c256bbf880db3ac99sewardj
2616024598e40c84666cc311a42c256bbf880db3ac99sewardj#define mvswap(zzp1, zzp2, zzn)       \
2617024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                     \
2618024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 yyp1 = (zzp1);               \
2619024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 yyp2 = (zzp2);               \
2620024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 yyn  = (zzn);                \
2621024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (yyn > 0) {                  \
2622024598e40c84666cc311a42c256bbf880db3ac99sewardj      mswap(ptr[yyp1], ptr[yyp2]);    \
2623024598e40c84666cc311a42c256bbf880db3ac99sewardj      yyp1++; yyp2++; yyn--;          \
2624024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                  \
2625024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2626024598e40c84666cc311a42c256bbf880db3ac99sewardj
2627024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2628024598e40c84666cc311a42c256bbf880db3ac99sewardj__inline__
2629024598e40c84666cc311a42c256bbf880db3ac99sewardjUChar mmed3 ( UChar a, UChar b, UChar c )
2630024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2631024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar t;
2632024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (a > b) { t = a; a = b; b = t; };
2633024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (b > c) {
2634024598e40c84666cc311a42c256bbf880db3ac99sewardj      b = c;
2635024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (a > b) b = a;
2636024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2637024598e40c84666cc311a42c256bbf880db3ac99sewardj   return b;
2638024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2639024598e40c84666cc311a42c256bbf880db3ac99sewardj
2640024598e40c84666cc311a42c256bbf880db3ac99sewardj#define mmin(a,b) ((a) < (b)) ? (a) : (b)
2641024598e40c84666cc311a42c256bbf880db3ac99sewardj
2642024598e40c84666cc311a42c256bbf880db3ac99sewardj#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
2643024598e40c84666cc311a42c256bbf880db3ac99sewardj                          stackHi[sp] = hz; \
2644024598e40c84666cc311a42c256bbf880db3ac99sewardj                          stackD [sp] = dz; \
2645024598e40c84666cc311a42c256bbf880db3ac99sewardj                          sp++; }
2646024598e40c84666cc311a42c256bbf880db3ac99sewardj
2647024598e40c84666cc311a42c256bbf880db3ac99sewardj#define mpop(lz,hz,dz) { sp--;             \
2648024598e40c84666cc311a42c256bbf880db3ac99sewardj                         lz = stackLo[sp]; \
2649024598e40c84666cc311a42c256bbf880db3ac99sewardj                         hz = stackHi[sp]; \
2650024598e40c84666cc311a42c256bbf880db3ac99sewardj                         dz = stackD [sp]; }
2651024598e40c84666cc311a42c256bbf880db3ac99sewardj
2652024598e40c84666cc311a42c256bbf880db3ac99sewardj
2653024598e40c84666cc311a42c256bbf880db3ac99sewardj#define mnextsize(az) (nextHi[az]-nextLo[az])
2654024598e40c84666cc311a42c256bbf880db3ac99sewardj
2655024598e40c84666cc311a42c256bbf880db3ac99sewardj#define mnextswap(az,bz)                                        \
2656024598e40c84666cc311a42c256bbf880db3ac99sewardj   { Int32 tz;                                                  \
2657024598e40c84666cc311a42c256bbf880db3ac99sewardj     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
2658024598e40c84666cc311a42c256bbf880db3ac99sewardj     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
2659024598e40c84666cc311a42c256bbf880db3ac99sewardj     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
2660024598e40c84666cc311a42c256bbf880db3ac99sewardj
2661024598e40c84666cc311a42c256bbf880db3ac99sewardj
2662024598e40c84666cc311a42c256bbf880db3ac99sewardj#define MAIN_QSORT_SMALL_THRESH 20
2663024598e40c84666cc311a42c256bbf880db3ac99sewardj#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
2664024598e40c84666cc311a42c256bbf880db3ac99sewardj#define MAIN_QSORT_STACK_SIZE 100
2665024598e40c84666cc311a42c256bbf880db3ac99sewardj
2666024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2667024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid mainQSort3 ( UInt32* ptr,
2668024598e40c84666cc311a42c256bbf880db3ac99sewardj                  UChar*  block,
2669024598e40c84666cc311a42c256bbf880db3ac99sewardj                  UInt16* quadrant,
2670024598e40c84666cc311a42c256bbf880db3ac99sewardj                  Int32   nblock,
2671024598e40c84666cc311a42c256bbf880db3ac99sewardj                  Int32   loSt,
2672024598e40c84666cc311a42c256bbf880db3ac99sewardj                  Int32   hiSt,
2673024598e40c84666cc311a42c256bbf880db3ac99sewardj                  Int32   dSt,
2674024598e40c84666cc311a42c256bbf880db3ac99sewardj                  Int32*  budget )
2675024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2676024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
2677024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 sp, lo, hi, d;
2678024598e40c84666cc311a42c256bbf880db3ac99sewardj
2679024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
2680024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
2681024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 stackD [MAIN_QSORT_STACK_SIZE];
2682024598e40c84666cc311a42c256bbf880db3ac99sewardj
2683024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nextLo[3];
2684024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nextHi[3];
2685024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nextD [3];
2686024598e40c84666cc311a42c256bbf880db3ac99sewardj
2687024598e40c84666cc311a42c256bbf880db3ac99sewardj   sp = 0;
2688024598e40c84666cc311a42c256bbf880db3ac99sewardj   mpush ( loSt, hiSt, dSt );
2689024598e40c84666cc311a42c256bbf880db3ac99sewardj
2690024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (sp > 0) {
2691024598e40c84666cc311a42c256bbf880db3ac99sewardj
2692024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
2693024598e40c84666cc311a42c256bbf880db3ac99sewardj
2694024598e40c84666cc311a42c256bbf880db3ac99sewardj      mpop ( lo, hi, d );
2695024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
2696024598e40c84666cc311a42c256bbf880db3ac99sewardj          d > MAIN_QSORT_DEPTH_THRESH) {
2697024598e40c84666cc311a42c256bbf880db3ac99sewardj         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
2698024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (*budget < 0) return;
2699024598e40c84666cc311a42c256bbf880db3ac99sewardj         continue;
2700024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2701024598e40c84666cc311a42c256bbf880db3ac99sewardj
2702024598e40c84666cc311a42c256bbf880db3ac99sewardj      med = (Int32)
2703024598e40c84666cc311a42c256bbf880db3ac99sewardj            mmed3 ( block[ptr[ lo         ]+d],
2704024598e40c84666cc311a42c256bbf880db3ac99sewardj                    block[ptr[ hi         ]+d],
2705024598e40c84666cc311a42c256bbf880db3ac99sewardj                    block[ptr[ (lo+hi)>>1 ]+d] );
2706024598e40c84666cc311a42c256bbf880db3ac99sewardj
2707024598e40c84666cc311a42c256bbf880db3ac99sewardj      unLo = ltLo = lo;
2708024598e40c84666cc311a42c256bbf880db3ac99sewardj      unHi = gtHi = hi;
2709024598e40c84666cc311a42c256bbf880db3ac99sewardj
2710024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
2711024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (True) {
2712024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (unLo > unHi) break;
2713024598e40c84666cc311a42c256bbf880db3ac99sewardj            n = ((Int32)block[ptr[unLo]+d]) - med;
2714024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n == 0) {
2715024598e40c84666cc311a42c256bbf880db3ac99sewardj               mswap(ptr[unLo], ptr[ltLo]);
2716024598e40c84666cc311a42c256bbf880db3ac99sewardj               ltLo++; unLo++; continue;
2717024598e40c84666cc311a42c256bbf880db3ac99sewardj            };
2718024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n >  0) break;
2719024598e40c84666cc311a42c256bbf880db3ac99sewardj            unLo++;
2720024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2721024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (True) {
2722024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (unLo > unHi) break;
2723024598e40c84666cc311a42c256bbf880db3ac99sewardj            n = ((Int32)block[ptr[unHi]+d]) - med;
2724024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n == 0) {
2725024598e40c84666cc311a42c256bbf880db3ac99sewardj               mswap(ptr[unHi], ptr[gtHi]);
2726024598e40c84666cc311a42c256bbf880db3ac99sewardj               gtHi--; unHi--; continue;
2727024598e40c84666cc311a42c256bbf880db3ac99sewardj            };
2728024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n <  0) break;
2729024598e40c84666cc311a42c256bbf880db3ac99sewardj            unHi--;
2730024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2731024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (unLo > unHi) break;
2732024598e40c84666cc311a42c256bbf880db3ac99sewardj         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
2733024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2734024598e40c84666cc311a42c256bbf880db3ac99sewardj
2735024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
2736024598e40c84666cc311a42c256bbf880db3ac99sewardj
2737024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (gtHi < ltLo) {
2738024598e40c84666cc311a42c256bbf880db3ac99sewardj         mpush(lo, hi, d+1 );
2739024598e40c84666cc311a42c256bbf880db3ac99sewardj         continue;
2740024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2741024598e40c84666cc311a42c256bbf880db3ac99sewardj
2742024598e40c84666cc311a42c256bbf880db3ac99sewardj      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
2743024598e40c84666cc311a42c256bbf880db3ac99sewardj      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
2744024598e40c84666cc311a42c256bbf880db3ac99sewardj
2745024598e40c84666cc311a42c256bbf880db3ac99sewardj      n = lo + unLo - ltLo - 1;
2746024598e40c84666cc311a42c256bbf880db3ac99sewardj      m = hi - (gtHi - unHi) + 1;
2747024598e40c84666cc311a42c256bbf880db3ac99sewardj
2748024598e40c84666cc311a42c256bbf880db3ac99sewardj      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
2749024598e40c84666cc311a42c256bbf880db3ac99sewardj      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
2750024598e40c84666cc311a42c256bbf880db3ac99sewardj      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
2751024598e40c84666cc311a42c256bbf880db3ac99sewardj
2752024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
2753024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
2754024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
2755024598e40c84666cc311a42c256bbf880db3ac99sewardj
2756024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
2757024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
2758024598e40c84666cc311a42c256bbf880db3ac99sewardj
2759024598e40c84666cc311a42c256bbf880db3ac99sewardj      mpush (nextLo[0], nextHi[0], nextD[0]);
2760024598e40c84666cc311a42c256bbf880db3ac99sewardj      mpush (nextLo[1], nextHi[1], nextD[1]);
2761024598e40c84666cc311a42c256bbf880db3ac99sewardj      mpush (nextLo[2], nextHi[2], nextD[2]);
2762024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2763024598e40c84666cc311a42c256bbf880db3ac99sewardj}
2764024598e40c84666cc311a42c256bbf880db3ac99sewardj
2765024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef mswap
2766024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef mvswap
2767024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef mpush
2768024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef mpop
2769024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef mmin
2770024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef mnextsize
2771024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef mnextswap
2772024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef MAIN_QSORT_SMALL_THRESH
2773024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef MAIN_QSORT_DEPTH_THRESH
2774024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef MAIN_QSORT_STACK_SIZE
2775024598e40c84666cc311a42c256bbf880db3ac99sewardj
2776024598e40c84666cc311a42c256bbf880db3ac99sewardj
2777024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
2778024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Pre:
2779024598e40c84666cc311a42c256bbf880db3ac99sewardj      nblock > N_OVERSHOOT
2780024598e40c84666cc311a42c256bbf880db3ac99sewardj      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
2781024598e40c84666cc311a42c256bbf880db3ac99sewardj      ((UChar*)block32) [0 .. nblock-1] holds block
2782024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr exists for [0 .. nblock-1]
2783024598e40c84666cc311a42c256bbf880db3ac99sewardj
2784024598e40c84666cc311a42c256bbf880db3ac99sewardj   Post:
2785024598e40c84666cc311a42c256bbf880db3ac99sewardj      ((UChar*)block32) [0 .. nblock-1] holds block
2786024598e40c84666cc311a42c256bbf880db3ac99sewardj      All other areas of block32 destroyed
2787024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab [0 .. 65536 ] destroyed
2788024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr [0 .. nblock-1] holds sorted order
2789024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (*budget < 0), sorting was abandoned
2790024598e40c84666cc311a42c256bbf880db3ac99sewardj*/
2791024598e40c84666cc311a42c256bbf880db3ac99sewardj
2792024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
2793024598e40c84666cc311a42c256bbf880db3ac99sewardj#define SETMASK (1 << 21)
2794024598e40c84666cc311a42c256bbf880db3ac99sewardj#define CLEARMASK (~(SETMASK))
2795024598e40c84666cc311a42c256bbf880db3ac99sewardj
2796024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
2797024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid mainSort ( UInt32* ptr,
2798024598e40c84666cc311a42c256bbf880db3ac99sewardj                UChar*  block,
2799024598e40c84666cc311a42c256bbf880db3ac99sewardj                UInt16* quadrant,
2800024598e40c84666cc311a42c256bbf880db3ac99sewardj                UInt32* ftab,
2801024598e40c84666cc311a42c256bbf880db3ac99sewardj                Int32   nblock,
2802024598e40c84666cc311a42c256bbf880db3ac99sewardj                Int32   verb,
2803024598e40c84666cc311a42c256bbf880db3ac99sewardj                Int32*  budget )
2804024598e40c84666cc311a42c256bbf880db3ac99sewardj{
2805024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  i, j, k, ss, sb;
2806024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  runningOrder[256];
2807024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool   bigDone[256];
2808024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  copyStart[256];
2809024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  copyEnd  [256];
2810024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar  c1;
2811024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  numQSorted;
2812024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt16 s;
2813024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
2814024598e40c84666cc311a42c256bbf880db3ac99sewardj
2815024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- set up the 2-byte frequency table --*/
2816024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 65536; i >= 0; i--) ftab[i] = 0;
2817024598e40c84666cc311a42c256bbf880db3ac99sewardj
2818024598e40c84666cc311a42c256bbf880db3ac99sewardj   j = block[0] << 8;
2819024598e40c84666cc311a42c256bbf880db3ac99sewardj   i = nblock-1;
2820024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (; i >= 3; i -= 4) {
2821024598e40c84666cc311a42c256bbf880db3ac99sewardj      quadrant[i] = 0;
2822024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
2823024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[j]++;
2824024598e40c84666cc311a42c256bbf880db3ac99sewardj      quadrant[i-1] = 0;
2825024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
2826024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[j]++;
2827024598e40c84666cc311a42c256bbf880db3ac99sewardj      quadrant[i-2] = 0;
2828024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
2829024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[j]++;
2830024598e40c84666cc311a42c256bbf880db3ac99sewardj      quadrant[i-3] = 0;
2831024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
2832024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[j]++;
2833024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2834024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (; i >= 0; i--) {
2835024598e40c84666cc311a42c256bbf880db3ac99sewardj      quadrant[i] = 0;
2836024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
2837024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[j]++;
2838024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2839024598e40c84666cc311a42c256bbf880db3ac99sewardj
2840024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- (emphasises close relationship of block & quadrant) --*/
2841024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
2842024598e40c84666cc311a42c256bbf880db3ac99sewardj      block   [nblock+i] = block[i];
2843024598e40c84666cc311a42c256bbf880db3ac99sewardj      quadrant[nblock+i] = 0;
2844024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2845024598e40c84666cc311a42c256bbf880db3ac99sewardj
2846024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
2847024598e40c84666cc311a42c256bbf880db3ac99sewardj
2848024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- Complete the initial radix sort --*/
2849024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
2850024598e40c84666cc311a42c256bbf880db3ac99sewardj
2851024598e40c84666cc311a42c256bbf880db3ac99sewardj   s = block[0] << 8;
2852024598e40c84666cc311a42c256bbf880db3ac99sewardj   i = nblock-1;
2853024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (; i >= 3; i -= 4) {
2854024598e40c84666cc311a42c256bbf880db3ac99sewardj      s = (s >> 8) | (block[i] << 8);
2855024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = ftab[s] -1;
2856024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[s] = j;
2857024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr[j] = i;
2858024598e40c84666cc311a42c256bbf880db3ac99sewardj      s = (s >> 8) | (block[i-1] << 8);
2859024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = ftab[s] -1;
2860024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[s] = j;
2861024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr[j] = i-1;
2862024598e40c84666cc311a42c256bbf880db3ac99sewardj      s = (s >> 8) | (block[i-2] << 8);
2863024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = ftab[s] -1;
2864024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[s] = j;
2865024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr[j] = i-2;
2866024598e40c84666cc311a42c256bbf880db3ac99sewardj      s = (s >> 8) | (block[i-3] << 8);
2867024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = ftab[s] -1;
2868024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[s] = j;
2869024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr[j] = i-3;
2870024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2871024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (; i >= 0; i--) {
2872024598e40c84666cc311a42c256bbf880db3ac99sewardj      s = (s >> 8) | (block[i] << 8);
2873024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = ftab[s] -1;
2874024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab[s] = j;
2875024598e40c84666cc311a42c256bbf880db3ac99sewardj      ptr[j] = i;
2876024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2877024598e40c84666cc311a42c256bbf880db3ac99sewardj
2878024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--
2879024598e40c84666cc311a42c256bbf880db3ac99sewardj      Now ftab contains the first loc of every small bucket.
2880024598e40c84666cc311a42c256bbf880db3ac99sewardj      Calculate the running order, from smallest to largest
2881024598e40c84666cc311a42c256bbf880db3ac99sewardj      big bucket.
2882024598e40c84666cc311a42c256bbf880db3ac99sewardj   --*/
2883024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i <= 255; i++) {
2884024598e40c84666cc311a42c256bbf880db3ac99sewardj      bigDone     [i] = False;
2885024598e40c84666cc311a42c256bbf880db3ac99sewardj      runningOrder[i] = i;
2886024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2887024598e40c84666cc311a42c256bbf880db3ac99sewardj
2888024598e40c84666cc311a42c256bbf880db3ac99sewardj   {
2889024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32 vv;
2890024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32 h = 1;
2891024598e40c84666cc311a42c256bbf880db3ac99sewardj      do h = 3 * h + 1; while (h <= 256);
2892024598e40c84666cc311a42c256bbf880db3ac99sewardj      do {
2893024598e40c84666cc311a42c256bbf880db3ac99sewardj         h = h / 3;
2894024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = h; i <= 255; i++) {
2895024598e40c84666cc311a42c256bbf880db3ac99sewardj            vv = runningOrder[i];
2896024598e40c84666cc311a42c256bbf880db3ac99sewardj            j = i;
2897024598e40c84666cc311a42c256bbf880db3ac99sewardj            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
2898024598e40c84666cc311a42c256bbf880db3ac99sewardj               runningOrder[j] = runningOrder[j-h];
2899024598e40c84666cc311a42c256bbf880db3ac99sewardj               j = j - h;
2900024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (j <= (h - 1)) goto zero;
2901024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
2902024598e40c84666cc311a42c256bbf880db3ac99sewardj            zero:
2903024598e40c84666cc311a42c256bbf880db3ac99sewardj            runningOrder[j] = vv;
2904024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2905024598e40c84666cc311a42c256bbf880db3ac99sewardj      } while (h != 1);
2906024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
2907024598e40c84666cc311a42c256bbf880db3ac99sewardj
2908024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--
2909024598e40c84666cc311a42c256bbf880db3ac99sewardj      The main sorting loop.
2910024598e40c84666cc311a42c256bbf880db3ac99sewardj   --*/
2911024598e40c84666cc311a42c256bbf880db3ac99sewardj
2912024598e40c84666cc311a42c256bbf880db3ac99sewardj   numQSorted = 0;
2913024598e40c84666cc311a42c256bbf880db3ac99sewardj
2914024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i <= 255; i++) {
2915024598e40c84666cc311a42c256bbf880db3ac99sewardj
2916024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--
2917024598e40c84666cc311a42c256bbf880db3ac99sewardj         Process big buckets, starting with the least full.
2918024598e40c84666cc311a42c256bbf880db3ac99sewardj         Basically this is a 3-step process in which we call
2919024598e40c84666cc311a42c256bbf880db3ac99sewardj         mainQSort3 to sort the small buckets [ss, j], but
2920024598e40c84666cc311a42c256bbf880db3ac99sewardj         also make a big effort to avoid the calls if we can.
2921024598e40c84666cc311a42c256bbf880db3ac99sewardj      --*/
2922024598e40c84666cc311a42c256bbf880db3ac99sewardj      ss = runningOrder[i];
2923024598e40c84666cc311a42c256bbf880db3ac99sewardj
2924024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--
2925024598e40c84666cc311a42c256bbf880db3ac99sewardj         Step 1:
2926024598e40c84666cc311a42c256bbf880db3ac99sewardj         Complete the big bucket [ss] by quicksorting
2927024598e40c84666cc311a42c256bbf880db3ac99sewardj         any unsorted small buckets [ss, j], for j != ss.
2928024598e40c84666cc311a42c256bbf880db3ac99sewardj         Hopefully previous pointer-scanning phases have already
2929024598e40c84666cc311a42c256bbf880db3ac99sewardj         completed many of the small buckets [ss, j], so
2930024598e40c84666cc311a42c256bbf880db3ac99sewardj         we don't have to sort them at all.
2931024598e40c84666cc311a42c256bbf880db3ac99sewardj      --*/
2932024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (j = 0; j <= 255; j++) {
2933024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (j != ss) {
2934024598e40c84666cc311a42c256bbf880db3ac99sewardj            sb = (ss << 8) + j;
2935024598e40c84666cc311a42c256bbf880db3ac99sewardj            if ( ! (ftab[sb] & SETMASK) ) {
2936024598e40c84666cc311a42c256bbf880db3ac99sewardj               Int32 lo = ftab[sb]   & CLEARMASK;
2937024598e40c84666cc311a42c256bbf880db3ac99sewardj               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
2938024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (hi > lo) {
2939024598e40c84666cc311a42c256bbf880db3ac99sewardj                  if (verb >= 4)
2940024598e40c84666cc311a42c256bbf880db3ac99sewardj                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
2941024598e40c84666cc311a42c256bbf880db3ac99sewardj                                "done %d   this %d\n",
2942024598e40c84666cc311a42c256bbf880db3ac99sewardj                                ss, j, numQSorted, hi - lo + 1 );
2943024598e40c84666cc311a42c256bbf880db3ac99sewardj                  mainQSort3 (
2944024598e40c84666cc311a42c256bbf880db3ac99sewardj                     ptr, block, quadrant, nblock,
2945024598e40c84666cc311a42c256bbf880db3ac99sewardj                     lo, hi, BZ_N_RADIX, budget
2946024598e40c84666cc311a42c256bbf880db3ac99sewardj                  );
2947024598e40c84666cc311a42c256bbf880db3ac99sewardj                  numQSorted += (hi - lo + 1);
2948024598e40c84666cc311a42c256bbf880db3ac99sewardj                  if (*budget < 0) return;
2949024598e40c84666cc311a42c256bbf880db3ac99sewardj               }
2950024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
2951024598e40c84666cc311a42c256bbf880db3ac99sewardj            ftab[sb] |= SETMASK;
2952024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2953024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2954024598e40c84666cc311a42c256bbf880db3ac99sewardj
2955024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH ( !bigDone[ss], 1006 );
2956024598e40c84666cc311a42c256bbf880db3ac99sewardj
2957024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--
2958024598e40c84666cc311a42c256bbf880db3ac99sewardj         Step 2:
2959024598e40c84666cc311a42c256bbf880db3ac99sewardj         Now scan this big bucket [ss] so as to synthesise the
2960024598e40c84666cc311a42c256bbf880db3ac99sewardj         sorted order for small buckets [t, ss] for all t,
2961024598e40c84666cc311a42c256bbf880db3ac99sewardj         including, magically, the bucket [ss,ss] too.
2962024598e40c84666cc311a42c256bbf880db3ac99sewardj         This will avoid doing Real Work in subsequent Step 1's.
2963024598e40c84666cc311a42c256bbf880db3ac99sewardj      --*/
2964024598e40c84666cc311a42c256bbf880db3ac99sewardj      {
2965024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (j = 0; j <= 255; j++) {
2966024598e40c84666cc311a42c256bbf880db3ac99sewardj            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
2967024598e40c84666cc311a42c256bbf880db3ac99sewardj            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
2968024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2969024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
2970024598e40c84666cc311a42c256bbf880db3ac99sewardj            k = ptr[j]-1; if (k < 0) k += nblock;
2971024598e40c84666cc311a42c256bbf880db3ac99sewardj            c1 = block[k];
2972024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (!bigDone[c1])
2973024598e40c84666cc311a42c256bbf880db3ac99sewardj               ptr[ copyStart[c1]++ ] = k;
2974024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2975024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
2976024598e40c84666cc311a42c256bbf880db3ac99sewardj            k = ptr[j]-1; if (k < 0) k += nblock;
2977024598e40c84666cc311a42c256bbf880db3ac99sewardj            c1 = block[k];
2978024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (!bigDone[c1])
2979024598e40c84666cc311a42c256bbf880db3ac99sewardj               ptr[ copyEnd[c1]-- ] = k;
2980024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
2981024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
2982024598e40c84666cc311a42c256bbf880db3ac99sewardj
2983024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
2984024598e40c84666cc311a42c256bbf880db3ac99sewardj                ||
2985024598e40c84666cc311a42c256bbf880db3ac99sewardj                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
2986024598e40c84666cc311a42c256bbf880db3ac99sewardj                   Necessity for this case is demonstrated by compressing
2987024598e40c84666cc311a42c256bbf880db3ac99sewardj                   a sequence of approximately 48.5 million of character
2988024598e40c84666cc311a42c256bbf880db3ac99sewardj                   251; 1.0.0/1.0.1 will then die here. */
2989024598e40c84666cc311a42c256bbf880db3ac99sewardj                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
2990024598e40c84666cc311a42c256bbf880db3ac99sewardj                1007 )
2991024598e40c84666cc311a42c256bbf880db3ac99sewardj
2992024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
2993024598e40c84666cc311a42c256bbf880db3ac99sewardj
2994024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--
2995024598e40c84666cc311a42c256bbf880db3ac99sewardj         Step 3:
2996024598e40c84666cc311a42c256bbf880db3ac99sewardj         The [ss] big bucket is now done.  Record this fact,
2997024598e40c84666cc311a42c256bbf880db3ac99sewardj         and update the quadrant descriptors.  Remember to
2998024598e40c84666cc311a42c256bbf880db3ac99sewardj         update quadrants in the overshoot area too, if
2999024598e40c84666cc311a42c256bbf880db3ac99sewardj         necessary.  The "if (i < 255)" test merely skips
3000024598e40c84666cc311a42c256bbf880db3ac99sewardj         this updating for the last bucket processed, since
3001024598e40c84666cc311a42c256bbf880db3ac99sewardj         updating for the last bucket is pointless.
3002024598e40c84666cc311a42c256bbf880db3ac99sewardj
3003024598e40c84666cc311a42c256bbf880db3ac99sewardj         The quadrant array provides a way to incrementally
3004024598e40c84666cc311a42c256bbf880db3ac99sewardj         cache sort orderings, as they appear, so as to
3005024598e40c84666cc311a42c256bbf880db3ac99sewardj         make subsequent comparisons in fullGtU() complete
3006024598e40c84666cc311a42c256bbf880db3ac99sewardj         faster.  For repetitive blocks this makes a big
3007024598e40c84666cc311a42c256bbf880db3ac99sewardj         difference (but not big enough to be able to avoid
3008024598e40c84666cc311a42c256bbf880db3ac99sewardj         the fallback sorting mechanism, exponential radix sort).
3009024598e40c84666cc311a42c256bbf880db3ac99sewardj
3010024598e40c84666cc311a42c256bbf880db3ac99sewardj         The precise meaning is: at all times:
3011024598e40c84666cc311a42c256bbf880db3ac99sewardj
3012024598e40c84666cc311a42c256bbf880db3ac99sewardj            for 0 <= i < nblock and 0 <= j <= nblock
3013024598e40c84666cc311a42c256bbf880db3ac99sewardj
3014024598e40c84666cc311a42c256bbf880db3ac99sewardj            if block[i] != block[j],
3015024598e40c84666cc311a42c256bbf880db3ac99sewardj
3016024598e40c84666cc311a42c256bbf880db3ac99sewardj               then the relative values of quadrant[i] and
3017024598e40c84666cc311a42c256bbf880db3ac99sewardj                    quadrant[j] are meaningless.
3018024598e40c84666cc311a42c256bbf880db3ac99sewardj
3019024598e40c84666cc311a42c256bbf880db3ac99sewardj               else {
3020024598e40c84666cc311a42c256bbf880db3ac99sewardj                  if quadrant[i] < quadrant[j]
3021024598e40c84666cc311a42c256bbf880db3ac99sewardj                     then the string starting at i lexicographically
3022024598e40c84666cc311a42c256bbf880db3ac99sewardj                     precedes the string starting at j
3023024598e40c84666cc311a42c256bbf880db3ac99sewardj
3024024598e40c84666cc311a42c256bbf880db3ac99sewardj                  else if quadrant[i] > quadrant[j]
3025024598e40c84666cc311a42c256bbf880db3ac99sewardj                     then the string starting at j lexicographically
3026024598e40c84666cc311a42c256bbf880db3ac99sewardj                     precedes the string starting at i
3027024598e40c84666cc311a42c256bbf880db3ac99sewardj
3028024598e40c84666cc311a42c256bbf880db3ac99sewardj                  else
3029024598e40c84666cc311a42c256bbf880db3ac99sewardj                     the relative ordering of the strings starting
3030024598e40c84666cc311a42c256bbf880db3ac99sewardj                     at i and j has not yet been determined.
3031024598e40c84666cc311a42c256bbf880db3ac99sewardj               }
3032024598e40c84666cc311a42c256bbf880db3ac99sewardj      --*/
3033024598e40c84666cc311a42c256bbf880db3ac99sewardj      bigDone[ss] = True;
3034024598e40c84666cc311a42c256bbf880db3ac99sewardj
3035024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (i < 255) {
3036024598e40c84666cc311a42c256bbf880db3ac99sewardj         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
3037024598e40c84666cc311a42c256bbf880db3ac99sewardj         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
3038024598e40c84666cc311a42c256bbf880db3ac99sewardj         Int32 shifts   = 0;
3039024598e40c84666cc311a42c256bbf880db3ac99sewardj
3040024598e40c84666cc311a42c256bbf880db3ac99sewardj         while ((bbSize >> shifts) > 65534) shifts++;
3041024598e40c84666cc311a42c256bbf880db3ac99sewardj
3042024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (j = bbSize-1; j >= 0; j--) {
3043024598e40c84666cc311a42c256bbf880db3ac99sewardj            Int32 a2update     = ptr[bbStart + j];
3044024598e40c84666cc311a42c256bbf880db3ac99sewardj            UInt16 qVal        = (UInt16)(j >> shifts);
3045024598e40c84666cc311a42c256bbf880db3ac99sewardj            quadrant[a2update] = qVal;
3046024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (a2update < BZ_N_OVERSHOOT)
3047024598e40c84666cc311a42c256bbf880db3ac99sewardj               quadrant[a2update + nblock] = qVal;
3048024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3049024598e40c84666cc311a42c256bbf880db3ac99sewardj         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
3050024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3051024598e40c84666cc311a42c256bbf880db3ac99sewardj
3052024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3053024598e40c84666cc311a42c256bbf880db3ac99sewardj
3054024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (verb >= 4)
3055024598e40c84666cc311a42c256bbf880db3ac99sewardj      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
3056024598e40c84666cc311a42c256bbf880db3ac99sewardj                 nblock, numQSorted, nblock - numQSorted );
3057024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3058024598e40c84666cc311a42c256bbf880db3ac99sewardj
3059024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef BIGFREQ
3060024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef SETMASK
3061024598e40c84666cc311a42c256bbf880db3ac99sewardj#undef CLEARMASK
3062024598e40c84666cc311a42c256bbf880db3ac99sewardj
3063024598e40c84666cc311a42c256bbf880db3ac99sewardj
3064024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
3065024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Pre:
3066024598e40c84666cc311a42c256bbf880db3ac99sewardj      nblock > 0
3067024598e40c84666cc311a42c256bbf880db3ac99sewardj      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
3068024598e40c84666cc311a42c256bbf880db3ac99sewardj      ((UChar*)arr2)  [0 .. nblock-1] holds block
3069024598e40c84666cc311a42c256bbf880db3ac99sewardj      arr1 exists for [0 .. nblock-1]
3070024598e40c84666cc311a42c256bbf880db3ac99sewardj
3071024598e40c84666cc311a42c256bbf880db3ac99sewardj   Post:
3072024598e40c84666cc311a42c256bbf880db3ac99sewardj      ((UChar*)arr2) [0 .. nblock-1] holds block
3073024598e40c84666cc311a42c256bbf880db3ac99sewardj      All other areas of block destroyed
3074024598e40c84666cc311a42c256bbf880db3ac99sewardj      ftab [ 0 .. 65536 ] destroyed
3075024598e40c84666cc311a42c256bbf880db3ac99sewardj      arr1 [0 .. nblock-1] holds sorted order
3076024598e40c84666cc311a42c256bbf880db3ac99sewardj*/
3077024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ2_blockSort ( EState* s )
3078024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3079024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt32* ptr    = s->ptr;
3080024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar*  block  = s->block;
3081024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt32* ftab   = s->ftab;
3082024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   nblock = s->nblock;
3083024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   verb   = s->verbosity;
3084024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   wfact  = s->workFactor;
3085024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt16* quadrant;
3086024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   budget;
3087024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   budgetInit;
3088024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   i;
3089024598e40c84666cc311a42c256bbf880db3ac99sewardj
3090024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nblock < /* 10000 */1000 ) {
3091024598e40c84666cc311a42c256bbf880db3ac99sewardj      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
3092024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
3093024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* Calculate the location for quadrant, remembering to get
3094024598e40c84666cc311a42c256bbf880db3ac99sewardj         the alignment right.  Assumes that &(block[0]) is at least
3095024598e40c84666cc311a42c256bbf880db3ac99sewardj         2-byte aligned -- this should be ok since block is really
3096024598e40c84666cc311a42c256bbf880db3ac99sewardj         the first section of arr2.
3097024598e40c84666cc311a42c256bbf880db3ac99sewardj      */
3098024598e40c84666cc311a42c256bbf880db3ac99sewardj      i = nblock+BZ_N_OVERSHOOT;
3099024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (i & 1) i++;
3100024598e40c84666cc311a42c256bbf880db3ac99sewardj      quadrant = (UInt16*)(&(block[i]));
3101024598e40c84666cc311a42c256bbf880db3ac99sewardj
3102024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* (wfact-1) / 3 puts the default-factor-30
3103024598e40c84666cc311a42c256bbf880db3ac99sewardj         transition point at very roughly the same place as
3104024598e40c84666cc311a42c256bbf880db3ac99sewardj         with v0.1 and v0.9.0.
3105024598e40c84666cc311a42c256bbf880db3ac99sewardj         Not that it particularly matters any more, since the
3106024598e40c84666cc311a42c256bbf880db3ac99sewardj         resulting compressed stream is now the same regardless
3107024598e40c84666cc311a42c256bbf880db3ac99sewardj         of whether or not we use the main sort or fallback sort.
3108024598e40c84666cc311a42c256bbf880db3ac99sewardj      */
3109024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (wfact < 1  ) wfact = 1;
3110024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (wfact > 100) wfact = 100;
3111024598e40c84666cc311a42c256bbf880db3ac99sewardj      budgetInit = nblock * ((wfact-1) / 3);
3112024598e40c84666cc311a42c256bbf880db3ac99sewardj      budget = budgetInit;
3113024598e40c84666cc311a42c256bbf880db3ac99sewardj
3114024598e40c84666cc311a42c256bbf880db3ac99sewardj      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
3115024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (0 && verb >= 3)
3116024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
3117024598e40c84666cc311a42c256bbf880db3ac99sewardj                    budgetInit - budget,
3118024598e40c84666cc311a42c256bbf880db3ac99sewardj                    nblock,
3119024598e40c84666cc311a42c256bbf880db3ac99sewardj                    (float)(budgetInit - budget) /
3120024598e40c84666cc311a42c256bbf880db3ac99sewardj                    (float)(nblock==0 ? 1 : nblock) );
3121024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (budget < 0) {
3122024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (verb >= 2)
3123024598e40c84666cc311a42c256bbf880db3ac99sewardj            VPrintf0 ( "    too repetitive; using fallback"
3124024598e40c84666cc311a42c256bbf880db3ac99sewardj                       " sorting algorithm\n" );
3125024598e40c84666cc311a42c256bbf880db3ac99sewardj         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
3126024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3127024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3128024598e40c84666cc311a42c256bbf880db3ac99sewardj
3129024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->origPtr = -1;
3130024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < s->nblock; i++)
3131024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ptr[i] == 0)
3132024598e40c84666cc311a42c256bbf880db3ac99sewardj         { s->origPtr = i; break; };
3133024598e40c84666cc311a42c256bbf880db3ac99sewardj
3134024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH( s->origPtr != -1, 1003 );
3135024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3136024598e40c84666cc311a42c256bbf880db3ac99sewardj
3137024598e40c84666cc311a42c256bbf880db3ac99sewardj
3138024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3139024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                       blocksort.c ---*/
3140024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3141024598e40c84666cc311a42c256bbf880db3ac99sewardj
3142024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3143024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Huffman coding low-level stuff                        ---*/
3144024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                             huffman.c ---*/
3145024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3146024598e40c84666cc311a42c256bbf880db3ac99sewardj
3147024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
3148024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
3149024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
3150024598e40c84666cc311a42c256bbf880db3ac99sewardj
3151024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
3152024598e40c84666cc311a42c256bbf880db3ac99sewardj
3153024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
3154024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
3155024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
3156024598e40c84666cc311a42c256bbf880db3ac99sewardj
3157024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
3158024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
3159024598e40c84666cc311a42c256bbf880db3ac99sewardj
3160024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
3161024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
3162024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
3163024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
3164024598e40c84666cc311a42c256bbf880db3ac99sewardj
3165024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
3166024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
3167024598e40c84666cc311a42c256bbf880db3ac99sewardj
3168024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
3169024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
3170024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
3171024598e40c84666cc311a42c256bbf880db3ac99sewardj
3172024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
3173024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3174024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3175024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3176024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3177024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
3178024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3179024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3180024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3181024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3182024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3183024598e40c84666cc311a42c256bbf880db3ac99sewardj
3184024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
3185024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
3186024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
3187024598e40c84666cc311a42c256bbf880db3ac99sewardj
3188024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
3189024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
3190024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
3191024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
3192024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
3193024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
3194024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
3195024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
3196024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
3197024598e40c84666cc311a42c256bbf880db3ac99sewardj
3198024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
3199024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
3200024598e40c84666cc311a42c256bbf880db3ac99sewardj
3201024598e40c84666cc311a42c256bbf880db3ac99sewardj
3202024598e40c84666cc311a42c256bbf880db3ac99sewardj
3203024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3204024598e40c84666cc311a42c256bbf880db3ac99sewardj#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
3205024598e40c84666cc311a42c256bbf880db3ac99sewardj#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
3206024598e40c84666cc311a42c256bbf880db3ac99sewardj#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
3207024598e40c84666cc311a42c256bbf880db3ac99sewardj
3208024598e40c84666cc311a42c256bbf880db3ac99sewardj#define ADDWEIGHTS(zw1,zw2)                           \
3209024598e40c84666cc311a42c256bbf880db3ac99sewardj   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
3210024598e40c84666cc311a42c256bbf880db3ac99sewardj   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
3211024598e40c84666cc311a42c256bbf880db3ac99sewardj
3212024598e40c84666cc311a42c256bbf880db3ac99sewardj#define UPHEAP(z)                                     \
3213024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                                     \
3214024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 zz, tmp;                                     \
3215024598e40c84666cc311a42c256bbf880db3ac99sewardj   zz = z; tmp = heap[zz];                            \
3216024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
3217024598e40c84666cc311a42c256bbf880db3ac99sewardj      heap[zz] = heap[zz >> 1];                       \
3218024598e40c84666cc311a42c256bbf880db3ac99sewardj      zz >>= 1;                                       \
3219024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                                  \
3220024598e40c84666cc311a42c256bbf880db3ac99sewardj   heap[zz] = tmp;                                    \
3221024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3222024598e40c84666cc311a42c256bbf880db3ac99sewardj
3223024598e40c84666cc311a42c256bbf880db3ac99sewardj#define DOWNHEAP(z)                                   \
3224024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                                     \
3225024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 zz, yy, tmp;                                 \
3226024598e40c84666cc311a42c256bbf880db3ac99sewardj   zz = z; tmp = heap[zz];                            \
3227024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {                                     \
3228024598e40c84666cc311a42c256bbf880db3ac99sewardj      yy = zz << 1;                                   \
3229024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (yy > nHeap) break;                          \
3230024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (yy < nHeap &&                               \
3231024598e40c84666cc311a42c256bbf880db3ac99sewardj          weight[heap[yy+1]] < weight[heap[yy]])      \
3232024598e40c84666cc311a42c256bbf880db3ac99sewardj         yy++;                                        \
3233024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (weight[tmp] < weight[heap[yy]]) break;      \
3234024598e40c84666cc311a42c256bbf880db3ac99sewardj      heap[zz] = heap[yy];                            \
3235024598e40c84666cc311a42c256bbf880db3ac99sewardj      zz = yy;                                        \
3236024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                                  \
3237024598e40c84666cc311a42c256bbf880db3ac99sewardj   heap[zz] = tmp;                                    \
3238024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3239024598e40c84666cc311a42c256bbf880db3ac99sewardj
3240024598e40c84666cc311a42c256bbf880db3ac99sewardj
3241024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3242024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ2_hbMakeCodeLengths ( UChar *len,
3243024598e40c84666cc311a42c256bbf880db3ac99sewardj                             Int32 *freq,
3244024598e40c84666cc311a42c256bbf880db3ac99sewardj                             Int32 alphaSize,
3245024598e40c84666cc311a42c256bbf880db3ac99sewardj                             Int32 maxLen )
3246024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3247024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--
3248024598e40c84666cc311a42c256bbf880db3ac99sewardj      Nodes and heap entries run from 1.  Entry 0
3249024598e40c84666cc311a42c256bbf880db3ac99sewardj      for both the heap and nodes is a sentinel.
3250024598e40c84666cc311a42c256bbf880db3ac99sewardj   --*/
3251024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nNodes, nHeap, n1, n2, i, j, k;
3252024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool  tooLong;
3253024598e40c84666cc311a42c256bbf880db3ac99sewardj
3254024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
3255024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
3256024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
3257024598e40c84666cc311a42c256bbf880db3ac99sewardj
3258024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < alphaSize; i++)
3259024598e40c84666cc311a42c256bbf880db3ac99sewardj      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
3260024598e40c84666cc311a42c256bbf880db3ac99sewardj
3261024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
3262024598e40c84666cc311a42c256bbf880db3ac99sewardj
3263024598e40c84666cc311a42c256bbf880db3ac99sewardj      nNodes = alphaSize;
3264024598e40c84666cc311a42c256bbf880db3ac99sewardj      nHeap = 0;
3265024598e40c84666cc311a42c256bbf880db3ac99sewardj
3266024598e40c84666cc311a42c256bbf880db3ac99sewardj      heap[0] = 0;
3267024598e40c84666cc311a42c256bbf880db3ac99sewardj      weight[0] = 0;
3268024598e40c84666cc311a42c256bbf880db3ac99sewardj      parent[0] = -2;
3269024598e40c84666cc311a42c256bbf880db3ac99sewardj
3270024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 1; i <= alphaSize; i++) {
3271024598e40c84666cc311a42c256bbf880db3ac99sewardj         parent[i] = -1;
3272024598e40c84666cc311a42c256bbf880db3ac99sewardj         nHeap++;
3273024598e40c84666cc311a42c256bbf880db3ac99sewardj         heap[nHeap] = i;
3274024598e40c84666cc311a42c256bbf880db3ac99sewardj         UPHEAP(nHeap);
3275024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3276024598e40c84666cc311a42c256bbf880db3ac99sewardj
3277024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
3278024598e40c84666cc311a42c256bbf880db3ac99sewardj
3279024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (nHeap > 1) {
3280024598e40c84666cc311a42c256bbf880db3ac99sewardj         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
3281024598e40c84666cc311a42c256bbf880db3ac99sewardj         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
3282024598e40c84666cc311a42c256bbf880db3ac99sewardj         nNodes++;
3283024598e40c84666cc311a42c256bbf880db3ac99sewardj         parent[n1] = parent[n2] = nNodes;
3284024598e40c84666cc311a42c256bbf880db3ac99sewardj         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
3285024598e40c84666cc311a42c256bbf880db3ac99sewardj         parent[nNodes] = -1;
3286024598e40c84666cc311a42c256bbf880db3ac99sewardj         nHeap++;
3287024598e40c84666cc311a42c256bbf880db3ac99sewardj         heap[nHeap] = nNodes;
3288024598e40c84666cc311a42c256bbf880db3ac99sewardj         UPHEAP(nHeap);
3289024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3290024598e40c84666cc311a42c256bbf880db3ac99sewardj
3291024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
3292024598e40c84666cc311a42c256bbf880db3ac99sewardj
3293024598e40c84666cc311a42c256bbf880db3ac99sewardj      tooLong = False;
3294024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 1; i <= alphaSize; i++) {
3295024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = 0;
3296024598e40c84666cc311a42c256bbf880db3ac99sewardj         k = i;
3297024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (parent[k] >= 0) { k = parent[k]; j++; }
3298024598e40c84666cc311a42c256bbf880db3ac99sewardj         len[i-1] = j;
3299024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (j > maxLen) tooLong = True;
3300024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3301024598e40c84666cc311a42c256bbf880db3ac99sewardj
3302024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (! tooLong) break;
3303024598e40c84666cc311a42c256bbf880db3ac99sewardj
3304024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* 17 Oct 04: keep-going condition for the following loop used
3305024598e40c84666cc311a42c256bbf880db3ac99sewardj         to be 'i < alphaSize', which missed the last element,
3306024598e40c84666cc311a42c256bbf880db3ac99sewardj         theoretically leading to the possibility of the compressor
3307024598e40c84666cc311a42c256bbf880db3ac99sewardj         looping.  However, this count-scaling step is only needed if
3308024598e40c84666cc311a42c256bbf880db3ac99sewardj         one of the generated Huffman code words is longer than
3309024598e40c84666cc311a42c256bbf880db3ac99sewardj         maxLen, which up to and including version 1.0.2 was 20 bits,
3310024598e40c84666cc311a42c256bbf880db3ac99sewardj         which is extremely unlikely.  In version 1.0.3 maxLen was
3311024598e40c84666cc311a42c256bbf880db3ac99sewardj         changed to 17 bits, which has minimal effect on compression
3312024598e40c84666cc311a42c256bbf880db3ac99sewardj         ratio, but does mean this scaling step is used from time to
3313024598e40c84666cc311a42c256bbf880db3ac99sewardj         time, enough to verify that it works.
3314024598e40c84666cc311a42c256bbf880db3ac99sewardj
3315024598e40c84666cc311a42c256bbf880db3ac99sewardj         This means that bzip2-1.0.3 and later will only produce
3316024598e40c84666cc311a42c256bbf880db3ac99sewardj         Huffman codes with a maximum length of 17 bits.  However, in
3317024598e40c84666cc311a42c256bbf880db3ac99sewardj         order to preserve backwards compatibility with bitstreams
3318024598e40c84666cc311a42c256bbf880db3ac99sewardj         produced by versions pre-1.0.3, the decompressor must still
3319024598e40c84666cc311a42c256bbf880db3ac99sewardj         handle lengths of up to 20. */
3320024598e40c84666cc311a42c256bbf880db3ac99sewardj
3321024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 1; i <= alphaSize; i++) {
3322024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = weight[i] >> 8;
3323024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = 1 + (j / 2);
3324024598e40c84666cc311a42c256bbf880db3ac99sewardj         weight[i] = j << 8;
3325024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3326024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3327024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3328024598e40c84666cc311a42c256bbf880db3ac99sewardj
3329024598e40c84666cc311a42c256bbf880db3ac99sewardj
3330024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3331024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ2_hbAssignCodes ( Int32 *code,
3332024598e40c84666cc311a42c256bbf880db3ac99sewardj                         UChar *length,
3333024598e40c84666cc311a42c256bbf880db3ac99sewardj                         Int32 minLen,
3334024598e40c84666cc311a42c256bbf880db3ac99sewardj                         Int32 maxLen,
3335024598e40c84666cc311a42c256bbf880db3ac99sewardj                         Int32 alphaSize )
3336024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3337024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 n, vec, i;
3338024598e40c84666cc311a42c256bbf880db3ac99sewardj
3339024598e40c84666cc311a42c256bbf880db3ac99sewardj   vec = 0;
3340024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (n = minLen; n <= maxLen; n++) {
3341024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < alphaSize; i++)
3342024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (length[i] == n) { code[i] = vec; vec++; };
3343024598e40c84666cc311a42c256bbf880db3ac99sewardj      vec <<= 1;
3344024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3345024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3346024598e40c84666cc311a42c256bbf880db3ac99sewardj
3347024598e40c84666cc311a42c256bbf880db3ac99sewardj
3348024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3349024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ2_hbCreateDecodeTables ( Int32 *limit,
3350024598e40c84666cc311a42c256bbf880db3ac99sewardj                                Int32 *base,
3351024598e40c84666cc311a42c256bbf880db3ac99sewardj                                Int32 *perm,
3352024598e40c84666cc311a42c256bbf880db3ac99sewardj                                UChar *length,
3353024598e40c84666cc311a42c256bbf880db3ac99sewardj                                Int32 minLen,
3354024598e40c84666cc311a42c256bbf880db3ac99sewardj                                Int32 maxLen,
3355024598e40c84666cc311a42c256bbf880db3ac99sewardj                                Int32 alphaSize )
3356024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3357024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 pp, i, j, vec;
3358024598e40c84666cc311a42c256bbf880db3ac99sewardj
3359024598e40c84666cc311a42c256bbf880db3ac99sewardj   pp = 0;
3360024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = minLen; i <= maxLen; i++)
3361024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (j = 0; j < alphaSize; j++)
3362024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (length[j] == i) { perm[pp] = j; pp++; };
3363024598e40c84666cc311a42c256bbf880db3ac99sewardj
3364024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
3365024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
3366024598e40c84666cc311a42c256bbf880db3ac99sewardj
3367024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
3368024598e40c84666cc311a42c256bbf880db3ac99sewardj
3369024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
3370024598e40c84666cc311a42c256bbf880db3ac99sewardj   vec = 0;
3371024598e40c84666cc311a42c256bbf880db3ac99sewardj
3372024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = minLen; i <= maxLen; i++) {
3373024598e40c84666cc311a42c256bbf880db3ac99sewardj      vec += (base[i+1] - base[i]);
3374024598e40c84666cc311a42c256bbf880db3ac99sewardj      limit[i] = vec-1;
3375024598e40c84666cc311a42c256bbf880db3ac99sewardj      vec <<= 1;
3376024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3377024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = minLen + 1; i <= maxLen; i++)
3378024598e40c84666cc311a42c256bbf880db3ac99sewardj      base[i] = ((limit[i-1] + 1) << 1) - base[i];
3379024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3380024598e40c84666cc311a42c256bbf880db3ac99sewardj
3381024598e40c84666cc311a42c256bbf880db3ac99sewardj
3382024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3383024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                         huffman.c ---*/
3384024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3385024598e40c84666cc311a42c256bbf880db3ac99sewardj
3386024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3387024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Compression machinery (not incl block sorting)        ---*/
3388024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                            compress.c ---*/
3389024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
3390024598e40c84666cc311a42c256bbf880db3ac99sewardj
3391024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
3392024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
3393024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
3394024598e40c84666cc311a42c256bbf880db3ac99sewardj
3395024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
3396024598e40c84666cc311a42c256bbf880db3ac99sewardj
3397024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
3398024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
3399024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
3400024598e40c84666cc311a42c256bbf880db3ac99sewardj
3401024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
3402024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
3403024598e40c84666cc311a42c256bbf880db3ac99sewardj
3404024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
3405024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
3406024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
3407024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
3408024598e40c84666cc311a42c256bbf880db3ac99sewardj
3409024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
3410024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
3411024598e40c84666cc311a42c256bbf880db3ac99sewardj
3412024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
3413024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
3414024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
3415024598e40c84666cc311a42c256bbf880db3ac99sewardj
3416024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
3417024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3418024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3419024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3420024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3421024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
3422024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3423024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3424024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3425024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3426024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3427024598e40c84666cc311a42c256bbf880db3ac99sewardj
3428024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
3429024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
3430024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
3431024598e40c84666cc311a42c256bbf880db3ac99sewardj
3432024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
3433024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
3434024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
3435024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
3436024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
3437024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
3438024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
3439024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
3440024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
3441024598e40c84666cc311a42c256bbf880db3ac99sewardj
3442024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
3443024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
3444024598e40c84666cc311a42c256bbf880db3ac99sewardj
3445024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
3446024598e40c84666cc311a42c256bbf880db3ac99sewardj   CHANGES
3447024598e40c84666cc311a42c256bbf880db3ac99sewardj   ~~~~~~~
3448024598e40c84666cc311a42c256bbf880db3ac99sewardj   0.9.0 -- original version.
3449024598e40c84666cc311a42c256bbf880db3ac99sewardj
3450024598e40c84666cc311a42c256bbf880db3ac99sewardj   0.9.0a/b -- no changes in this file.
3451024598e40c84666cc311a42c256bbf880db3ac99sewardj
3452024598e40c84666cc311a42c256bbf880db3ac99sewardj   0.9.0c
3453024598e40c84666cc311a42c256bbf880db3ac99sewardj      * changed setting of nGroups in sendMTFValues() so as to
3454024598e40c84666cc311a42c256bbf880db3ac99sewardj        do a bit better on small files
3455024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
3456024598e40c84666cc311a42c256bbf880db3ac99sewardj
3457024598e40c84666cc311a42c256bbf880db3ac99sewardj
3458024598e40c84666cc311a42c256bbf880db3ac99sewardj
3459024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3460024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Bit stream I/O                              ---*/
3461024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3462024598e40c84666cc311a42c256bbf880db3ac99sewardj
3463024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3464024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ2_bsInitWrite ( EState* s )
3465024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3466024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->bsLive = 0;
3467024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->bsBuff = 0;
3468024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3469024598e40c84666cc311a42c256bbf880db3ac99sewardj
3470024598e40c84666cc311a42c256bbf880db3ac99sewardj
3471024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3472024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
3473024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid bsFinishWrite ( EState* s )
3474024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3475024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (s->bsLive > 0) {
3476024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
3477024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->numZ++;
3478024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->bsBuff <<= 8;
3479024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->bsLive -= 8;
3480024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3481024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3482024598e40c84666cc311a42c256bbf880db3ac99sewardj
3483024598e40c84666cc311a42c256bbf880db3ac99sewardj
3484024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3485024598e40c84666cc311a42c256bbf880db3ac99sewardj#define bsNEEDW(nz)                           \
3486024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                             \
3487024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (s->bsLive >= 8) {                   \
3488024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->zbits[s->numZ]                       \
3489024598e40c84666cc311a42c256bbf880db3ac99sewardj         = (UChar)(s->bsBuff >> 24);          \
3490024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->numZ++;                              \
3491024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->bsBuff <<= 8;                        \
3492024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->bsLive -= 8;                         \
3493024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                          \
3494024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3495024598e40c84666cc311a42c256bbf880db3ac99sewardj
3496024598e40c84666cc311a42c256bbf880db3ac99sewardj
3497024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3498024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
3499024598e40c84666cc311a42c256bbf880db3ac99sewardj__inline__
3500024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid bsW ( EState* s, Int32 n, UInt32 v )
3501024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3502024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsNEEDW ( n );
3503024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->bsBuff |= (v << (32 - s->bsLive - n));
3504024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->bsLive += n;
3505024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3506024598e40c84666cc311a42c256bbf880db3ac99sewardj
3507024598e40c84666cc311a42c256bbf880db3ac99sewardj
3508024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3509024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
3510024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid bsPutUInt32 ( EState* s, UInt32 u )
3511024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3512024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsW ( s, 8, (u >> 24) & 0xffL );
3513024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsW ( s, 8, (u >> 16) & 0xffL );
3514024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsW ( s, 8, (u >>  8) & 0xffL );
3515024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsW ( s, 8,  u        & 0xffL );
3516024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3517024598e40c84666cc311a42c256bbf880db3ac99sewardj
3518024598e40c84666cc311a42c256bbf880db3ac99sewardj
3519024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3520024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
3521024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid bsPutUChar ( EState* s, UChar c )
3522024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3523024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsW( s, 8, (UInt32)c );
3524024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3525024598e40c84666cc311a42c256bbf880db3ac99sewardj
3526024598e40c84666cc311a42c256bbf880db3ac99sewardj
3527024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3528024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- The back end proper                         ---*/
3529024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3530024598e40c84666cc311a42c256bbf880db3ac99sewardj
3531024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3532024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
3533024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid makeMaps_e ( EState* s )
3534024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3535024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 i;
3536024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->nInUse = 0;
3537024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < 256; i++)
3538024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->inUse[i]) {
3539024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->unseqToSeq[i] = s->nInUse;
3540024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->nInUse++;
3541024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3542024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3543024598e40c84666cc311a42c256bbf880db3ac99sewardj
3544024598e40c84666cc311a42c256bbf880db3ac99sewardj
3545024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3546024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
3547024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid generateMTFValues ( EState* s )
3548024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3549024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar   yy[256];
3550024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   i, j;
3551024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   zPend;
3552024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   wr;
3553024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   EOB;
3554024598e40c84666cc311a42c256bbf880db3ac99sewardj
3555024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*
3556024598e40c84666cc311a42c256bbf880db3ac99sewardj      After sorting (eg, here),
3557024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
3558024598e40c84666cc311a42c256bbf880db3ac99sewardj         and
3559024598e40c84666cc311a42c256bbf880db3ac99sewardj         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
3560024598e40c84666cc311a42c256bbf880db3ac99sewardj         holds the original block data.
3561024598e40c84666cc311a42c256bbf880db3ac99sewardj
3562024598e40c84666cc311a42c256bbf880db3ac99sewardj      The first thing to do is generate the MTF values,
3563024598e40c84666cc311a42c256bbf880db3ac99sewardj      and put them in
3564024598e40c84666cc311a42c256bbf880db3ac99sewardj         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
3565024598e40c84666cc311a42c256bbf880db3ac99sewardj      Because there are strictly fewer or equal MTF values
3566024598e40c84666cc311a42c256bbf880db3ac99sewardj      than block values, ptr values in this area are overwritten
3567024598e40c84666cc311a42c256bbf880db3ac99sewardj      with MTF values only when they are no longer needed.
3568024598e40c84666cc311a42c256bbf880db3ac99sewardj
3569024598e40c84666cc311a42c256bbf880db3ac99sewardj      The final compressed bitstream is generated into the
3570024598e40c84666cc311a42c256bbf880db3ac99sewardj      area starting at
3571024598e40c84666cc311a42c256bbf880db3ac99sewardj         (UChar*) (&((UChar*)s->arr2)[s->nblock])
3572024598e40c84666cc311a42c256bbf880db3ac99sewardj
3573024598e40c84666cc311a42c256bbf880db3ac99sewardj      These storage aliases are set up in bzCompressInit(),
3574024598e40c84666cc311a42c256bbf880db3ac99sewardj      except for the last one, which is arranged in
3575024598e40c84666cc311a42c256bbf880db3ac99sewardj      compressBlock().
3576024598e40c84666cc311a42c256bbf880db3ac99sewardj   */
3577024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt32* ptr   = s->ptr;
3578024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar* block  = s->block;
3579024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt16* mtfv  = s->mtfv;
3580024598e40c84666cc311a42c256bbf880db3ac99sewardj
3581024598e40c84666cc311a42c256bbf880db3ac99sewardj   makeMaps_e ( s );
3582024598e40c84666cc311a42c256bbf880db3ac99sewardj   EOB = s->nInUse+1;
3583024598e40c84666cc311a42c256bbf880db3ac99sewardj
3584024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
3585024598e40c84666cc311a42c256bbf880db3ac99sewardj
3586024598e40c84666cc311a42c256bbf880db3ac99sewardj   wr = 0;
3587024598e40c84666cc311a42c256bbf880db3ac99sewardj   zPend = 0;
3588024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
3589024598e40c84666cc311a42c256bbf880db3ac99sewardj
3590024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < s->nblock; i++) {
3591024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar ll_i;
3592024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertD ( wr <= i, "generateMTFValues(1)" );
3593024598e40c84666cc311a42c256bbf880db3ac99sewardj      j = ptr[i]-1; if (j < 0) j += s->nblock;
3594024598e40c84666cc311a42c256bbf880db3ac99sewardj      ll_i = s->unseqToSeq[block[j]];
3595024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
3596024598e40c84666cc311a42c256bbf880db3ac99sewardj
3597024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (yy[0] == ll_i) {
3598024598e40c84666cc311a42c256bbf880db3ac99sewardj         zPend++;
3599024598e40c84666cc311a42c256bbf880db3ac99sewardj      } else {
3600024598e40c84666cc311a42c256bbf880db3ac99sewardj
3601024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (zPend > 0) {
3602024598e40c84666cc311a42c256bbf880db3ac99sewardj            zPend--;
3603024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (True) {
3604024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (zPend & 1) {
3605024598e40c84666cc311a42c256bbf880db3ac99sewardj                  mtfv[wr] = BZ_RUNB; wr++;
3606024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->mtfFreq[BZ_RUNB]++;
3607024598e40c84666cc311a42c256bbf880db3ac99sewardj               } else {
3608024598e40c84666cc311a42c256bbf880db3ac99sewardj                  mtfv[wr] = BZ_RUNA; wr++;
3609024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->mtfFreq[BZ_RUNA]++;
3610024598e40c84666cc311a42c256bbf880db3ac99sewardj               }
3611024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (zPend < 2) break;
3612024598e40c84666cc311a42c256bbf880db3ac99sewardj               zPend = (zPend - 2) / 2;
3613024598e40c84666cc311a42c256bbf880db3ac99sewardj            };
3614024598e40c84666cc311a42c256bbf880db3ac99sewardj            zPend = 0;
3615024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3616024598e40c84666cc311a42c256bbf880db3ac99sewardj         {
3617024598e40c84666cc311a42c256bbf880db3ac99sewardj            register UChar  rtmp;
3618024598e40c84666cc311a42c256bbf880db3ac99sewardj            register UChar* ryy_j;
3619024598e40c84666cc311a42c256bbf880db3ac99sewardj            register UChar  rll_i;
3620024598e40c84666cc311a42c256bbf880db3ac99sewardj            rtmp  = yy[1];
3621024598e40c84666cc311a42c256bbf880db3ac99sewardj            yy[1] = yy[0];
3622024598e40c84666cc311a42c256bbf880db3ac99sewardj            ryy_j = &(yy[1]);
3623024598e40c84666cc311a42c256bbf880db3ac99sewardj            rll_i = ll_i;
3624024598e40c84666cc311a42c256bbf880db3ac99sewardj            while ( rll_i != rtmp ) {
3625024598e40c84666cc311a42c256bbf880db3ac99sewardj               register UChar rtmp2;
3626024598e40c84666cc311a42c256bbf880db3ac99sewardj               ryy_j++;
3627024598e40c84666cc311a42c256bbf880db3ac99sewardj               rtmp2  = rtmp;
3628024598e40c84666cc311a42c256bbf880db3ac99sewardj               rtmp   = *ryy_j;
3629024598e40c84666cc311a42c256bbf880db3ac99sewardj               *ryy_j = rtmp2;
3630024598e40c84666cc311a42c256bbf880db3ac99sewardj            };
3631024598e40c84666cc311a42c256bbf880db3ac99sewardj            yy[0] = rtmp;
3632024598e40c84666cc311a42c256bbf880db3ac99sewardj            j = ryy_j - &(yy[0]);
3633024598e40c84666cc311a42c256bbf880db3ac99sewardj            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
3634024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3635024598e40c84666cc311a42c256bbf880db3ac99sewardj
3636024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3637024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3638024598e40c84666cc311a42c256bbf880db3ac99sewardj
3639024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (zPend > 0) {
3640024598e40c84666cc311a42c256bbf880db3ac99sewardj      zPend--;
3641024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
3642024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (zPend & 1) {
3643024598e40c84666cc311a42c256bbf880db3ac99sewardj            mtfv[wr] = BZ_RUNB; wr++;
3644024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->mtfFreq[BZ_RUNB]++;
3645024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
3646024598e40c84666cc311a42c256bbf880db3ac99sewardj            mtfv[wr] = BZ_RUNA; wr++;
3647024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->mtfFreq[BZ_RUNA]++;
3648024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3649024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (zPend < 2) break;
3650024598e40c84666cc311a42c256bbf880db3ac99sewardj         zPend = (zPend - 2) / 2;
3651024598e40c84666cc311a42c256bbf880db3ac99sewardj      };
3652024598e40c84666cc311a42c256bbf880db3ac99sewardj      zPend = 0;
3653024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3654024598e40c84666cc311a42c256bbf880db3ac99sewardj
3655024598e40c84666cc311a42c256bbf880db3ac99sewardj   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
3656024598e40c84666cc311a42c256bbf880db3ac99sewardj
3657024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->nMTF = wr;
3658024598e40c84666cc311a42c256bbf880db3ac99sewardj}
3659024598e40c84666cc311a42c256bbf880db3ac99sewardj
3660024598e40c84666cc311a42c256bbf880db3ac99sewardj
3661024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
3662024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_LESSER_ICOST  0
3663024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_GREATER_ICOST 15
3664024598e40c84666cc311a42c256bbf880db3ac99sewardj
3665024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
3666024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid sendMTFValues ( EState* s )
3667024598e40c84666cc311a42c256bbf880db3ac99sewardj{
3668024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
3669024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
3670024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 nGroups, nBytes;
3671024598e40c84666cc311a42c256bbf880db3ac99sewardj
3672024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--
3673024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3674024598e40c84666cc311a42c256bbf880db3ac99sewardj   is a global since the decoder also needs it.
3675024598e40c84666cc311a42c256bbf880db3ac99sewardj
3676024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3677024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3678024598e40c84666cc311a42c256bbf880db3ac99sewardj   are also globals only used in this proc.
3679024598e40c84666cc311a42c256bbf880db3ac99sewardj   Made global to keep stack frame size small.
3680024598e40c84666cc311a42c256bbf880db3ac99sewardj   --*/
3681024598e40c84666cc311a42c256bbf880db3ac99sewardj
3682024598e40c84666cc311a42c256bbf880db3ac99sewardj
3683024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt16 cost[BZ_N_GROUPS];
3684024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32  fave[BZ_N_GROUPS];
3685024598e40c84666cc311a42c256bbf880db3ac99sewardj
3686024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt16* mtfv = s->mtfv;
3687024598e40c84666cc311a42c256bbf880db3ac99sewardj
3688024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->verbosity >= 3)
3689024598e40c84666cc311a42c256bbf880db3ac99sewardj      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
3690024598e40c84666cc311a42c256bbf880db3ac99sewardj                "%d+2 syms in use\n",
3691024598e40c84666cc311a42c256bbf880db3ac99sewardj                s->nblock, s->nMTF, s->nInUse );
3692024598e40c84666cc311a42c256bbf880db3ac99sewardj
3693024598e40c84666cc311a42c256bbf880db3ac99sewardj   alphaSize = s->nInUse+2;
3694024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (t = 0; t < BZ_N_GROUPS; t++)
3695024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (v = 0; v < alphaSize; v++)
3696024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->len[t][v] = BZ_GREATER_ICOST;
3697024598e40c84666cc311a42c256bbf880db3ac99sewardj
3698024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- Decide how many coding tables to use ---*/
3699024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH ( s->nMTF > 0, 3001 );
3700024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->nMTF < 200)  nGroups = 2; else
3701024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->nMTF < 600)  nGroups = 3; else
3702024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->nMTF < 1200) nGroups = 4; else
3703024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->nMTF < 2400) nGroups = 5; else
3704024598e40c84666cc311a42c256bbf880db3ac99sewardj                       nGroups = 6;
3705024598e40c84666cc311a42c256bbf880db3ac99sewardj
3706024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- Generate an initial set of coding tables ---*/
3707024598e40c84666cc311a42c256bbf880db3ac99sewardj   {
3708024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32 nPart, remF, tFreq, aFreq;
3709024598e40c84666cc311a42c256bbf880db3ac99sewardj
3710024598e40c84666cc311a42c256bbf880db3ac99sewardj      nPart = nGroups;
3711024598e40c84666cc311a42c256bbf880db3ac99sewardj      remF  = s->nMTF;
3712024598e40c84666cc311a42c256bbf880db3ac99sewardj      gs = 0;
3713024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (nPart > 0) {
3714024598e40c84666cc311a42c256bbf880db3ac99sewardj         tFreq = remF / nPart;
3715024598e40c84666cc311a42c256bbf880db3ac99sewardj         ge = gs-1;
3716024598e40c84666cc311a42c256bbf880db3ac99sewardj         aFreq = 0;
3717024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (aFreq < tFreq && ge < alphaSize-1) {
3718024598e40c84666cc311a42c256bbf880db3ac99sewardj            ge++;
3719024598e40c84666cc311a42c256bbf880db3ac99sewardj            aFreq += s->mtfFreq[ge];
3720024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3721024598e40c84666cc311a42c256bbf880db3ac99sewardj
3722024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (ge > gs
3723024598e40c84666cc311a42c256bbf880db3ac99sewardj             && nPart != nGroups && nPart != 1
3724024598e40c84666cc311a42c256bbf880db3ac99sewardj             && ((nGroups-nPart) % 2 == 1)) {
3725024598e40c84666cc311a42c256bbf880db3ac99sewardj            aFreq -= s->mtfFreq[ge];
3726024598e40c84666cc311a42c256bbf880db3ac99sewardj            ge--;
3727024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3728024598e40c84666cc311a42c256bbf880db3ac99sewardj
3729024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (0 && s->verbosity >= 3)
3730024598e40c84666cc311a42c256bbf880db3ac99sewardj            VPrintf5( "      initial group %d, [%d .. %d], "
3731024598e40c84666cc311a42c256bbf880db3ac99sewardj                      "has %d syms (%4.1f%%)\n",
3732024598e40c84666cc311a42c256bbf880db3ac99sewardj                      nPart, gs, ge, aFreq,
3733024598e40c84666cc311a42c256bbf880db3ac99sewardj                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
3734024598e40c84666cc311a42c256bbf880db3ac99sewardj
3735024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (v = 0; v < alphaSize; v++)
3736024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (v >= gs && v <= ge)
3737024598e40c84666cc311a42c256bbf880db3ac99sewardj               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
3738024598e40c84666cc311a42c256bbf880db3ac99sewardj               s->len[nPart-1][v] = BZ_GREATER_ICOST;
3739024598e40c84666cc311a42c256bbf880db3ac99sewardj
3740024598e40c84666cc311a42c256bbf880db3ac99sewardj         nPart--;
3741024598e40c84666cc311a42c256bbf880db3ac99sewardj         gs = ge+1;
3742024598e40c84666cc311a42c256bbf880db3ac99sewardj         remF -= aFreq;
3743024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3744024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3745024598e40c84666cc311a42c256bbf880db3ac99sewardj
3746024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*---
3747024598e40c84666cc311a42c256bbf880db3ac99sewardj      Iterate up to BZ_N_ITERS times to improve the tables.
3748024598e40c84666cc311a42c256bbf880db3ac99sewardj   ---*/
3749024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (iter = 0; iter < BZ_N_ITERS; iter++) {
3750024598e40c84666cc311a42c256bbf880db3ac99sewardj
3751024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (t = 0; t < nGroups; t++) fave[t] = 0;
3752024598e40c84666cc311a42c256bbf880db3ac99sewardj
3753024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (t = 0; t < nGroups; t++)
3754024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (v = 0; v < alphaSize; v++)
3755024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->rfreq[t][v] = 0;
3756024598e40c84666cc311a42c256bbf880db3ac99sewardj
3757024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*---
3758024598e40c84666cc311a42c256bbf880db3ac99sewardj        Set up an auxiliary length table which is used to fast-track
3759024598e40c84666cc311a42c256bbf880db3ac99sewardj	the common case (nGroups == 6).
3760024598e40c84666cc311a42c256bbf880db3ac99sewardj      ---*/
3761024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (nGroups == 6) {
3762024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (v = 0; v < alphaSize; v++) {
3763024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
3764024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
3765024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
3766024598e40c84666cc311a42c256bbf880db3ac99sewardj	 }
3767024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3768024598e40c84666cc311a42c256bbf880db3ac99sewardj
3769024598e40c84666cc311a42c256bbf880db3ac99sewardj      nSelectors = 0;
3770024598e40c84666cc311a42c256bbf880db3ac99sewardj      totc = 0;
3771024598e40c84666cc311a42c256bbf880db3ac99sewardj      gs = 0;
3772024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
3773024598e40c84666cc311a42c256bbf880db3ac99sewardj
3774024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*--- Set group start & end marks. --*/
3775024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (gs >= s->nMTF) break;
3776024598e40c84666cc311a42c256bbf880db3ac99sewardj         ge = gs + BZ_G_SIZE - 1;
3777024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (ge >= s->nMTF) ge = s->nMTF-1;
3778024598e40c84666cc311a42c256bbf880db3ac99sewardj
3779024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*--
3780024598e40c84666cc311a42c256bbf880db3ac99sewardj            Calculate the cost of this group as coded
3781024598e40c84666cc311a42c256bbf880db3ac99sewardj            by each of the coding tables.
3782024598e40c84666cc311a42c256bbf880db3ac99sewardj         --*/
3783024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (t = 0; t < nGroups; t++) cost[t] = 0;
3784024598e40c84666cc311a42c256bbf880db3ac99sewardj
3785024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (nGroups == 6 && 50 == ge-gs+1) {
3786024598e40c84666cc311a42c256bbf880db3ac99sewardj            /*--- fast track the common case ---*/
3787024598e40c84666cc311a42c256bbf880db3ac99sewardj            register UInt32 cost01, cost23, cost45;
3788024598e40c84666cc311a42c256bbf880db3ac99sewardj            register UInt16 icv;
3789024598e40c84666cc311a42c256bbf880db3ac99sewardj            cost01 = cost23 = cost45 = 0;
3790024598e40c84666cc311a42c256bbf880db3ac99sewardj
3791024598e40c84666cc311a42c256bbf880db3ac99sewardj#           define BZ_ITER(nn)                \
3792024598e40c84666cc311a42c256bbf880db3ac99sewardj               icv = mtfv[gs+(nn)];           \
3793024598e40c84666cc311a42c256bbf880db3ac99sewardj               cost01 += s->len_pack[icv][0]; \
3794024598e40c84666cc311a42c256bbf880db3ac99sewardj               cost23 += s->len_pack[icv][1]; \
3795024598e40c84666cc311a42c256bbf880db3ac99sewardj               cost45 += s->len_pack[icv][2]; \
3796024598e40c84666cc311a42c256bbf880db3ac99sewardj
3797024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
3798024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
3799024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
3800024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
3801024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
3802024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
3803024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
3804024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
3805024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
3806024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
3807024598e40c84666cc311a42c256bbf880db3ac99sewardj
3808024598e40c84666cc311a42c256bbf880db3ac99sewardj#           undef BZ_ITER
3809024598e40c84666cc311a42c256bbf880db3ac99sewardj
3810024598e40c84666cc311a42c256bbf880db3ac99sewardj            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
3811024598e40c84666cc311a42c256bbf880db3ac99sewardj            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
3812024598e40c84666cc311a42c256bbf880db3ac99sewardj            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
3813024598e40c84666cc311a42c256bbf880db3ac99sewardj
3814024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
3815024598e40c84666cc311a42c256bbf880db3ac99sewardj	    /*--- slow version which correctly handles all situations ---*/
3816024598e40c84666cc311a42c256bbf880db3ac99sewardj            for (i = gs; i <= ge; i++) {
3817024598e40c84666cc311a42c256bbf880db3ac99sewardj               UInt16 icv = mtfv[i];
3818024598e40c84666cc311a42c256bbf880db3ac99sewardj               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
3819024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
3820024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3821024598e40c84666cc311a42c256bbf880db3ac99sewardj
3822024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*--
3823024598e40c84666cc311a42c256bbf880db3ac99sewardj            Find the coding table which is best for this group,
3824024598e40c84666cc311a42c256bbf880db3ac99sewardj            and record its identity in the selector table.
3825024598e40c84666cc311a42c256bbf880db3ac99sewardj         --*/
3826024598e40c84666cc311a42c256bbf880db3ac99sewardj         bc = 999999999; bt = -1;
3827024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (t = 0; t < nGroups; t++)
3828024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (cost[t] < bc) { bc = cost[t]; bt = t; };
3829024598e40c84666cc311a42c256bbf880db3ac99sewardj         totc += bc;
3830024598e40c84666cc311a42c256bbf880db3ac99sewardj         fave[bt]++;
3831024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->selector[nSelectors] = bt;
3832024598e40c84666cc311a42c256bbf880db3ac99sewardj         nSelectors++;
3833024598e40c84666cc311a42c256bbf880db3ac99sewardj
3834024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*--
3835024598e40c84666cc311a42c256bbf880db3ac99sewardj            Increment the symbol frequencies for the selected table.
3836024598e40c84666cc311a42c256bbf880db3ac99sewardj          --*/
3837024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (nGroups == 6 && 50 == ge-gs+1) {
3838024598e40c84666cc311a42c256bbf880db3ac99sewardj            /*--- fast track the common case ---*/
3839024598e40c84666cc311a42c256bbf880db3ac99sewardj
3840024598e40c84666cc311a42c256bbf880db3ac99sewardj#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
3841024598e40c84666cc311a42c256bbf880db3ac99sewardj
3842024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
3843024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
3844024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
3845024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
3846024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
3847024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
3848024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
3849024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
3850024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
3851024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
3852024598e40c84666cc311a42c256bbf880db3ac99sewardj
3853024598e40c84666cc311a42c256bbf880db3ac99sewardj#           undef BZ_ITUR
3854024598e40c84666cc311a42c256bbf880db3ac99sewardj
3855024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
3856024598e40c84666cc311a42c256bbf880db3ac99sewardj	    /*--- slow version which correctly handles all situations ---*/
3857024598e40c84666cc311a42c256bbf880db3ac99sewardj            for (i = gs; i <= ge; i++)
3858024598e40c84666cc311a42c256bbf880db3ac99sewardj               s->rfreq[bt][ mtfv[i] ]++;
3859024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
3860024598e40c84666cc311a42c256bbf880db3ac99sewardj
3861024598e40c84666cc311a42c256bbf880db3ac99sewardj         gs = ge+1;
3862024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3863024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->verbosity >= 3) {
3864024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf2 ( "      pass %d: size is %d, grp uses are ",
3865024598e40c84666cc311a42c256bbf880db3ac99sewardj                   iter+1, totc/8 );
3866024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (t = 0; t < nGroups; t++)
3867024598e40c84666cc311a42c256bbf880db3ac99sewardj            VPrintf1 ( "%d ", fave[t] );
3868024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf0 ( "\n" );
3869024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3870024598e40c84666cc311a42c256bbf880db3ac99sewardj
3871024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--
3872024598e40c84666cc311a42c256bbf880db3ac99sewardj        Recompute the tables based on the accumulated frequencies.
3873024598e40c84666cc311a42c256bbf880db3ac99sewardj      --*/
3874024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
3875024598e40c84666cc311a42c256bbf880db3ac99sewardj         comment in huffman.c for details. */
3876024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (t = 0; t < nGroups; t++)
3877024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
3878024598e40c84666cc311a42c256bbf880db3ac99sewardj                                 alphaSize, 17 /*20*/ );
3879024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3880024598e40c84666cc311a42c256bbf880db3ac99sewardj
3881024598e40c84666cc311a42c256bbf880db3ac99sewardj
3882024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH( nGroups < 8, 3002 );
3883024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH( nSelectors < 32768 &&
3884024598e40c84666cc311a42c256bbf880db3ac99sewardj            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
3885024598e40c84666cc311a42c256bbf880db3ac99sewardj            3003 );
3886024598e40c84666cc311a42c256bbf880db3ac99sewardj
3887024598e40c84666cc311a42c256bbf880db3ac99sewardj
3888024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- Compute MTF values for the selectors. ---*/
3889024598e40c84666cc311a42c256bbf880db3ac99sewardj   {
3890024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
3891024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < nGroups; i++) pos[i] = i;
3892024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < nSelectors; i++) {
3893024598e40c84666cc311a42c256bbf880db3ac99sewardj         ll_i = s->selector[i];
3894024598e40c84666cc311a42c256bbf880db3ac99sewardj         j = 0;
3895024598e40c84666cc311a42c256bbf880db3ac99sewardj         tmp = pos[j];
3896024598e40c84666cc311a42c256bbf880db3ac99sewardj         while ( ll_i != tmp ) {
3897024598e40c84666cc311a42c256bbf880db3ac99sewardj            j++;
3898024598e40c84666cc311a42c256bbf880db3ac99sewardj            tmp2 = tmp;
3899024598e40c84666cc311a42c256bbf880db3ac99sewardj            tmp = pos[j];
3900024598e40c84666cc311a42c256bbf880db3ac99sewardj            pos[j] = tmp2;
3901024598e40c84666cc311a42c256bbf880db3ac99sewardj         };
3902024598e40c84666cc311a42c256bbf880db3ac99sewardj         pos[0] = tmp;
3903024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->selectorMtf[i] = j;
3904024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3905024598e40c84666cc311a42c256bbf880db3ac99sewardj   };
3906024598e40c84666cc311a42c256bbf880db3ac99sewardj
3907024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- Assign actual codes for the tables. --*/
3908024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (t = 0; t < nGroups; t++) {
3909024598e40c84666cc311a42c256bbf880db3ac99sewardj      minLen = 32;
3910024598e40c84666cc311a42c256bbf880db3ac99sewardj      maxLen = 0;
3911024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < alphaSize; i++) {
3912024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
3913024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->len[t][i] < minLen) minLen = s->len[t][i];
3914024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3915024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
3916024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH ( !(minLen < 1),  3005 );
3917024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
3918024598e40c84666cc311a42c256bbf880db3ac99sewardj                          minLen, maxLen, alphaSize );
3919024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3920024598e40c84666cc311a42c256bbf880db3ac99sewardj
3921024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- Transmit the mapping table. ---*/
3922024598e40c84666cc311a42c256bbf880db3ac99sewardj   {
3923024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool inUse16[16];
3924024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < 16; i++) {
3925024598e40c84666cc311a42c256bbf880db3ac99sewardj          inUse16[i] = False;
3926024598e40c84666cc311a42c256bbf880db3ac99sewardj          for (j = 0; j < 16; j++)
3927024598e40c84666cc311a42c256bbf880db3ac99sewardj             if (s->inUse[i * 16 + j]) inUse16[i] = True;
3928024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3929024598e40c84666cc311a42c256bbf880db3ac99sewardj
3930024598e40c84666cc311a42c256bbf880db3ac99sewardj      nBytes = s->numZ;
3931024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < 16; i++)
3932024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
3933024598e40c84666cc311a42c256bbf880db3ac99sewardj
3934024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < 16; i++)
3935024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (inUse16[i])
3936024598e40c84666cc311a42c256bbf880db3ac99sewardj            for (j = 0; j < 16; j++) {
3937024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
3938024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
3939024598e40c84666cc311a42c256bbf880db3ac99sewardj
3940024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->verbosity >= 3)
3941024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
3942024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3943024598e40c84666cc311a42c256bbf880db3ac99sewardj
3944024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- Now the selectors. ---*/
3945024598e40c84666cc311a42c256bbf880db3ac99sewardj   nBytes = s->numZ;
3946024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsW ( s, 3, nGroups );
3947024598e40c84666cc311a42c256bbf880db3ac99sewardj   bsW ( s, 15, nSelectors );
3948024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < nSelectors; i++) {
3949024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
3950024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsW(s,1,0);
3951024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3952024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->verbosity >= 3)
3953024598e40c84666cc311a42c256bbf880db3ac99sewardj      VPrintf1( "selectors %d, ", s->numZ-nBytes );
3954024598e40c84666cc311a42c256bbf880db3ac99sewardj
3955024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- Now the coding tables. ---*/
3956024598e40c84666cc311a42c256bbf880db3ac99sewardj   nBytes = s->numZ;
3957024598e40c84666cc311a42c256bbf880db3ac99sewardj
3958024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (t = 0; t < nGroups; t++) {
3959024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32 curr = s->len[t][0];
3960024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsW ( s, 5, curr );
3961024598e40c84666cc311a42c256bbf880db3ac99sewardj      for (i = 0; i < alphaSize; i++) {
3962024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
3963024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
3964024598e40c84666cc311a42c256bbf880db3ac99sewardj         bsW ( s, 1, 0 );
3965024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
3966024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
3967024598e40c84666cc311a42c256bbf880db3ac99sewardj
3968024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->verbosity >= 3)
3969024598e40c84666cc311a42c256bbf880db3ac99sewardj      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
3970024598e40c84666cc311a42c256bbf880db3ac99sewardj
3971024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*--- And finally, the block data proper ---*/
3972024598e40c84666cc311a42c256bbf880db3ac99sewardj   nBytes = s->numZ;
3973024598e40c84666cc311a42c256bbf880db3ac99sewardj   selCtr = 0;
3974024598e40c84666cc311a42c256bbf880db3ac99sewardj   gs = 0;
3975024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
3976024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (gs >= s->nMTF) break;
3977024598e40c84666cc311a42c256bbf880db3ac99sewardj      ge = gs + BZ_G_SIZE - 1;
3978024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ge >= s->nMTF) ge = s->nMTF-1;
3979024598e40c84666cc311a42c256bbf880db3ac99sewardj      AssertH ( s->selector[selCtr] < nGroups, 3006 );
3980024598e40c84666cc311a42c256bbf880db3ac99sewardj
3981024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (nGroups == 6 && 50 == ge-gs+1) {
3982024598e40c84666cc311a42c256bbf880db3ac99sewardj            /*--- fast track the common case ---*/
3983024598e40c84666cc311a42c256bbf880db3ac99sewardj            UInt16 mtfv_i;
3984024598e40c84666cc311a42c256bbf880db3ac99sewardj            UChar* s_len_sel_selCtr
3985024598e40c84666cc311a42c256bbf880db3ac99sewardj               = &(s->len[s->selector[selCtr]][0]);
3986024598e40c84666cc311a42c256bbf880db3ac99sewardj            Int32* s_code_sel_selCtr
3987024598e40c84666cc311a42c256bbf880db3ac99sewardj               = &(s->code[s->selector[selCtr]][0]);
3988024598e40c84666cc311a42c256bbf880db3ac99sewardj
3989024598e40c84666cc311a42c256bbf880db3ac99sewardj#           define BZ_ITAH(nn)                      \
3990024598e40c84666cc311a42c256bbf880db3ac99sewardj               mtfv_i = mtfv[gs+(nn)];              \
3991024598e40c84666cc311a42c256bbf880db3ac99sewardj               bsW ( s,                             \
3992024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s_len_sel_selCtr[mtfv_i],      \
3993024598e40c84666cc311a42c256bbf880db3ac99sewardj                     s_code_sel_selCtr[mtfv_i] )
3994024598e40c84666cc311a42c256bbf880db3ac99sewardj
3995024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
3996024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
3997024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
3998024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
3999024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
4000024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
4001024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
4002024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
4003024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
4004024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
4005024598e40c84666cc311a42c256bbf880db3ac99sewardj
4006024598e40c84666cc311a42c256bbf880db3ac99sewardj#           undef BZ_ITAH
4007024598e40c84666cc311a42c256bbf880db3ac99sewardj
4008024598e40c84666cc311a42c256bbf880db3ac99sewardj      } else {
4009024598e40c84666cc311a42c256bbf880db3ac99sewardj	 /*--- slow version which correctly handles all situations ---*/
4010024598e40c84666cc311a42c256bbf880db3ac99sewardj         for (i = gs; i <= ge; i++) {
4011024598e40c84666cc311a42c256bbf880db3ac99sewardj            bsW ( s,
4012024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->len  [s->selector[selCtr]] [mtfv[i]],
4013024598e40c84666cc311a42c256bbf880db3ac99sewardj                  s->code [s->selector[selCtr]] [mtfv[i]] );
4014024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4015024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
4016024598e40c84666cc311a42c256bbf880db3ac99sewardj
4017024598e40c84666cc311a42c256bbf880db3ac99sewardj
4018024598e40c84666cc311a42c256bbf880db3ac99sewardj      gs = ge+1;
4019024598e40c84666cc311a42c256bbf880db3ac99sewardj      selCtr++;
4020024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4021024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH( selCtr == nSelectors, 3007 );
4022024598e40c84666cc311a42c256bbf880db3ac99sewardj
4023024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->verbosity >= 3)
4024024598e40c84666cc311a42c256bbf880db3ac99sewardj      VPrintf1( "codes %d\n", s->numZ-nBytes );
4025024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4026024598e40c84666cc311a42c256bbf880db3ac99sewardj
4027024598e40c84666cc311a42c256bbf880db3ac99sewardj
4028024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4029024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ2_compressBlock ( EState* s, Bool is_last_block )
4030024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4031024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->nblock > 0) {
4032024598e40c84666cc311a42c256bbf880db3ac99sewardj
4033024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ_FINALISE_CRC ( s->blockCRC );
4034024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
4035024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->combinedCRC ^= s->blockCRC;
4036024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->blockNo > 1) s->numZ = 0;
4037024598e40c84666cc311a42c256bbf880db3ac99sewardj
4038024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->verbosity >= 2)
4039024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf4( "    block %d: crc = 0x%08x, "
4040024598e40c84666cc311a42c256bbf880db3ac99sewardj                   "combined CRC = 0x%08x, size = %d\n",
4041024598e40c84666cc311a42c256bbf880db3ac99sewardj                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
4042024598e40c84666cc311a42c256bbf880db3ac99sewardj
4043024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ2_blockSort ( s );
4044024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4045024598e40c84666cc311a42c256bbf880db3ac99sewardj
4046024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
4047024598e40c84666cc311a42c256bbf880db3ac99sewardj
4048024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- If this is the first block, create the stream header. --*/
4049024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->blockNo == 1) {
4050024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ2_bsInitWrite ( s );
4051024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, BZ_HDR_B );
4052024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, BZ_HDR_Z );
4053024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, BZ_HDR_h );
4054024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
4055024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4056024598e40c84666cc311a42c256bbf880db3ac99sewardj
4057024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->nblock > 0) {
4058024598e40c84666cc311a42c256bbf880db3ac99sewardj
4059024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
4060024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
4061024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
4062024598e40c84666cc311a42c256bbf880db3ac99sewardj
4063024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- Now the block's CRC, so it is in a known place. --*/
4064024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUInt32 ( s, s->blockCRC );
4065024598e40c84666cc311a42c256bbf880db3ac99sewardj
4066024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*--
4067024598e40c84666cc311a42c256bbf880db3ac99sewardj         Now a single bit indicating (non-)randomisation.
4068024598e40c84666cc311a42c256bbf880db3ac99sewardj         As of version 0.9.5, we use a better sorting algorithm
4069024598e40c84666cc311a42c256bbf880db3ac99sewardj         which makes randomisation unnecessary.  So always set
4070024598e40c84666cc311a42c256bbf880db3ac99sewardj         the randomised bit to 'no'.  Of course, the decoder
4071024598e40c84666cc311a42c256bbf880db3ac99sewardj         still needs to be able to handle randomised blocks
4072024598e40c84666cc311a42c256bbf880db3ac99sewardj         so as to maintain backwards compatibility with
4073024598e40c84666cc311a42c256bbf880db3ac99sewardj         older versions of bzip2.
4074024598e40c84666cc311a42c256bbf880db3ac99sewardj      --*/
4075024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsW(s,1,0);
4076024598e40c84666cc311a42c256bbf880db3ac99sewardj
4077024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsW ( s, 24, s->origPtr );
4078024598e40c84666cc311a42c256bbf880db3ac99sewardj      generateMTFValues ( s );
4079024598e40c84666cc311a42c256bbf880db3ac99sewardj      sendMTFValues ( s );
4080024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4081024598e40c84666cc311a42c256bbf880db3ac99sewardj
4082024598e40c84666cc311a42c256bbf880db3ac99sewardj
4083024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- If this is the last block, add the stream trailer. --*/
4084024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (is_last_block) {
4085024598e40c84666cc311a42c256bbf880db3ac99sewardj
4086024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
4087024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
4088024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
4089024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsPutUInt32 ( s, s->combinedCRC );
4090024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->verbosity >= 2)
4091024598e40c84666cc311a42c256bbf880db3ac99sewardj         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
4092024598e40c84666cc311a42c256bbf880db3ac99sewardj      bsFinishWrite ( s );
4093024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4094024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4095024598e40c84666cc311a42c256bbf880db3ac99sewardj
4096024598e40c84666cc311a42c256bbf880db3ac99sewardj
4097024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4098024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                        compress.c ---*/
4099024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4100024598e40c84666cc311a42c256bbf880db3ac99sewardj
4101024598e40c84666cc311a42c256bbf880db3ac99sewardj
4102024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4103024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Table for randomising repetitive blocks               ---*/
4104024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                           randtable.c ---*/
4105024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4106024598e40c84666cc311a42c256bbf880db3ac99sewardj
4107024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
4108024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
4109024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
4110024598e40c84666cc311a42c256bbf880db3ac99sewardj
4111024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4112024598e40c84666cc311a42c256bbf880db3ac99sewardj
4113024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
4114024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
4115024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
4116024598e40c84666cc311a42c256bbf880db3ac99sewardj
4117024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
4118024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
4119024598e40c84666cc311a42c256bbf880db3ac99sewardj
4120024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
4121024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
4122024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
4123024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
4124024598e40c84666cc311a42c256bbf880db3ac99sewardj
4125024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
4126024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
4127024598e40c84666cc311a42c256bbf880db3ac99sewardj
4128024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
4129024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
4130024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
4131024598e40c84666cc311a42c256bbf880db3ac99sewardj
4132024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4133024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4134024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4135024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4136024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4137024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4138024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4139024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4140024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4141024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4142024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4143024598e40c84666cc311a42c256bbf880db3ac99sewardj
4144024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
4145024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
4146024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
4147024598e40c84666cc311a42c256bbf880db3ac99sewardj
4148024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
4149024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
4150024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
4151024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
4152024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
4153024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
4154024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
4155024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
4156024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
4157024598e40c84666cc311a42c256bbf880db3ac99sewardj
4158024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
4159024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
4160024598e40c84666cc311a42c256bbf880db3ac99sewardj
4161024598e40c84666cc311a42c256bbf880db3ac99sewardj
4162024598e40c84666cc311a42c256bbf880db3ac99sewardj
4163024598e40c84666cc311a42c256bbf880db3ac99sewardj
4164024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
4165024598e40c84666cc311a42c256bbf880db3ac99sewardjInt32 BZ2_rNums[512] = {
4166024598e40c84666cc311a42c256bbf880db3ac99sewardj   619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
4167024598e40c84666cc311a42c256bbf880db3ac99sewardj   985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
4168024598e40c84666cc311a42c256bbf880db3ac99sewardj   733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
4169024598e40c84666cc311a42c256bbf880db3ac99sewardj   419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
4170024598e40c84666cc311a42c256bbf880db3ac99sewardj   878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
4171024598e40c84666cc311a42c256bbf880db3ac99sewardj   862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
4172024598e40c84666cc311a42c256bbf880db3ac99sewardj   150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
4173024598e40c84666cc311a42c256bbf880db3ac99sewardj   170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
4174024598e40c84666cc311a42c256bbf880db3ac99sewardj   73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
4175024598e40c84666cc311a42c256bbf880db3ac99sewardj   909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
4176024598e40c84666cc311a42c256bbf880db3ac99sewardj   641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
4177024598e40c84666cc311a42c256bbf880db3ac99sewardj   161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
4178024598e40c84666cc311a42c256bbf880db3ac99sewardj   382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
4179024598e40c84666cc311a42c256bbf880db3ac99sewardj   98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
4180024598e40c84666cc311a42c256bbf880db3ac99sewardj   227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
4181024598e40c84666cc311a42c256bbf880db3ac99sewardj   469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
4182024598e40c84666cc311a42c256bbf880db3ac99sewardj   184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
4183024598e40c84666cc311a42c256bbf880db3ac99sewardj   715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
4184024598e40c84666cc311a42c256bbf880db3ac99sewardj   951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
4185024598e40c84666cc311a42c256bbf880db3ac99sewardj   652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
4186024598e40c84666cc311a42c256bbf880db3ac99sewardj   645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
4187024598e40c84666cc311a42c256bbf880db3ac99sewardj   609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
4188024598e40c84666cc311a42c256bbf880db3ac99sewardj   653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
4189024598e40c84666cc311a42c256bbf880db3ac99sewardj   411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
4190024598e40c84666cc311a42c256bbf880db3ac99sewardj   170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
4191024598e40c84666cc311a42c256bbf880db3ac99sewardj   857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
4192024598e40c84666cc311a42c256bbf880db3ac99sewardj   669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
4193024598e40c84666cc311a42c256bbf880db3ac99sewardj   944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
4194024598e40c84666cc311a42c256bbf880db3ac99sewardj   344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
4195024598e40c84666cc311a42c256bbf880db3ac99sewardj   897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
4196024598e40c84666cc311a42c256bbf880db3ac99sewardj   433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
4197024598e40c84666cc311a42c256bbf880db3ac99sewardj   686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
4198024598e40c84666cc311a42c256bbf880db3ac99sewardj   946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
4199024598e40c84666cc311a42c256bbf880db3ac99sewardj   978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
4200024598e40c84666cc311a42c256bbf880db3ac99sewardj   680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
4201024598e40c84666cc311a42c256bbf880db3ac99sewardj   707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
4202024598e40c84666cc311a42c256bbf880db3ac99sewardj   297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
4203024598e40c84666cc311a42c256bbf880db3ac99sewardj   134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
4204024598e40c84666cc311a42c256bbf880db3ac99sewardj   343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
4205024598e40c84666cc311a42c256bbf880db3ac99sewardj   140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
4206024598e40c84666cc311a42c256bbf880db3ac99sewardj   170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
4207024598e40c84666cc311a42c256bbf880db3ac99sewardj   369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
4208024598e40c84666cc311a42c256bbf880db3ac99sewardj   804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
4209024598e40c84666cc311a42c256bbf880db3ac99sewardj   896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
4210024598e40c84666cc311a42c256bbf880db3ac99sewardj   661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
4211024598e40c84666cc311a42c256bbf880db3ac99sewardj   768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
4212024598e40c84666cc311a42c256bbf880db3ac99sewardj   61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
4213024598e40c84666cc311a42c256bbf880db3ac99sewardj   372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
4214024598e40c84666cc311a42c256bbf880db3ac99sewardj   780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
4215024598e40c84666cc311a42c256bbf880db3ac99sewardj   920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
4216024598e40c84666cc311a42c256bbf880db3ac99sewardj   645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
4217024598e40c84666cc311a42c256bbf880db3ac99sewardj   936, 638
4218024598e40c84666cc311a42c256bbf880db3ac99sewardj};
4219024598e40c84666cc311a42c256bbf880db3ac99sewardj
4220024598e40c84666cc311a42c256bbf880db3ac99sewardj
4221024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4222024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                       randtable.c ---*/
4223024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4224024598e40c84666cc311a42c256bbf880db3ac99sewardj
4225024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4226024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Table for doing CRCs                                  ---*/
4227024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                            crctable.c ---*/
4228024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4229024598e40c84666cc311a42c256bbf880db3ac99sewardj
4230024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
4231024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
4232024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
4233024598e40c84666cc311a42c256bbf880db3ac99sewardj
4234024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4235024598e40c84666cc311a42c256bbf880db3ac99sewardj
4236024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
4237024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
4238024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
4239024598e40c84666cc311a42c256bbf880db3ac99sewardj
4240024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
4241024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
4242024598e40c84666cc311a42c256bbf880db3ac99sewardj
4243024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
4244024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
4245024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
4246024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
4247024598e40c84666cc311a42c256bbf880db3ac99sewardj
4248024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
4249024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
4250024598e40c84666cc311a42c256bbf880db3ac99sewardj
4251024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
4252024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
4253024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
4254024598e40c84666cc311a42c256bbf880db3ac99sewardj
4255024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4256024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4257024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4258024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4259024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4260024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4261024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4262024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4263024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4264024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4265024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4266024598e40c84666cc311a42c256bbf880db3ac99sewardj
4267024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
4268024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
4269024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
4270024598e40c84666cc311a42c256bbf880db3ac99sewardj
4271024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
4272024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
4273024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
4274024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
4275024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
4276024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
4277024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
4278024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
4279024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
4280024598e40c84666cc311a42c256bbf880db3ac99sewardj
4281024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
4282024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
4283024598e40c84666cc311a42c256bbf880db3ac99sewardj
4284024598e40c84666cc311a42c256bbf880db3ac99sewardj
4285024598e40c84666cc311a42c256bbf880db3ac99sewardj
4286024598e40c84666cc311a42c256bbf880db3ac99sewardj
4287024598e40c84666cc311a42c256bbf880db3ac99sewardj
4288024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
4289024598e40c84666cc311a42c256bbf880db3ac99sewardj  I think this is an implementation of the AUTODIN-II,
4290024598e40c84666cc311a42c256bbf880db3ac99sewardj  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
4291024598e40c84666cc311a42c256bbf880db3ac99sewardj  from code by Rob Warnock, in Section 51 of the
4292024598e40c84666cc311a42c256bbf880db3ac99sewardj  comp.compression FAQ.
4293024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
4294024598e40c84666cc311a42c256bbf880db3ac99sewardj
4295024598e40c84666cc311a42c256bbf880db3ac99sewardjUInt32 BZ2_crc32Table[256] = {
4296024598e40c84666cc311a42c256bbf880db3ac99sewardj
4297024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- Ugly, innit? --*/
4298024598e40c84666cc311a42c256bbf880db3ac99sewardj
4299024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
4300024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
4301024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
4302024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
4303024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
4304024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
4305024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
4306024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
4307024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
4308024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
4309024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
4310024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
4311024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
4312024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
4313024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
4314024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
4315024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
4316024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
4317024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
4318024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
4319024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
4320024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
4321024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
4322024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
4323024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
4324024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
4325024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
4326024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
4327024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
4328024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
4329024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
4330024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
4331024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
4332024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
4333024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
4334024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
4335024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
4336024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
4337024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
4338024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
4339024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
4340024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
4341024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
4342024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
4343024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
4344024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
4345024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
4346024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
4347024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
4348024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
4349024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
4350024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
4351024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
4352024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
4353024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
4354024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
4355024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
4356024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
4357024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
4358024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
4359024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
4360024598e40c84666cc311a42c256bbf880db3ac99sewardj   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
4361024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
4362024598e40c84666cc311a42c256bbf880db3ac99sewardj   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
4363024598e40c84666cc311a42c256bbf880db3ac99sewardj};
4364024598e40c84666cc311a42c256bbf880db3ac99sewardj
4365024598e40c84666cc311a42c256bbf880db3ac99sewardj
4366024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4367024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                        crctable.c ---*/
4368024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4369024598e40c84666cc311a42c256bbf880db3ac99sewardj
4370024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4371024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Library top-level functions.                          ---*/
4372024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---                                               bzlib.c ---*/
4373024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
4374024598e40c84666cc311a42c256bbf880db3ac99sewardj
4375024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
4376024598e40c84666cc311a42c256bbf880db3ac99sewardj  This file is a part of bzip2 and/or libbzip2, a program and
4377024598e40c84666cc311a42c256bbf880db3ac99sewardj  library for lossless, block-sorting data compression.
4378024598e40c84666cc311a42c256bbf880db3ac99sewardj
4379024598e40c84666cc311a42c256bbf880db3ac99sewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4380024598e40c84666cc311a42c256bbf880db3ac99sewardj
4381024598e40c84666cc311a42c256bbf880db3ac99sewardj  Redistribution and use in source and binary forms, with or without
4382024598e40c84666cc311a42c256bbf880db3ac99sewardj  modification, are permitted provided that the following conditions
4383024598e40c84666cc311a42c256bbf880db3ac99sewardj  are met:
4384024598e40c84666cc311a42c256bbf880db3ac99sewardj
4385024598e40c84666cc311a42c256bbf880db3ac99sewardj  1. Redistributions of source code must retain the above copyright
4386024598e40c84666cc311a42c256bbf880db3ac99sewardj     notice, this list of conditions and the following disclaimer.
4387024598e40c84666cc311a42c256bbf880db3ac99sewardj
4388024598e40c84666cc311a42c256bbf880db3ac99sewardj  2. The origin of this software must not be misrepresented; you must
4389024598e40c84666cc311a42c256bbf880db3ac99sewardj     not claim that you wrote the original software.  If you use this
4390024598e40c84666cc311a42c256bbf880db3ac99sewardj     software in a product, an acknowledgment in the product
4391024598e40c84666cc311a42c256bbf880db3ac99sewardj     documentation would be appreciated but is not required.
4392024598e40c84666cc311a42c256bbf880db3ac99sewardj
4393024598e40c84666cc311a42c256bbf880db3ac99sewardj  3. Altered source versions must be plainly marked as such, and must
4394024598e40c84666cc311a42c256bbf880db3ac99sewardj     not be misrepresented as being the original software.
4395024598e40c84666cc311a42c256bbf880db3ac99sewardj
4396024598e40c84666cc311a42c256bbf880db3ac99sewardj  4. The name of the author may not be used to endorse or promote
4397024598e40c84666cc311a42c256bbf880db3ac99sewardj     products derived from this software without specific prior written
4398024598e40c84666cc311a42c256bbf880db3ac99sewardj     permission.
4399024598e40c84666cc311a42c256bbf880db3ac99sewardj
4400024598e40c84666cc311a42c256bbf880db3ac99sewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4401024598e40c84666cc311a42c256bbf880db3ac99sewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4402024598e40c84666cc311a42c256bbf880db3ac99sewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4403024598e40c84666cc311a42c256bbf880db3ac99sewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4404024598e40c84666cc311a42c256bbf880db3ac99sewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4405024598e40c84666cc311a42c256bbf880db3ac99sewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4406024598e40c84666cc311a42c256bbf880db3ac99sewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4407024598e40c84666cc311a42c256bbf880db3ac99sewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4408024598e40c84666cc311a42c256bbf880db3ac99sewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4409024598e40c84666cc311a42c256bbf880db3ac99sewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4410024598e40c84666cc311a42c256bbf880db3ac99sewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4411024598e40c84666cc311a42c256bbf880db3ac99sewardj
4412024598e40c84666cc311a42c256bbf880db3ac99sewardj  Julian Seward, Cambridge, UK.
4413024598e40c84666cc311a42c256bbf880db3ac99sewardj  jseward@bzip.org
4414024598e40c84666cc311a42c256bbf880db3ac99sewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
4415024598e40c84666cc311a42c256bbf880db3ac99sewardj
4416024598e40c84666cc311a42c256bbf880db3ac99sewardj  This program is based on (at least) the work of:
4417024598e40c84666cc311a42c256bbf880db3ac99sewardj     Mike Burrows
4418024598e40c84666cc311a42c256bbf880db3ac99sewardj     David Wheeler
4419024598e40c84666cc311a42c256bbf880db3ac99sewardj     Peter Fenwick
4420024598e40c84666cc311a42c256bbf880db3ac99sewardj     Alistair Moffat
4421024598e40c84666cc311a42c256bbf880db3ac99sewardj     Radford Neal
4422024598e40c84666cc311a42c256bbf880db3ac99sewardj     Ian H. Witten
4423024598e40c84666cc311a42c256bbf880db3ac99sewardj     Robert Sedgewick
4424024598e40c84666cc311a42c256bbf880db3ac99sewardj     Jon L. Bentley
4425024598e40c84666cc311a42c256bbf880db3ac99sewardj
4426024598e40c84666cc311a42c256bbf880db3ac99sewardj  For more information on these sources, see the manual.
4427024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
4428024598e40c84666cc311a42c256bbf880db3ac99sewardj
4429024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
4430024598e40c84666cc311a42c256bbf880db3ac99sewardj   CHANGES
4431024598e40c84666cc311a42c256bbf880db3ac99sewardj   ~~~~~~~
4432024598e40c84666cc311a42c256bbf880db3ac99sewardj   0.9.0 -- original version.
4433024598e40c84666cc311a42c256bbf880db3ac99sewardj
4434024598e40c84666cc311a42c256bbf880db3ac99sewardj   0.9.0a/b -- no changes in this file.
4435024598e40c84666cc311a42c256bbf880db3ac99sewardj
4436024598e40c84666cc311a42c256bbf880db3ac99sewardj   0.9.0c
4437024598e40c84666cc311a42c256bbf880db3ac99sewardj      * made zero-length BZ_FLUSH work correctly in bzCompress().
4438024598e40c84666cc311a42c256bbf880db3ac99sewardj      * fixed bzWrite/bzRead to ignore zero-length requests.
4439024598e40c84666cc311a42c256bbf880db3ac99sewardj      * fixed bzread to correctly handle read requests after EOF.
4440024598e40c84666cc311a42c256bbf880db3ac99sewardj      * wrong parameter order in call to bzDecompressInit in
4441024598e40c84666cc311a42c256bbf880db3ac99sewardj        bzBuffToBuffDecompress.  Fixed.
4442024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
4443024598e40c84666cc311a42c256bbf880db3ac99sewardj
4444024598e40c84666cc311a42c256bbf880db3ac99sewardj
4445024598e40c84666cc311a42c256bbf880db3ac99sewardj
4446024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4447024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Compression stuff                           ---*/
4448024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4449024598e40c84666cc311a42c256bbf880db3ac99sewardj
4450024598e40c84666cc311a42c256bbf880db3ac99sewardj
4451024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4452024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ2_bz__AssertH__fail ( int errcode )
4453024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4454024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf("BZ2_bz__AssertH__fail(%d) called, exiting\n", errcode);
4455024598e40c84666cc311a42c256bbf880db3ac99sewardj   (*serviceFn)(0,0);
4456024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4457024598e40c84666cc311a42c256bbf880db3ac99sewardj
4458024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid bz_internal_error ( int errcode )
4459024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4460024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf("bz_internal_error called, exiting\n", errcode);
4461024598e40c84666cc311a42c256bbf880db3ac99sewardj   (*serviceFn)(0,0);
4462024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4463024598e40c84666cc311a42c256bbf880db3ac99sewardj
4464024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4465024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4466024598e40c84666cc311a42c256bbf880db3ac99sewardjint bz_config_ok ( void )
4467024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4468024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (sizeof(int)   != 4) return 0;
4469024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (sizeof(short) != 2) return 0;
4470024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (sizeof(char)  != 1) return 0;
4471024598e40c84666cc311a42c256bbf880db3ac99sewardj   return 1;
4472024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4473024598e40c84666cc311a42c256bbf880db3ac99sewardj
4474024598e40c84666cc311a42c256bbf880db3ac99sewardj
4475024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4476024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4477024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid* default_bzalloc ( void* opaque, Int32 items, Int32 size )
4478024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4479024598e40c84666cc311a42c256bbf880db3ac99sewardj   void* v = (void*) (*serviceFn)(2, items * size );
4480024598e40c84666cc311a42c256bbf880db3ac99sewardj   return v;
4481024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4482024598e40c84666cc311a42c256bbf880db3ac99sewardj
4483024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4484024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid default_bzfree ( void* opaque, void* addr )
4485024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4486024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (addr != NULL) (*serviceFn)( 3, (HWord)addr );
4487024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4488024598e40c84666cc311a42c256bbf880db3ac99sewardj
4489024598e40c84666cc311a42c256bbf880db3ac99sewardj
4490024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4491024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4492024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid prepare_new_block ( EState* s )
4493024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4494024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 i;
4495024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->nblock = 0;
4496024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->numZ = 0;
4497024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->state_out_pos = 0;
4498024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_INITIALISE_CRC ( s->blockCRC );
4499024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < 256; i++) s->inUse[i] = False;
4500024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->blockNo++;
4501024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4502024598e40c84666cc311a42c256bbf880db3ac99sewardj
4503024598e40c84666cc311a42c256bbf880db3ac99sewardj
4504024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4505024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4506024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid init_RL ( EState* s )
4507024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4508024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->state_in_ch  = 256;
4509024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->state_in_len = 0;
4510024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4511024598e40c84666cc311a42c256bbf880db3ac99sewardj
4512024598e40c84666cc311a42c256bbf880db3ac99sewardj
4513024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4514024598e40c84666cc311a42c256bbf880db3ac99sewardjBool isempty_RL ( EState* s )
4515024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4516024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->state_in_ch < 256 && s->state_in_len > 0)
4517024598e40c84666cc311a42c256bbf880db3ac99sewardj      return False; else
4518024598e40c84666cc311a42c256bbf880db3ac99sewardj      return True;
4519024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4520024598e40c84666cc311a42c256bbf880db3ac99sewardj
4521024598e40c84666cc311a42c256bbf880db3ac99sewardj
4522024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4523024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzCompressInit)
4524024598e40c84666cc311a42c256bbf880db3ac99sewardj                    ( bz_stream* strm,
4525024598e40c84666cc311a42c256bbf880db3ac99sewardj                     int        blockSize100k,
4526024598e40c84666cc311a42c256bbf880db3ac99sewardj                     int        verbosity,
4527024598e40c84666cc311a42c256bbf880db3ac99sewardj                     int        workFactor )
4528024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4529024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   n;
4530024598e40c84666cc311a42c256bbf880db3ac99sewardj   EState* s;
4531024598e40c84666cc311a42c256bbf880db3ac99sewardj
4532024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
4533024598e40c84666cc311a42c256bbf880db3ac99sewardj
4534024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm == NULL ||
4535024598e40c84666cc311a42c256bbf880db3ac99sewardj       blockSize100k < 1 || blockSize100k > 9 ||
4536024598e40c84666cc311a42c256bbf880db3ac99sewardj       workFactor < 0 || workFactor > 250)
4537024598e40c84666cc311a42c256bbf880db3ac99sewardj     return BZ_PARAM_ERROR;
4538024598e40c84666cc311a42c256bbf880db3ac99sewardj
4539024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (workFactor == 0) workFactor = 30;
4540024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
4541024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
4542024598e40c84666cc311a42c256bbf880db3ac99sewardj
4543024598e40c84666cc311a42c256bbf880db3ac99sewardj   s = BZALLOC( sizeof(EState) );
4544024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s == NULL) return BZ_MEM_ERROR;
4545024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->strm = strm;
4546024598e40c84666cc311a42c256bbf880db3ac99sewardj
4547024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->arr1 = NULL;
4548024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->arr2 = NULL;
4549024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->ftab = NULL;
4550024598e40c84666cc311a42c256bbf880db3ac99sewardj
4551024598e40c84666cc311a42c256bbf880db3ac99sewardj   n       = 100000 * blockSize100k;
4552024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
4553024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
4554024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
4555024598e40c84666cc311a42c256bbf880db3ac99sewardj
4556024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
4557024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->arr1 != NULL) BZFREE(s->arr1);
4558024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->arr2 != NULL) BZFREE(s->arr2);
4559024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->ftab != NULL) BZFREE(s->ftab);
4560024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s       != NULL) BZFREE(s);
4561024598e40c84666cc311a42c256bbf880db3ac99sewardj      return BZ_MEM_ERROR;
4562024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4563024598e40c84666cc311a42c256bbf880db3ac99sewardj
4564024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->blockNo           = 0;
4565024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->state             = BZ_S_INPUT;
4566024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->mode              = BZ_M_RUNNING;
4567024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->combinedCRC       = 0;
4568024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->blockSize100k     = blockSize100k;
4569024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->nblockMAX         = 100000 * blockSize100k - 19;
4570024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->verbosity         = verbosity;
4571024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->workFactor        = workFactor;
4572024598e40c84666cc311a42c256bbf880db3ac99sewardj
4573024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->block             = (UChar*)s->arr2;
4574024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->mtfv              = (UInt16*)s->arr1;
4575024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->zbits             = NULL;
4576024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->ptr               = (UInt32*)s->arr1;
4577024598e40c84666cc311a42c256bbf880db3ac99sewardj
4578024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->state          = s;
4579024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_in_lo32  = 0;
4580024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_in_hi32  = 0;
4581024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_out_lo32 = 0;
4582024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_out_hi32 = 0;
4583024598e40c84666cc311a42c256bbf880db3ac99sewardj   init_RL ( s );
4584024598e40c84666cc311a42c256bbf880db3ac99sewardj   prepare_new_block ( s );
4585024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OK;
4586024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4587024598e40c84666cc311a42c256bbf880db3ac99sewardj
4588024598e40c84666cc311a42c256bbf880db3ac99sewardj
4589024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4590024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4591024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid add_pair_to_block ( EState* s )
4592024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4593024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 i;
4594024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar ch = (UChar)(s->state_in_ch);
4595024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < s->state_in_len; i++) {
4596024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ_UPDATE_CRC( s->blockCRC, ch );
4597024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4598024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->inUse[s->state_in_ch] = True;
4599024598e40c84666cc311a42c256bbf880db3ac99sewardj   switch (s->state_in_len) {
4600024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 1:
4601024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4602024598e40c84666cc311a42c256bbf880db3ac99sewardj         break;
4603024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 2:
4604024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4605024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4606024598e40c84666cc311a42c256bbf880db3ac99sewardj         break;
4607024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 3:
4608024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4609024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4610024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4611024598e40c84666cc311a42c256bbf880db3ac99sewardj         break;
4612024598e40c84666cc311a42c256bbf880db3ac99sewardj      default:
4613024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->inUse[s->state_in_len-4] = True;
4614024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4615024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4616024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4617024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
4618024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
4619024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->nblock++;
4620024598e40c84666cc311a42c256bbf880db3ac99sewardj         break;
4621024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4622024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4623024598e40c84666cc311a42c256bbf880db3ac99sewardj
4624024598e40c84666cc311a42c256bbf880db3ac99sewardj
4625024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4626024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4627024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid flush_RL ( EState* s )
4628024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4629024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->state_in_ch < 256) add_pair_to_block ( s );
4630024598e40c84666cc311a42c256bbf880db3ac99sewardj   init_RL ( s );
4631024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4632024598e40c84666cc311a42c256bbf880db3ac99sewardj
4633024598e40c84666cc311a42c256bbf880db3ac99sewardj
4634024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4635024598e40c84666cc311a42c256bbf880db3ac99sewardj#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
4636024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                                 \
4637024598e40c84666cc311a42c256bbf880db3ac99sewardj   UInt32 zchh = (UInt32)(zchh0);                 \
4638024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- fast track the common case --*/           \
4639024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (zchh != zs->state_in_ch &&                 \
4640024598e40c84666cc311a42c256bbf880db3ac99sewardj       zs->state_in_len == 1) {                   \
4641024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar ch = (UChar)(zs->state_in_ch);        \
4642024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
4643024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->inUse[zs->state_in_ch] = True;          \
4644024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->block[zs->nblock] = (UChar)ch;          \
4645024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->nblock++;                               \
4646024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->state_in_ch = zchh;                     \
4647024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                              \
4648024598e40c84666cc311a42c256bbf880db3ac99sewardj   else                                           \
4649024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*-- general, uncommon cases --*/              \
4650024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (zchh != zs->state_in_ch ||                 \
4651024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->state_in_len == 255) {                  \
4652024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (zs->state_in_ch < 256)                  \
4653024598e40c84666cc311a42c256bbf880db3ac99sewardj         add_pair_to_block ( zs );                \
4654024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->state_in_ch = zchh;                     \
4655024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->state_in_len = 1;                       \
4656024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {                                       \
4657024598e40c84666cc311a42c256bbf880db3ac99sewardj      zs->state_in_len++;                         \
4658024598e40c84666cc311a42c256bbf880db3ac99sewardj   }                                              \
4659024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4660024598e40c84666cc311a42c256bbf880db3ac99sewardj
4661024598e40c84666cc311a42c256bbf880db3ac99sewardj
4662024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4663024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4664024598e40c84666cc311a42c256bbf880db3ac99sewardjBool copy_input_until_stop ( EState* s )
4665024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4666024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool progress_in = False;
4667024598e40c84666cc311a42c256bbf880db3ac99sewardj
4668024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->mode == BZ_M_RUNNING) {
4669024598e40c84666cc311a42c256bbf880db3ac99sewardj
4670024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- fast track the common case --*/
4671024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
4672024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- block full? --*/
4673024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock >= s->nblockMAX) break;
4674024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- no input? --*/
4675024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->strm->avail_in == 0) break;
4676024598e40c84666cc311a42c256bbf880db3ac99sewardj         progress_in = True;
4677024598e40c84666cc311a42c256bbf880db3ac99sewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
4678024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->next_in++;
4679024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->avail_in--;
4680024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->total_in_lo32++;
4681024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
4682024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
4683024598e40c84666cc311a42c256bbf880db3ac99sewardj
4684024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
4685024598e40c84666cc311a42c256bbf880db3ac99sewardj
4686024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- general, uncommon case --*/
4687024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
4688024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- block full? --*/
4689024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock >= s->nblockMAX) break;
4690024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- no input? --*/
4691024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->strm->avail_in == 0) break;
4692024598e40c84666cc311a42c256bbf880db3ac99sewardj         /*-- flush/finish end? --*/
4693024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->avail_in_expect == 0) break;
4694024598e40c84666cc311a42c256bbf880db3ac99sewardj         progress_in = True;
4695024598e40c84666cc311a42c256bbf880db3ac99sewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
4696024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->next_in++;
4697024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->avail_in--;
4698024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->total_in_lo32++;
4699024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
4700024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->avail_in_expect--;
4701024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
4702024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4703024598e40c84666cc311a42c256bbf880db3ac99sewardj   return progress_in;
4704024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4705024598e40c84666cc311a42c256bbf880db3ac99sewardj
4706024598e40c84666cc311a42c256bbf880db3ac99sewardj
4707024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4708024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4709024598e40c84666cc311a42c256bbf880db3ac99sewardjBool copy_output_until_stop ( EState* s )
4710024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4711024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool progress_out = False;
4712024598e40c84666cc311a42c256bbf880db3ac99sewardj
4713024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
4714024598e40c84666cc311a42c256bbf880db3ac99sewardj
4715024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- no output space? --*/
4716024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->strm->avail_out == 0) break;
4717024598e40c84666cc311a42c256bbf880db3ac99sewardj
4718024598e40c84666cc311a42c256bbf880db3ac99sewardj      /*-- block done? --*/
4719024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->state_out_pos >= s->numZ) break;
4720024598e40c84666cc311a42c256bbf880db3ac99sewardj
4721024598e40c84666cc311a42c256bbf880db3ac99sewardj      progress_out = True;
4722024598e40c84666cc311a42c256bbf880db3ac99sewardj      *(s->strm->next_out) = s->zbits[s->state_out_pos];
4723024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->state_out_pos++;
4724024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->avail_out--;
4725024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->next_out++;
4726024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->total_out_lo32++;
4727024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
4728024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4729024598e40c84666cc311a42c256bbf880db3ac99sewardj
4730024598e40c84666cc311a42c256bbf880db3ac99sewardj   return progress_out;
4731024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4732024598e40c84666cc311a42c256bbf880db3ac99sewardj
4733024598e40c84666cc311a42c256bbf880db3ac99sewardj
4734024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4735024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4736024598e40c84666cc311a42c256bbf880db3ac99sewardjBool handle_compress ( bz_stream* strm )
4737024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4738024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool progress_in  = False;
4739024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool progress_out = False;
4740024598e40c84666cc311a42c256bbf880db3ac99sewardj   EState* s = strm->state;
4741024598e40c84666cc311a42c256bbf880db3ac99sewardj
4742024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
4743024598e40c84666cc311a42c256bbf880db3ac99sewardj
4744024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->state == BZ_S_OUTPUT) {
4745024598e40c84666cc311a42c256bbf880db3ac99sewardj         progress_out |= copy_output_until_stop ( s );
4746024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->state_out_pos < s->numZ) break;
4747024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->mode == BZ_M_FINISHING &&
4748024598e40c84666cc311a42c256bbf880db3ac99sewardj             s->avail_in_expect == 0 &&
4749024598e40c84666cc311a42c256bbf880db3ac99sewardj             isempty_RL(s)) break;
4750024598e40c84666cc311a42c256bbf880db3ac99sewardj         prepare_new_block ( s );
4751024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state = BZ_S_INPUT;
4752024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->mode == BZ_M_FLUSHING &&
4753024598e40c84666cc311a42c256bbf880db3ac99sewardj             s->avail_in_expect == 0 &&
4754024598e40c84666cc311a42c256bbf880db3ac99sewardj             isempty_RL(s)) break;
4755024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
4756024598e40c84666cc311a42c256bbf880db3ac99sewardj
4757024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->state == BZ_S_INPUT) {
4758024598e40c84666cc311a42c256bbf880db3ac99sewardj         progress_in |= copy_input_until_stop ( s );
4759024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
4760024598e40c84666cc311a42c256bbf880db3ac99sewardj            flush_RL ( s );
4761024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
4762024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->state = BZ_S_OUTPUT;
4763024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4764024598e40c84666cc311a42c256bbf880db3ac99sewardj         else
4765024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock >= s->nblockMAX) {
4766024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ2_compressBlock ( s, False );
4767024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->state = BZ_S_OUTPUT;
4768024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4769024598e40c84666cc311a42c256bbf880db3ac99sewardj         else
4770024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->strm->avail_in == 0) {
4771024598e40c84666cc311a42c256bbf880db3ac99sewardj            break;
4772024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4773024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
4774024598e40c84666cc311a42c256bbf880db3ac99sewardj
4775024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4776024598e40c84666cc311a42c256bbf880db3ac99sewardj
4777024598e40c84666cc311a42c256bbf880db3ac99sewardj   return progress_in || progress_out;
4778024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4779024598e40c84666cc311a42c256bbf880db3ac99sewardj
4780024598e40c84666cc311a42c256bbf880db3ac99sewardj
4781024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4782024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
4783024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4784024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool progress;
4785024598e40c84666cc311a42c256bbf880db3ac99sewardj   EState* s;
4786024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
4787024598e40c84666cc311a42c256bbf880db3ac99sewardj   s = strm->state;
4788024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s == NULL) return BZ_PARAM_ERROR;
4789024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
4790024598e40c84666cc311a42c256bbf880db3ac99sewardj
4791024598e40c84666cc311a42c256bbf880db3ac99sewardj   preswitch:
4792024598e40c84666cc311a42c256bbf880db3ac99sewardj   switch (s->mode) {
4793024598e40c84666cc311a42c256bbf880db3ac99sewardj
4794024598e40c84666cc311a42c256bbf880db3ac99sewardj      case BZ_M_IDLE:
4795024598e40c84666cc311a42c256bbf880db3ac99sewardj         return BZ_SEQUENCE_ERROR;
4796024598e40c84666cc311a42c256bbf880db3ac99sewardj
4797024598e40c84666cc311a42c256bbf880db3ac99sewardj      case BZ_M_RUNNING:
4798024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (action == BZ_RUN) {
4799024598e40c84666cc311a42c256bbf880db3ac99sewardj            progress = handle_compress ( strm );
4800024598e40c84666cc311a42c256bbf880db3ac99sewardj            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
4801024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4802024598e40c84666cc311a42c256bbf880db3ac99sewardj         else
4803024598e40c84666cc311a42c256bbf880db3ac99sewardj	 if (action == BZ_FLUSH) {
4804024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->avail_in_expect = strm->avail_in;
4805024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->mode = BZ_M_FLUSHING;
4806024598e40c84666cc311a42c256bbf880db3ac99sewardj            goto preswitch;
4807024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4808024598e40c84666cc311a42c256bbf880db3ac99sewardj         else
4809024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (action == BZ_FINISH) {
4810024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->avail_in_expect = strm->avail_in;
4811024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->mode = BZ_M_FINISHING;
4812024598e40c84666cc311a42c256bbf880db3ac99sewardj            goto preswitch;
4813024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4814024598e40c84666cc311a42c256bbf880db3ac99sewardj         else
4815024598e40c84666cc311a42c256bbf880db3ac99sewardj            return BZ_PARAM_ERROR;
4816024598e40c84666cc311a42c256bbf880db3ac99sewardj
4817024598e40c84666cc311a42c256bbf880db3ac99sewardj      case BZ_M_FLUSHING:
4818024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
4819024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->avail_in_expect != s->strm->avail_in)
4820024598e40c84666cc311a42c256bbf880db3ac99sewardj            return BZ_SEQUENCE_ERROR;
4821024598e40c84666cc311a42c256bbf880db3ac99sewardj         progress = handle_compress ( strm );
4822024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
4823024598e40c84666cc311a42c256bbf880db3ac99sewardj             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
4824024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->mode = BZ_M_RUNNING;
4825024598e40c84666cc311a42c256bbf880db3ac99sewardj         return BZ_RUN_OK;
4826024598e40c84666cc311a42c256bbf880db3ac99sewardj
4827024598e40c84666cc311a42c256bbf880db3ac99sewardj      case BZ_M_FINISHING:
4828024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
4829024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->avail_in_expect != s->strm->avail_in)
4830024598e40c84666cc311a42c256bbf880db3ac99sewardj            return BZ_SEQUENCE_ERROR;
4831024598e40c84666cc311a42c256bbf880db3ac99sewardj         progress = handle_compress ( strm );
4832024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (!progress) return BZ_SEQUENCE_ERROR;
4833024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
4834024598e40c84666cc311a42c256bbf880db3ac99sewardj             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
4835024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->mode = BZ_M_IDLE;
4836024598e40c84666cc311a42c256bbf880db3ac99sewardj         return BZ_STREAM_END;
4837024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
4838024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OK; /*--not reached--*/
4839024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4840024598e40c84666cc311a42c256bbf880db3ac99sewardj
4841024598e40c84666cc311a42c256bbf880db3ac99sewardj
4842024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4843024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
4844024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4845024598e40c84666cc311a42c256bbf880db3ac99sewardj   EState* s;
4846024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
4847024598e40c84666cc311a42c256bbf880db3ac99sewardj   s = strm->state;
4848024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s == NULL) return BZ_PARAM_ERROR;
4849024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
4850024598e40c84666cc311a42c256bbf880db3ac99sewardj
4851024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->arr1 != NULL) BZFREE(s->arr1);
4852024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->arr2 != NULL) BZFREE(s->arr2);
4853024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->ftab != NULL) BZFREE(s->ftab);
4854024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZFREE(strm->state);
4855024598e40c84666cc311a42c256bbf880db3ac99sewardj
4856024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->state = NULL;
4857024598e40c84666cc311a42c256bbf880db3ac99sewardj
4858024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OK;
4859024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4860024598e40c84666cc311a42c256bbf880db3ac99sewardj
4861024598e40c84666cc311a42c256bbf880db3ac99sewardj
4862024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4863024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Decompression stuff                         ---*/
4864024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4865024598e40c84666cc311a42c256bbf880db3ac99sewardj
4866024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4867024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzDecompressInit)
4868024598e40c84666cc311a42c256bbf880db3ac99sewardj                     ( bz_stream* strm,
4869024598e40c84666cc311a42c256bbf880db3ac99sewardj                       int        verbosity,
4870024598e40c84666cc311a42c256bbf880db3ac99sewardj                       int        small )
4871024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4872024598e40c84666cc311a42c256bbf880db3ac99sewardj   DState* s;
4873024598e40c84666cc311a42c256bbf880db3ac99sewardj
4874024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
4875024598e40c84666cc311a42c256bbf880db3ac99sewardj
4876024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
4877024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
4878024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
4879024598e40c84666cc311a42c256bbf880db3ac99sewardj
4880024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
4881024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
4882024598e40c84666cc311a42c256bbf880db3ac99sewardj
4883024598e40c84666cc311a42c256bbf880db3ac99sewardj   s = BZALLOC( sizeof(DState) );
4884024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s == NULL) return BZ_MEM_ERROR;
4885024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->strm                  = strm;
4886024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->state              = s;
4887024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->state                 = BZ_X_MAGIC_1;
4888024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->bsLive                = 0;
4889024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->bsBuff                = 0;
4890024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->calculatedCombinedCRC = 0;
4891024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_in_lo32      = 0;
4892024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_in_hi32      = 0;
4893024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_out_lo32     = 0;
4894024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->total_out_hi32     = 0;
4895024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->smallDecompress       = (Bool)small;
4896024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->ll4                   = NULL;
4897024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->ll16                  = NULL;
4898024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->tt                    = NULL;
4899024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->currBlockNo           = 0;
4900024598e40c84666cc311a42c256bbf880db3ac99sewardj   s->verbosity             = verbosity;
4901024598e40c84666cc311a42c256bbf880db3ac99sewardj
4902024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OK;
4903024598e40c84666cc311a42c256bbf880db3ac99sewardj}
4904024598e40c84666cc311a42c256bbf880db3ac99sewardj
4905024598e40c84666cc311a42c256bbf880db3ac99sewardj
4906024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
4907024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Return  True iff data corruption is discovered.
4908024598e40c84666cc311a42c256bbf880db3ac99sewardj   Returns False if there is no problem.
4909024598e40c84666cc311a42c256bbf880db3ac99sewardj*/
4910024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
4911024598e40c84666cc311a42c256bbf880db3ac99sewardjBool unRLE_obuf_to_output_FAST ( DState* s )
4912024598e40c84666cc311a42c256bbf880db3ac99sewardj{
4913024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar k1;
4914024598e40c84666cc311a42c256bbf880db3ac99sewardj
4915024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->blockRandomised) {
4916024598e40c84666cc311a42c256bbf880db3ac99sewardj
4917024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
4918024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* try to finish existing run */
4919024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (True) {
4920024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->strm->avail_out == 0) return False;
4921024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->state_out_len == 0) break;
4922024598e40c84666cc311a42c256bbf880db3ac99sewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
4923024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
4924024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->state_out_len--;
4925024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->next_out++;
4926024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->avail_out--;
4927024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->total_out_lo32++;
4928024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
4929024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
4930024598e40c84666cc311a42c256bbf880db3ac99sewardj
4931024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* can a new run be started? */
4932024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) return False;
4933024598e40c84666cc311a42c256bbf880db3ac99sewardj
4934024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* Only caused by corrupt data stream? */
4935024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used > s->save_nblock+1)
4936024598e40c84666cc311a42c256bbf880db3ac99sewardj            return True;
4937024598e40c84666cc311a42c256bbf880db3ac99sewardj
4938024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 1;
4939024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_ch = s->k0;
4940024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4941024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4942024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
4943024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
4944024598e40c84666cc311a42c256bbf880db3ac99sewardj
4945024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 2;
4946024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4947024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4948024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
4949024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
4950024598e40c84666cc311a42c256bbf880db3ac99sewardj
4951024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 3;
4952024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4953024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4954024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
4955024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
4956024598e40c84666cc311a42c256bbf880db3ac99sewardj
4957024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4958024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
4959024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = ((Int32)k1) + 4;
4960024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
4961024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
4962024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
4963024598e40c84666cc311a42c256bbf880db3ac99sewardj
4964024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
4965024598e40c84666cc311a42c256bbf880db3ac99sewardj
4966024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* restore */
4967024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
4968024598e40c84666cc311a42c256bbf880db3ac99sewardj      UChar         c_state_out_ch       = s->state_out_ch;
4969024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32         c_state_out_len      = s->state_out_len;
4970024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32         c_nblock_used        = s->nblock_used;
4971024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32         c_k0                 = s->k0;
4972024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32*       c_tt                 = s->tt;
4973024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32        c_tPos               = s->tPos;
4974024598e40c84666cc311a42c256bbf880db3ac99sewardj      char*         cs_next_out          = s->strm->next_out;
4975024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int  cs_avail_out         = s->strm->avail_out;
4976024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* end restore */
4977024598e40c84666cc311a42c256bbf880db3ac99sewardj
4978024598e40c84666cc311a42c256bbf880db3ac99sewardj      UInt32       avail_out_INIT = cs_avail_out;
4979024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32        s_save_nblockPP = s->save_nblock+1;
4980024598e40c84666cc311a42c256bbf880db3ac99sewardj      unsigned int total_out_lo32_old;
4981024598e40c84666cc311a42c256bbf880db3ac99sewardj
4982024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
4983024598e40c84666cc311a42c256bbf880db3ac99sewardj
4984024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* try to finish existing run */
4985024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (c_state_out_len > 0) {
4986024598e40c84666cc311a42c256bbf880db3ac99sewardj            while (True) {
4987024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (cs_avail_out == 0) goto return_notr;
4988024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (c_state_out_len == 1) break;
4989024598e40c84666cc311a42c256bbf880db3ac99sewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
4990024598e40c84666cc311a42c256bbf880db3ac99sewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
4991024598e40c84666cc311a42c256bbf880db3ac99sewardj               c_state_out_len--;
4992024598e40c84666cc311a42c256bbf880db3ac99sewardj               cs_next_out++;
4993024598e40c84666cc311a42c256bbf880db3ac99sewardj               cs_avail_out--;
4994024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
4995024598e40c84666cc311a42c256bbf880db3ac99sewardj            s_state_out_len_eq_one:
4996024598e40c84666cc311a42c256bbf880db3ac99sewardj            {
4997024598e40c84666cc311a42c256bbf880db3ac99sewardj               if (cs_avail_out == 0) {
4998024598e40c84666cc311a42c256bbf880db3ac99sewardj                  c_state_out_len = 1; goto return_notr;
4999024598e40c84666cc311a42c256bbf880db3ac99sewardj               };
5000024598e40c84666cc311a42c256bbf880db3ac99sewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
5001024598e40c84666cc311a42c256bbf880db3ac99sewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
5002024598e40c84666cc311a42c256bbf880db3ac99sewardj               cs_next_out++;
5003024598e40c84666cc311a42c256bbf880db3ac99sewardj               cs_avail_out--;
5004024598e40c84666cc311a42c256bbf880db3ac99sewardj            }
5005024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
5006024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* Only caused by corrupt data stream? */
5007024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (c_nblock_used > s_save_nblockPP)
5008024598e40c84666cc311a42c256bbf880db3ac99sewardj            return True;
5009024598e40c84666cc311a42c256bbf880db3ac99sewardj
5010024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* can a new run be started? */
5011024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (c_nblock_used == s_save_nblockPP) {
5012024598e40c84666cc311a42c256bbf880db3ac99sewardj            c_state_out_len = 0; goto return_notr;
5013024598e40c84666cc311a42c256bbf880db3ac99sewardj         };
5014024598e40c84666cc311a42c256bbf880db3ac99sewardj         c_state_out_ch = c_k0;
5015024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5016024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != c_k0) {
5017024598e40c84666cc311a42c256bbf880db3ac99sewardj            c_k0 = k1; goto s_state_out_len_eq_one;
5018024598e40c84666cc311a42c256bbf880db3ac99sewardj         };
5019024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (c_nblock_used == s_save_nblockPP)
5020024598e40c84666cc311a42c256bbf880db3ac99sewardj            goto s_state_out_len_eq_one;
5021024598e40c84666cc311a42c256bbf880db3ac99sewardj
5022024598e40c84666cc311a42c256bbf880db3ac99sewardj         c_state_out_len = 2;
5023024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5024024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (c_nblock_used == s_save_nblockPP) continue;
5025024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
5026024598e40c84666cc311a42c256bbf880db3ac99sewardj
5027024598e40c84666cc311a42c256bbf880db3ac99sewardj         c_state_out_len = 3;
5028024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5029024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (c_nblock_used == s_save_nblockPP) continue;
5030024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
5031024598e40c84666cc311a42c256bbf880db3ac99sewardj
5032024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
5033024598e40c84666cc311a42c256bbf880db3ac99sewardj         c_state_out_len = ((Int32)k1) + 4;
5034024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_FAST_C(c_k0); c_nblock_used++;
5035024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5036024598e40c84666cc311a42c256bbf880db3ac99sewardj
5037024598e40c84666cc311a42c256bbf880db3ac99sewardj      return_notr:
5038024598e40c84666cc311a42c256bbf880db3ac99sewardj      total_out_lo32_old = s->strm->total_out_lo32;
5039024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
5040024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->strm->total_out_lo32 < total_out_lo32_old)
5041024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->strm->total_out_hi32++;
5042024598e40c84666cc311a42c256bbf880db3ac99sewardj
5043024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* save */
5044024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->calculatedBlockCRC = c_calculatedBlockCRC;
5045024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->state_out_ch       = c_state_out_ch;
5046024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->state_out_len      = c_state_out_len;
5047024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->nblock_used        = c_nblock_used;
5048024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->k0                 = c_k0;
5049024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->tt                 = c_tt;
5050024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->tPos               = c_tPos;
5051024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->next_out     = cs_next_out;
5052024598e40c84666cc311a42c256bbf880db3ac99sewardj      s->strm->avail_out    = cs_avail_out;
5053024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* end save */
5054024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5055024598e40c84666cc311a42c256bbf880db3ac99sewardj   return False;
5056024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5057024598e40c84666cc311a42c256bbf880db3ac99sewardj
5058024598e40c84666cc311a42c256bbf880db3ac99sewardj
5059024598e40c84666cc311a42c256bbf880db3ac99sewardj
5060024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5061024598e40c84666cc311a42c256bbf880db3ac99sewardj/* Return  True iff data corruption is discovered.
5062024598e40c84666cc311a42c256bbf880db3ac99sewardj   Returns False if there is no problem.
5063024598e40c84666cc311a42c256bbf880db3ac99sewardj*/
5064024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
5065024598e40c84666cc311a42c256bbf880db3ac99sewardjBool unRLE_obuf_to_output_SMALL ( DState* s )
5066024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5067024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar k1;
5068024598e40c84666cc311a42c256bbf880db3ac99sewardj
5069024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->blockRandomised) {
5070024598e40c84666cc311a42c256bbf880db3ac99sewardj
5071024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
5072024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* try to finish existing run */
5073024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (True) {
5074024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->strm->avail_out == 0) return False;
5075024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->state_out_len == 0) break;
5076024598e40c84666cc311a42c256bbf880db3ac99sewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
5077024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
5078024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->state_out_len--;
5079024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->next_out++;
5080024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->avail_out--;
5081024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->total_out_lo32++;
5082024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
5083024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
5084024598e40c84666cc311a42c256bbf880db3ac99sewardj
5085024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* can a new run be started? */
5086024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) return False;
5087024598e40c84666cc311a42c256bbf880db3ac99sewardj
5088024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* Only caused by corrupt data stream? */
5089024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used > s->save_nblock+1)
5090024598e40c84666cc311a42c256bbf880db3ac99sewardj            return True;
5091024598e40c84666cc311a42c256bbf880db3ac99sewardj
5092024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 1;
5093024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_ch = s->k0;
5094024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5095024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5096024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5097024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5098024598e40c84666cc311a42c256bbf880db3ac99sewardj
5099024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 2;
5100024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5101024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5102024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5103024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5104024598e40c84666cc311a42c256bbf880db3ac99sewardj
5105024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 3;
5106024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5107024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5108024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5109024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5110024598e40c84666cc311a42c256bbf880db3ac99sewardj
5111024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5112024598e40c84666cc311a42c256bbf880db3ac99sewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
5113024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = ((Int32)k1) + 4;
5114024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
5115024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
5116024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5117024598e40c84666cc311a42c256bbf880db3ac99sewardj
5118024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
5119024598e40c84666cc311a42c256bbf880db3ac99sewardj
5120024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
5121024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* try to finish existing run */
5122024598e40c84666cc311a42c256bbf880db3ac99sewardj         while (True) {
5123024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->strm->avail_out == 0) return False;
5124024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->state_out_len == 0) break;
5125024598e40c84666cc311a42c256bbf880db3ac99sewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
5126024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
5127024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->state_out_len--;
5128024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->next_out++;
5129024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->avail_out--;
5130024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->strm->total_out_lo32++;
5131024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
5132024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
5133024598e40c84666cc311a42c256bbf880db3ac99sewardj
5134024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* can a new run be started? */
5135024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) return False;
5136024598e40c84666cc311a42c256bbf880db3ac99sewardj
5137024598e40c84666cc311a42c256bbf880db3ac99sewardj         /* Only caused by corrupt data stream? */
5138024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used > s->save_nblock+1)
5139024598e40c84666cc311a42c256bbf880db3ac99sewardj            return True;
5140024598e40c84666cc311a42c256bbf880db3ac99sewardj
5141024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 1;
5142024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_ch = s->k0;
5143024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5144024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5145024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5146024598e40c84666cc311a42c256bbf880db3ac99sewardj
5147024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 2;
5148024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5149024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5150024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5151024598e40c84666cc311a42c256bbf880db3ac99sewardj
5152024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = 3;
5153024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5154024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1) continue;
5155024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
5156024598e40c84666cc311a42c256bbf880db3ac99sewardj
5157024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(k1); s->nblock_used++;
5158024598e40c84666cc311a42c256bbf880db3ac99sewardj         s->state_out_len = ((Int32)k1) + 4;
5159024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ_GET_SMALL(s->k0); s->nblock_used++;
5160024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5161024598e40c84666cc311a42c256bbf880db3ac99sewardj
5162024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5163024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5164024598e40c84666cc311a42c256bbf880db3ac99sewardj
5165024598e40c84666cc311a42c256bbf880db3ac99sewardj
5166024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5167024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
5168024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5169024598e40c84666cc311a42c256bbf880db3ac99sewardj   Bool    corrupt;
5170024598e40c84666cc311a42c256bbf880db3ac99sewardj   DState* s;
5171024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
5172024598e40c84666cc311a42c256bbf880db3ac99sewardj   s = strm->state;
5173024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s == NULL) return BZ_PARAM_ERROR;
5174024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
5175024598e40c84666cc311a42c256bbf880db3ac99sewardj
5176024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
5177024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
5178024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->state == BZ_X_OUTPUT) {
5179024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->smallDecompress)
5180024598e40c84666cc311a42c256bbf880db3ac99sewardj            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
5181024598e40c84666cc311a42c256bbf880db3ac99sewardj            corrupt = unRLE_obuf_to_output_FAST  ( s );
5182024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (corrupt) return BZ_DATA_ERROR;
5183024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
5184024598e40c84666cc311a42c256bbf880db3ac99sewardj            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
5185024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->verbosity >= 3)
5186024598e40c84666cc311a42c256bbf880db3ac99sewardj               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
5187024598e40c84666cc311a42c256bbf880db3ac99sewardj                          s->calculatedBlockCRC );
5188024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->verbosity >= 2) VPrintf0 ( "]" );
5189024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->calculatedBlockCRC != s->storedBlockCRC)
5190024598e40c84666cc311a42c256bbf880db3ac99sewardj               return BZ_DATA_ERROR;
5191024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->calculatedCombinedCRC
5192024598e40c84666cc311a42c256bbf880db3ac99sewardj               = (s->calculatedCombinedCRC << 1) |
5193024598e40c84666cc311a42c256bbf880db3ac99sewardj                    (s->calculatedCombinedCRC >> 31);
5194024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
5195024598e40c84666cc311a42c256bbf880db3ac99sewardj            s->state = BZ_X_BLKHDR_1;
5196024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
5197024598e40c84666cc311a42c256bbf880db3ac99sewardj            return BZ_OK;
5198024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
5199024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5200024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (s->state >= BZ_X_MAGIC_1) {
5201024598e40c84666cc311a42c256bbf880db3ac99sewardj         Int32 r = BZ2_decompress ( s );
5202024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (r == BZ_STREAM_END) {
5203024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->verbosity >= 3)
5204024598e40c84666cc311a42c256bbf880db3ac99sewardj               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
5205024598e40c84666cc311a42c256bbf880db3ac99sewardj                          s->storedCombinedCRC, s->calculatedCombinedCRC );
5206024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
5207024598e40c84666cc311a42c256bbf880db3ac99sewardj               return BZ_DATA_ERROR;
5208024598e40c84666cc311a42c256bbf880db3ac99sewardj            return r;
5209024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
5210024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (s->state != BZ_X_OUTPUT) return r;
5211024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5212024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5213024598e40c84666cc311a42c256bbf880db3ac99sewardj
5214024598e40c84666cc311a42c256bbf880db3ac99sewardj   AssertH ( 0, 6001 );
5215024598e40c84666cc311a42c256bbf880db3ac99sewardj
5216024598e40c84666cc311a42c256bbf880db3ac99sewardj   return 0;  /*NOTREACHED*/
5217024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5218024598e40c84666cc311a42c256bbf880db3ac99sewardj
5219024598e40c84666cc311a42c256bbf880db3ac99sewardj
5220024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5221024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
5222024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5223024598e40c84666cc311a42c256bbf880db3ac99sewardj   DState* s;
5224024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm == NULL) return BZ_PARAM_ERROR;
5225024598e40c84666cc311a42c256bbf880db3ac99sewardj   s = strm->state;
5226024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s == NULL) return BZ_PARAM_ERROR;
5227024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
5228024598e40c84666cc311a42c256bbf880db3ac99sewardj
5229024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->tt   != NULL) BZFREE(s->tt);
5230024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->ll16 != NULL) BZFREE(s->ll16);
5231024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (s->ll4  != NULL) BZFREE(s->ll4);
5232024598e40c84666cc311a42c256bbf880db3ac99sewardj
5233024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZFREE(strm->state);
5234024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm->state = NULL;
5235024598e40c84666cc311a42c256bbf880db3ac99sewardj
5236024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OK;
5237024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5238024598e40c84666cc311a42c256bbf880db3ac99sewardj
5239024598e40c84666cc311a42c256bbf880db3ac99sewardj
5240024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_NO_STDIO
5241024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5242024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- File I/O stuff                              ---*/
5243024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5244024598e40c84666cc311a42c256bbf880db3ac99sewardj
5245024598e40c84666cc311a42c256bbf880db3ac99sewardj#define BZ_SETERR(eee)                    \
5246024598e40c84666cc311a42c256bbf880db3ac99sewardj{                                         \
5247024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzerror != NULL) *bzerror = eee;   \
5248024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf != NULL) bzf->lastErr = eee;   \
5249024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5250024598e40c84666cc311a42c256bbf880db3ac99sewardj
5251024598e40c84666cc311a42c256bbf880db3ac99sewardjtypedef
5252024598e40c84666cc311a42c256bbf880db3ac99sewardj   struct {
5253024598e40c84666cc311a42c256bbf880db3ac99sewardj      FILE*     handle;
5254024598e40c84666cc311a42c256bbf880db3ac99sewardj      Char      buf[BZ_MAX_UNUSED];
5255024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32     bufN;
5256024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool      writing;
5257024598e40c84666cc311a42c256bbf880db3ac99sewardj      bz_stream strm;
5258024598e40c84666cc311a42c256bbf880db3ac99sewardj      Int32     lastErr;
5259024598e40c84666cc311a42c256bbf880db3ac99sewardj      Bool      initialisedOk;
5260024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5261024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile;
5262024598e40c84666cc311a42c256bbf880db3ac99sewardj
5263024598e40c84666cc311a42c256bbf880db3ac99sewardj
5264024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------*/
5265024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic Bool myfeof ( FILE* f )
5266024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5267024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 c = fgetc ( f );
5268024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (c == EOF) return True;
5269024598e40c84666cc311a42c256bbf880db3ac99sewardj   ungetc ( c, f );
5270024598e40c84666cc311a42c256bbf880db3ac99sewardj   return False;
5271024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5272024598e40c84666cc311a42c256bbf880db3ac99sewardj
5273024598e40c84666cc311a42c256bbf880db3ac99sewardj
5274024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5275024598e40c84666cc311a42c256bbf880db3ac99sewardjBZFILE* BZ_API(BZ2_bzWriteOpen)
5276024598e40c84666cc311a42c256bbf880db3ac99sewardj                    ( int*  bzerror,
5277024598e40c84666cc311a42c256bbf880db3ac99sewardj                      FILE* f,
5278024598e40c84666cc311a42c256bbf880db3ac99sewardj                      int   blockSize100k,
5279024598e40c84666cc311a42c256bbf880db3ac99sewardj                      int   verbosity,
5280024598e40c84666cc311a42c256bbf880db3ac99sewardj                      int   workFactor )
5281024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5282024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   ret;
5283024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile* bzf = NULL;
5284024598e40c84666cc311a42c256bbf880db3ac99sewardj
5285024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5286024598e40c84666cc311a42c256bbf880db3ac99sewardj
5287024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (f == NULL ||
5288024598e40c84666cc311a42c256bbf880db3ac99sewardj       (blockSize100k < 1 || blockSize100k > 9) ||
5289024598e40c84666cc311a42c256bbf880db3ac99sewardj       (workFactor < 0 || workFactor > 250) ||
5290024598e40c84666cc311a42c256bbf880db3ac99sewardj       (verbosity < 0 || verbosity > 4))
5291024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
5292024598e40c84666cc311a42c256bbf880db3ac99sewardj
5293024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ferror(f))
5294024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
5295024598e40c84666cc311a42c256bbf880db3ac99sewardj
5296024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf = malloc ( sizeof(bzFile) );
5297024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf == NULL)
5298024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
5299024598e40c84666cc311a42c256bbf880db3ac99sewardj
5300024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5301024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->initialisedOk = False;
5302024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->bufN          = 0;
5303024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->handle        = f;
5304024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->writing       = True;
5305024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.bzalloc  = NULL;
5306024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.bzfree   = NULL;
5307024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.opaque   = NULL;
5308024598e40c84666cc311a42c256bbf880db3ac99sewardj
5309024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (workFactor == 0) workFactor = 30;
5310024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
5311024598e40c84666cc311a42c256bbf880db3ac99sewardj                              verbosity, workFactor );
5312024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret != BZ_OK)
5313024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
5314024598e40c84666cc311a42c256bbf880db3ac99sewardj
5315024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.avail_in = 0;
5316024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->initialisedOk = True;
5317024598e40c84666cc311a42c256bbf880db3ac99sewardj   return bzf;
5318024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5319024598e40c84666cc311a42c256bbf880db3ac99sewardj
5320024598e40c84666cc311a42c256bbf880db3ac99sewardj
5321024598e40c84666cc311a42c256bbf880db3ac99sewardj
5322024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5323024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ_API(BZ2_bzWrite)
5324024598e40c84666cc311a42c256bbf880db3ac99sewardj             ( int*    bzerror,
5325024598e40c84666cc311a42c256bbf880db3ac99sewardj               BZFILE* b,
5326024598e40c84666cc311a42c256bbf880db3ac99sewardj               void*   buf,
5327024598e40c84666cc311a42c256bbf880db3ac99sewardj               int     len )
5328024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5329024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32 n, n2, ret;
5330024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile* bzf = (bzFile*)b;
5331024598e40c84666cc311a42c256bbf880db3ac99sewardj
5332024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5333024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf == NULL || buf == NULL || len < 0)
5334024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
5335024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (!(bzf->writing))
5336024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5337024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ferror(bzf->handle))
5338024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
5339024598e40c84666cc311a42c256bbf880db3ac99sewardj
5340024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (len == 0)
5341024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_OK); return; };
5342024598e40c84666cc311a42c256bbf880db3ac99sewardj
5343024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.avail_in = len;
5344024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.next_in  = buf;
5345024598e40c84666cc311a42c256bbf880db3ac99sewardj
5346024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
5347024598e40c84666cc311a42c256bbf880db3ac99sewardj      bzf->strm.avail_out = BZ_MAX_UNUSED;
5348024598e40c84666cc311a42c256bbf880db3ac99sewardj      bzf->strm.next_out = bzf->buf;
5349024598e40c84666cc311a42c256bbf880db3ac99sewardj      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
5350024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ret != BZ_RUN_OK)
5351024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(ret); return; };
5352024598e40c84666cc311a42c256bbf880db3ac99sewardj
5353024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
5354024598e40c84666cc311a42c256bbf880db3ac99sewardj         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
5355024598e40c84666cc311a42c256bbf880db3ac99sewardj         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
5356024598e40c84666cc311a42c256bbf880db3ac99sewardj                       n, bzf->handle );
5357024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (n != n2 || ferror(bzf->handle))
5358024598e40c84666cc311a42c256bbf880db3ac99sewardj            { BZ_SETERR(BZ_IO_ERROR); return; };
5359024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5360024598e40c84666cc311a42c256bbf880db3ac99sewardj
5361024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (bzf->strm.avail_in == 0)
5362024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(BZ_OK); return; };
5363024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5364024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5365024598e40c84666cc311a42c256bbf880db3ac99sewardj
5366024598e40c84666cc311a42c256bbf880db3ac99sewardj
5367024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5368024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ_API(BZ2_bzWriteClose)
5369024598e40c84666cc311a42c256bbf880db3ac99sewardj                  ( int*          bzerror,
5370024598e40c84666cc311a42c256bbf880db3ac99sewardj                    BZFILE*       b,
5371024598e40c84666cc311a42c256bbf880db3ac99sewardj                    int           abandon,
5372024598e40c84666cc311a42c256bbf880db3ac99sewardj                    unsigned int* nbytes_in,
5373024598e40c84666cc311a42c256bbf880db3ac99sewardj                    unsigned int* nbytes_out )
5374024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5375024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzWriteClose64 ( bzerror, b, abandon,
5376024598e40c84666cc311a42c256bbf880db3ac99sewardj                        nbytes_in, NULL, nbytes_out, NULL );
5377024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5378024598e40c84666cc311a42c256bbf880db3ac99sewardj
5379024598e40c84666cc311a42c256bbf880db3ac99sewardj
5380024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ_API(BZ2_bzWriteClose64)
5381024598e40c84666cc311a42c256bbf880db3ac99sewardj                  ( int*          bzerror,
5382024598e40c84666cc311a42c256bbf880db3ac99sewardj                    BZFILE*       b,
5383024598e40c84666cc311a42c256bbf880db3ac99sewardj                    int           abandon,
5384024598e40c84666cc311a42c256bbf880db3ac99sewardj                    unsigned int* nbytes_in_lo32,
5385024598e40c84666cc311a42c256bbf880db3ac99sewardj                    unsigned int* nbytes_in_hi32,
5386024598e40c84666cc311a42c256bbf880db3ac99sewardj                    unsigned int* nbytes_out_lo32,
5387024598e40c84666cc311a42c256bbf880db3ac99sewardj                    unsigned int* nbytes_out_hi32 )
5388024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5389024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   n, n2, ret;
5390024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile* bzf = (bzFile*)b;
5391024598e40c84666cc311a42c256bbf880db3ac99sewardj
5392024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf == NULL)
5393024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_OK); return; };
5394024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (!(bzf->writing))
5395024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5396024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ferror(bzf->handle))
5397024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
5398024598e40c84666cc311a42c256bbf880db3ac99sewardj
5399024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
5400024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
5401024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
5402024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
5403024598e40c84666cc311a42c256bbf880db3ac99sewardj
5404024598e40c84666cc311a42c256bbf880db3ac99sewardj   if ((!abandon) && bzf->lastErr == BZ_OK) {
5405024598e40c84666cc311a42c256bbf880db3ac99sewardj      while (True) {
5406024598e40c84666cc311a42c256bbf880db3ac99sewardj         bzf->strm.avail_out = BZ_MAX_UNUSED;
5407024598e40c84666cc311a42c256bbf880db3ac99sewardj         bzf->strm.next_out = bzf->buf;
5408024598e40c84666cc311a42c256bbf880db3ac99sewardj         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
5409024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
5410024598e40c84666cc311a42c256bbf880db3ac99sewardj            { BZ_SETERR(ret); return; };
5411024598e40c84666cc311a42c256bbf880db3ac99sewardj
5412024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
5413024598e40c84666cc311a42c256bbf880db3ac99sewardj            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
5414024598e40c84666cc311a42c256bbf880db3ac99sewardj            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
5415024598e40c84666cc311a42c256bbf880db3ac99sewardj                          n, bzf->handle );
5416024598e40c84666cc311a42c256bbf880db3ac99sewardj            if (n != n2 || ferror(bzf->handle))
5417024598e40c84666cc311a42c256bbf880db3ac99sewardj               { BZ_SETERR(BZ_IO_ERROR); return; };
5418024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
5419024598e40c84666cc311a42c256bbf880db3ac99sewardj
5420024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (ret == BZ_STREAM_END) break;
5421024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5422024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5423024598e40c84666cc311a42c256bbf880db3ac99sewardj
5424024598e40c84666cc311a42c256bbf880db3ac99sewardj   if ( !abandon && !ferror ( bzf->handle ) ) {
5425024598e40c84666cc311a42c256bbf880db3ac99sewardj      fflush ( bzf->handle );
5426024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ferror(bzf->handle))
5427024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(BZ_IO_ERROR); return; };
5428024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5429024598e40c84666cc311a42c256bbf880db3ac99sewardj
5430024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_in_lo32 != NULL)
5431024598e40c84666cc311a42c256bbf880db3ac99sewardj      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
5432024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_in_hi32 != NULL)
5433024598e40c84666cc311a42c256bbf880db3ac99sewardj      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
5434024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_out_lo32 != NULL)
5435024598e40c84666cc311a42c256bbf880db3ac99sewardj      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
5436024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (nbytes_out_hi32 != NULL)
5437024598e40c84666cc311a42c256bbf880db3ac99sewardj      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
5438024598e40c84666cc311a42c256bbf880db3ac99sewardj
5439024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5440024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzCompressEnd ( &(bzf->strm) );
5441024598e40c84666cc311a42c256bbf880db3ac99sewardj   free ( bzf );
5442024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5443024598e40c84666cc311a42c256bbf880db3ac99sewardj
5444024598e40c84666cc311a42c256bbf880db3ac99sewardj
5445024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5446024598e40c84666cc311a42c256bbf880db3ac99sewardjBZFILE* BZ_API(BZ2_bzReadOpen)
5447024598e40c84666cc311a42c256bbf880db3ac99sewardj                   ( int*  bzerror,
5448024598e40c84666cc311a42c256bbf880db3ac99sewardj                     FILE* f,
5449024598e40c84666cc311a42c256bbf880db3ac99sewardj                     int   verbosity,
5450024598e40c84666cc311a42c256bbf880db3ac99sewardj                     int   small,
5451024598e40c84666cc311a42c256bbf880db3ac99sewardj                     void* unused,
5452024598e40c84666cc311a42c256bbf880db3ac99sewardj                     int   nUnused )
5453024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5454024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile* bzf = NULL;
5455024598e40c84666cc311a42c256bbf880db3ac99sewardj   int     ret;
5456024598e40c84666cc311a42c256bbf880db3ac99sewardj
5457024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5458024598e40c84666cc311a42c256bbf880db3ac99sewardj
5459024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (f == NULL ||
5460024598e40c84666cc311a42c256bbf880db3ac99sewardj       (small != 0 && small != 1) ||
5461024598e40c84666cc311a42c256bbf880db3ac99sewardj       (verbosity < 0 || verbosity > 4) ||
5462024598e40c84666cc311a42c256bbf880db3ac99sewardj       (unused == NULL && nUnused != 0) ||
5463024598e40c84666cc311a42c256bbf880db3ac99sewardj       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
5464024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
5465024598e40c84666cc311a42c256bbf880db3ac99sewardj
5466024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ferror(f))
5467024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
5468024598e40c84666cc311a42c256bbf880db3ac99sewardj
5469024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf = malloc ( sizeof(bzFile) );
5470024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf == NULL)
5471024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
5472024598e40c84666cc311a42c256bbf880db3ac99sewardj
5473024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5474024598e40c84666cc311a42c256bbf880db3ac99sewardj
5475024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->initialisedOk = False;
5476024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->handle        = f;
5477024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->bufN          = 0;
5478024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->writing       = False;
5479024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.bzalloc  = NULL;
5480024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.bzfree   = NULL;
5481024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.opaque   = NULL;
5482024598e40c84666cc311a42c256bbf880db3ac99sewardj
5483024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (nUnused > 0) {
5484024598e40c84666cc311a42c256bbf880db3ac99sewardj      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
5485024598e40c84666cc311a42c256bbf880db3ac99sewardj      unused = ((void*)( 1 + ((UChar*)(unused))  ));
5486024598e40c84666cc311a42c256bbf880db3ac99sewardj      nUnused--;
5487024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5488024598e40c84666cc311a42c256bbf880db3ac99sewardj
5489024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
5490024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret != BZ_OK)
5491024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
5492024598e40c84666cc311a42c256bbf880db3ac99sewardj
5493024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.avail_in = bzf->bufN;
5494024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.next_in  = bzf->buf;
5495024598e40c84666cc311a42c256bbf880db3ac99sewardj
5496024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->initialisedOk = True;
5497024598e40c84666cc311a42c256bbf880db3ac99sewardj   return bzf;
5498024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5499024598e40c84666cc311a42c256bbf880db3ac99sewardj
5500024598e40c84666cc311a42c256bbf880db3ac99sewardj
5501024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5502024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
5503024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5504024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile* bzf = (bzFile*)b;
5505024598e40c84666cc311a42c256bbf880db3ac99sewardj
5506024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5507024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf == NULL)
5508024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_OK); return; };
5509024598e40c84666cc311a42c256bbf880db3ac99sewardj
5510024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf->writing)
5511024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5512024598e40c84666cc311a42c256bbf880db3ac99sewardj
5513024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf->initialisedOk)
5514024598e40c84666cc311a42c256bbf880db3ac99sewardj      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
5515024598e40c84666cc311a42c256bbf880db3ac99sewardj   free ( bzf );
5516024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5517024598e40c84666cc311a42c256bbf880db3ac99sewardj
5518024598e40c84666cc311a42c256bbf880db3ac99sewardj
5519024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5520024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzRead)
5521024598e40c84666cc311a42c256bbf880db3ac99sewardj           ( int*    bzerror,
5522024598e40c84666cc311a42c256bbf880db3ac99sewardj             BZFILE* b,
5523024598e40c84666cc311a42c256bbf880db3ac99sewardj             void*   buf,
5524024598e40c84666cc311a42c256bbf880db3ac99sewardj             int     len )
5525024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5526024598e40c84666cc311a42c256bbf880db3ac99sewardj   Int32   n, ret;
5527024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile* bzf = (bzFile*)b;
5528024598e40c84666cc311a42c256bbf880db3ac99sewardj
5529024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5530024598e40c84666cc311a42c256bbf880db3ac99sewardj
5531024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf == NULL || buf == NULL || len < 0)
5532024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
5533024598e40c84666cc311a42c256bbf880db3ac99sewardj
5534024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf->writing)
5535024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
5536024598e40c84666cc311a42c256bbf880db3ac99sewardj
5537024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (len == 0)
5538024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_OK); return 0; };
5539024598e40c84666cc311a42c256bbf880db3ac99sewardj
5540024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.avail_out = len;
5541024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzf->strm.next_out = buf;
5542024598e40c84666cc311a42c256bbf880db3ac99sewardj
5543024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (True) {
5544024598e40c84666cc311a42c256bbf880db3ac99sewardj
5545024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ferror(bzf->handle))
5546024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(BZ_IO_ERROR); return 0; };
5547024598e40c84666cc311a42c256bbf880db3ac99sewardj
5548024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
5549024598e40c84666cc311a42c256bbf880db3ac99sewardj         n = fread ( bzf->buf, sizeof(UChar),
5550024598e40c84666cc311a42c256bbf880db3ac99sewardj                     BZ_MAX_UNUSED, bzf->handle );
5551024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (ferror(bzf->handle))
5552024598e40c84666cc311a42c256bbf880db3ac99sewardj            { BZ_SETERR(BZ_IO_ERROR); return 0; };
5553024598e40c84666cc311a42c256bbf880db3ac99sewardj         bzf->bufN = n;
5554024598e40c84666cc311a42c256bbf880db3ac99sewardj         bzf->strm.avail_in = bzf->bufN;
5555024598e40c84666cc311a42c256bbf880db3ac99sewardj         bzf->strm.next_in = bzf->buf;
5556024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5557024598e40c84666cc311a42c256bbf880db3ac99sewardj
5558024598e40c84666cc311a42c256bbf880db3ac99sewardj      ret = BZ2_bzDecompress ( &(bzf->strm) );
5559024598e40c84666cc311a42c256bbf880db3ac99sewardj
5560024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ret != BZ_OK && ret != BZ_STREAM_END)
5561024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(ret); return 0; };
5562024598e40c84666cc311a42c256bbf880db3ac99sewardj
5563024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ret == BZ_OK && myfeof(bzf->handle) &&
5564024598e40c84666cc311a42c256bbf880db3ac99sewardj          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
5565024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
5566024598e40c84666cc311a42c256bbf880db3ac99sewardj
5567024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (ret == BZ_STREAM_END)
5568024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(BZ_STREAM_END);
5569024598e40c84666cc311a42c256bbf880db3ac99sewardj           return len - bzf->strm.avail_out; };
5570024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (bzf->strm.avail_out == 0)
5571024598e40c84666cc311a42c256bbf880db3ac99sewardj         { BZ_SETERR(BZ_OK); return len; };
5572024598e40c84666cc311a42c256bbf880db3ac99sewardj
5573024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5574024598e40c84666cc311a42c256bbf880db3ac99sewardj
5575024598e40c84666cc311a42c256bbf880db3ac99sewardj   return 0; /*not reached*/
5576024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5577024598e40c84666cc311a42c256bbf880db3ac99sewardj
5578024598e40c84666cc311a42c256bbf880db3ac99sewardj
5579024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5580024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ_API(BZ2_bzReadGetUnused)
5581024598e40c84666cc311a42c256bbf880db3ac99sewardj                     ( int*    bzerror,
5582024598e40c84666cc311a42c256bbf880db3ac99sewardj                       BZFILE* b,
5583024598e40c84666cc311a42c256bbf880db3ac99sewardj                       void**  unused,
5584024598e40c84666cc311a42c256bbf880db3ac99sewardj                       int*    nUnused )
5585024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5586024598e40c84666cc311a42c256bbf880db3ac99sewardj   bzFile* bzf = (bzFile*)b;
5587024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf == NULL)
5588024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
5589024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzf->lastErr != BZ_STREAM_END)
5590024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5591024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (unused == NULL || nUnused == NULL)
5592024598e40c84666cc311a42c256bbf880db3ac99sewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
5593024598e40c84666cc311a42c256bbf880db3ac99sewardj
5594024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ_SETERR(BZ_OK);
5595024598e40c84666cc311a42c256bbf880db3ac99sewardj   *nUnused = bzf->strm.avail_in;
5596024598e40c84666cc311a42c256bbf880db3ac99sewardj   *unused = bzf->strm.next_in;
5597024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5598024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
5599024598e40c84666cc311a42c256bbf880db3ac99sewardj
5600024598e40c84666cc311a42c256bbf880db3ac99sewardj
5601024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5602024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- Misc convenience stuff                      ---*/
5603024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5604024598e40c84666cc311a42c256bbf880db3ac99sewardj
5605024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5606024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzBuffToBuffCompress)
5607024598e40c84666cc311a42c256bbf880db3ac99sewardj                         ( char*         dest,
5608024598e40c84666cc311a42c256bbf880db3ac99sewardj                           unsigned int* destLen,
5609024598e40c84666cc311a42c256bbf880db3ac99sewardj                           char*         source,
5610024598e40c84666cc311a42c256bbf880db3ac99sewardj                           unsigned int  sourceLen,
5611024598e40c84666cc311a42c256bbf880db3ac99sewardj                           int           blockSize100k,
5612024598e40c84666cc311a42c256bbf880db3ac99sewardj                           int           verbosity,
5613024598e40c84666cc311a42c256bbf880db3ac99sewardj                           int           workFactor )
5614024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5615024598e40c84666cc311a42c256bbf880db3ac99sewardj   bz_stream strm;
5616024598e40c84666cc311a42c256bbf880db3ac99sewardj   int ret;
5617024598e40c84666cc311a42c256bbf880db3ac99sewardj
5618024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (dest == NULL || destLen == NULL ||
5619024598e40c84666cc311a42c256bbf880db3ac99sewardj       source == NULL ||
5620024598e40c84666cc311a42c256bbf880db3ac99sewardj       blockSize100k < 1 || blockSize100k > 9 ||
5621024598e40c84666cc311a42c256bbf880db3ac99sewardj       verbosity < 0 || verbosity > 4 ||
5622024598e40c84666cc311a42c256bbf880db3ac99sewardj       workFactor < 0 || workFactor > 250)
5623024598e40c84666cc311a42c256bbf880db3ac99sewardj      return BZ_PARAM_ERROR;
5624024598e40c84666cc311a42c256bbf880db3ac99sewardj
5625024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (workFactor == 0) workFactor = 30;
5626024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.bzalloc = NULL;
5627024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.bzfree = NULL;
5628024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.opaque = NULL;
5629024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret = BZ2_bzCompressInit ( &strm, blockSize100k,
5630024598e40c84666cc311a42c256bbf880db3ac99sewardj                              verbosity, workFactor );
5631024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret != BZ_OK) return ret;
5632024598e40c84666cc311a42c256bbf880db3ac99sewardj
5633024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.next_in = source;
5634024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.next_out = dest;
5635024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.avail_in = sourceLen;
5636024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.avail_out = *destLen;
5637024598e40c84666cc311a42c256bbf880db3ac99sewardj
5638024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
5639024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret == BZ_FINISH_OK) goto output_overflow;
5640024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret != BZ_STREAM_END) goto errhandler;
5641024598e40c84666cc311a42c256bbf880db3ac99sewardj
5642024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* normal termination */
5643024598e40c84666cc311a42c256bbf880db3ac99sewardj   *destLen -= strm.avail_out;
5644024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzCompressEnd ( &strm );
5645024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OK;
5646024598e40c84666cc311a42c256bbf880db3ac99sewardj
5647024598e40c84666cc311a42c256bbf880db3ac99sewardj   output_overflow:
5648024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzCompressEnd ( &strm );
5649024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OUTBUFF_FULL;
5650024598e40c84666cc311a42c256bbf880db3ac99sewardj
5651024598e40c84666cc311a42c256bbf880db3ac99sewardj   errhandler:
5652024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzCompressEnd ( &strm );
5653024598e40c84666cc311a42c256bbf880db3ac99sewardj   return ret;
5654024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5655024598e40c84666cc311a42c256bbf880db3ac99sewardj
5656024598e40c84666cc311a42c256bbf880db3ac99sewardj
5657024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5658024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzBuffToBuffDecompress)
5659024598e40c84666cc311a42c256bbf880db3ac99sewardj                           ( char*         dest,
5660024598e40c84666cc311a42c256bbf880db3ac99sewardj                             unsigned int* destLen,
5661024598e40c84666cc311a42c256bbf880db3ac99sewardj                             char*         source,
5662024598e40c84666cc311a42c256bbf880db3ac99sewardj                             unsigned int  sourceLen,
5663024598e40c84666cc311a42c256bbf880db3ac99sewardj                             int           small,
5664024598e40c84666cc311a42c256bbf880db3ac99sewardj                             int           verbosity )
5665024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5666024598e40c84666cc311a42c256bbf880db3ac99sewardj   bz_stream strm;
5667024598e40c84666cc311a42c256bbf880db3ac99sewardj   int ret;
5668024598e40c84666cc311a42c256bbf880db3ac99sewardj
5669024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (dest == NULL || destLen == NULL ||
5670024598e40c84666cc311a42c256bbf880db3ac99sewardj       source == NULL ||
5671024598e40c84666cc311a42c256bbf880db3ac99sewardj       (small != 0 && small != 1) ||
5672024598e40c84666cc311a42c256bbf880db3ac99sewardj       verbosity < 0 || verbosity > 4)
5673024598e40c84666cc311a42c256bbf880db3ac99sewardj          return BZ_PARAM_ERROR;
5674024598e40c84666cc311a42c256bbf880db3ac99sewardj
5675024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.bzalloc = NULL;
5676024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.bzfree = NULL;
5677024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.opaque = NULL;
5678024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
5679024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret != BZ_OK) return ret;
5680024598e40c84666cc311a42c256bbf880db3ac99sewardj
5681024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.next_in = source;
5682024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.next_out = dest;
5683024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.avail_in = sourceLen;
5684024598e40c84666cc311a42c256bbf880db3ac99sewardj   strm.avail_out = *destLen;
5685024598e40c84666cc311a42c256bbf880db3ac99sewardj
5686024598e40c84666cc311a42c256bbf880db3ac99sewardj   ret = BZ2_bzDecompress ( &strm );
5687024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret == BZ_OK) goto output_overflow_or_eof;
5688024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (ret != BZ_STREAM_END) goto errhandler;
5689024598e40c84666cc311a42c256bbf880db3ac99sewardj
5690024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* normal termination */
5691024598e40c84666cc311a42c256bbf880db3ac99sewardj   *destLen -= strm.avail_out;
5692024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzDecompressEnd ( &strm );
5693024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_OK;
5694024598e40c84666cc311a42c256bbf880db3ac99sewardj
5695024598e40c84666cc311a42c256bbf880db3ac99sewardj   output_overflow_or_eof:
5696024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (strm.avail_out > 0) {
5697024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ2_bzDecompressEnd ( &strm );
5698024598e40c84666cc311a42c256bbf880db3ac99sewardj      return BZ_UNEXPECTED_EOF;
5699024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
5700024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ2_bzDecompressEnd ( &strm );
5701024598e40c84666cc311a42c256bbf880db3ac99sewardj      return BZ_OUTBUFF_FULL;
5702024598e40c84666cc311a42c256bbf880db3ac99sewardj   };
5703024598e40c84666cc311a42c256bbf880db3ac99sewardj
5704024598e40c84666cc311a42c256bbf880db3ac99sewardj   errhandler:
5705024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzDecompressEnd ( &strm );
5706024598e40c84666cc311a42c256bbf880db3ac99sewardj   return ret;
5707024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5708024598e40c84666cc311a42c256bbf880db3ac99sewardj
5709024598e40c84666cc311a42c256bbf880db3ac99sewardj
5710024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5711024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
5712024598e40c84666cc311a42c256bbf880db3ac99sewardj   Code contributed by Yoshioka Tsuneo
5713024598e40c84666cc311a42c256bbf880db3ac99sewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
5714024598e40c84666cc311a42c256bbf880db3ac99sewardj   to support better zlib compatibility.
5715024598e40c84666cc311a42c256bbf880db3ac99sewardj   This code is not _officially_ part of libbzip2 (yet);
5716024598e40c84666cc311a42c256bbf880db3ac99sewardj   I haven't tested it, documented it, or considered the
5717024598e40c84666cc311a42c256bbf880db3ac99sewardj   threading-safeness of it.
5718024598e40c84666cc311a42c256bbf880db3ac99sewardj   If this code breaks, please contact both Yoshioka and me.
5719024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
5720024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5721024598e40c84666cc311a42c256bbf880db3ac99sewardj
5722024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5723024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
5724024598e40c84666cc311a42c256bbf880db3ac99sewardj   return version like "0.9.0c".
5725024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
5726024598e40c84666cc311a42c256bbf880db3ac99sewardjconst char * BZ_API(BZ2_bzlibVersion)(void)
5727024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5728024598e40c84666cc311a42c256bbf880db3ac99sewardj   return BZ_VERSION;
5729024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5730024598e40c84666cc311a42c256bbf880db3ac99sewardj
5731024598e40c84666cc311a42c256bbf880db3ac99sewardj
5732024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifndef BZ_NO_STDIO
5733024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5734024598e40c84666cc311a42c256bbf880db3ac99sewardj
5735024598e40c84666cc311a42c256bbf880db3ac99sewardj#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
5736024598e40c84666cc311a42c256bbf880db3ac99sewardj#   include <fcntl.h>
5737024598e40c84666cc311a42c256bbf880db3ac99sewardj#   include <io.h>
5738024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
5739024598e40c84666cc311a42c256bbf880db3ac99sewardj#else
5740024598e40c84666cc311a42c256bbf880db3ac99sewardj#   define SET_BINARY_MODE(file)
5741024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
5742024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic
5743024598e40c84666cc311a42c256bbf880db3ac99sewardjBZFILE * bzopen_or_bzdopen
5744024598e40c84666cc311a42c256bbf880db3ac99sewardj               ( const char *path,   /* no use when bzdopen */
5745024598e40c84666cc311a42c256bbf880db3ac99sewardj                 int fd,             /* no use when bzdopen */
5746024598e40c84666cc311a42c256bbf880db3ac99sewardj                 const char *mode,
5747024598e40c84666cc311a42c256bbf880db3ac99sewardj                 int open_mode)      /* bzopen: 0, bzdopen:1 */
5748024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5749024598e40c84666cc311a42c256bbf880db3ac99sewardj   int    bzerr;
5750024598e40c84666cc311a42c256bbf880db3ac99sewardj   char   unused[BZ_MAX_UNUSED];
5751024598e40c84666cc311a42c256bbf880db3ac99sewardj   int    blockSize100k = 9;
5752024598e40c84666cc311a42c256bbf880db3ac99sewardj   int    writing       = 0;
5753024598e40c84666cc311a42c256bbf880db3ac99sewardj   char   mode2[10]     = "";
5754024598e40c84666cc311a42c256bbf880db3ac99sewardj   FILE   *fp           = NULL;
5755024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZFILE *bzfp         = NULL;
5756024598e40c84666cc311a42c256bbf880db3ac99sewardj   int    verbosity     = 0;
5757024598e40c84666cc311a42c256bbf880db3ac99sewardj   int    workFactor    = 30;
5758024598e40c84666cc311a42c256bbf880db3ac99sewardj   int    smallMode     = 0;
5759024598e40c84666cc311a42c256bbf880db3ac99sewardj   int    nUnused       = 0;
5760024598e40c84666cc311a42c256bbf880db3ac99sewardj
5761024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (mode == NULL) return NULL;
5762024598e40c84666cc311a42c256bbf880db3ac99sewardj   while (*mode) {
5763024598e40c84666cc311a42c256bbf880db3ac99sewardj      switch (*mode) {
5764024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 'r':
5765024598e40c84666cc311a42c256bbf880db3ac99sewardj         writing = 0; break;
5766024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 'w':
5767024598e40c84666cc311a42c256bbf880db3ac99sewardj         writing = 1; break;
5768024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 's':
5769024598e40c84666cc311a42c256bbf880db3ac99sewardj         smallMode = 1; break;
5770024598e40c84666cc311a42c256bbf880db3ac99sewardj      default:
5771024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (isdigit((int)(*mode))) {
5772024598e40c84666cc311a42c256bbf880db3ac99sewardj            blockSize100k = *mode-BZ_HDR_0;
5773024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
5774024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5775024598e40c84666cc311a42c256bbf880db3ac99sewardj      mode++;
5776024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5777024598e40c84666cc311a42c256bbf880db3ac99sewardj   strcat(mode2, writing ? "w" : "r" );
5778024598e40c84666cc311a42c256bbf880db3ac99sewardj   strcat(mode2,"b");   /* binary mode */
5779024598e40c84666cc311a42c256bbf880db3ac99sewardj
5780024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (open_mode==0) {
5781024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (path==NULL || strcmp(path,"")==0) {
5782024598e40c84666cc311a42c256bbf880db3ac99sewardj        fp = (writing ? stdout : stdin);
5783024598e40c84666cc311a42c256bbf880db3ac99sewardj        SET_BINARY_MODE(fp);
5784024598e40c84666cc311a42c256bbf880db3ac99sewardj      } else {
5785024598e40c84666cc311a42c256bbf880db3ac99sewardj        fp = fopen(path,mode2);
5786024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5787024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
5788024598e40c84666cc311a42c256bbf880db3ac99sewardj#ifdef BZ_STRICT_ANSI
5789024598e40c84666cc311a42c256bbf880db3ac99sewardj      fp = NULL;
5790024598e40c84666cc311a42c256bbf880db3ac99sewardj#else
5791024598e40c84666cc311a42c256bbf880db3ac99sewardj      fp = fdopen(fd,mode2);
5792024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
5793024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5794024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (fp == NULL) return NULL;
5795024598e40c84666cc311a42c256bbf880db3ac99sewardj
5796024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (writing) {
5797024598e40c84666cc311a42c256bbf880db3ac99sewardj      /* Guard against total chaos and anarchy -- JRS */
5798024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (blockSize100k < 1) blockSize100k = 1;
5799024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (blockSize100k > 9) blockSize100k = 9;
5800024598e40c84666cc311a42c256bbf880db3ac99sewardj      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
5801024598e40c84666cc311a42c256bbf880db3ac99sewardj                             verbosity,workFactor);
5802024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
5803024598e40c84666cc311a42c256bbf880db3ac99sewardj      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
5804024598e40c84666cc311a42c256bbf880db3ac99sewardj                            unused,nUnused);
5805024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5806024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzfp == NULL) {
5807024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (fp != stdin && fp != stdout) fclose(fp);
5808024598e40c84666cc311a42c256bbf880db3ac99sewardj      return NULL;
5809024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5810024598e40c84666cc311a42c256bbf880db3ac99sewardj   return bzfp;
5811024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5812024598e40c84666cc311a42c256bbf880db3ac99sewardj
5813024598e40c84666cc311a42c256bbf880db3ac99sewardj
5814024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5815024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
5816024598e40c84666cc311a42c256bbf880db3ac99sewardj   open file for read or write.
5817024598e40c84666cc311a42c256bbf880db3ac99sewardj      ex) bzopen("file","w9")
5818024598e40c84666cc311a42c256bbf880db3ac99sewardj      case path="" or NULL => use stdin or stdout.
5819024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
5820024598e40c84666cc311a42c256bbf880db3ac99sewardjBZFILE * BZ_API(BZ2_bzopen)
5821024598e40c84666cc311a42c256bbf880db3ac99sewardj               ( const char *path,
5822024598e40c84666cc311a42c256bbf880db3ac99sewardj                 const char *mode )
5823024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5824024598e40c84666cc311a42c256bbf880db3ac99sewardj   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
5825024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5826024598e40c84666cc311a42c256bbf880db3ac99sewardj
5827024598e40c84666cc311a42c256bbf880db3ac99sewardj
5828024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5829024598e40c84666cc311a42c256bbf880db3ac99sewardjBZFILE * BZ_API(BZ2_bzdopen)
5830024598e40c84666cc311a42c256bbf880db3ac99sewardj               ( int fd,
5831024598e40c84666cc311a42c256bbf880db3ac99sewardj                 const char *mode )
5832024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5833024598e40c84666cc311a42c256bbf880db3ac99sewardj   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
5834024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5835024598e40c84666cc311a42c256bbf880db3ac99sewardj
5836024598e40c84666cc311a42c256bbf880db3ac99sewardj
5837024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5838024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
5839024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5840024598e40c84666cc311a42c256bbf880db3ac99sewardj   int bzerr, nread;
5841024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
5842024598e40c84666cc311a42c256bbf880db3ac99sewardj   nread = BZ2_bzRead(&bzerr,b,buf,len);
5843024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
5844024598e40c84666cc311a42c256bbf880db3ac99sewardj      return nread;
5845024598e40c84666cc311a42c256bbf880db3ac99sewardj   } else {
5846024598e40c84666cc311a42c256bbf880db3ac99sewardj      return -1;
5847024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5848024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5849024598e40c84666cc311a42c256bbf880db3ac99sewardj
5850024598e40c84666cc311a42c256bbf880db3ac99sewardj
5851024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5852024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
5853024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5854024598e40c84666cc311a42c256bbf880db3ac99sewardj   int bzerr;
5855024598e40c84666cc311a42c256bbf880db3ac99sewardj
5856024598e40c84666cc311a42c256bbf880db3ac99sewardj   BZ2_bzWrite(&bzerr,b,buf,len);
5857024598e40c84666cc311a42c256bbf880db3ac99sewardj   if(bzerr == BZ_OK){
5858024598e40c84666cc311a42c256bbf880db3ac99sewardj      return len;
5859024598e40c84666cc311a42c256bbf880db3ac99sewardj   }else{
5860024598e40c84666cc311a42c256bbf880db3ac99sewardj      return -1;
5861024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5862024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5863024598e40c84666cc311a42c256bbf880db3ac99sewardj
5864024598e40c84666cc311a42c256bbf880db3ac99sewardj
5865024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5866024598e40c84666cc311a42c256bbf880db3ac99sewardjint BZ_API(BZ2_bzflush) (BZFILE *b)
5867024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5868024598e40c84666cc311a42c256bbf880db3ac99sewardj   /* do nothing now... */
5869024598e40c84666cc311a42c256bbf880db3ac99sewardj   return 0;
5870024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5871024598e40c84666cc311a42c256bbf880db3ac99sewardj
5872024598e40c84666cc311a42c256bbf880db3ac99sewardj
5873024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5874024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid BZ_API(BZ2_bzclose) (BZFILE* b)
5875024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5876024598e40c84666cc311a42c256bbf880db3ac99sewardj   int bzerr;
5877024598e40c84666cc311a42c256bbf880db3ac99sewardj   FILE *fp = ((bzFile *)b)->handle;
5878024598e40c84666cc311a42c256bbf880db3ac99sewardj
5879024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (b==NULL) {return;}
5880024598e40c84666cc311a42c256bbf880db3ac99sewardj   if(((bzFile*)b)->writing){
5881024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
5882024598e40c84666cc311a42c256bbf880db3ac99sewardj      if(bzerr != BZ_OK){
5883024598e40c84666cc311a42c256bbf880db3ac99sewardj         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
5884024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
5885024598e40c84666cc311a42c256bbf880db3ac99sewardj   }else{
5886024598e40c84666cc311a42c256bbf880db3ac99sewardj      BZ2_bzReadClose(&bzerr,b);
5887024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5888024598e40c84666cc311a42c256bbf880db3ac99sewardj   if(fp!=stdin && fp!=stdout){
5889024598e40c84666cc311a42c256bbf880db3ac99sewardj      fclose(fp);
5890024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
5891024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5892024598e40c84666cc311a42c256bbf880db3ac99sewardj
5893024598e40c84666cc311a42c256bbf880db3ac99sewardj
5894024598e40c84666cc311a42c256bbf880db3ac99sewardj/*---------------------------------------------------*/
5895024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--
5896024598e40c84666cc311a42c256bbf880db3ac99sewardj   return last error code
5897024598e40c84666cc311a42c256bbf880db3ac99sewardj--*/
5898024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic char *bzerrorstrings[] = {
5899024598e40c84666cc311a42c256bbf880db3ac99sewardj       "OK"
5900024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"SEQUENCE_ERROR"
5901024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"PARAM_ERROR"
5902024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"MEM_ERROR"
5903024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"DATA_ERROR"
5904024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"DATA_ERROR_MAGIC"
5905024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"IO_ERROR"
5906024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"UNEXPECTED_EOF"
5907024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"OUTBUFF_FULL"
5908024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"CONFIG_ERROR"
5909024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5910024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5911024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5912024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5913024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5914024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5915024598e40c84666cc311a42c256bbf880db3ac99sewardj};
5916024598e40c84666cc311a42c256bbf880db3ac99sewardj
5917024598e40c84666cc311a42c256bbf880db3ac99sewardj
5918024598e40c84666cc311a42c256bbf880db3ac99sewardjconst char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
5919024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5920024598e40c84666cc311a42c256bbf880db3ac99sewardj   int err = ((bzFile *)b)->lastErr;
5921024598e40c84666cc311a42c256bbf880db3ac99sewardj
5922024598e40c84666cc311a42c256bbf880db3ac99sewardj   if(err>0) err = 0;
5923024598e40c84666cc311a42c256bbf880db3ac99sewardj   *errnum = err;
5924024598e40c84666cc311a42c256bbf880db3ac99sewardj   return bzerrorstrings[err*-1];
5925024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5926024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
5927024598e40c84666cc311a42c256bbf880db3ac99sewardj
5928024598e40c84666cc311a42c256bbf880db3ac99sewardj
5929024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
5930024598e40c84666cc311a42c256bbf880db3ac99sewardj/*--- end                                           bzlib.c ---*/
5931024598e40c84666cc311a42c256bbf880db3ac99sewardj/*-------------------------------------------------------------*/
5932024598e40c84666cc311a42c256bbf880db3ac99sewardj
5933024598e40c84666cc311a42c256bbf880db3ac99sewardj
5934024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
5935024598e40c84666cc311a42c256bbf880db3ac99sewardj/////////////////////////////////////////////////////////////////////
5936024598e40c84666cc311a42c256bbf880db3ac99sewardj
5937024598e40c84666cc311a42c256bbf880db3ac99sewardj
5938024598e40c84666cc311a42c256bbf880db3ac99sewardj/* A test program written to test robustness to decompression of
5939024598e40c84666cc311a42c256bbf880db3ac99sewardj   corrupted data.  Usage is
5940024598e40c84666cc311a42c256bbf880db3ac99sewardj       unzcrash filename
5941024598e40c84666cc311a42c256bbf880db3ac99sewardj   and the program will read the specified file, compress it (in memory),
5942024598e40c84666cc311a42c256bbf880db3ac99sewardj   and then repeatedly decompress it, each time with a different bit of
5943024598e40c84666cc311a42c256bbf880db3ac99sewardj   the compressed data inverted, so as to test all possible one-bit errors.
5944024598e40c84666cc311a42c256bbf880db3ac99sewardj   This should not cause any invalid memory accesses.  If it does,
5945024598e40c84666cc311a42c256bbf880db3ac99sewardj   I want to know about it!
5946024598e40c84666cc311a42c256bbf880db3ac99sewardj
5947024598e40c84666cc311a42c256bbf880db3ac99sewardj   p.s.  As you can see from the above description, the process is
5948024598e40c84666cc311a42c256bbf880db3ac99sewardj   incredibly slow.  A file of size eg 5KB will cause it to run for
5949024598e40c84666cc311a42c256bbf880db3ac99sewardj   many hours.
5950024598e40c84666cc311a42c256bbf880db3ac99sewardj*/
5951024598e40c84666cc311a42c256bbf880db3ac99sewardj
5952024598e40c84666cc311a42c256bbf880db3ac99sewardj//#include <stdio.h>
5953024598e40c84666cc311a42c256bbf880db3ac99sewardj//#include <assert.h>
5954024598e40c84666cc311a42c256bbf880db3ac99sewardj//#include "bzlib.h"
5955024598e40c84666cc311a42c256bbf880db3ac99sewardj
5956024598e40c84666cc311a42c256bbf880db3ac99sewardj#define M_BLOCK 1000000
5957024598e40c84666cc311a42c256bbf880db3ac99sewardj
5958024598e40c84666cc311a42c256bbf880db3ac99sewardj
5959024598e40c84666cc311a42c256bbf880db3ac99sewardj#define M_BLOCK_OUT (M_BLOCK + 1000000)
5960024598e40c84666cc311a42c256bbf880db3ac99sewardj char inbuf[M_BLOCK];
5961024598e40c84666cc311a42c256bbf880db3ac99sewardj char outbuf[M_BLOCK_OUT];
5962024598e40c84666cc311a42c256bbf880db3ac99sewardj char zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
5963024598e40c84666cc311a42c256bbf880db3ac99sewardj
5964024598e40c84666cc311a42c256bbf880db3ac99sewardjint nIn;
5965024598e40c84666cc311a42c256bbf880db3ac99sewardjunsigned int nOut;
5966024598e40c84666cc311a42c256bbf880db3ac99sewardjunsigned int nZ;
5967024598e40c84666cc311a42c256bbf880db3ac99sewardj
5968024598e40c84666cc311a42c256bbf880db3ac99sewardj#if 0
5969024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic char *bzerrorstrings[] = {
5970024598e40c84666cc311a42c256bbf880db3ac99sewardj       "OK"
5971024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"SEQUENCE_ERROR"
5972024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"PARAM_ERROR"
5973024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"MEM_ERROR"
5974024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"DATA_ERROR"
5975024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"DATA_ERROR_MAGIC"
5976024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"IO_ERROR"
5977024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"UNEXPECTED_EOF"
5978024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"OUTBUFF_FULL"
5979024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5980024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5981024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5982024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5983024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5984024598e40c84666cc311a42c256bbf880db3ac99sewardj      ,"???"   /* for future */
5985024598e40c84666cc311a42c256bbf880db3ac99sewardj};
5986024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
5987024598e40c84666cc311a42c256bbf880db3ac99sewardj
5988024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid flip_bit ( int bit )
5989024598e40c84666cc311a42c256bbf880db3ac99sewardj{
5990024598e40c84666cc311a42c256bbf880db3ac99sewardj   int byteno = bit / 8;
5991024598e40c84666cc311a42c256bbf880db3ac99sewardj   int bitno  = bit % 8;
5992024598e40c84666cc311a42c256bbf880db3ac99sewardj   UChar mask = 1 << bitno;
5993024598e40c84666cc311a42c256bbf880db3ac99sewardj   //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
5994024598e40c84666cc311a42c256bbf880db3ac99sewardj   //          byteno, bitno, (int)mask );
5995024598e40c84666cc311a42c256bbf880db3ac99sewardj   zbuf[byteno] ^= mask;
5996024598e40c84666cc311a42c256bbf880db3ac99sewardj}
5997024598e40c84666cc311a42c256bbf880db3ac99sewardj
5998024598e40c84666cc311a42c256bbf880db3ac99sewardjvoid set_inbuf ( void )
5999024598e40c84666cc311a42c256bbf880db3ac99sewardj{
6000024598e40c84666cc311a42c256bbf880db3ac99sewardj  inbuf[0] = 0;
6001024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "At her sixtieth birthday party, Margaret Thatcher ");
6002024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "blew on the cake to light the candles.\n");
6003024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "This program, bzip2, the associated library libbzip2, and all\n");
6004024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "documentation, are copyright (C) 1996-2004 Julian R Seward.  All\n");
6005024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "rights reserved.\n");
6006024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6007024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Redistribution and use in source and binary forms, with or without\n");
6008024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "modification, are permitted provided that the following conditions\n");
6009024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "are met:\n");
6010024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6011024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "1. Redistributions of source code must retain the above copyright\n");
6012024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   notice, this list of conditions and the following disclaimer.\n");
6013024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6014024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "2. The origin of this software must not be misrepresented; you must\n");
6015024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   not claim that you wrote the original software.  If you use this\n");
6016024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   software in a product, an acknowledgment in the product\n");
6017024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   documentation would be appreciated but is not required.\n");
6018024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6019024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "3. Altered source versions must be plainly marked as such, and must\n");
6020024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   not be misrepresented as being the original software.\n");
6021024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6022024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "4. The name of the author may not be used to endorse or promote\n");
6023024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   products derived from this software without specific prior written\n");
6024024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   permission.\n");
6025024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6026024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n");
6027024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n");
6028024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n");
6029024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n");
6030024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n");
6031024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n");
6032024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n");
6033024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n");
6034024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n");
6035024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n");
6036024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n");
6037024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6038024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6039024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6040024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6041024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6042024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6043024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6044024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6045024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6046024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6047024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6048024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6049024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6050024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6051024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6052024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6053024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6054024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6055024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6056024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6057024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6058024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6059024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6060024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6061024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6062024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6063024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6064024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6065024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6066024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6067024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6068024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6069024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6070024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6071024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6072024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6073024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6074024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6075024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6076024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6077024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6078024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6079024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "		    GNU GENERAL PUBLIC LICENSE\n");
6080024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "		       Version 2, June 1991\n");
6081024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6082024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n");
6083024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n");
6084024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, " Everyone is permitted to copy and distribute verbatim copies\n");
6085024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, " of this license document, but changing it is not allowed.\n");
6086024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6087024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "			    Preamble\n");
6088024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6089024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  The licenses for most software are designed to take away your\n");
6090024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "freedom to share and change it.  By contrast, the GNU General Public\n");
6091024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "License is intended to guarantee your freedom to share and change free\n");
6092024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "software--to make sure the software is free for all its users.  This\n");
6093024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "General Public License applies to most of the Free Software\n");
6094024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Foundation's software and to any other program whose authors commit to\n");
6095024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "using it.  (Some other Free Software Foundation software is covered by\n");
6096024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "the GNU Library General Public License instead.)  You can apply it to\n");
6097024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "your programs, too.\n");
6098024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6099024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  When we speak of free software, we are referring to freedom, not\n");
6100024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "price.  Our General Public Licenses are designed to make sure that you\n");
6101024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "have the freedom to distribute copies of free software (and charge for\n");
6102024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "this service if you wish), that you receive source code or can get it\n");
6103024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "if you want it, that you can change the software or use pieces of it\n");
6104024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "in new free programs; and that you know you can do these things.\n");
6105024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6106024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  To protect your rights, we need to make restrictions that forbid\n");
6107024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "anyone to deny you these rights or to ask you to surrender the rights.\n");
6108024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "These restrictions translate to certain responsibilities for you if you\n");
6109024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "distribute copies of the software, or if you modify it.\n");
6110024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6111024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  For example, if you distribute copies of such a program, whether\n");
6112024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "gratis or for a fee, you must give the recipients all the rights that\n");
6113024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "you have.  You must make sure that they, too, receive or can get the\n");
6114024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "source code.  And you must show them these terms so they know their\n");
6115024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "rights.\n");
6116024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6117024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  We protect your rights with two steps: (1) copyright the software, and\n");
6118024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "(2) offer you this license which gives you legal permission to copy,\n");
6119024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "distribute and/or modify the software.\n");
6120024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6121024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  Also, for each author's protection and ours, we want to make certain\n");
6122024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "that everyone understands that there is no warranty for this free\n");
6123024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "software.  If the software is modified by someone else and passed on, we\n");
6124024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "want its recipients to know that what they have is not the original, so\n");
6125024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "that any problems introduced by others will not reflect on the original\n");
6126024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "authors' reputations.\n");
6127024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6128024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  Finally, any free program is threatened constantly by software\n");
6129024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "patents.  We wish to avoid the danger that redistributors of a free\n");
6130024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "program will individually obtain patent licenses, in effect making the\n");
6131024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "program proprietary.  To prevent this, we have made it clear that any\n");
6132024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "patent must be licensed for everyone's free use or not licensed at all.\n");
6133024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6134024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  The precise terms and conditions for copying, distribution and\n");
6135024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "modification follow.\n");
6136024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6137024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "		    GNU GENERAL PUBLIC LICENSE\n");
6138024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n");
6139024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6140024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  0. This License applies to any program or other work which contains\n");
6141024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "a notice placed by the copyright holder saying it may be distributed\n");
6142024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "under the terms of this General Public License.  The Program, below,\n");
6143024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "refers to any such program or work, and a work based on the Program\n");
6144024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "means either the Program or any derivative work under copyright law:\n");
6145024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "that is to say, a work containing the Program or a portion of it,\n");
6146024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "either verbatim or with modifications and/or translated into another\n");
6147024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "language.  (Hereinafter, translation is included without limitation in\n");
6148024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "the term modification.)  Each licensee is addressed as you.\n");
6149024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6150024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Activities other than copying, distribution and modification are not\n");
6151024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "covered by this License; they are outside its scope.  The act of\n");
6152024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "running the Program is not restricted, and the output from the Program\n");
6153024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "is covered only if its contents constitute a work based on the\n");
6154024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Program (independent of having been made by running the Program).\n");
6155024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Whether that is true depends on what the Program does.\n");
6156024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6157024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  1. You may copy and distribute verbatim copies of the Program's\n");
6158024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "source code as you receive it, in any medium, provided that you\n");
6159024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "conspicuously and appropriately publish on each copy an appropriate\n");
6160024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "copyright notice and disclaimer of warranty; keep intact all the\n");
6161024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "notices that refer to this License and to the absence of any warranty;\n");
6162024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "and give any other recipients of the Program a copy of this License\n");
6163024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "along with the Program.\n");
6164024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6165024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "You may charge a fee for the physical act of transferring a copy, and\n");
6166024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "you may at your option offer warranty protection in exchange for a fee.\n");
6167024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6168024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  2. You may modify your copy or copies of the Program or any portion\n");
6169024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "of it, thus forming a work based on the Program, and copy and\n");
6170024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "distribute such modifications or work under the terms of Section 1\n");
6171024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "above, provided that you also meet all of these conditions:\n");
6172024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6173024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    a) You must cause the modified files to carry prominent notices\n");
6174024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    stating that you changed the files and the date of any change.\n");
6175024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6176024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    b) You must cause any work that you distribute or publish, that in\n");
6177024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    whole or in part contains or is derived from the Program or any\n");
6178024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    part thereof, to be licensed as a whole at no charge to all third\n");
6179024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    parties under the terms of this License.\n");
6180024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6181024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    c) If the modified program normally reads commands interactively\n");
6182024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    when run, you must cause it, when started running for such\n");
6183024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    interactive use in the most ordinary way, to print or display an\n");
6184024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    announcement including an appropriate copyright notice and a\n");
6185024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    notice that there is no warranty (or else, saying that you provide\n");
6186024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    a warranty) and that users may redistribute the program under\n");
6187024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    these conditions, and telling the user how to view a copy of this\n");
6188024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    License.  (Exception: if the Program itself is interactive but\n");
6189024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    does not normally print such an announcement, your work based on\n");
6190024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    the Program is not required to print an announcement.)\n");
6191024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6192024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "These requirements apply to the modified work as a whole.  If\n");
6193024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "identifiable sections of that work are not derived from the Program,\n");
6194024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "and can be reasonably considered independent and separate works in\n");
6195024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "themselves, then this License, and its terms, do not apply to those\n");
6196024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "sections when you distribute them as separate works.  But when you\n");
6197024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "distribute the same sections as part of a whole which is a work based\n");
6198024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "on the Program, the distribution of the whole must be on the terms of\n");
6199024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "this License, whose permissions for other licensees extend to the\n");
6200024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "entire whole, and thus to each and every part regardless of who wrote it.\n");
6201024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6202024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Thus, it is not the intent of this section to claim rights or contest\n");
6203024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "your rights to work written entirely by you; rather, the intent is to\n");
6204024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "exercise the right to control the distribution of derivative or\n");
6205024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "collective works based on the Program.\n");
6206024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6207024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "In addition, mere aggregation of another work not based on the Program\n");
6208024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "with the Program (or with a work based on the Program) on a volume of\n");
6209024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "a storage or distribution medium does not bring the other work under\n");
6210024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "the scope of this License.\n");
6211024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6212024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  3. You may copy and distribute the Program (or a work based on it,\n");
6213024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "under Section 2) in object code or executable form under the terms of\n");
6214024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Sections 1 and 2 above provided that you also do one of the following:\n");
6215024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6216024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    a) Accompany it with the complete corresponding machine-readable\n");
6217024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    source code, which must be distributed under the terms of Sections\n");
6218024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    1 and 2 above on a medium customarily used for software interchange; or,\n");
6219024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6220024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    b) Accompany it with a written offer, valid for at least three\n");
6221024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    years, to give any third party, for a charge no more than your\n");
6222024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    cost of physically performing source distribution, a complete\n");
6223024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    machine-readable copy of the corresponding source code, to be\n");
6224024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    distributed under the terms of Sections 1 and 2 above on a medium\n");
6225024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    customarily used for software interchange; or,\n");
6226024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6227024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    c) Accompany it with the information you received as to the offer\n");
6228024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    to distribute corresponding source code.  (This alternative is\n");
6229024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    allowed only for noncommercial distribution and only if you\n");
6230024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    received the program in object code or executable form with such\n");
6231024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    an offer, in accord with Subsection b above.)\n");
6232024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6233024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "The source code for a work means the preferred form of the work for\n");
6234024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "making modifications to it.  For an executable work, complete source\n");
6235024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "code means all the source code for all modules it contains, plus any\n");
6236024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "associated interface definition files, plus the scripts used to\n");
6237024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "control compilation and installation of the executable.  However, as a\n");
6238024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "special exception, the source code distributed need not include\n");
6239024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "anything that is normally distributed (in either source or binary\n");
6240024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "form) with the major components (compiler, kernel, and so on) of the\n");
6241024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "operating system on which the executable runs, unless that component\n");
6242024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "itself accompanies the executable.\n");
6243024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6244024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "If distribution of executable or object code is made by offering\n");
6245024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "access to copy from a designated place, then offering equivalent\n");
6246024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "access to copy the source code from the same place counts as\n");
6247024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "distribution of the source code, even though third parties are not\n");
6248024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "compelled to copy the source along with the object code.\n");
6249024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6250024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  4. You may not copy, modify, sublicense, or distribute the Program\n");
6251024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "except as expressly provided under this License.  Any attempt\n");
6252024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "otherwise to copy, modify, sublicense or distribute the Program is\n");
6253024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "void, and will automatically terminate your rights under this License.\n");
6254024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "However, parties who have received copies, or rights, from you under\n");
6255024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "this License will not have their licenses terminated so long as such\n");
6256024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "parties remain in full compliance.\n");
6257024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6258024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  5. You are not required to accept this License, since you have not\n");
6259024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "signed it.  However, nothing else grants you permission to modify or\n");
6260024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "distribute the Program or its derivative works.  These actions are\n");
6261024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "prohibited by law if you do not accept this License.  Therefore, by\n");
6262024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "modifying or distributing the Program (or any work based on the\n");
6263024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Program), you indicate your acceptance of this License to do so, and\n");
6264024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "all its terms and conditions for copying, distributing or modifying\n");
6265024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "the Program or works based on it.\n");
6266024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6267024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  6. Each time you redistribute the Program (or any work based on the\n");
6268024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Program), the recipient automatically receives a license from the\n");
6269024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "original licensor to copy, distribute or modify the Program subject to\n");
6270024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "these terms and conditions.  You may not impose any further\n");
6271024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "restrictions on the recipients' exercise of the rights granted herein.\n");
6272024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "You are not responsible for enforcing compliance by third parties to\n");
6273024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "this License.\n");
6274024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6275024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  7. If, as a consequence of a court judgment or allegation of patent\n");
6276024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "infringement or for any other reason (not limited to patent issues),\n");
6277024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "conditions are imposed on you (whether by court order, agreement or\n");
6278024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "otherwise) that contradict the conditions of this License, they do not\n");
6279024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "excuse you from the conditions of this License.  If you cannot\n");
6280024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "distribute so as to satisfy simultaneously your obligations under this\n");
6281024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "License and any other pertinent obligations, then as a consequence you\n");
6282024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "may not distribute the Program at all.  For example, if a patent\n");
6283024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "license would not permit royalty-free redistribution of the Program by\n");
6284024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "all those who receive copies directly or indirectly through you, then\n");
6285024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "the only way you could satisfy both it and this License would be to\n");
6286024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "refrain entirely from distribution of the Program.\n");
6287024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6288024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "If any portion of this section is held invalid or unenforceable under\n");
6289024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "any particular circumstance, the balance of the section is intended to\n");
6290024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "apply and the section as a whole is intended to apply in other\n");
6291024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "circumstances.\n");
6292024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6293024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "It is not the purpose of this section to induce you to infringe any\n");
6294024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "patents or other property right claims or to contest validity of any\n");
6295024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "such claims; this section has the sole purpose of protecting the\n");
6296024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "integrity of the free software distribution system, which is\n");
6297024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "implemented by public license practices.  Many people have made\n");
6298024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "generous contributions to the wide range of software distributed\n");
6299024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "through that system in reliance on consistent application of that\n");
6300024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "system; it is up to the author/donor to decide if he or she is willing\n");
6301024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "to distribute software through any other system and a licensee cannot\n");
6302024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "impose that choice.\n");
6303024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6304024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "This section is intended to make thoroughly clear what is believed to\n");
6305024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "be a consequence of the rest of this License.\n");
6306024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6307024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  8. If the distribution and/or use of the Program is restricted in\n");
6308024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "certain countries either by patents or by copyrighted interfaces, the\n");
6309024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "original copyright holder who places the Program under this License\n");
6310024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "may add an explicit geographical distribution limitation excluding\n");
6311024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "those countries, so that distribution is permitted only in or among\n");
6312024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "countries not thus excluded.  In such case, this License incorporates\n");
6313024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "the limitation as if written in the body of this License.\n");
6314024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6315024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  9. The Free Software Foundation may publish revised and/or new versions\n");
6316024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "of the General Public License from time to time.  Such new versions will\n");
6317024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "be similar in spirit to the present version, but may differ in detail to\n");
6318024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "address new problems or concerns.\n");
6319024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6320024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Each version is given a distinguishing version number.  If the Program\n");
6321024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "specifies a version number of this License which applies to it and any\n");
6322024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "later version, you have the option of following the terms and conditions\n");
6323024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "either of that version or of any later version published by the Free\n");
6324024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Software Foundation.  If the Program does not specify a version number of\n");
6325024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "this License, you may choose any version ever published by the Free Software\n");
6326024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Foundation.\n");
6327024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6328024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  10. If you wish to incorporate parts of the Program into other free\n");
6329024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "programs whose distribution conditions are different, write to the author\n");
6330024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "to ask for permission.  For software which is copyrighted by the Free\n");
6331024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Software Foundation, write to the Free Software Foundation; we sometimes\n");
6332024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "make exceptions for this.  Our decision will be guided by the two goals\n");
6333024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "of preserving the free status of all derivatives of our free software and\n");
6334024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "of promoting the sharing and reuse of software generally.\n");
6335024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6336024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "			    NO WARRANTY\n");
6337024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6338024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n");
6339024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n");
6340024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n");
6341024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "PROVIDE THE PROGRAM AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n");
6342024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n");
6343024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n");
6344024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n");
6345024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n");
6346024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "REPAIR OR CORRECTION.\n");
6347024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6348024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n");
6349024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n");
6350024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n");
6351024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n");
6352024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n");
6353024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n");
6354024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n");
6355024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n");
6356024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "POSSIBILITY OF SUCH DAMAGES.\n");
6357024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6358024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "		     END OF TERMS AND CONDITIONS\n");
6359024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6360024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "	    How to Apply These Terms to Your New Programs\n");
6361024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6362024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  If you develop a new program, and you want it to be of the greatest\n");
6363024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "possible use to the public, the best way to achieve this is to make it\n");
6364024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "free software which everyone can redistribute and change under these terms.\n");
6365024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6366024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  To do so, attach the following notices to the program.  It is safest\n");
6367024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "to attach them to the start of each source file to most effectively\n");
6368024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "convey the exclusion of warranty; and each file should have at least\n");
6369024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "the copyright line and a pointer to where the full notice is found.\n");
6370024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6371024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    <one line to give the program's name and a brief idea of what it does.>\n");
6372024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    Copyright (C) <year>  <name of author>\n");
6373024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6374024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    This program is free software; you can redistribute it and/or modify\n");
6375024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    it under the terms of the GNU General Public License as published by\n");
6376024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    the Free Software Foundation; either version 2 of the License, or\n");
6377024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    (at your option) any later version.\n");
6378024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6379024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    This program is distributed in the hope that it will be useful,\n");
6380024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
6381024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
6382024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    GNU General Public License for more details.\n");
6383024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6384024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    You should have received a copy of the GNU General Public License\n");
6385024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    along with this program; if not, write to the Free Software\n");
6386024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n");
6387024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6388024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6389024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Also add information on how to contact you by electronic and paper mail.\n");
6390024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6391024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "If the program is interactive, make it output a short notice like this\n");
6392024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "when it starts in an interactive mode:\n");
6393024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6394024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    Gnomovision version 69, Copyright (C) year  name of author\n");
6395024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n");
6396024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    This is free software, and you are welcome to redistribute it\n");
6397024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "    under certain conditions; type `show c' for details.\n");
6398024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6399024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "The hypothetical commands `show w' and `show c' should show the appropriate\n");
6400024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "parts of the General Public License.  Of course, the commands you use may\n");
6401024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "be called something other than `show w' and `show c'; they could even be\n");
6402024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "mouse-clicks or menu items--whatever suits your program.\n");
6403024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6404024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "You should also get your employer (if you work as a programmer) or your\n");
6405024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "school, if any, to sign a copyright disclaimer for the program, if\n");
6406024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "necessary.  Here is a sample; alter the names:\n");
6407024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6408024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n");
6409024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n");
6410024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6411024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  <signature of Ty Coon>, 1 April 1989\n");
6412024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "  Ty Coon, President of Vice\n");
6413024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6414024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "This General Public License does not permit incorporating your program into\n");
6415024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "proprietary programs.  If your program is a subroutine library, you may\n");
6416024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "consider it more useful to permit linking proprietary applications with the\n");
6417024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "library.  If this is what you want to do, use the GNU Library General\n");
6418024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "Public License instead of this License.\n");
6419024598e40c84666cc311a42c256bbf880db3ac99sewardj
6420024598e40c84666cc311a42c256bbf880db3ac99sewardj  my_strcat(inbuf, "\n");
6421024598e40c84666cc311a42c256bbf880db3ac99sewardj}
6422024598e40c84666cc311a42c256bbf880db3ac99sewardj
6423024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <stdio.h>
6424024598e40c84666cc311a42c256bbf880db3ac99sewardj#include <assert.h>
6425024598e40c84666cc311a42c256bbf880db3ac99sewardj
6426024598e40c84666cc311a42c256bbf880db3ac99sewardj/* For providing services. */
6427024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic HWord g_serviceFn ( HWord arg1, HWord arg2 )
6428024598e40c84666cc311a42c256bbf880db3ac99sewardj{
6429024598e40c84666cc311a42c256bbf880db3ac99sewardj   switch (arg1) {
6430024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 0: /* EXIT */
6431024598e40c84666cc311a42c256bbf880db3ac99sewardj         exit(0);
6432024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 1: /* PUTC */
6433024598e40c84666cc311a42c256bbf880db3ac99sewardj         putchar(arg2);
6434024598e40c84666cc311a42c256bbf880db3ac99sewardj         return 0;
6435024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 2: /* MALLOC */
6436024598e40c84666cc311a42c256bbf880db3ac99sewardj         return (HWord)malloc(arg2);
6437024598e40c84666cc311a42c256bbf880db3ac99sewardj      case 3: /* FREE */
6438024598e40c84666cc311a42c256bbf880db3ac99sewardj         free((void*)arg2);
6439024598e40c84666cc311a42c256bbf880db3ac99sewardj         return 0;
6440024598e40c84666cc311a42c256bbf880db3ac99sewardj      default:
6441024598e40c84666cc311a42c256bbf880db3ac99sewardj         assert(0);
6442024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
6443024598e40c84666cc311a42c256bbf880db3ac99sewardj}
6444024598e40c84666cc311a42c256bbf880db3ac99sewardj
6445024598e40c84666cc311a42c256bbf880db3ac99sewardjstatic char *bzerrorstrings[] = {
6446024598e40c84666cc311a42c256bbf880db3ac99sewardj       "OK"
6447024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"SEQUENCE_ERROR"
6448024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"PARAM_ERROR"
6449024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"MEM_ERROR"
6450024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"DATA_ERROR"
6451024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"DATA_ERROR_MAGIC"
6452024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"IO_ERROR"
6453024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"UNEXPECTED_EOF"
6454024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"OUTBUFF_FULL"
6455024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"CONFIG_ERROR"
6456024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"???"   /* for future */
6457024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"???"   /* for future */
6458024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"???"   /* for future */
6459024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"???"   /* for future */
6460024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"???"   /* for future */
6461024598e40c84666cc311a42c256bbf880db3ac99sewardj       ,"???"   /* for future */
6462024598e40c84666cc311a42c256bbf880db3ac99sewardj};
6463024598e40c84666cc311a42c256bbf880db3ac99sewardj
6464024598e40c84666cc311a42c256bbf880db3ac99sewardj// If given a cmd line arg, behave as a correctness regtest
6465024598e40c84666cc311a42c256bbf880db3ac99sewardj// (run fast and be verbose).  If not, run for a long time
6466024598e40c84666cc311a42c256bbf880db3ac99sewardj// which is what is needed for the performance suite.
6467024598e40c84666cc311a42c256bbf880db3ac99sewardjint main ( int argc, char** argv )
6468024598e40c84666cc311a42c256bbf880db3ac99sewardj{
6469024598e40c84666cc311a42c256bbf880db3ac99sewardj   int   r;
6470024598e40c84666cc311a42c256bbf880db3ac99sewardj   int   bit;
6471024598e40c84666cc311a42c256bbf880db3ac99sewardj   int   i;
6472024598e40c84666cc311a42c256bbf880db3ac99sewardj
6473024598e40c84666cc311a42c256bbf880db3ac99sewardj   int regtest;
6474024598e40c84666cc311a42c256bbf880db3ac99sewardj   assert(argc == 1 || argc == 2);
6475024598e40c84666cc311a42c256bbf880db3ac99sewardj   regtest = argc==2;
6476024598e40c84666cc311a42c256bbf880db3ac99sewardj   regtest = 1;
6477024598e40c84666cc311a42c256bbf880db3ac99sewardj   serviceFn = g_serviceFn;
6478024598e40c84666cc311a42c256bbf880db3ac99sewardj
6479024598e40c84666cc311a42c256bbf880db3ac99sewardj   set_inbuf();
6480024598e40c84666cc311a42c256bbf880db3ac99sewardj   nIn = vex_strlen(inbuf)+1;
6481024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf( "%d bytes read\n", nIn );
6482024598e40c84666cc311a42c256bbf880db3ac99sewardj
6483024598e40c84666cc311a42c256bbf880db3ac99sewardj   nZ = M_BLOCK;
6484024598e40c84666cc311a42c256bbf880db3ac99sewardj   r = BZ2_bzBuffToBuffCompress (
6485024598e40c84666cc311a42c256bbf880db3ac99sewardj          zbuf, &nZ, inbuf, nIn, 9, 3/*verb*/, 30 );
6486024598e40c84666cc311a42c256bbf880db3ac99sewardj
6487024598e40c84666cc311a42c256bbf880db3ac99sewardj   if (r != BZ_OK) {
6488024598e40c84666cc311a42c256bbf880db3ac99sewardj     vex_printf("initial compress failed!\n");
6489024598e40c84666cc311a42c256bbf880db3ac99sewardj     (*serviceFn)(0,0);
6490024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
6491024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf( "%d after compression\n", nZ );
6492024598e40c84666cc311a42c256bbf880db3ac99sewardj
6493024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (bit = 0; bit < nZ*8; bit += (bit < 35 ? 1 : (regtest?2377:137))) {
6494024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (regtest)
6495024598e40c84666cc311a42c256bbf880db3ac99sewardj         vex_printf( "bit %d  ", bit );
6496024598e40c84666cc311a42c256bbf880db3ac99sewardj      flip_bit ( bit );
6497024598e40c84666cc311a42c256bbf880db3ac99sewardj      nOut = M_BLOCK_OUT;
6498024598e40c84666cc311a42c256bbf880db3ac99sewardj      r = BZ2_bzBuffToBuffDecompress (
6499024598e40c84666cc311a42c256bbf880db3ac99sewardj             outbuf, &nOut, zbuf, nZ, 1/*small*/, 0 );
6500024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (regtest)
6501024598e40c84666cc311a42c256bbf880db3ac99sewardj         vex_printf( " %d  %s ", r, bzerrorstrings[-r] );
6502024598e40c84666cc311a42c256bbf880db3ac99sewardj
6503024598e40c84666cc311a42c256bbf880db3ac99sewardj      if (r != BZ_OK) {
6504024598e40c84666cc311a42c256bbf880db3ac99sewardj	 if (regtest)
6505024598e40c84666cc311a42c256bbf880db3ac99sewardj            vex_printf( "\n" );
6506024598e40c84666cc311a42c256bbf880db3ac99sewardj      } else {
6507024598e40c84666cc311a42c256bbf880db3ac99sewardj         if (nOut != nIn) {
6508024598e40c84666cc311a42c256bbf880db3ac99sewardj           vex_printf(  "nIn/nOut mismatch %d %d\n", nIn, nOut );
6509024598e40c84666cc311a42c256bbf880db3ac99sewardj           (*serviceFn)(0,0);
6510024598e40c84666cc311a42c256bbf880db3ac99sewardj         } else {
6511024598e40c84666cc311a42c256bbf880db3ac99sewardj           for (i = 0; i < nOut; i++)
6512024598e40c84666cc311a42c256bbf880db3ac99sewardj             if (inbuf[i] != outbuf[i]) {
6513024598e40c84666cc311a42c256bbf880db3ac99sewardj                vex_printf(  "mismatch at %d\n", i );
6514024598e40c84666cc311a42c256bbf880db3ac99sewardj                (*serviceFn)(0,0);
6515024598e40c84666cc311a42c256bbf880db3ac99sewardj           }
6516024598e40c84666cc311a42c256bbf880db3ac99sewardj           if (i == nOut) vex_printf( "really ok!\n" );
6517024598e40c84666cc311a42c256bbf880db3ac99sewardj         }
6518024598e40c84666cc311a42c256bbf880db3ac99sewardj      }
6519024598e40c84666cc311a42c256bbf880db3ac99sewardj
6520024598e40c84666cc311a42c256bbf880db3ac99sewardj      flip_bit ( bit );
6521024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
6522024598e40c84666cc311a42c256bbf880db3ac99sewardj
6523024598e40c84666cc311a42c256bbf880db3ac99sewardj#if 0
6524024598e40c84666cc311a42c256bbf880db3ac99sewardj   assert (nOut == nIn);
6525024598e40c84666cc311a42c256bbf880db3ac99sewardj   for (i = 0; i < nOut; i++) {
6526024598e40c84666cc311a42c256bbf880db3ac99sewardj     if (inbuf[i] != outbuf[i]) {
6527024598e40c84666cc311a42c256bbf880db3ac99sewardj        vex_printf( "difference at %d !\n", i );
6528024598e40c84666cc311a42c256bbf880db3ac99sewardj        return 1;
6529024598e40c84666cc311a42c256bbf880db3ac99sewardj     }
6530024598e40c84666cc311a42c256bbf880db3ac99sewardj   }
6531024598e40c84666cc311a42c256bbf880db3ac99sewardj#endif
6532024598e40c84666cc311a42c256bbf880db3ac99sewardj
6533024598e40c84666cc311a42c256bbf880db3ac99sewardj   vex_printf( "all ok\n" );
6534024598e40c84666cc311a42c256bbf880db3ac99sewardj   (*serviceFn)(0,0);
6535024598e40c84666cc311a42c256bbf880db3ac99sewardj   /*NOTREACHED*/
6536024598e40c84666cc311a42c256bbf880db3ac99sewardj   return 0;
6537024598e40c84666cc311a42c256bbf880db3ac99sewardj}
6538