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