17cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// This benchmark is basically bzip2 (mashed to be a single file)
27cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// compressing and decompressing some data.  It tests Valgrind's handling of
37cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// realistic and "difficult" (ie. lots of branches and memory accesses)
47cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// integer code.  Execution is spread out over quite a few basic blocks;
57cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// --profile-flags indicates that to get to the top 90%th percentile of
67cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// dynamic BB counts requires considering the top 51 basic blocks
77cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
87cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// This program can be used both as part of the performance test
97cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// suite, in which case we want it to run for quite a while,
107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// and as part of the regression (correctness) test suite, in
117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// which case we want it to run quickly and be verbose.
127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// So it does the latter iff given a command line arg.
137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// Licensing: the code within is mostly taken from bzip2, which has a BSD
157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// license.  There is a little code from VEX, which is licensed under GPLv2
167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// And it's all written by Julian Seward.
177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_NO_STDIO
197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Private header file for the library.                  ---*/
237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                       bzlib_private.h ---*/
247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef _BZLIB_PRIVATE_H
827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define _BZLIB_PRIVATE_H
837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <stdlib.h>
857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_NO_STDIO
877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <stdio.h>
887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <ctype.h>
897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <string.h>
907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Public header file for the library.                   ---*/
957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                               bzlib.h ---*/
967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
1007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
1017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
1037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
1057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
1067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
1077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
1097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
1107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
1127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
1137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
1147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
1157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
1177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
1187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
1207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
1217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
1227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
1367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
1377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
1387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
1407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
1417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
1427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
1437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
1447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
1457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
1467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
1477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
1487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
1507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
1517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef _BZLIB_H
1547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define _BZLIB_H
1557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifdef __cplusplus
1577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern "C" {
1587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
1597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RUN               0
1617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_FLUSH             1
1627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_FINISH            2
1637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_OK                0
1657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RUN_OK            1
1667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_FLUSH_OK          2
1677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_FINISH_OK         3
1687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_STREAM_END        4
1697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_SEQUENCE_ERROR    (-1)
1707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_PARAM_ERROR       (-2)
1717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_MEM_ERROR         (-3)
1727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_DATA_ERROR        (-4)
1737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_DATA_ERROR_MAGIC  (-5)
1747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_IO_ERROR          (-6)
1757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_UNEXPECTED_EOF    (-7)
1767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_OUTBUFF_FULL      (-8)
1777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_CONFIG_ERROR      (-9)
1787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef
1807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   struct {
1817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      char *next_in;
1827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int avail_in;
1837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int total_in_lo32;
1847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int total_in_hi32;
1857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      char *next_out;
1877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int avail_out;
1887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int total_out_lo32;
1897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int total_out_hi32;
1907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void *state;
1927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void *(*bzalloc)(void *,int,int);
1947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void (*bzfree)(void *,void *);
1957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void *opaque;
1967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
1977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bz_stream;
1987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
1997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_IMPORT
2017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_EXPORT
2027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
2037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_NO_STDIO
2057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Need a definitition for FILE */
2067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <stdio.h>
2077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
2087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifdef _WIN32
2107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   include <windows.h>
2117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   ifdef small
2127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* windows.h define small to char */
2137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#      undef small
2147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   endif
2157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   ifdef BZ_EXPORT
2167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define BZ_API(func) WINAPI func
2177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define BZ_EXTERN extern
2187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   else
2197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* import windows dll dynamically */
2207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define BZ_API(func) (WINAPI * func)
2217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define BZ_EXTERN
2227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   endif
2237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#else
2247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define BZ_API(func) func
2257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define BZ_EXTERN extern
2267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
2277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Core (low-level) library functions --*/
2307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
2327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream* strm,
2337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int        blockSize100k,
2347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int        verbosity,
2357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int        workFactor
2367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzCompress) (
2397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream* strm,
2407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int action
2417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
2447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream* strm
2457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
2487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream *strm,
2497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int       verbosity,
2507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int       small
2517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzDecompress) (
2547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream* strm
2557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
2587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream *strm
2597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- High(er) level library functions --*/
2647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_NO_STDIO
2667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_MAX_UNUSED 5000
2677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef void BZFILE;
2697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
2717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*  bzerror,
2727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      FILE* f,
2737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int   verbosity,
2747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int   small,
2757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void* unused,
2767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int   nUnused
2777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN void BZ_API(BZ2_bzReadClose) (
2807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*    bzerror,
2817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b
2827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
2857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*    bzerror,
2867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b,
2877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void**  unused,
2887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*    nUnused
2897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzRead) (
2927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*    bzerror,
2937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b,
2947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void*   buf,
2957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int     len
2967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
2977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
2997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*  bzerror,
3007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      FILE* f,
3017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int   blockSize100k,
3027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int   verbosity,
3037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int   workFactor
3047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN void BZ_API(BZ2_bzWrite) (
3077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*    bzerror,
3087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b,
3097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void*   buf,
3107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int     len
3117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
3147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*          bzerror,
3157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE*       b,
3167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int           abandon,
3177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* nbytes_in,
3187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* nbytes_out
3197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
3227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int*          bzerror,
3237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE*       b,
3247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int           abandon,
3257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* nbytes_in_lo32,
3267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* nbytes_in_hi32,
3277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* nbytes_out_lo32,
3287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* nbytes_out_hi32
3297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
3317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Utility functions --*/
3347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
3367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      char*         dest,
3377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* destLen,
3387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      char*         source,
3397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int  sourceLen,
3407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int           blockSize100k,
3417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int           verbosity,
3427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int           workFactor
3437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
3467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      char*         dest,
3477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int* destLen,
3487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      char*         source,
3497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int  sourceLen,
3507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int           small,
3517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int           verbosity
3527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
3567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Code contributed by Yoshioka Tsuneo
3577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
3587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   to support better zlib compatibility.
3597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   This code is not _officially_ part of libbzip2 (yet);
3607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   I haven't tested it, documented it, or considered the
3617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   threading-safeness of it.
3627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   If this code breaks, please contact both Yoshioka and me.
3637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
3647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
3667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void
3677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_NO_STDIO
3707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
3717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      const char *path,
3727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      const char *mode
3737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
3767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int        fd,
3777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      const char *mode
3787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzread) (
3817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b,
3827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void* buf,
3837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int len
3847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzwrite) (
3877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b,
3887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      void*   buf,
3897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int     len
3907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN int BZ_API(BZ2_bzflush) (
3937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b
3947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
3967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN void BZ_API(BZ2_bzclose) (
3977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE* b
3987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
3997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ_EXTERN const char * BZ_API(BZ2_bzerror) (
4017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZFILE *b,
4027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      int    *errnum
4037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   );
4047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
4057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifdef __cplusplus
4077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
4087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
4097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
4117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
4137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                           bzlib.h ---*/
4147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
4157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- General stuff. --*/
4207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_VERSION  "1.0.3, 17-Oct-2004"
4227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef char            Char;
4247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef unsigned char   Bool;
4257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef unsigned char   UChar;
4267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef int             Int32;
4277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef unsigned int    UInt32;
4287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef short           Int16;
4297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef unsigned short  UInt16;
4307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define True  ((Bool)1)
4327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define False ((Bool)0)
4337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef __GNUC__
4357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define __inline__  /* */
4367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
4377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_NO_STDIO
4397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void BZ2_bz__AssertH__fail ( int errcode );
4407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define AssertH(cond,errcode) \
4417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
4427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#if BZ_DEBUG
4437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define AssertD(cond,msg) \
4447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { if (!(cond)) {       \
4457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fprintf ( stderr,   \
4467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
4477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      exit(1); \
4487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }}
4497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#else
4507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define AssertD(cond,msg) /* */
4517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
4527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf0(zf) \
4537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   fprintf(stderr,zf)
4547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf1(zf,za1) \
4557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   fprintf(stderr,zf,za1)
4567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf2(zf,za1,za2) \
4577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   fprintf(stderr,zf,za1,za2)
4587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf3(zf,za1,za2,za3) \
4597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   fprintf(stderr,zf,za1,za2,za3)
4607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf4(zf,za1,za2,za3,za4) \
4617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   fprintf(stderr,zf,za1,za2,za3,za4)
4627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
4637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   fprintf(stderr,zf,za1,za2,za3,za4,za5)
4647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#else
4657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void bz_internal_error ( int errcode );
4667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define AssertH(cond,errcode) \
4677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { if (!(cond)) bz_internal_error ( errcode ); }
4687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define AssertD(cond,msg) /* */
4697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf0(zf) \
4707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf(zf)
4717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf1(zf,za1) \
4727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf(zf,za1)
4737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf2(zf,za1,za2) \
4747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf(zf,za1,za2)
4757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf3(zf,za1,za2,za3) \
4767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf(zf,za1,za2,za3)
4777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf4(zf,za1,za2,za3,za4) \
4787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf(zf,za1,za2,za3,za4)
4797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
4807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf(zf,za1,za2,za3,za4,za5)
4817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
4827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
4857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
4867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Header bytes. --*/
4897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_HDR_B 0x42   /* 'B' */
4917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_HDR_Z 0x5a   /* 'Z' */
4927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_HDR_h 0x68   /* 'h' */
4937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_HDR_0 0x30   /* '0' */
4947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Constants for the back end. --*/
4967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
4977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_MAX_ALPHA_SIZE 258
4987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_MAX_CODE_LEN    23
4997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RUNA 0
5017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RUNB 1
5027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_N_GROUPS 6
5047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_G_SIZE   50
5057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_N_ITERS  4
5067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
5087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Stuff for randomising repetitive blocks. --*/
5127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern Int32 BZ2_rNums[512];
5147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RAND_DECLS                          \
5167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 rNToGo;                               \
5177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 rTPos                                 \
5187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RAND_INIT_MASK                      \
5207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->rNToGo = 0;                              \
5217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->rTPos  = 0                               \
5227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
5247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_RAND_UPD_MASK                       \
5267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->rNToGo == 0) {                       \
5277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->rNToGo = BZ2_rNums[s->rTPos];         \
5287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->rTPos++;                              \
5297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->rTPos == 512) s->rTPos = 0;       \
5307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                           \
5317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->rNToGo--;
5327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Stuff for doing CRCs. --*/
5367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern UInt32 BZ2_crc32Table[256];
5387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_INITIALISE_CRC(crcVar)              \
5407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                              \
5417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   crcVar = 0xffffffffL;                       \
5427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
5437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_FINALISE_CRC(crcVar)                \
5457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                              \
5467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   crcVar = ~(crcVar);                         \
5477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
5487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_UPDATE_CRC(crcVar,cha)              \
5507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                              \
5517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   crcVar = (crcVar << 8) ^                    \
5527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ2_crc32Table[(crcVar >> 24) ^    \
5537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           ((UChar)cha)];      \
5547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
5557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- States and modes for compression. --*/
5597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_M_IDLE      1
5617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_M_RUNNING   2
5627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_M_FLUSHING  3
5637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_M_FINISHING 4
5647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_S_OUTPUT    1
5667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_S_INPUT     2
5677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_N_RADIX 2
5697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_N_QSORT 12
5707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_N_SHELL 18
5717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
5727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Structure holding all the compression-side stuff. --*/
5777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef
5797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   struct {
5807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* pointer back to the struct bz_stream */
5817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream* strm;
5827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* mode this stream is in, and whether inputting */
5847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* or outputting data */
5857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    mode;
5867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    state;
5877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* remembers avail_in when flush/finish requested */
5897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   avail_in_expect;
5907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* for doing the block sorting */
5927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32*  arr1;
5937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32*  arr2;
5947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32*  ftab;
5957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    origPtr;
5967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
5977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* aliases for arr1 and arr2 */
5987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32*  ptr;
5997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar*   block;
6007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt16*  mtfv;
6017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar*   zbits;
6027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* for deciding when to use the fallback sorting algorithm */
6047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    workFactor;
6057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* run-length-encoding of the input */
6077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   state_in_ch;
6087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    state_in_len;
6097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ_RAND_DECLS;
6107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* input and output limits and current posns */
6127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    nblock;
6137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    nblockMAX;
6147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    numZ;
6157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    state_out_pos;
6167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* map of bytes used in block */
6187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    nInUse;
6197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool     inUse[256];
6207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    unseqToSeq[256];
6217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* the buffer for bit stream creation */
6237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   bsBuff;
6247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    bsLive;
6257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* block and combined CRCs */
6277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   blockCRC;
6287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   combinedCRC;
6297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* misc administratium */
6317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    verbosity;
6327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    blockNo;
6337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    blockSize100k;
6347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* stuff for coding the MTF values */
6367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    nMTF;
6377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
6387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    selector   [BZ_MAX_SELECTORS];
6397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
6407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
6427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
6437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
6447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* second dimension: only 3 needed; 4 makes index calculations faster */
6457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
6467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
6487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   EState;
6497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- externs for compression. --*/
6537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void
6557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_blockSort ( EState* );
6567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void
6587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_compressBlock ( EState*, Bool );
6597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void
6617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_bsInitWrite ( EState* );
6627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void
6647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
6657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void
6677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
6687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- states for decompression. --*/
6727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_IDLE        1
6747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_OUTPUT      2
6757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MAGIC_1     10
6777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MAGIC_2     11
6787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MAGIC_3     12
6797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MAGIC_4     13
6807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BLKHDR_1    14
6817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BLKHDR_2    15
6827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BLKHDR_3    16
6837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BLKHDR_4    17
6847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BLKHDR_5    18
6857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BLKHDR_6    19
6867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BCRC_1      20
6877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BCRC_2      21
6887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BCRC_3      22
6897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_BCRC_4      23
6907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_RANDBIT     24
6917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ORIGPTR_1   25
6927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ORIGPTR_2   26
6937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ORIGPTR_3   27
6947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MAPPING_1   28
6957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MAPPING_2   29
6967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_SELECTOR_1  30
6977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_SELECTOR_2  31
6987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_SELECTOR_3  32
6997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_CODING_1    33
7007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_CODING_2    34
7017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_CODING_3    35
7027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MTF_1       36
7037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MTF_2       37
7047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MTF_3       38
7057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MTF_4       39
7067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MTF_5       40
7077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_MTF_6       41
7087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ENDHDR_2    42
7097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ENDHDR_3    43
7107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ENDHDR_4    44
7117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ENDHDR_5    45
7127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_ENDHDR_6    46
7137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_CCRC_1      47
7147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_CCRC_2      48
7157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_CCRC_3      49
7167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_X_CCRC_4      50
7177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Constants for the fast MTF decoder. --*/
7217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define MTFA_SIZE 4096
7237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define MTFL_SIZE 16
7247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Structure holding all the decompression-side stuff. --*/
7287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef
7307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   struct {
7317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* pointer back to the struct bz_stream */
7327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream* strm;
7337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* state indicator for this stream */
7357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    state;
7367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* for doing the final run-length decoding */
7387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    state_out_ch;
7397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    state_out_len;
7407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool     blockRandomised;
7417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ_RAND_DECLS;
7427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* the buffer for bit stream reading */
7447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   bsBuff;
7457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    bsLive;
7467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* misc administratium */
7487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    blockSize100k;
7497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool     smallDecompress;
7507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    currBlockNo;
7517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    verbosity;
7527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* for undoing the Burrows-Wheeler transform */
7547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    origPtr;
7557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   tPos;
7567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    k0;
7577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    unzftab[256];
7587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    nblock_used;
7597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    cftab[257];
7607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    cftabCopy[257];
7617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* for undoing the Burrows-Wheeler transform (FAST) */
7637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   *tt;
7647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* for undoing the Burrows-Wheeler transform (SMALL) */
7667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt16   *ll16;
7677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    *ll4;
7687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* stored and calculated CRCs */
7707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   storedBlockCRC;
7717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   storedCombinedCRC;
7727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   calculatedBlockCRC;
7737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32   calculatedCombinedCRC;
7747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* map of bytes used in block */
7767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    nInUse;
7777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool     inUse[256];
7787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool     inUse16[16];
7797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    seqToUnseq[256];
7807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* for decoding the MTF values */
7827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    mtfa   [MTFA_SIZE];
7837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    mtfbase[256 / MTFL_SIZE];
7847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    selector   [BZ_MAX_SELECTORS];
7857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
7867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    minLens[BZ_N_GROUPS];
7927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
7937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* save area for scalars in the main decompress code */
7947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_i;
7957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_j;
7967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_t;
7977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_alphaSize;
7987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_nGroups;
7997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_nSelectors;
8007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_EOB;
8017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_groupNo;
8027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_groupPos;
8037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_nextSym;
8047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_nblockMAX;
8057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_nblock;
8067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_es;
8077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_N;
8087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_curr;
8097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_zt;
8107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_zn;
8117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_zvec;
8127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_zj;
8137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_gSel;
8147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32    save_gMinlen;
8157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32*   save_gLimit;
8167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32*   save_gBase;
8177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32*   save_gPerm;
8187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
8207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   DState;
8217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- Macros for decompression. --*/
8257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_GET_FAST(cccc)                     \
8277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    s->tPos = s->tt[s->tPos];                 \
8287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    cccc = (UChar)(s->tPos & 0xff);           \
8297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    s->tPos >>= 8;
8307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_GET_FAST_C(cccc)                   \
8327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    c_tPos = c_tt[c_tPos];                    \
8337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    cccc = (UChar)(c_tPos & 0xff);            \
8347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    c_tPos >>= 8;
8357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define SET_LL4(i,n)                                          \
8377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { if (((i) & 0x1) == 0)                                    \
8387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
8397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
8407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
8417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define GET_LL4(i)                             \
8437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
8447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define SET_LL(i,n)                          \
8467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
8477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     SET_LL4(i, n >> 16);                    \
8487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
8497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define GET_LL(i) \
8517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
8527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_GET_SMALL(cccc)                            \
8547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
8557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->tPos = GET_LL(s->tPos);
8567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- externs for decompression. --*/
8597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern Int32
8617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_indexIntoF ( Int32, Int32* );
8627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern Int32
8647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_decompress ( DState* );
8657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjextern void
8677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
8687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           Int32,  Int32, Int32 );
8697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
8727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
8757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifdef BZ_NO_STDIO
8777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef NULL
8787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define NULL 0
8797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
8807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
8817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
8847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                   bzlib_private.h ---*/
8857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
8867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Something which has the same size as void* on the host.  That is,
8897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   it is 32 bits on a 32-bit host and 64 bits on a 64-bit host, and so
8907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   it can safely be coerced to and from a pointer type on the host
8917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   machine. */
8927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef  unsigned long HWord;
8937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef  char          HChar;
8947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef  signed int    Int;
8957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef  unsigned int  UInt;
8967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
8977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef    signed long long int   Long;
8987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef  unsigned long long int   ULong;
8997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
9027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
9037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic HWord (*serviceFn)(HWord,HWord) = 0;
9057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#if 0
9077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic char* my_strcpy ( char* dest, const char* src )
9087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
9097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   char* dest_orig = dest;
9107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (*src) *dest++ = *src++;
9117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   *dest = 0;
9127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return dest_orig;
9137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
9147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void* my_memcpy ( void *dest, const void *src, int sz )
9167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
9177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   const char *s = (const char *)src;
9187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   char *d = (char *)dest;
9197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (sz--)
9217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      *d++ = *s++;
9227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return dest;
9247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
9257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void* my_memmove( void *dst, const void *src, unsigned int len )
9277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
9287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    register char *d;
9297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    register char *s;
9307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    if ( dst > src ) {
9317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        d = (char *)dst + len - 1;
9327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        s = (char *)src + len - 1;
9337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        while ( len >= 4 ) {
9347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d-- = *s--;
9357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d-- = *s--;
9367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d-- = *s--;
9377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d-- = *s--;
9387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            len -= 4;
9397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        }
9407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        while ( len-- ) {
9417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d-- = *s--;
9427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        }
9437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    } else if ( dst < src ) {
9447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        d = (char *)dst;
9457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        s = (char *)src;
9467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        while ( len >= 4 ) {
9477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d++ = *s++;
9487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d++ = *s++;
9497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d++ = *s++;
9507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d++ = *s++;
9517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            len -= 4;
9527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        }
9537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        while ( len-- ) {
9547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *d++ = *s++;
9557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        }
9567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    }
9577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    return dst;
9587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
9597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
9607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjchar* my_strcat ( char* dest, const char* src )
9627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
9637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   char* dest_orig = dest;
9647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (*dest) dest++;
9657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (*src) *dest++ = *src++;
9667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   *dest = 0;
9677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return dest_orig;
9687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
9697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
9727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void vex_log_bytes ( char* p, int n )
9747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
9757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int i;
9767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < n; i++)
9777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      (*serviceFn)( 1, (int)p[i] );
9787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
9797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------------*/
9817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- vex_printf                                        ---*/
9827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------------*/
9837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* This should be the only <...> include in the entire VEX library.
9857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   New code for vex_util.c should go above this point. */
9867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <stdarg.h>
9877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic HChar vex_toupper ( HChar c )
9897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
9907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c >= 'a' && c <= 'z')
9917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return c + ('A' - 'a');
9927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   else
9937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return c;
9947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
9957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
9967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic Int vex_strlen ( const HChar* str )
9977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
9987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int i = 0;
9997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (str[i] != 0) i++;
10007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return i;
10017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
10027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool vex_streq ( const HChar* s1, const HChar* s2 )
10047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
10057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
10067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (*s1 == 0 && *s2 == 0)
10077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return True;
10087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (*s1 != *s2)
10097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return False;
10107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1++;
10117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s2++;
10127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
10137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
10147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Some flags.  */
10167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VG_MSG_SIGNED    1 /* The value is signed. */
10177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VG_MSG_ZJUSTIFY  2 /* Must justify with '0'. */
10187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VG_MSG_LJUSTIFY  4 /* Must justify on the left. */
10197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VG_MSG_PAREN     8 /* Parenthesize if present (for %y) */
10207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define VG_MSG_COMMA    16 /* Add commas to numbers (for %d, %u) */
10217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Copy a string into the buffer. */
10237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic UInt
10247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjmyvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
10257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                Bool capitalise )
10267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
10277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#  define MAYBE_TOUPPER(ch) (capitalise ? vex_toupper(ch) : (ch))
10287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt ret = 0;
10297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int i, extra;
10307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int len = vex_strlen(str);
10317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (width == 0) {
10337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ret += len;
10347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < len; i++)
10357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         send(MAYBE_TOUPPER(str[i]));
10367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return ret;
10377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
10387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (len > width) {
10407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ret += width;
10417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < width; i++)
10427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         send(MAYBE_TOUPPER(str[i]));
10437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return ret;
10447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
10457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   extra = width - len;
10477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (flags & VG_MSG_LJUSTIFY) {
10487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ret += extra;
10497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < extra; i++)
10507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         send(' ');
10517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
10527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret += len;
10537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < len; i++)
10547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      send(MAYBE_TOUPPER(str[i]));
10557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (!(flags & VG_MSG_LJUSTIFY)) {
10567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ret += extra;
10577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < extra; i++)
10587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         send(' ');
10597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
10607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#  undef MAYBE_TOUPPER
10627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return ret;
10647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
10657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Write P into the buffer according to these args:
10677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj *  If SIGN is true, p is a signed.
10687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj *  BASE is the base.
10697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj *  If WITH_ZERO is true, '0' must be added.
10707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj *  WIDTH is the width of the field.
10717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj */
10727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic UInt
10737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjmyvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
10747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
10757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   HChar buf[40];
10767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int   ind = 0;
10777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int   i, nc = 0;
10787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool  neg = False;
10797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   HChar *digits = "0123456789ABCDEF";
10807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt  ret = 0;
10817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt  p = (UInt)pL;
10827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (base < 2 || base > 16)
10847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return ret;
10857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
10877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      p   = - (Int)p;
10887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      neg = True;
10897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
10907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
10917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (p == 0)
10927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      buf[ind++] = '0';
10937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   else {
10947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (p > 0) {
10957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if ((flags & VG_MSG_COMMA) && 10 == base &&
10967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             0 == (ind-nc) % 3 && 0 != ind)
10977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         {
10987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            buf[ind++] = ',';
10997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            nc++;
11007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
11017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         buf[ind++] = digits[p % base];
11027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         p /= base;
11037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
11057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (neg)
11077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      buf[ind++] = '-';
11087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
11107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for(; ind < width; ind++) {
11117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	//vassert(ind < 39);
11127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         buf[ind] = ((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
11137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
11157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* Reverse copy to buffer.  */
11177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret += ind;
11187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = ind -1; i >= 0; i--) {
11197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      send(buf[i]);
11207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
11217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
11227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for(; ind < width; ind++) {
11237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 ret++;
11247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         send(' ');  // Never pad with zeroes on RHS -- changes the value!
11257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
11277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return ret;
11287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
11297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* A simple vprintf().  */
11327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
11337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjUInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
11347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
11357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt ret = 0;
11367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int i;
11377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int flags;
11387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int width;
11397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool is_long;
11407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* We assume that vargs has already been initialised by the
11427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      caller, using va_start, and that the caller will similarly
11437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      clean up with va_end.
11447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   */
11457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; format[i] != 0; i++) {
11477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (format[i] != '%') {
11487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         send(format[i]);
11497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 ret++;
11507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         continue;
11517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i++;
11537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* A '%' has been found.  Ignore a trailing %. */
11547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (format[i] == 0)
11557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         break;
11567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (format[i] == '%') {
11577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* `%%' is replaced by `%'. */
11587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         send('%');
11597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 ret++;
11607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         continue;
11617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      flags = 0;
11637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      is_long = False;
11647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      width = 0; /* length of the field. */
11657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (format[i] == '(') {
11667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 flags |= VG_MSG_PAREN;
11677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 i++;
11687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* If ',' follows '%', commas will be inserted. */
11707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (format[i] == ',') {
11717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         flags |= VG_MSG_COMMA;
11727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i++;
11737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* If '-' follows '%', justify on the left. */
11757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (format[i] == '-') {
11767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         flags |= VG_MSG_LJUSTIFY;
11777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i++;
11787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* If '0' follows '%', pads will be inserted. */
11807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (format[i] == '0') {
11817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         flags |= VG_MSG_ZJUSTIFY;
11827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i++;
11837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* Compute the field length. */
11857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (format[i] >= '0' && format[i] <= '9') {
11867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         width *= 10;
11877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         width += format[i++] - '0';
11887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (format[i] == 'l') {
11907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i++;
11917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         is_long = True;
11927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
11937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
11947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      switch (format[i]) {
11957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         case 'd': /* %d */
11967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            flags |= VG_MSG_SIGNED;
11977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (is_long)
11987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ret += myvprintf_int64(send, flags, 10, width,
11997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj				      (ULong)(va_arg (vargs, Long)));
12007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            else
12017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ret += myvprintf_int64(send, flags, 10, width,
12027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj				      (ULong)(va_arg (vargs, Int)));
12037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
12047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         case 'u': /* %u */
12057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (is_long)
12067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ret += myvprintf_int64(send, flags, 10, width,
12077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj				      (ULong)(va_arg (vargs, ULong)));
12087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            else
12097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ret += myvprintf_int64(send, flags, 10, width,
12107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj				      (ULong)(va_arg (vargs, UInt)));
12117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
12127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         case 'p': /* %p */
12137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	    ret += 2;
12147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            send('0');
12157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            send('x');
12167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ret += myvprintf_int64(send, flags, 16, width,
12177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj				   (ULong)((HWord)va_arg (vargs, void *)));
12187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
12197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         case 'x': /* %x */
12207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (is_long)
12217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ret += myvprintf_int64(send, flags, 16, width,
12227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj				      (ULong)(va_arg (vargs, ULong)));
12237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            else
12247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ret += myvprintf_int64(send, flags, 16, width,
12257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj				      (ULong)(va_arg (vargs, UInt)));
12267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
12277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         case 'c': /* %c */
12287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	    ret++;
12297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            send((va_arg (vargs, int)));
12307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
12317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         case 's': case 'S': { /* %s */
12327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            char *str = va_arg (vargs, char *);
12337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (str == (char*) 0) str = "(null)";
12347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ret += myvprintf_str(send, flags, width, str,
12357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                 (format[i]=='S'));
12367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
12377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 }
12387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#        if 0
12397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 case 'y': { /* %y - print symbol */
12407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	    Addr a = va_arg(vargs, Addr);
12417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
124246cc04521acf2827eb33310fadc119bf2dc039e4florian
124346cc04521acf2827eb33310fadc119bf2dc039e4florian
124446cc04521acf2827eb33310fadc119bf2dc039e4florian            HChar *name;
124546cc04521acf2827eb33310fadc119bf2dc039e4florian	    if (VG_(get_fnname_w_offset)(a, &name)) {
124646cc04521acf2827eb33310fadc119bf2dc039e4florian               HChar buf[1 + VG_strlen(name) + 1 + 1];
12477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	       if (flags & VG_MSG_PAREN) {
124846cc04521acf2827eb33310fadc119bf2dc039e4florian                  VG_(sprintf)(str, "(%s)", name):
124946cc04521acf2827eb33310fadc119bf2dc039e4florian	       } else {
125046cc04521acf2827eb33310fadc119bf2dc039e4florian                  VG_(sprintf)(str, "%s", name):
125146cc04521acf2827eb33310fadc119bf2dc039e4florian               }
12527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	       ret += myvprintf_str(send, flags, width, buf, 0);
12537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	    }
12547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	    break;
12557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 }
12567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#        endif
12577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         default:
12587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
12597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
12607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
12617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return ret;
12627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
12637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* A general replacement for printf().  Note that only low-level
12667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   debugging info should be sent via here.  The official route is to
12677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   to use vg_message().  This interface is deprecated.
12687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj*/
12697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic HChar myprintf_buf[1000];
12707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic Int   n_myprintf_buf;
12717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic void add_to_myprintf_buf ( HChar c )
12737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
12747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
12757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      (*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) );
12767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      n_myprintf_buf = 0;
12777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      myprintf_buf[n_myprintf_buf] = 0;
12787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
12797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   myprintf_buf[n_myprintf_buf++] = c;
12807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   myprintf_buf[n_myprintf_buf] = 0;
12817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
12827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic UInt vex_printf ( const char *format, ... )
12847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
12857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt ret;
12867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   va_list vargs;
12877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   va_start(vargs,format);
12887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   n_myprintf_buf = 0;
12907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   myprintf_buf[n_myprintf_buf] = 0;
12917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
12927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (n_myprintf_buf > 0) {
12947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      (*vex_log_bytes)( myprintf_buf, n_myprintf_buf );
12957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
12967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   va_end(vargs);
12987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
12997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return ret;
13007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
13017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------------------*/
13037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                          vex_util.c ---*/
13047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------------------*/
13057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
13087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
13097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
13107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
13117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
13147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Decompression machinery                               ---*/
13157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                          decompress.c ---*/
13167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
13177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
13197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
13207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
13217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
13237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
13257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
13267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
13277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
13297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
13307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
13327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
13337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
13347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
13357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
13377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
13387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
13407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
13417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
13427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
13447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
13497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
13507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
13517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
13527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
13567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
13577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
13587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
13607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
13617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
13627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
13637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
13647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
13657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
13667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
13677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
13687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
13707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
13717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
13767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
13777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid makeMaps_d ( DState* s )
13787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
13797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 i;
13807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->nInUse = 0;
13817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < 256; i++)
13827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->inUse[i]) {
13837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->seqToUnseq[s->nInUse] = i;
13847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->nInUse++;
13857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
13867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
13877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
13907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define RETURN(rrr)                               \
13917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { retVal = rrr; goto save_state_and_return; };
13927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
13937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define GET_BITS(lll,vvv,nnn)                     \
13947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   case lll: s->state = lll;                      \
13957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {                                 \
13967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->bsLive >= nnn) {                     \
13977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         UInt32 v;                                \
13987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         v = (s->bsBuff >>                        \
13997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
14007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->bsLive -= nnn;                        \
14017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         vvv = v;                                 \
14027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         break;                                   \
14037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }                                           \
14047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
14057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->bsBuff                                   \
14067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         = (s->bsBuff << 8) |                     \
14077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           ((UInt32)                              \
14087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj              (*((UChar*)(s->strm->next_in))));   \
14097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->bsLive += 8;                             \
14107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->next_in++;                         \
14117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->avail_in--;                        \
14127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->total_in_lo32++;                   \
14137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->strm->total_in_lo32 == 0)            \
14147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->total_in_hi32++;                \
14157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
14167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define GET_UCHAR(lll,uuu)                        \
14187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   GET_BITS(lll,uuu,8)
14197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define GET_BIT(lll,uuu)                          \
14217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   GET_BITS(lll,uuu,1)
14227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
14247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define GET_MTF_VAL(label1,label2,lval)           \
14257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                                 \
14267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (groupPos == 0) {                           \
14277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      groupNo++;                                  \
14287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (groupNo >= nSelectors)                  \
14297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         RETURN(BZ_DATA_ERROR);                   \
14307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      groupPos = BZ_G_SIZE;                       \
14317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gSel = s->selector[groupNo];                \
14327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gMinlen = s->minLens[gSel];                 \
14337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gLimit = &(s->limit[gSel][0]);              \
14347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gPerm = &(s->perm[gSel][0]);                \
14357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gBase = &(s->base[gSel][0]);                \
14367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                              \
14377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   groupPos--;                                    \
14387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zn = gMinlen;                                  \
14397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   GET_BITS(label1, zvec, zn);                    \
14407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (1) {                                    \
14417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (zn > 20 /* the longest code */)         \
14427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         RETURN(BZ_DATA_ERROR);                   \
14437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (zvec <= gLimit[zn]) break;              \
14447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zn++;                                       \
14457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_BIT(label2, zj);                        \
14467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zvec = (zvec << 1) | zj;                    \
14477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   };                                             \
14487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (zvec - gBase[zn] < 0                       \
14497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
14507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      RETURN(BZ_DATA_ERROR);                      \
14517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   lval = gPerm[zvec - gBase[zn]];                \
14527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
14537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
14577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
14587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
14597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nb, na, mid;
14607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nb = 0;
14617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   na = 256;
14627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   do {
14637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mid = (nb + na) >> 1;
14647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (indx >= cftab[mid]) nb = mid; else na = mid;
14657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
14667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (na - nb != 1);
14677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return nb;
14687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
14697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
14717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjInt32 BZ2_decompress ( DState* s )
14727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
14737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar      uc;
14747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32      retVal;
14757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32      minLen, maxLen;
14767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bz_stream* strm = s->strm;
14777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
14787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* stuff that needs to be saved/restored */
14797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  i;
14807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  j;
14817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  t;
14827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  alphaSize;
14837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  nGroups;
14847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  nSelectors;
14857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  EOB;
14867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  groupNo;
14877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  groupPos;
14887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  nextSym;
14897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  nblockMAX;
14907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  nblock;
14917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  es;
14927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  N;
14937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  curr;
14947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  zt;
14957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  zn;
14967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  zvec;
14977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  zj;
14987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  gSel;
14997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  gMinlen;
15007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32* gLimit;
15017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32* gBase;
15027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32* gPerm;
15037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->state == BZ_X_MAGIC_1) {
15057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*initialise the save area*/
15067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_i           = 0;
15077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_j           = 0;
15087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_t           = 0;
15097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_alphaSize   = 0;
15107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_nGroups     = 0;
15117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_nSelectors  = 0;
15127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_EOB         = 0;
15137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_groupNo     = 0;
15147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_groupPos    = 0;
15157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_nextSym     = 0;
15167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_nblockMAX   = 0;
15177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_nblock      = 0;
15187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_es          = 0;
15197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_N           = 0;
15207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_curr        = 0;
15217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_zt          = 0;
15227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_zn          = 0;
15237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_zvec        = 0;
15247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_zj          = 0;
15257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_gSel        = 0;
15267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_gMinlen     = 0;
15277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_gLimit      = NULL;
15287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_gBase       = NULL;
15297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->save_gPerm       = NULL;
15307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
15317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*restore from the save area*/
15337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i           = s->save_i;
15347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   j           = s->save_j;
15357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   t           = s->save_t;
15367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   alphaSize   = s->save_alphaSize;
15377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nGroups     = s->save_nGroups;
15387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nSelectors  = s->save_nSelectors;
15397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   EOB         = s->save_EOB;
15407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   groupNo     = s->save_groupNo;
15417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   groupPos    = s->save_groupPos;
15427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nextSym     = s->save_nextSym;
15437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nblockMAX   = s->save_nblockMAX;
15447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nblock      = s->save_nblock;
15457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   es          = s->save_es;
15467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   N           = s->save_N;
15477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   curr        = s->save_curr;
15487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zt          = s->save_zt;
15497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zn          = s->save_zn;
15507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zvec        = s->save_zvec;
15517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zj          = s->save_zj;
15527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   gSel        = s->save_gSel;
15537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   gMinlen     = s->save_gMinlen;
15547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   gLimit      = s->save_gLimit;
15557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   gBase       = s->save_gBase;
15567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   gPerm       = s->save_gPerm;
15577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   retVal = BZ_OK;
15597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   switch (s->state) {
15617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_MAGIC_1, uc);
15637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
15647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_MAGIC_2, uc);
15667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
15677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_MAGIC_3, uc)
15697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
15707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
15727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->blockSize100k < (BZ_HDR_0 + 1) ||
15737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
15747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->blockSize100k -= BZ_HDR_0;
15757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->smallDecompress) {
15777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
15787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->ll4  = BZALLOC(
15797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
15807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   );
15817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
15827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } else {
15837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
15847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
15857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
15867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BLKHDR_1, uc);
15887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
15897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc == 0x17) goto endhdr_2;
15907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
15917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BLKHDR_2, uc);
15927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
15937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BLKHDR_3, uc);
15947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
15957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BLKHDR_4, uc);
15967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
15977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BLKHDR_5, uc);
15987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
15997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BLKHDR_6, uc);
16007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
16017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->currBlockNo++;
16037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->verbosity >= 2)
16047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
16057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedBlockCRC = 0;
16077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BCRC_1, uc);
16087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
16097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BCRC_2, uc);
16107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
16117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BCRC_3, uc);
16127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
16137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_BCRC_4, uc);
16147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
16157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
16177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->origPtr = 0;
16197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
16207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
16217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
16227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
16237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
16247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
16257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->origPtr < 0)
16277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         RETURN(BZ_DATA_ERROR);
16287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->origPtr > 10 + 100000*s->blockSize100k)
16297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         RETURN(BZ_DATA_ERROR);
16307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--- Receive the mapping table ---*/
16327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < 16; i++) {
16337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         GET_BIT(BZ_X_MAPPING_1, uc);
16347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (uc == 1)
16357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->inUse16[i] = True; else
16367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->inUse16[i] = False;
16377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
16387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < 256; i++) s->inUse[i] = False;
16407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < 16; i++)
16427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->inUse16[i])
16437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            for (j = 0; j < 16; j++) {
16447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               GET_BIT(BZ_X_MAPPING_2, uc);
16457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (uc == 1) s->inUse[i * 16 + j] = True;
16467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
16477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      makeMaps_d ( s );
16487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
16497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      alphaSize = s->nInUse+2;
16507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--- Now the selectors ---*/
16527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
16537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
16547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
16557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
16567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < nSelectors; i++) {
16577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = 0;
16587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (True) {
16597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            GET_BIT(BZ_X_SELECTOR_3, uc);
16607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (uc == 0) break;
16617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j++;
16627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
16637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
16647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->selectorMtf[i] = j;
16657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
16667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--- Undo the MTF values for the selectors. ---*/
16687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      {
16697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         UChar pos[BZ_N_GROUPS], tmp, v;
16707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (v = 0; v < nGroups; v++) pos[v] = v;
16717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = 0; i < nSelectors; i++) {
16737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            v = s->selectorMtf[i];
16747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            tmp = pos[v];
16757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (v > 0) { pos[v] = pos[v-1]; v--; }
16767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            pos[0] = tmp;
16777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->selector[i] = tmp;
16787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
16797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
16807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--- Now the coding tables ---*/
16827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (t = 0; t < nGroups; t++) {
16837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         GET_BITS(BZ_X_CODING_1, curr, 5);
16847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = 0; i < alphaSize; i++) {
16857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (True) {
16867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
16877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               GET_BIT(BZ_X_CODING_2, uc);
16887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (uc == 0) break;
16897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               GET_BIT(BZ_X_CODING_3, uc);
16907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (uc == 0) curr++; else curr--;
16917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
16927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->len[t][i] = curr;
16937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
16947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
16957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
16967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--- Create the Huffman decoding tables ---*/
16977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (t = 0; t < nGroups; t++) {
16987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         minLen = 32;
16997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         maxLen = 0;
17007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = 0; i < alphaSize; i++) {
17017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
17027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->len[t][i] < minLen) minLen = s->len[t][i];
17037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
17047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ2_hbCreateDecodeTables (
17057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            &(s->limit[t][0]),
17067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            &(s->base[t][0]),
17077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            &(s->perm[t][0]),
17087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            &(s->len[t][0]),
17097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            minLen, maxLen, alphaSize
17107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         );
17117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->minLens[t] = minLen;
17127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
17137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--- Now the MTF values ---*/
17157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      EOB      = s->nInUse+1;
17177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nblockMAX = 100000 * s->blockSize100k;
17187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      groupNo  = -1;
17197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      groupPos = 0;
17207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
17227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- MTF init --*/
17247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      {
17257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Int32 ii, jj, kk;
17267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         kk = MTFA_SIZE-1;
17277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
17287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
17297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
17307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               kk--;
17317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
17327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->mtfbase[ii] = kk + 1;
17337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
17347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
17357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- end MTF init --*/
17367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nblock = 0;
17387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
17397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
17417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (nextSym == EOB) break;
17437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
17457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            es = -1;
17477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            N = 1;
17487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            do {
17497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
17507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
17517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               N = N * 2;
17527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
17537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
17547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
17557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            es++;
17577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
17587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->unzftab[uc] += es;
17597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->smallDecompress)
17617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               while (es > 0) {
17627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
17637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->ll16[nblock] = (UInt16)uc;
17647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  nblock++;
17657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  es--;
17667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               }
17677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            else
17687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               while (es > 0) {
17697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
17707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->tt[nblock] = (UInt32)uc;
17717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  nblock++;
17727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  es--;
17737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               };
17747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            continue;
17767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
17787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
17807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            /*-- uc = MTF ( nextSym-1 ) --*/
17827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            {
17837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               Int32 ii, jj, kk, pp, lno, off;
17847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               UInt32 nn;
17857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               nn = (UInt32)(nextSym - 1);
17867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
17877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (nn < MTFL_SIZE) {
17887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  /* avoid general-case expense */
17897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  pp = s->mtfbase[0];
17907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  uc = s->mtfa[pp+nn];
17917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  while (nn > 3) {
17927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     Int32 z = pp+nn;
17937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
17947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
17957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
17967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
17977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     nn -= 4;
17987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  }
17997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  while (nn > 0) {
18007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
18017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  };
18027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->mtfa[pp] = uc;
18037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               } else {
18047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  /* general case */
18057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  lno = nn / MTFL_SIZE;
18067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  off = nn % MTFL_SIZE;
18077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  pp = s->mtfbase[lno] + off;
18087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  uc = s->mtfa[pp];
18097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  while (pp > s->mtfbase[lno]) {
18107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfa[pp] = s->mtfa[pp-1]; pp--;
18117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  };
18127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->mtfbase[lno]++;
18137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  while (lno > 0) {
18147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfbase[lno]--;
18157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s->mtfa[s->mtfbase[lno]]
18167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
18177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     lno--;
18187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  }
18197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->mtfbase[0]--;
18207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->mtfa[s->mtfbase[0]] = uc;
18217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  if (s->mtfbase[0] == 0) {
18227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     kk = MTFA_SIZE-1;
18237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
18247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
18257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
18267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           kk--;
18277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                        }
18287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                        s->mtfbase[ii] = kk + 1;
18297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     }
18307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  }
18317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               }
18327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
18337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            /*-- end uc = MTF ( nextSym-1 ) --*/
18347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->unzftab[s->seqToUnseq[uc]]++;
18367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->smallDecompress)
18377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
18387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
18397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            nblock++;
18407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
18427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            continue;
18437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
18447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
18457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* Now we know what nblock is, we can do a better sanity
18477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         check on s->origPtr.
18487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      */
18497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->origPtr < 0 || s->origPtr >= nblock)
18507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         RETURN(BZ_DATA_ERROR);
18517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- Set up cftab to facilitate generation of T^(-1) --*/
18537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->cftab[0] = 0;
18547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
18557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
18567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i <= 256; i++) {
18577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
18587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            /* s->cftab[i] can legitimately be == nblock */
18597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            RETURN(BZ_DATA_ERROR);
18607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
18617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
18627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->state_out_len = 0;
18647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->state_out_ch  = 0;
18657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
18667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->state = BZ_X_OUTPUT;
18677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
18687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->smallDecompress) {
18707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- Make a copy of cftab, used in generation of T --*/
18727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
18737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- compute the T vector --*/
18757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = 0; i < nblock; i++) {
18767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            uc = (UChar)(s->ll16[i]);
18777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            SET_LL(i, s->cftabCopy[uc]);
18787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->cftabCopy[uc]++;
18797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
18807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- Compute T^(-1) by pointer reversal on T --*/
18827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i = s->origPtr;
18837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = GET_LL(i);
18847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         do {
18857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            Int32 tmp = GET_LL(j);
18867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            SET_LL(j, i);
18877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            i = j;
18887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j = tmp;
18897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
18907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (i != s->origPtr);
18917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
18927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->tPos = s->origPtr;
18937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->nblock_used = 0;
18947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->blockRandomised) {
18957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_RAND_INIT_MASK;
18967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
18977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
18987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
18997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
19007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
19017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } else {
19037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- compute the T^(-1) vector --*/
19057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = 0; i < nblock; i++) {
19067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            uc = (UChar)(s->tt[i] & 0xff);
19077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->tt[s->cftab[uc]] |= (i << 8);
19087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->cftab[uc]++;
19097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
19107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->tPos = s->tt[s->origPtr] >> 8;
19127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->nblock_used = 0;
19137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->blockRandomised) {
19147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_RAND_INIT_MASK;
19157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
19167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
19177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
19187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
19197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
19207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
19227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      RETURN(BZ_OK);
19247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj    endhdr_2:
19287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ENDHDR_2, uc);
19307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
19317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ENDHDR_3, uc);
19327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
19337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ENDHDR_4, uc);
19347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
19357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ENDHDR_5, uc);
19367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
19377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_ENDHDR_6, uc);
19387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
19397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedCombinedCRC = 0;
19417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_CCRC_1, uc);
19427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_CCRC_2, uc);
19447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_CCRC_3, uc);
19467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      GET_UCHAR(BZ_X_CCRC_4, uc);
19487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->state = BZ_X_IDLE;
19517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      RETURN(BZ_STREAM_END);
19527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      default: AssertH ( False, 4001 );
19547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
19557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH ( False, 4002 );
19577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   save_state_and_return:
19597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_i           = i;
19617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_j           = j;
19627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_t           = t;
19637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_alphaSize   = alphaSize;
19647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_nGroups     = nGroups;
19657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_nSelectors  = nSelectors;
19667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_EOB         = EOB;
19677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_groupNo     = groupNo;
19687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_groupPos    = groupPos;
19697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_nextSym     = nextSym;
19707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_nblockMAX   = nblockMAX;
19717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_nblock      = nblock;
19727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_es          = es;
19737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_N           = N;
19747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_curr        = curr;
19757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_zt          = zt;
19767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_zn          = zn;
19777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_zvec        = zvec;
19787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_zj          = zj;
19797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_gSel        = gSel;
19807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_gMinlen     = gMinlen;
19817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_gLimit      = gLimit;
19827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_gBase       = gBase;
19837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->save_gPerm       = gPerm;
19847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return retVal;
19867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
19877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
19907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                      decompress.c ---*/
19917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
19927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
19947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Block sorting machinery                               ---*/
19957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                           blocksort.c ---*/
19967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
19977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
19987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
19997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
20007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
20017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
20037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
20057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
20067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
20077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
20097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
20107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
20127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
20137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
20147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
20157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
20177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
20187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
20207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
20217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
20227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
20367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
20377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
20387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
20407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
20417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
20427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
20437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
20447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
20457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
20467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
20477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
20487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
20507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  To get some idea how the block sorting algorithms in this file
20527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  work, read my paper
20537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     On the Performance of BWT Sorting Algorithms
20547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  in Proceedings of the IEEE Data Compression Conference 2000,
20557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
20567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  file implements the algorithm called  cache  in the paper.
20577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
20587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
20627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Fallback O(N log(N)^2) sorting        ---*/
20637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- algorithm, for repetitive blocks      ---*/
20647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
20657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
20677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
20687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj__inline__
20697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid fallbackSimpleSort ( UInt32* fmap,
20707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          UInt32* eclass,
20717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          Int32   lo,
20727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          Int32   hi )
20737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
20747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 i, j, tmp;
20757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt32 ec_tmp;
20767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (lo == hi) return;
20787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (hi - lo > 3) {
20807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for ( i = hi-4; i >= lo; i-- ) {
20817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         tmp = fmap[i];
20827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ec_tmp = eclass[tmp];
20837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
20847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            fmap[j-4] = fmap[j];
20857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fmap[j-4] = tmp;
20867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
20877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
20887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for ( i = hi-1; i >= lo; i-- ) {
20907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      tmp = fmap[i];
20917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ec_tmp = eclass[tmp];
20927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
20937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fmap[j-1] = fmap[j];
20947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fmap[j-1] = tmp;
20957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
20967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
20977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
20997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
21007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define fswap(zz1, zz2) \
21017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
21027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define fvswap(zzp1, zzp2, zzn)       \
21047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                     \
21057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 yyp1 = (zzp1);               \
21067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 yyp2 = (zzp2);               \
21077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 yyn  = (zzn);                \
21087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (yyn > 0) {                  \
21097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fswap(fmap[yyp1], fmap[yyp2]);  \
21107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      yyp1++; yyp2++; yyn--;          \
21117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                  \
21127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
21137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define fmin(a,b) ((a) < (b)) ? (a) : (b)
21167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define fpush(lz,hz) { stackLo[sp] = lz; \
21187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       stackHi[sp] = hz; \
21197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       sp++; }
21207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define fpop(lz,hz) { sp--;              \
21227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      lz = stackLo[sp];  \
21237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      hz = stackHi[sp]; }
21247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define FALLBACK_QSORT_SMALL_THRESH 10
21267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define FALLBACK_QSORT_STACK_SIZE   100
21277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
21307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid fallbackQSort3 ( UInt32* fmap,
21317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      UInt32* eclass,
21327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      Int32   loSt,
21337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      Int32   hiSt )
21347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
21357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 unLo, unHi, ltLo, gtHi, n, m;
21367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 sp, lo, hi;
21377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt32 med, r, r3;
21387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
21397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
21407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   r = 0;
21427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   sp = 0;
21447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   fpush ( loSt, hiSt );
21457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (sp > 0) {
21477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
21497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fpop ( lo, hi );
21517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
21527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fallbackSimpleSort ( fmap, eclass, lo, hi );
21537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         continue;
21547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
21557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* Random partitioning.  Median of 3 sometimes fails to
21577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         avoid bad cases.  Median of 9 seems to help but
21587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         looks rather expensive.  This too seems to work but
21597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         is cheaper.  Guidance for the magic constants
21607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         7621 and 32768 is taken from Sedgewick's algorithms
21617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         book, chapter 35.
21627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      */
21637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      r = ((r * 7621) + 1) % 32768;
21647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      r3 = r % 3;
21657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (r3 == 0) med = eclass[fmap[lo]]; else
21667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
21677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   med = eclass[fmap[hi]];
21687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unLo = ltLo = lo;
21707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unHi = gtHi = hi;
21717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (1) {
21737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (1) {
21747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (unLo > unHi) break;
21757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
21767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n == 0) {
21777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               fswap(fmap[unLo], fmap[ltLo]);
21787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ltLo++; unLo++;
21797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               continue;
21807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            };
21817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n > 0) break;
21827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            unLo++;
21837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
21847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (1) {
21857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (unLo > unHi) break;
21867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
21877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n == 0) {
21887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               fswap(fmap[unHi], fmap[gtHi]);
21897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               gtHi--; unHi--;
21907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               continue;
21917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            };
21927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n < 0) break;
21937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            unHi--;
21947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
21957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (unLo > unHi) break;
21967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
21977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
21987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
21997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
22007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (gtHi < ltLo) continue;
22027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
22047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
22057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      n = lo + unLo - ltLo - 1;
22077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      m = hi - (gtHi - unHi) + 1;
22087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (n - lo > hi - m) {
22107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fpush ( lo, n );
22117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fpush ( m, hi );
22127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } else {
22137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fpush ( m, hi );
22147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fpush ( lo, n );
22157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
22167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
22177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
22187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef fmin
22207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef fpush
22217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef fpop
22227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef fswap
22237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef fvswap
22247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef FALLBACK_QSORT_SMALL_THRESH
22257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef FALLBACK_QSORT_STACK_SIZE
22267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
22297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Pre:
22307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nblock > 0
22317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      eclass exists for [0 .. nblock-1]
22327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
22337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr exists for [0 .. nblock-1]
22347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Post:
22367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
22377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      All other areas of eclass destroyed
22387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fmap [0 .. nblock-1] holds sorted order
22397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bhtab [ 0 .. 2+(nblock/32) ] destroyed
22407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj*/
22417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
22437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
22447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
22457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define      WORD_BH(zz)  bhtab[(zz) >> 5]
22467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
22477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
22497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid fallbackSort ( UInt32* fmap,
22507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    UInt32* eclass,
22517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    UInt32* bhtab,
22527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    Int32   nblock,
22537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    Int32   verb )
22547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
22557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 ftab[257];
22567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 ftabCopy[256];
22577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 H, i, j, k, l, r, cc, cc1;
22587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nNotDone;
22597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nBhtab;
22607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar* eclass8 = (UChar*)eclass;
22617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--
22637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Initial 1-char radix sort to generate
22647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      initial fmap and initial BH bits.
22657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   --*/
22667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (verb >= 4)
22677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      VPrintf0 ( "        bucket sorting ...\n" );
22687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < 257;    i++) ftab[i] = 0;
22697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
22707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
22717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
22727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < nblock; i++) {
22747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = eclass8[i];
22757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      k = ftab[j] - 1;
22767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[j] = k;
22777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fmap[k] = i;
22787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
22797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nBhtab = 2 + (nblock / 32);
22817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
22827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
22837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--
22857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Inductively refine the buckets.  Kind-of an
22867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      "exponential radix sort" (!), inspired by the
22877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Manber-Myers suffix array construction algorithm.
22887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   --*/
22897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- set sentinel bits for block-end detection --*/
22917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < 32; i++) {
22927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      SET_BH(nblock + 2*i);
22937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      CLEAR_BH(nblock + 2*i + 1);
22947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
22957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
22967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- the log(N) loop --*/
22977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   H = 1;
22987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (1) {
22997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (verb >= 4)
23017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf1 ( "        depth %6d has ", H );
23027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = 0;
23047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < nblock; i++) {
23057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (ISSET_BH(i)) j = i;
23067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k = fmap[i] - H; if (k < 0) k += nblock;
23077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         eclass[k] = j;
23087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
23097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nNotDone = 0;
23117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      r = -1;
23127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (1) {
23137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 /*-- find the next non-singleton bucket --*/
23157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k = r + 1;
23167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
23177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (ISSET_BH(k)) {
23187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (WORD_BH(k) == 0xffffffff) k += 32;
23197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (ISSET_BH(k)) k++;
23207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
23217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         l = k - 1;
23227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (l >= nblock) break;
23237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
23247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (!ISSET_BH(k)) {
23257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (WORD_BH(k) == 0x00000000) k += 32;
23267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (!ISSET_BH(k)) k++;
23277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
23287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         r = k - 1;
23297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (r >= nblock) break;
23307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- now [l, r] bracket current bucket --*/
23327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (r > l) {
23337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            nNotDone += (r - l + 1);
23347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            fallbackQSort3 ( fmap, eclass, l, r );
23357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            /*-- scan bucket and generate header bits-- */
23377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            cc = -1;
23387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            for (i = l; i <= r; i++) {
23397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cc1 = eclass[fmap[i]];
23407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (cc != cc1) { SET_BH(i); cc = cc1; };
23417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
23427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
23437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
23447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (verb >= 4)
23467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
23477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      H *= 2;
23497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (H > nblock || nNotDone == 0) break;
23507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
23517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--
23537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Reconstruct the original block in
23547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      eclass8 [0 .. nblock-1], since the
23557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      previous phase destroyed it.
23567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   --*/
23577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (verb >= 4)
23587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      VPrintf0 ( "        reconstructing block ...\n" );
23597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   j = 0;
23607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < nblock; i++) {
23617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (ftabCopy[j] == 0) j++;
23627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftabCopy[j]--;
23637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      eclass8[fmap[i]] = (UChar)j;
23647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
23657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH ( j < 256, 1005 );
23667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
23677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef       SET_BH
23697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef     CLEAR_BH
23707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef     ISSET_BH
23717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef      WORD_BH
23727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef UNALIGNED_BH
23737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
23767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- The main, O(N^2 log(N)) sorting       ---*/
23777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- algorithm.  Faster for "normal"       ---*/
23787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- non-repetitive blocks.                ---*/
23797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
23807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
23827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
23837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj__inline__
23847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool mainGtU ( UInt32  i1,
23857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               UInt32  i2,
23867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               UChar*  block,
23877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               UInt16* quadrant,
23887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               UInt32  nblock,
23897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               Int32*  budget )
23907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
23917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  k;
23927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar  c1, c2;
23937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt16 s1, s2;
23947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
23957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertD ( i1 != i2, "mainGtU" );
23967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 1 */
23977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
23987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
23997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 2 */
24017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 3 */
24057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 4 */
24097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 5 */
24137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 6 */
24177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 7 */
24217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 8 */
24257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 9 */
24297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 10 */
24337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 11 */
24377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* 12 */
24417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   c1 = block[i1]; c2 = block[i2];
24427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c1 != c2) return (c1 > c2);
24437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i1++; i2++;
24447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
24457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   k = nblock + 8;
24467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
24477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   do {
24487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 1 */
24497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 2 */
24557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 3 */
24617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 4 */
24677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 5 */
24737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 6 */
24797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 7 */
24857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 8 */
24917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      c1 = block[i1]; c2 = block[i2];
24927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (c1 != c2) return (c1 > c2);
24937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s1 != s2) return (s1 > s2);
24957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i1++; i2++;
24967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
24977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (i1 >= nblock) i1 -= nblock;
24987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (i2 >= nblock) i2 -= nblock;
24997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      k -= 8;
25017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      (*budget)--;
25027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
25037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (k >= 0);
25047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return False;
25067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
25077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
25107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
25117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Knuth's increments seem to work better
25127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   than Incerpi-Sedgewick here.  Possibly
25137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   because the number of elems to sort is
25147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   usually small, typically <= 20.
25157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
25167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
25177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjInt32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
25187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   9841, 29524, 88573, 265720,
25197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   797161, 2391484 };
25207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
25227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid mainSimpleSort ( UInt32* ptr,
25237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      UChar*  block,
25247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      UInt16* quadrant,
25257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      Int32   nblock,
25267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      Int32   lo,
25277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      Int32   hi,
25287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      Int32   d,
25297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      Int32*  budget )
25307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
25317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 i, j, h, bigN, hp;
25327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt32 v;
25337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bigN = hi - lo + 1;
25357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bigN < 2) return;
25367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   hp = 0;
25387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (incs[hp] < bigN) hp++;
25397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   hp--;
25407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (; hp >= 0; hp--) {
25427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      h = incs[hp];
25437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i = lo + h;
25457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
25467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- copy 1 --*/
25487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (i > hi) break;
25497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         v = ptr[i];
25507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = i;
25517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while ( mainGtU (
25527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
25537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 ) ) {
25547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ptr[j] = ptr[j-h];
25557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j = j - h;
25567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (j <= (lo + h - 1)) break;
25577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
25587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ptr[j] = v;
25597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i++;
25607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- copy 2 --*/
25627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (i > hi) break;
25637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         v = ptr[i];
25647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = i;
25657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while ( mainGtU (
25667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
25677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 ) ) {
25687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ptr[j] = ptr[j-h];
25697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j = j - h;
25707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (j <= (lo + h - 1)) break;
25717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
25727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ptr[j] = v;
25737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i++;
25747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- copy 3 --*/
25767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (i > hi) break;
25777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         v = ptr[i];
25787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = i;
25797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while ( mainGtU (
25807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
25817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 ) ) {
25827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ptr[j] = ptr[j-h];
25837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j = j - h;
25847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (j <= (lo + h - 1)) break;
25857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
25867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ptr[j] = v;
25877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         i++;
25887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (*budget < 0) return;
25907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
25917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
25927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
25937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
25957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
25967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
25977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   The following is an implementation of
25987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   an elegant 3-way quicksort for strings,
25997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   described in a paper "Fast Algorithms for
26007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Sorting and Searching Strings", by Robert
26017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Sedgewick and Jon L. Bentley.
26027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
26037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define mswap(zz1, zz2) \
26057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
26067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define mvswap(zzp1, zzp2, zzn)       \
26087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                     \
26097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 yyp1 = (zzp1);               \
26107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 yyp2 = (zzp2);               \
26117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 yyn  = (zzn);                \
26127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (yyn > 0) {                  \
26137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mswap(ptr[yyp1], ptr[yyp2]);    \
26147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      yyp1++; yyp2++; yyn--;          \
26157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                  \
26167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
26177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
26197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj__inline__
26207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjUChar mmed3 ( UChar a, UChar b, UChar c )
26217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
26227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar t;
26237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (a > b) { t = a; a = b; b = t; };
26247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (b > c) {
26257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      b = c;
26267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (a > b) b = a;
26277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
26287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return b;
26297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
26307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define mmin(a,b) ((a) < (b)) ? (a) : (b)
26327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
26347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          stackHi[sp] = hz; \
26357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          stackD [sp] = dz; \
26367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          sp++; }
26377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define mpop(lz,hz,dz) { sp--;             \
26397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         lz = stackLo[sp]; \
26407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         hz = stackHi[sp]; \
26417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         dz = stackD [sp]; }
26427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define mnextsize(az) (nextHi[az]-nextLo[az])
26457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define mnextswap(az,bz)                                        \
26477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   { Int32 tz;                                                  \
26487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
26497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
26507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
26517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define MAIN_QSORT_SMALL_THRESH 20
26547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
26557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define MAIN_QSORT_STACK_SIZE 100
26567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
26587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid mainQSort3 ( UInt32* ptr,
26597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  UChar*  block,
26607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  UInt16* quadrant,
26617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  Int32   nblock,
26627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  Int32   loSt,
26637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  Int32   hiSt,
26647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  Int32   dSt,
26657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  Int32*  budget )
26667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
26677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
26687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 sp, lo, hi, d;
26697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
26717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
26727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 stackD [MAIN_QSORT_STACK_SIZE];
26737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nextLo[3];
26757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nextHi[3];
26767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nextD [3];
26777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   sp = 0;
26797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   mpush ( loSt, hiSt, dSt );
26807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (sp > 0) {
26827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
26847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mpop ( lo, hi, d );
26867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
26877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          d > MAIN_QSORT_DEPTH_THRESH) {
26887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
26897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (*budget < 0) return;
26907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         continue;
26917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
26927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      med = (Int32)
26947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            mmed3 ( block[ptr[ lo         ]+d],
26957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    block[ptr[ hi         ]+d],
26967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    block[ptr[ (lo+hi)>>1 ]+d] );
26977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
26987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unLo = ltLo = lo;
26997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unHi = gtHi = hi;
27007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
27027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (True) {
27037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (unLo > unHi) break;
27047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            n = ((Int32)block[ptr[unLo]+d]) - med;
27057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n == 0) {
27067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               mswap(ptr[unLo], ptr[ltLo]);
27077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ltLo++; unLo++; continue;
27087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            };
27097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n >  0) break;
27107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            unLo++;
27117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
27127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (True) {
27137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (unLo > unHi) break;
27147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            n = ((Int32)block[ptr[unHi]+d]) - med;
27157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n == 0) {
27167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               mswap(ptr[unHi], ptr[gtHi]);
27177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               gtHi--; unHi--; continue;
27187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            };
27197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n <  0) break;
27207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            unHi--;
27217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
27227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (unLo > unHi) break;
27237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
27247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
27257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
27277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (gtHi < ltLo) {
27297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         mpush(lo, hi, d+1 );
27307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         continue;
27317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
27327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
27347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
27357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      n = lo + unLo - ltLo - 1;
27377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      m = hi - (gtHi - unHi) + 1;
27387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
27407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
27417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
27427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
27447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
27457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
27467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
27487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
27497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mpush (nextLo[0], nextHi[0], nextD[0]);
27517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mpush (nextLo[1], nextHi[1], nextD[1]);
27527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mpush (nextLo[2], nextHi[2], nextD[2]);
27537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
27547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
27557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef mswap
27577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef mvswap
27587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef mpush
27597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef mpop
27607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef mmin
27617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef mnextsize
27627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef mnextswap
27637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef MAIN_QSORT_SMALL_THRESH
27647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef MAIN_QSORT_DEPTH_THRESH
27657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef MAIN_QSORT_STACK_SIZE
27667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
27697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Pre:
27707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nblock > N_OVERSHOOT
27717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
27727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ((UChar*)block32) [0 .. nblock-1] holds block
27737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr exists for [0 .. nblock-1]
27747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Post:
27767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ((UChar*)block32) [0 .. nblock-1] holds block
27777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      All other areas of block32 destroyed
27787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab [0 .. 65536 ] destroyed
27797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr [0 .. nblock-1] holds sorted order
27807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (*budget < 0), sorting was abandoned
27817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj*/
27827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
27837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
27847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define SETMASK (1 << 21)
27857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define CLEARMASK (~(SETMASK))
27867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
2787f5049f7037c3d9e4b376d87c62a943da4de5509bsewardjstatic __attribute__((noinline))
27887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid mainSort ( UInt32* ptr,
27897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                UChar*  block,
27907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                UInt16* quadrant,
27917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                UInt32* ftab,
27927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                Int32   nblock,
27937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                Int32   verb,
27947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                Int32*  budget )
27957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
27967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  i, j, k, ss, sb;
27977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  runningOrder[256];
27987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool   bigDone[256];
27997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  copyStart[256];
28007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  copyEnd  [256];
28017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar  c1;
28027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  numQSorted;
28037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt16 s;
28047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
28057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- set up the 2-byte frequency table --*/
28077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 65536; i >= 0; i--) ftab[i] = 0;
28087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   j = block[0] << 8;
28107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i = nblock-1;
28117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (; i >= 3; i -= 4) {
28127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      quadrant[i] = 0;
28137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
28147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[j]++;
28157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      quadrant[i-1] = 0;
28167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
28177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[j]++;
28187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      quadrant[i-2] = 0;
28197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
28207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[j]++;
28217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      quadrant[i-3] = 0;
28227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
28237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[j]++;
28247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
28257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (; i >= 0; i--) {
28267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      quadrant[i] = 0;
28277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
28287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[j]++;
28297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
28307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- (emphasises close relationship of block & quadrant) --*/
28327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
28337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      block   [nblock+i] = block[i];
28347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      quadrant[nblock+i] = 0;
28357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
28367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
28387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- Complete the initial radix sort --*/
28407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
28417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s = block[0] << 8;
28437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   i = nblock-1;
28447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (; i >= 3; i -= 4) {
28457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s = (s >> 8) | (block[i] << 8);
28467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = ftab[s] -1;
28477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[s] = j;
28487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr[j] = i;
28497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s = (s >> 8) | (block[i-1] << 8);
28507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = ftab[s] -1;
28517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[s] = j;
28527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr[j] = i-1;
28537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s = (s >> 8) | (block[i-2] << 8);
28547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = ftab[s] -1;
28557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[s] = j;
28567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr[j] = i-2;
28577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s = (s >> 8) | (block[i-3] << 8);
28587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = ftab[s] -1;
28597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[s] = j;
28607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr[j] = i-3;
28617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
28627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (; i >= 0; i--) {
28637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s = (s >> 8) | (block[i] << 8);
28647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = ftab[s] -1;
28657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab[s] = j;
28667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ptr[j] = i;
28677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
28687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--
28707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Now ftab contains the first loc of every small bucket.
28717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Calculate the running order, from smallest to largest
28727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      big bucket.
28737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   --*/
28747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i <= 255; i++) {
28757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bigDone     [i] = False;
28767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      runningOrder[i] = i;
28777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
28787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   {
28807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32 vv;
28817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32 h = 1;
28827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      do h = 3 * h + 1; while (h <= 256);
28837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      do {
28847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         h = h / 3;
28857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = h; i <= 255; i++) {
28867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            vv = runningOrder[i];
28877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j = i;
28887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
28897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               runningOrder[j] = runningOrder[j-h];
28907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               j = j - h;
28917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (j <= (h - 1)) goto zero;
28927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
28937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            zero:
28947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            runningOrder[j] = vv;
28957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
28967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } while (h != 1);
28977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
28987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
28997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--
29007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      The main sorting loop.
29017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   --*/
29027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   numQSorted = 0;
29047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i <= 255; i++) {
29067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--
29087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Process big buckets, starting with the least full.
29097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Basically this is a 3-step process in which we call
29107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         mainQSort3 to sort the small buckets [ss, j], but
29117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         also make a big effort to avoid the calls if we can.
29127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      --*/
29137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ss = runningOrder[i];
29147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--
29167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Step 1:
29177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Complete the big bucket [ss] by quicksorting
29187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         any unsorted small buckets [ss, j], for j != ss.
29197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Hopefully previous pointer-scanning phases have already
29207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         completed many of the small buckets [ss, j], so
29217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         we don't have to sort them at all.
29227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      --*/
29237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (j = 0; j <= 255; j++) {
29247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (j != ss) {
29257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            sb = (ss << 8) + j;
29267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if ( ! (ftab[sb] & SETMASK) ) {
29277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               Int32 lo = ftab[sb]   & CLEARMASK;
29287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
29297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (hi > lo) {
29307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  if (verb >= 4)
29317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
29327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                "done %d   this %d\n",
29337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                ss, j, numQSorted, hi - lo + 1 );
29347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  mainQSort3 (
29357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     ptr, block, quadrant, nblock,
29367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     lo, hi, BZ_N_RADIX, budget
29377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  );
29387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  numQSorted += (hi - lo + 1);
29397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  if (*budget < 0) return;
29407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               }
29417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
29427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ftab[sb] |= SETMASK;
29437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
29447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
29457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH ( !bigDone[ss], 1006 );
29477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--
29497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Step 2:
29507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Now scan this big bucket [ss] so as to synthesise the
29517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         sorted order for small buckets [t, ss] for all t,
29527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         including, magically, the bucket [ss,ss] too.
29537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         This will avoid doing Real Work in subsequent Step 1's.
29547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      --*/
29557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      {
29567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (j = 0; j <= 255; j++) {
29577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
29587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
29597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
29607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
29617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            k = ptr[j]-1; if (k < 0) k += nblock;
29627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            c1 = block[k];
29637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (!bigDone[c1])
29647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ptr[ copyStart[c1]++ ] = k;
29657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
29667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
29677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            k = ptr[j]-1; if (k < 0) k += nblock;
29687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            c1 = block[k];
29697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (!bigDone[c1])
29707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ptr[ copyEnd[c1]-- ] = k;
29717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
29727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
29737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
29757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                ||
29767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
29777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   Necessity for this case is demonstrated by compressing
29787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   a sequence of approximately 48.5 million of character
29797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   251; 1.0.0/1.0.1 will then die here. */
29807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
29817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                1007 )
29827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
29847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--
29867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Step 3:
29877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         The [ss] big bucket is now done.  Record this fact,
29887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         and update the quadrant descriptors.  Remember to
29897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         update quadrants in the overshoot area too, if
29907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         necessary.  The "if (i < 255)" test merely skips
29917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         this updating for the last bucket processed, since
29927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         updating for the last bucket is pointless.
29937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
29947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         The quadrant array provides a way to incrementally
29957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         cache sort orderings, as they appear, so as to
29967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         make subsequent comparisons in fullGtU() complete
29977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         faster.  For repetitive blocks this makes a big
29987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         difference (but not big enough to be able to avoid
29997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         the fallback sorting mechanism, exponential radix sort).
30007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         The precise meaning is: at all times:
30027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            for 0 <= i < nblock and 0 <= j <= nblock
30047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if block[i] != block[j],
30067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               then the relative values of quadrant[i] and
30087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    quadrant[j] are meaningless.
30097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               else {
30117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  if quadrant[i] < quadrant[j]
30127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     then the string starting at i lexicographically
30137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     precedes the string starting at j
30147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  else if quadrant[i] > quadrant[j]
30167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     then the string starting at j lexicographically
30177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     precedes the string starting at i
30187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  else
30207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     the relative ordering of the strings starting
30217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     at i and j has not yet been determined.
30227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               }
30237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      --*/
30247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bigDone[ss] = True;
30257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (i < 255) {
30277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
30287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
30297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Int32 shifts   = 0;
30307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while ((bbSize >> shifts) > 65534) shifts++;
30327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (j = bbSize-1; j >= 0; j--) {
30347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            Int32 a2update     = ptr[bbStart + j];
30357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            UInt16 qVal        = (UInt16)(j >> shifts);
30367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            quadrant[a2update] = qVal;
30377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (a2update < BZ_N_OVERSHOOT)
30387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               quadrant[a2update + nblock] = qVal;
30397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
30407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
30417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
30427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
30447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (verb >= 4)
30467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
30477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 nblock, numQSorted, nblock - numQSorted );
30487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
30497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef BIGFREQ
30517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef SETMASK
30527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#undef CLEARMASK
30537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
30567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Pre:
30577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nblock > 0
30587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
30597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ((UChar*)arr2)  [0 .. nblock-1] holds block
30607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      arr1 exists for [0 .. nblock-1]
30617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Post:
30637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ((UChar*)arr2) [0 .. nblock-1] holds block
30647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      All other areas of block destroyed
30657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ftab [ 0 .. 65536 ] destroyed
30667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      arr1 [0 .. nblock-1] holds sorted order
30677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj*/
30687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ2_blockSort ( EState* s )
30697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
30707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt32* ptr    = s->ptr;
30717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar*  block  = s->block;
30727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt32* ftab   = s->ftab;
30737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   nblock = s->nblock;
30747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   verb   = s->verbosity;
30757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   wfact  = s->workFactor;
30767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt16* quadrant;
30777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   budget;
30787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   budgetInit;
30797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   i;
30807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nblock < /* 10000 */1000 ) {
30827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
30837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
30847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* Calculate the location for quadrant, remembering to get
30857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         the alignment right.  Assumes that &(block[0]) is at least
30867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         2-byte aligned -- this should be ok since block is really
30877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         the first section of arr2.
30887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      */
30897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      i = nblock+BZ_N_OVERSHOOT;
30907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (i & 1) i++;
30917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      quadrant = (UInt16*)(&(block[i]));
30927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
30937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* (wfact-1) / 3 puts the default-factor-30
30947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         transition point at very roughly the same place as
30957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         with v0.1 and v0.9.0.
30967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Not that it particularly matters any more, since the
30977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         resulting compressed stream is now the same regardless
30987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         of whether or not we use the main sort or fallback sort.
30997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      */
31007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (wfact < 1  ) wfact = 1;
31017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (wfact > 100) wfact = 100;
31027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      budgetInit = nblock * ((wfact-1) / 3);
31037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      budget = budgetInit;
31047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
31067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (0 && verb >= 3)
31077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
31087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    budgetInit - budget,
31097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    nblock,
31107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    (float)(budgetInit - budget) /
31117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    (float)(nblock==0 ? 1 : nblock) );
31127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (budget < 0) {
31137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (verb >= 2)
31147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            VPrintf0 ( "    too repetitive; using fallback"
31157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       " sorting algorithm\n" );
31167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
31177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
31187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
31197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->origPtr = -1;
31217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < s->nblock; i++)
31227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ptr[i] == 0)
31237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { s->origPtr = i; break; };
31247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH( s->origPtr != -1, 1003 );
31267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
31277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
31307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                       blocksort.c ---*/
31317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
31327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
31347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Huffman coding low-level stuff                        ---*/
31357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                             huffman.c ---*/
31367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
31377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
31397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
31407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
31417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
31437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
31457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
31467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
31477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
31497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
31507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
31527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
31537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
31547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
31557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
31577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
31587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
31607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
31617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
31627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
31647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
31677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
31767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
31777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
31787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
31807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
31817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
31827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
31837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
31847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
31857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
31867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
31877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
31887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
31907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
31917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
31957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
31967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
31977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
31987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
31997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define ADDWEIGHTS(zw1,zw2)                           \
32007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
32017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
32027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define UPHEAP(z)                                     \
32047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                                     \
32057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 zz, tmp;                                     \
32067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zz = z; tmp = heap[zz];                            \
32077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
32087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      heap[zz] = heap[zz >> 1];                       \
32097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zz >>= 1;                                       \
32107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                                  \
32117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   heap[zz] = tmp;                                    \
32127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
32137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define DOWNHEAP(z)                                   \
32157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                                     \
32167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 zz, yy, tmp;                                 \
32177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zz = z; tmp = heap[zz];                            \
32187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {                                     \
32197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      yy = zz << 1;                                   \
32207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (yy > nHeap) break;                          \
32217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (yy < nHeap &&                               \
32227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          weight[heap[yy+1]] < weight[heap[yy]])      \
32237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         yy++;                                        \
32247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (weight[tmp] < weight[heap[yy]]) break;      \
32257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      heap[zz] = heap[yy];                            \
32267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zz = yy;                                        \
32277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                                  \
32287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   heap[zz] = tmp;                                    \
32297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
32307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
32337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ2_hbMakeCodeLengths ( UChar *len,
32347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             Int32 *freq,
32357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             Int32 alphaSize,
32367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             Int32 maxLen )
32377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
32387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--
32397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Nodes and heap entries run from 1.  Entry 0
32407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for both the heap and nodes is a sentinel.
32417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   --*/
32427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nNodes, nHeap, n1, n2, i, j, k;
32437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool  tooLong;
32447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
32467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
32477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
32487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < alphaSize; i++)
32507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
32517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
32537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nNodes = alphaSize;
32557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nHeap = 0;
32567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      heap[0] = 0;
32587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      weight[0] = 0;
32597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      parent[0] = -2;
32607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 1; i <= alphaSize; i++) {
32627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         parent[i] = -1;
32637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         nHeap++;
32647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         heap[nHeap] = i;
32657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         UPHEAP(nHeap);
32667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
32677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
32697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (nHeap > 1) {
32717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
32727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
32737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         nNodes++;
32747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         parent[n1] = parent[n2] = nNodes;
32757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
32767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         parent[nNodes] = -1;
32777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         nHeap++;
32787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         heap[nHeap] = nNodes;
32797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         UPHEAP(nHeap);
32807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
32817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
32837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      tooLong = False;
32857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 1; i <= alphaSize; i++) {
32867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = 0;
32877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k = i;
32887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (parent[k] >= 0) { k = parent[k]; j++; }
32897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         len[i-1] = j;
32907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (j > maxLen) tooLong = True;
32917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
32927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (! tooLong) break;
32947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
32957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* 17 Oct 04: keep-going condition for the following loop used
32967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         to be 'i < alphaSize', which missed the last element,
32977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         theoretically leading to the possibility of the compressor
32987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         looping.  However, this count-scaling step is only needed if
32997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         one of the generated Huffman code words is longer than
33007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         maxLen, which up to and including version 1.0.2 was 20 bits,
33017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         which is extremely unlikely.  In version 1.0.3 maxLen was
33027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         changed to 17 bits, which has minimal effect on compression
33037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ratio, but does mean this scaling step is used from time to
33047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         time, enough to verify that it works.
33057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         This means that bzip2-1.0.3 and later will only produce
33077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Huffman codes with a maximum length of 17 bits.  However, in
33087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         order to preserve backwards compatibility with bitstreams
33097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         produced by versions pre-1.0.3, the decompressor must still
33107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         handle lengths of up to 20. */
33117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 1; i <= alphaSize; i++) {
33137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = weight[i] >> 8;
33147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = 1 + (j / 2);
33157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         weight[i] = j << 8;
33167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
33177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
33187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
33197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
33227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ2_hbAssignCodes ( Int32 *code,
33237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         UChar *length,
33247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         Int32 minLen,
33257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         Int32 maxLen,
33267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         Int32 alphaSize )
33277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
33287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 n, vec, i;
33297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vec = 0;
33317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (n = minLen; n <= maxLen; n++) {
33327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < alphaSize; i++)
33337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (length[i] == n) { code[i] = vec; vec++; };
33347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      vec <<= 1;
33357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
33367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
33377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
33407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ2_hbCreateDecodeTables ( Int32 *limit,
33417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                Int32 *base,
33427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                Int32 *perm,
33437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                UChar *length,
33447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                Int32 minLen,
33457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                Int32 maxLen,
33467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                Int32 alphaSize )
33477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
33487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 pp, i, j, vec;
33497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   pp = 0;
33517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = minLen; i <= maxLen; i++)
33527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (j = 0; j < alphaSize; j++)
33537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (length[j] == i) { perm[pp] = j; pp++; };
33547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
33567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
33577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
33597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
33617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vec = 0;
33627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = minLen; i <= maxLen; i++) {
33647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      vec += (base[i+1] - base[i]);
33657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      limit[i] = vec-1;
33667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      vec <<= 1;
33677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
33687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = minLen + 1; i <= maxLen; i++)
33697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      base[i] = ((limit[i-1] + 1) << 1) - base[i];
33707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
33717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
33747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                         huffman.c ---*/
33757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
33767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
33787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Compression machinery (not incl block sorting)        ---*/
33797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                            compress.c ---*/
33807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
33817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
33837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
33847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
33857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
33877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
33897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
33907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
33917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
33937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
33947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
33957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
33967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
33977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
33987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
33997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
34017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
34027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
34047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
34057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
34067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
34117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
34137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
34207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
34217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
34227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
34247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
34257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
34267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
34277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
34287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
34297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
34307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
34317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
34327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
34347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
34357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
34377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   CHANGES
34387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ~~~~~~~
34397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0.9.0 -- original version.
34407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0.9.0a/b -- no changes in this file.
34427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0.9.0c
34447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      * changed setting of nGroups in sendMTFValues() so as to
34457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        do a bit better on small files
34467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
34477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
34517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Bit stream I/O                              ---*/
34527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
34537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
34557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ2_bsInitWrite ( EState* s )
34567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
34577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->bsLive = 0;
34587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->bsBuff = 0;
34597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
34607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
34637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
34647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid bsFinishWrite ( EState* s )
34657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
34667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (s->bsLive > 0) {
34677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
34687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->numZ++;
34697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->bsBuff <<= 8;
34707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->bsLive -= 8;
34717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
34727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
34737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
34767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define bsNEEDW(nz)                           \
34777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                             \
34787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (s->bsLive >= 8) {                   \
34797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->zbits[s->numZ]                       \
34807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         = (UChar)(s->bsBuff >> 24);          \
34817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->numZ++;                              \
34827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->bsBuff <<= 8;                        \
34837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->bsLive -= 8;                         \
34847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                          \
34857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
34867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
34897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
34907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj__inline__
34917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid bsW ( EState* s, Int32 n, UInt32 v )
34927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
34937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsNEEDW ( n );
34947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->bsBuff |= (v << (32 - s->bsLive - n));
34957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->bsLive += n;
34967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
34977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
34997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
35007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
35017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid bsPutUInt32 ( EState* s, UInt32 u )
35027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
35037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsW ( s, 8, (u >> 24) & 0xffL );
35047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsW ( s, 8, (u >> 16) & 0xffL );
35057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsW ( s, 8, (u >>  8) & 0xffL );
35067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsW ( s, 8,  u        & 0xffL );
35077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
35087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
35117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
35127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid bsPutUChar ( EState* s, UChar c )
35137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
35147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsW( s, 8, (UInt32)c );
35157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
35167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
35197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- The back end proper                         ---*/
35207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
35217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
35237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
35247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid makeMaps_e ( EState* s )
35257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
35267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 i;
35277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->nInUse = 0;
35287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < 256; i++)
35297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->inUse[i]) {
35307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->unseqToSeq[i] = s->nInUse;
35317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->nInUse++;
35327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
35337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
35347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
35377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
35387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid generateMTFValues ( EState* s )
35397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
35407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar   yy[256];
35417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   i, j;
35427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   zPend;
35437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   wr;
35447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   EOB;
35457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*
35477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      After sorting (eg, here),
35487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
35497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         and
35507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
35517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         holds the original block data.
35527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      The first thing to do is generate the MTF values,
35547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      and put them in
35557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
35567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Because there are strictly fewer or equal MTF values
35577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      than block values, ptr values in this area are overwritten
35587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      with MTF values only when they are no longer needed.
35597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      The final compressed bitstream is generated into the
35617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      area starting at
35627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         (UChar*) (&((UChar*)s->arr2)[s->nblock])
35637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      These storage aliases are set up in bzCompressInit(),
35657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      except for the last one, which is arranged in
35667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      compressBlock().
35677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   */
35687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt32* ptr   = s->ptr;
35697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar* block  = s->block;
35707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt16* mtfv  = s->mtfv;
35717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   makeMaps_e ( s );
35737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   EOB = s->nInUse+1;
35747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
35767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   wr = 0;
35787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zPend = 0;
35797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
35807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < s->nblock; i++) {
35827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar ll_i;
35837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertD ( wr <= i, "generateMTFValues(1)" );
35847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      j = ptr[i]-1; if (j < 0) j += s->nblock;
35857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ll_i = s->unseqToSeq[block[j]];
35867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
35877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (yy[0] == ll_i) {
35897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         zPend++;
35907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } else {
35917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
35927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (zPend > 0) {
35937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            zPend--;
35947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (True) {
35957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (zPend & 1) {
35967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  mtfv[wr] = BZ_RUNB; wr++;
35977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->mtfFreq[BZ_RUNB]++;
35987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               } else {
35997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  mtfv[wr] = BZ_RUNA; wr++;
36007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->mtfFreq[BZ_RUNA]++;
36017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               }
36027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (zPend < 2) break;
36037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               zPend = (zPend - 2) / 2;
36047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            };
36057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            zPend = 0;
36067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
36077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         {
36087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            register UChar  rtmp;
36097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            register UChar* ryy_j;
36107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            register UChar  rll_i;
36117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            rtmp  = yy[1];
36127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            yy[1] = yy[0];
36137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ryy_j = &(yy[1]);
36147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            rll_i = ll_i;
36157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while ( rll_i != rtmp ) {
36167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               register UChar rtmp2;
36177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ryy_j++;
36187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               rtmp2  = rtmp;
36197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               rtmp   = *ryy_j;
36207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               *ryy_j = rtmp2;
36217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            };
36227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            yy[0] = rtmp;
36237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j = ryy_j - &(yy[0]);
36247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
36257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
36267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
36287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
36297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (zPend > 0) {
36317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zPend--;
36327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
36337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (zPend & 1) {
36347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            mtfv[wr] = BZ_RUNB; wr++;
36357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->mtfFreq[BZ_RUNB]++;
36367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
36377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            mtfv[wr] = BZ_RUNA; wr++;
36387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->mtfFreq[BZ_RUNA]++;
36397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
36407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (zPend < 2) break;
36417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         zPend = (zPend - 2) / 2;
36427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      };
36437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zPend = 0;
36447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
36457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
36477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->nMTF = wr;
36497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
36507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
36537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_LESSER_ICOST  0
36547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_GREATER_ICOST 15
36557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
36577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid sendMTFValues ( EState* s )
36587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
36597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
36607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
36617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 nGroups, nBytes;
36627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--
36647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
36657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   is a global since the decoder also needs it.
36667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
36687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
36697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   are also globals only used in this proc.
36707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Made global to keep stack frame size small.
36717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   --*/
36727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt16 cost[BZ_N_GROUPS];
36757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32  fave[BZ_N_GROUPS];
36767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt16* mtfv = s->mtfv;
36787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->verbosity >= 3)
36807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
36817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                "%d+2 syms in use\n",
36827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                s->nblock, s->nMTF, s->nInUse );
36837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   alphaSize = s->nInUse+2;
36857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (t = 0; t < BZ_N_GROUPS; t++)
36867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (v = 0; v < alphaSize; v++)
36877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->len[t][v] = BZ_GREATER_ICOST;
36887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- Decide how many coding tables to use ---*/
36907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH ( s->nMTF > 0, 3001 );
36917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->nMTF < 200)  nGroups = 2; else
36927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->nMTF < 600)  nGroups = 3; else
36937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->nMTF < 1200) nGroups = 4; else
36947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->nMTF < 2400) nGroups = 5; else
36957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       nGroups = 6;
36967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
36977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- Generate an initial set of coding tables ---*/
36987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   {
36997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32 nPart, remF, tFreq, aFreq;
37007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nPart = nGroups;
37027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      remF  = s->nMTF;
37037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gs = 0;
37047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (nPart > 0) {
37057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         tFreq = remF / nPart;
37067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ge = gs-1;
37077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         aFreq = 0;
37087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (aFreq < tFreq && ge < alphaSize-1) {
37097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ge++;
37107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            aFreq += s->mtfFreq[ge];
37117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
37127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (ge > gs
37147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             && nPart != nGroups && nPart != 1
37157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             && ((nGroups-nPart) % 2 == 1)) {
37167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            aFreq -= s->mtfFreq[ge];
37177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            ge--;
37187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
37197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (0 && s->verbosity >= 3)
37217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            VPrintf5( "      initial group %d, [%d .. %d], "
37227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      "has %d syms (%4.1f%%)\n",
37237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      nPart, gs, ge, aFreq,
37247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
37257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (v = 0; v < alphaSize; v++)
37277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (v >= gs && v <= ge)
37287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
37297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               s->len[nPart-1][v] = BZ_GREATER_ICOST;
37307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         nPart--;
37327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         gs = ge+1;
37337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         remF -= aFreq;
37347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
37357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
37367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*---
37387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Iterate up to BZ_N_ITERS times to improve the tables.
37397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ---*/
37407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (iter = 0; iter < BZ_N_ITERS; iter++) {
37417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (t = 0; t < nGroups; t++) fave[t] = 0;
37437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (t = 0; t < nGroups; t++)
37457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (v = 0; v < alphaSize; v++)
37467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->rfreq[t][v] = 0;
37477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*---
37497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        Set up an auxiliary length table which is used to fast-track
37507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	the common case (nGroups == 6).
37517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ---*/
37527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (nGroups == 6) {
37537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (v = 0; v < alphaSize; v++) {
37547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
37557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
37567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
37577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 }
37587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
37597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nSelectors = 0;
37617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      totc = 0;
37627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gs = 0;
37637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
37647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*--- Set group start & end marks. --*/
37667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (gs >= s->nMTF) break;
37677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ge = gs + BZ_G_SIZE - 1;
37687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (ge >= s->nMTF) ge = s->nMTF-1;
37697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*--
37717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            Calculate the cost of this group as coded
37727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            by each of the coding tables.
37737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         --*/
37747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (t = 0; t < nGroups; t++) cost[t] = 0;
37757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (nGroups == 6 && 50 == ge-gs+1) {
37777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            /*--- fast track the common case ---*/
37787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            register UInt32 cost01, cost23, cost45;
37797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            register UInt16 icv;
37807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            cost01 = cost23 = cost45 = 0;
37817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#           define BZ_ITER(nn)                \
37837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               icv = mtfv[gs+(nn)];           \
37847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cost01 += s->len_pack[icv][0]; \
37857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cost23 += s->len_pack[icv][1]; \
37867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cost45 += s->len_pack[icv][2]; \
37877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
37897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
37907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
37917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
37927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
37937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
37947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
37957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
37967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
37977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
37987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
37997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#           undef BZ_ITER
38007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
38027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
38037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
38047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
38067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	    /*--- slow version which correctly handles all situations ---*/
38077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            for (i = gs; i <= ge; i++) {
38087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               UInt16 icv = mtfv[i];
38097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
38107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
38117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
38127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*--
38147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            Find the coding table which is best for this group,
38157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            and record its identity in the selector table.
38167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         --*/
38177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         bc = 999999999; bt = -1;
38187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (t = 0; t < nGroups; t++)
38197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (cost[t] < bc) { bc = cost[t]; bt = t; };
38207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         totc += bc;
38217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         fave[bt]++;
38227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->selector[nSelectors] = bt;
38237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         nSelectors++;
38247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*--
38267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            Increment the symbol frequencies for the selected table.
38277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          --*/
38287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (nGroups == 6 && 50 == ge-gs+1) {
38297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            /*--- fast track the common case ---*/
38307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
38327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
38347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
38357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
38367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
38377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
38387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
38397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
38407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
38417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
38427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
38437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#           undef BZ_ITUR
38457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
38477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	    /*--- slow version which correctly handles all situations ---*/
38487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            for (i = gs; i <= ge; i++)
38497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               s->rfreq[bt][ mtfv[i] ]++;
38507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
38517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         gs = ge+1;
38537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
38547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->verbosity >= 3) {
38557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf2 ( "      pass %d: size is %d, grp uses are ",
38567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   iter+1, totc/8 );
38577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (t = 0; t < nGroups; t++)
38587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            VPrintf1 ( "%d ", fave[t] );
38597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf0 ( "\n" );
38607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
38617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--
38637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        Recompute the tables based on the accumulated frequencies.
38647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      --*/
38657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
38667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         comment in huffman.c for details. */
38677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (t = 0; t < nGroups; t++)
38687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
38697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                                 alphaSize, 17 /*20*/ );
38707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
38717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH( nGroups < 8, 3002 );
38747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH( nSelectors < 32768 &&
38757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
38767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            3003 );
38777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- Compute MTF values for the selectors. ---*/
38807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   {
38817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
38827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < nGroups; i++) pos[i] = i;
38837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < nSelectors; i++) {
38847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ll_i = s->selector[i];
38857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         j = 0;
38867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         tmp = pos[j];
38877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while ( ll_i != tmp ) {
38887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            j++;
38897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            tmp2 = tmp;
38907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            tmp = pos[j];
38917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            pos[j] = tmp2;
38927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         };
38937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         pos[0] = tmp;
38947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->selectorMtf[i] = j;
38957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
38967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   };
38977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
38987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- Assign actual codes for the tables. --*/
38997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (t = 0; t < nGroups; t++) {
39007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      minLen = 32;
39017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      maxLen = 0;
39027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < alphaSize; i++) {
39037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
39047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->len[t][i] < minLen) minLen = s->len[t][i];
39057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
39067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
39077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH ( !(minLen < 1),  3005 );
39087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
39097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          minLen, maxLen, alphaSize );
39107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
39117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- Transmit the mapping table. ---*/
39137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   {
39147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool inUse16[16];
39157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < 16; i++) {
39167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          inUse16[i] = False;
39177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          for (j = 0; j < 16; j++)
39187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             if (s->inUse[i * 16 + j]) inUse16[i] = True;
39197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
39207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nBytes = s->numZ;
39227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < 16; i++)
39237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
39247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < 16; i++)
39267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (inUse16[i])
39277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            for (j = 0; j < 16; j++) {
39287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
39297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
39307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->verbosity >= 3)
39327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
39337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
39347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- Now the selectors. ---*/
39367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nBytes = s->numZ;
39377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsW ( s, 3, nGroups );
39387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bsW ( s, 15, nSelectors );
39397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < nSelectors; i++) {
39407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
39417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsW(s,1,0);
39427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
39437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->verbosity >= 3)
39447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      VPrintf1( "selectors %d, ", s->numZ-nBytes );
39457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- Now the coding tables. ---*/
39477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nBytes = s->numZ;
39487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (t = 0; t < nGroups; t++) {
39507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32 curr = s->len[t][0];
39517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsW ( s, 5, curr );
39527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      for (i = 0; i < alphaSize; i++) {
39537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
39547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
39557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         bsW ( s, 1, 0 );
39567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
39577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
39587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->verbosity >= 3)
39607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
39617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*--- And finally, the block data proper ---*/
39637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nBytes = s->numZ;
39647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   selCtr = 0;
39657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   gs = 0;
39667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
39677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (gs >= s->nMTF) break;
39687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ge = gs + BZ_G_SIZE - 1;
39697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ge >= s->nMTF) ge = s->nMTF-1;
39707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      AssertH ( s->selector[selCtr] < nGroups, 3006 );
39717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (nGroups == 6 && 50 == ge-gs+1) {
39737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            /*--- fast track the common case ---*/
39747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            UInt16 mtfv_i;
39757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            UChar* s_len_sel_selCtr
39767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               = &(s->len[s->selector[selCtr]][0]);
39777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            Int32* s_code_sel_selCtr
39787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               = &(s->code[s->selector[selCtr]][0]);
39797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#           define BZ_ITAH(nn)                      \
39817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               mtfv_i = mtfv[gs+(nn)];              \
39827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               bsW ( s,                             \
39837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s_len_sel_selCtr[mtfv_i],      \
39847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     s_code_sel_selCtr[mtfv_i] )
39857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
39877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
39887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
39897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
39907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
39917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
39927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
39937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
39947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
39957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
39967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#           undef BZ_ITAH
39987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
39997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } else {
40007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 /*--- slow version which correctly handles all situations ---*/
40017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         for (i = gs; i <= ge; i++) {
40027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            bsW ( s,
40037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->len  [s->selector[selCtr]] [mtfv[i]],
40047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  s->code [s->selector[selCtr]] [mtfv[i]] );
40057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
40067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
40077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      gs = ge+1;
40107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      selCtr++;
40117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
40127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH( selCtr == nSelectors, 3007 );
40137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->verbosity >= 3)
40157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      VPrintf1( "codes %d\n", s->numZ-nBytes );
40167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
40177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
40207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ2_compressBlock ( EState* s, Bool is_last_block )
40217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
40227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->nblock > 0) {
40237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ_FINALISE_CRC ( s->blockCRC );
40257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
40267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->combinedCRC ^= s->blockCRC;
40277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->blockNo > 1) s->numZ = 0;
40287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->verbosity >= 2)
40307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf4( "    block %d: crc = 0x%08x, "
40317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   "combined CRC = 0x%08x, size = %d\n",
40327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
40337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ2_blockSort ( s );
40357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
40367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
40387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- If this is the first block, create the stream header. --*/
40407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->blockNo == 1) {
40417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ2_bsInitWrite ( s );
40427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, BZ_HDR_B );
40437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, BZ_HDR_Z );
40447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, BZ_HDR_h );
40457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
40467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
40477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->nblock > 0) {
40497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
40517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
40527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
40537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- Now the block's CRC, so it is in a known place. --*/
40557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUInt32 ( s, s->blockCRC );
40567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*--
40587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Now a single bit indicating (non-)randomisation.
40597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         As of version 0.9.5, we use a better sorting algorithm
40607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         which makes randomisation unnecessary.  So always set
40617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         the randomised bit to 'no'.  Of course, the decoder
40627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         still needs to be able to handle randomised blocks
40637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         so as to maintain backwards compatibility with
40647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         older versions of bzip2.
40657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      --*/
40667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsW(s,1,0);
40677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsW ( s, 24, s->origPtr );
40697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      generateMTFValues ( s );
40707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      sendMTFValues ( s );
40717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
40727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- If this is the last block, add the stream trailer. --*/
40757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (is_last_block) {
40767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
40787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
40797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
40807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsPutUInt32 ( s, s->combinedCRC );
40817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->verbosity >= 2)
40827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
40837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bsFinishWrite ( s );
40847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
40857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
40867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
40897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                        compress.c ---*/
40907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
40917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
40947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Table for randomising repetitive blocks               ---*/
40957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                           randtable.c ---*/
40967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
40977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
40987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
40997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
41007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
41017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
41037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
41057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
41067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
41077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
41097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
41107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
41127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
41137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
41147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
41157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
41177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
41187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
41207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
41217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
41227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
41247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
41257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
41277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
41367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
41377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
41387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
41407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
41417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
41427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
41437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
41447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
41457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
41467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
41477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
41487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
41507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
41517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
41557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
41567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjInt32 BZ2_rNums[512] = {
41577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
41587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
41597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
41607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
41617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
41627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
41637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
41647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
41657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
41667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
41677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
41687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
41697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
41707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
41717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
41727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
41737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
41747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
41757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
41767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
41777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
41787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
41797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
41807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
41817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
41827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
41837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
41847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
41857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
41867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
41877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
41887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
41897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
41907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
41917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
41927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
41937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
41947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
41957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
41967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
41977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
41987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
41997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
42007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
42017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
42027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
42037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
42047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
42057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
42067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
42077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
42087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   936, 638
42097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj};
42107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
42137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                       randtable.c ---*/
42147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
42157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
42177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Table for doing CRCs                                  ---*/
42187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                            crctable.c ---*/
42197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
42207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
42227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
42237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
42247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
42267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
42287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
42297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
42307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
42327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
42337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
42357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
42367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
42377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
42387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
42407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
42417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
42437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
42447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
42457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
42477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
42507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
42597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
42607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
42617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
42637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
42647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
42657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
42667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
42677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
42687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
42697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
42707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
42717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
42737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
42747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
42807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  I think this is an implementation of the AUTODIN-II,
42817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
42827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  from code by Rob Warnock, in Section 51 of the
42837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  comp.compression FAQ.
42847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
42857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjUInt32 BZ2_crc32Table[256] = {
42877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- Ugly, innit? --*/
42897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
42907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
42917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
42927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
42937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
42947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
42957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
42967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
42977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
42987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
42997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
43007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
43017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
43027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
43037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
43047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
43057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
43067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
43077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
43087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
43097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
43107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
43117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
43127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
43137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
43147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
43157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
43167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
43177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
43187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
43197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
43207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
43217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
43227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
43237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
43247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
43257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
43267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
43277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
43287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
43297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
43307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
43317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
43327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
43337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
43347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
43357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
43367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
43377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
43387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
43397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
43407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
43417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
43427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
43437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
43447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
43457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
43467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
43477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
43487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
43497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
43507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
43517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
43527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
43537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
43547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj};
43557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
43587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                        crctable.c ---*/
43597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
43607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
43627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Library top-level functions.                          ---*/
43637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---                                               bzlib.c ---*/
43647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
43657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
43677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
43687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  library for lossless, block-sorting data compression.
43697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
43717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Redistribution and use in source and binary forms, with or without
43737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  modification, are permitted provided that the following conditions
43747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  are met:
43757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  1. Redistributions of source code must retain the above copyright
43777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     notice, this list of conditions and the following disclaimer.
43787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  2. The origin of this software must not be misrepresented; you must
43807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not claim that you wrote the original software.  If you use this
43817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     software in a product, an acknowledgment in the product
43827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     documentation would be appreciated but is not required.
43837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  3. Altered source versions must be plainly marked as such, and must
43857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     not be misrepresented as being the original software.
43867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  4. The name of the author may not be used to endorse or promote
43887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     products derived from this software without specific prior written
43897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     permission.
43907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
43917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
43927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
43957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
43997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  Julian Seward, Cambridge, UK.
44047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  jseward@bzip.org
44057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
44067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  This program is based on (at least) the work of:
44087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Mike Burrows
44097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     David Wheeler
44107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Peter Fenwick
44117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Alistair Moffat
44127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Radford Neal
44137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Ian H. Witten
44147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Robert Sedgewick
44157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     Jon L. Bentley
44167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  For more information on these sources, see the manual.
44187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
44197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
44217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   CHANGES
44227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ~~~~~~~
44237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0.9.0 -- original version.
44247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0.9.0a/b -- no changes in this file.
44267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   0.9.0c
44287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      * made zero-length BZ_FLUSH work correctly in bzCompress().
44297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      * fixed bzWrite/bzRead to ignore zero-length requests.
44307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      * fixed bzread to correctly handle read requests after EOF.
44317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      * wrong parameter order in call to bzDecompressInit in
44327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        bzBuffToBuffDecompress.  Fixed.
44337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
44347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
44387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Compression stuff                           ---*/
44397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
44407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
44437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ2_bz__AssertH__fail ( int errcode )
44447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
44457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf("BZ2_bz__AssertH__fail(%d) called, exiting\n", errcode);
44467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (*serviceFn)(0,0);
44477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
44487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid bz_internal_error ( int errcode )
44507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
44517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf("bz_internal_error called, exiting\n", errcode);
44527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (*serviceFn)(0,0);
44537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
44547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
44567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
44577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint bz_config_ok ( void )
44587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
44597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (sizeof(int)   != 4) return 0;
44607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (sizeof(short) != 2) return 0;
44617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (sizeof(char)  != 1) return 0;
44627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return 1;
44637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
44647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
44677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
44687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid* default_bzalloc ( void* opaque, Int32 items, Int32 size )
44697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
44707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   void* v = (void*) (*serviceFn)(2, items * size );
44717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return v;
44727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
44737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
44757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid default_bzfree ( void* opaque, void* addr )
44767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
44777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (addr != NULL) (*serviceFn)( 3, (HWord)addr );
44787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
44797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
44827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
44837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid prepare_new_block ( EState* s )
44847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
44857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 i;
44867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->nblock = 0;
44877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->numZ = 0;
44887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->state_out_pos = 0;
44897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_INITIALISE_CRC ( s->blockCRC );
44907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < 256; i++) s->inUse[i] = False;
44917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->blockNo++;
44927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
44937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
44957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
44967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
44977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid init_RL ( EState* s )
44987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
44997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->state_in_ch  = 256;
45007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->state_in_len = 0;
45017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
45027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
45057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool isempty_RL ( EState* s )
45067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
45077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->state_in_ch < 256 && s->state_in_len > 0)
45087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return False; else
45097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return True;
45107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
45117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
45147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzCompressInit)
45157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    ( bz_stream* strm,
45167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     int        blockSize100k,
45177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     int        verbosity,
45187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     int        workFactor )
45197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
45207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   n;
45217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   EState* s;
45227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
45247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm == NULL ||
45267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       blockSize100k < 1 || blockSize100k > 9 ||
45277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       workFactor < 0 || workFactor > 250)
45287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     return BZ_PARAM_ERROR;
45297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (workFactor == 0) workFactor = 30;
45317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
45327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
45337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s = BZALLOC( sizeof(EState) );
45357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s == NULL) return BZ_MEM_ERROR;
45367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->strm = strm;
45377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->arr1 = NULL;
45397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->arr2 = NULL;
45407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->ftab = NULL;
45417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   n       = 100000 * blockSize100k;
45437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
45447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
45457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
45467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
45487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->arr1 != NULL) BZFREE(s->arr1);
45497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->arr2 != NULL) BZFREE(s->arr2);
45507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->ftab != NULL) BZFREE(s->ftab);
45517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s       != NULL) BZFREE(s);
45527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return BZ_MEM_ERROR;
45537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
45547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->blockNo           = 0;
45567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->state             = BZ_S_INPUT;
45577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->mode              = BZ_M_RUNNING;
45587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->combinedCRC       = 0;
45597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->blockSize100k     = blockSize100k;
45607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->nblockMAX         = 100000 * blockSize100k - 19;
45617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->verbosity         = verbosity;
45627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->workFactor        = workFactor;
45637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->block             = (UChar*)s->arr2;
45657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->mtfv              = (UInt16*)s->arr1;
45667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->zbits             = NULL;
45677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->ptr               = (UInt32*)s->arr1;
45687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->state          = s;
45707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_in_lo32  = 0;
45717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_in_hi32  = 0;
45727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_out_lo32 = 0;
45737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_out_hi32 = 0;
45747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   init_RL ( s );
45757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   prepare_new_block ( s );
45767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OK;
45777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
45787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
45807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
45817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
45827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid add_pair_to_block ( EState* s )
45837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
45847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 i;
45857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar ch = (UChar)(s->state_in_ch);
45867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < s->state_in_len; i++) {
45877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ_UPDATE_CRC( s->blockCRC, ch );
45887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
45897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->inUse[s->state_in_ch] = True;
45907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   switch (s->state_in_len) {
45917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 1:
45927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         break;
45947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 2:
45957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         break;
45987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 3:
45997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
46007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
46017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
46027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         break;
46037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      default:
46047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->inUse[s->state_in_len-4] = True;
46057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
46067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
46077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
46087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
46097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
46107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->nblock++;
46117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         break;
46127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
46137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
46147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
46177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
46187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid flush_RL ( EState* s )
46197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
46207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->state_in_ch < 256) add_pair_to_block ( s );
46217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   init_RL ( s );
46227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
46237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
46267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
46277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                                 \
46287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UInt32 zchh = (UInt32)(zchh0);                 \
46297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- fast track the common case --*/           \
46307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (zchh != zs->state_in_ch &&                 \
46317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       zs->state_in_len == 1) {                   \
46327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar ch = (UChar)(zs->state_in_ch);        \
46337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
46347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->inUse[zs->state_in_ch] = True;          \
46357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->block[zs->nblock] = (UChar)ch;          \
46367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->nblock++;                               \
46377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->state_in_ch = zchh;                     \
46387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                              \
46397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   else                                           \
46407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*-- general, uncommon cases --*/              \
46417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (zchh != zs->state_in_ch ||                 \
46427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->state_in_len == 255) {                  \
46437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (zs->state_in_ch < 256)                  \
46447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         add_pair_to_block ( zs );                \
46457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->state_in_ch = zchh;                     \
46467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->state_in_len = 1;                       \
46477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {                                       \
46487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      zs->state_in_len++;                         \
46497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }                                              \
46507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
46517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
46547fc4d4aedc82a0403d26736f7c61b02e50c85a16florianstatic __attribute__((noinline))
46557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool copy_input_until_stop ( EState* s )
46567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
46577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool progress_in = False;
46587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->mode == BZ_M_RUNNING) {
46607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- fast track the common case --*/
46627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
46637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- block full? --*/
46647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock >= s->nblockMAX) break;
46657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- no input? --*/
46667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->strm->avail_in == 0) break;
46677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         progress_in = True;
46687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
46697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->next_in++;
46707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->avail_in--;
46717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->total_in_lo32++;
46727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
46737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
46747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
46767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- general, uncommon case --*/
46787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
46797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- block full? --*/
46807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock >= s->nblockMAX) break;
46817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- no input? --*/
46827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->strm->avail_in == 0) break;
46837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /*-- flush/finish end? --*/
46847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->avail_in_expect == 0) break;
46857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         progress_in = True;
46867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
46877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->next_in++;
46887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->avail_in--;
46897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->total_in_lo32++;
46907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
46917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->avail_in_expect--;
46927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
46937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      //exit(1);
46947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
46957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return progress_in;
46967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
46977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
46997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
47007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
47017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool copy_output_until_stop ( EState* s )
47027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
47037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool progress_out = False;
47047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
47067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- no output space? --*/
47087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->strm->avail_out == 0) break;
47097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /*-- block done? --*/
47117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->state_out_pos >= s->numZ) break;
47127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      progress_out = True;
47147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      *(s->strm->next_out) = s->zbits[s->state_out_pos];
47157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->state_out_pos++;
47167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->avail_out--;
47177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->next_out++;
47187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->total_out_lo32++;
47197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
47207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
47217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return progress_out;
47237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
47247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
47277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
47287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool handle_compress ( bz_stream* strm )
47297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
47307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool progress_in  = False;
47317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool progress_out = False;
47327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   EState* s = strm->state;
47337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
47357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->state == BZ_S_OUTPUT) {
47377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         progress_out |= copy_output_until_stop ( s );
47387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->state_out_pos < s->numZ) break;
47397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->mode == BZ_M_FINISHING &&
47407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             s->avail_in_expect == 0 &&
47417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             isempty_RL(s)) break;
47427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         prepare_new_block ( s );
47437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state = BZ_S_INPUT;
47447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->mode == BZ_M_FLUSHING &&
47457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             s->avail_in_expect == 0 &&
47467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             isempty_RL(s)) break;
47477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
47487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->state == BZ_S_INPUT) {
47507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         progress_in |= copy_input_until_stop ( s );
47517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
47527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            flush_RL ( s );
47537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
47547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->state = BZ_S_OUTPUT;
47557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
47567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         else
47577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock >= s->nblockMAX) {
47587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ2_compressBlock ( s, False );
47597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->state = BZ_S_OUTPUT;
47607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
47617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         else
47627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->strm->avail_in == 0) {
47637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            break;
47647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
47657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
47667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
47687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return progress_in || progress_out;
47707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
47717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
47747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
47757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
47767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool progress;
47777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   EState* s;
47787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
47797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s = strm->state;
47807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
47817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
47827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   preswitch:
47847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   switch (s->mode) {
47857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
47867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case BZ_M_IDLE:
47877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return BZ_SEQUENCE_ERROR;
47887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case BZ_M_RUNNING:
47897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (action == BZ_RUN) {
47907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            progress = handle_compress ( strm );
47917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
47927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
47937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         else
47947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 if (action == BZ_FLUSH) {
47957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->avail_in_expect = strm->avail_in;
47967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->mode = BZ_M_FLUSHING;
47977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            goto preswitch;
47987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
47997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         else
48007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (action == BZ_FINISH) {
48017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->avail_in_expect = strm->avail_in;
48027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->mode = BZ_M_FINISHING;
48037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            goto preswitch;
48047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
48057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         else
48067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return BZ_PARAM_ERROR;
48077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case BZ_M_FLUSHING:
48097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
48107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->avail_in_expect != s->strm->avail_in)
48117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return BZ_SEQUENCE_ERROR;
48127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         progress = handle_compress ( strm );
48137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
48147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
48157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->mode = BZ_M_RUNNING;
48167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return BZ_RUN_OK;
48177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case BZ_M_FINISHING:
48197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
48207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->avail_in_expect != s->strm->avail_in)
48217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return BZ_SEQUENCE_ERROR;
48227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         progress = handle_compress ( strm );
48237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (!progress) return BZ_SEQUENCE_ERROR;
48247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
48257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
48267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->mode = BZ_M_IDLE;
48277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return BZ_STREAM_END;
48287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
48297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OK; /*--not reached--*/
48307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
48317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
48347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
48357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
48367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   EState* s;
48377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
48387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s = strm->state;
48397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
48407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
48417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->arr1 != NULL) BZFREE(s->arr1);
48437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->arr2 != NULL) BZFREE(s->arr2);
48447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->ftab != NULL) BZFREE(s->ftab);
48457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZFREE(strm->state);
48467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->state = NULL;
48487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OK;
48507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
48517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
48547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Decompression stuff                         ---*/
48557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
48567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
48587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzDecompressInit)
48597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     ( bz_stream* strm,
48607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       int        verbosity,
48617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       int        small )
48627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
48637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   DState* s;
48647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
48667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
48687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
48697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
48707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
48727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
48737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s = BZALLOC( sizeof(DState) );
48757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s == NULL) return BZ_MEM_ERROR;
48767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->strm                  = strm;
48777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->state              = s;
48787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->state                 = BZ_X_MAGIC_1;
48797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->bsLive                = 0;
48807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->bsBuff                = 0;
48817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->calculatedCombinedCRC = 0;
48827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_in_lo32      = 0;
48837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_in_hi32      = 0;
48847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_out_lo32     = 0;
48857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->total_out_hi32     = 0;
48867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->smallDecompress       = (Bool)small;
48877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->ll4                   = NULL;
48887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->ll16                  = NULL;
48897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->tt                    = NULL;
48907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->currBlockNo           = 0;
48917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s->verbosity             = verbosity;
48927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OK;
48947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
48957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
48977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
48987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Return  True iff data corruption is discovered.
48997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Returns False if there is no problem.
49007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj*/
49017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
49027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool unRLE_obuf_to_output_FAST ( DState* s )
49037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
49047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar k1;
49057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->blockRandomised) {
49077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
49097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* try to finish existing run */
49107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (True) {
49117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->strm->avail_out == 0) return False;
49127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->state_out_len == 0) break;
49137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
49147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
49157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->state_out_len--;
49167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->next_out++;
49177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->avail_out--;
49187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->total_out_lo32++;
49197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
49207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
49217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* can a new run be started? */
49237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) return False;
49247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* Only caused by corrupt data stream? */
49267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used > s->save_nblock+1)
49277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return True;
49287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 1;
49307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_ch = s->k0;
49317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
49347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
49357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 2;
49377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
49407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
49417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 3;
49437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
49467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
49477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = ((Int32)k1) + 4;
49517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
49527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
49537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
49547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
49567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* restore */
49587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
49597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UChar         c_state_out_ch       = s->state_out_ch;
49607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32         c_state_out_len      = s->state_out_len;
49617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32         c_nblock_used        = s->nblock_used;
49627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32         c_k0                 = s->k0;
49637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32*       c_tt                 = s->tt;
49647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32        c_tPos               = s->tPos;
49657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      char*         cs_next_out          = s->strm->next_out;
49667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int  cs_avail_out         = s->strm->avail_out;
49677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* end restore */
49687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      UInt32       avail_out_INIT = cs_avail_out;
49707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32        s_save_nblockPP = s->save_nblock+1;
49717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unsigned int total_out_lo32_old;
49727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
49747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
49757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* try to finish existing run */
49767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (c_state_out_len > 0) {
49777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            while (True) {
49787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (cs_avail_out == 0) goto return_notr;
49797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (c_state_out_len == 1) break;
49807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
49817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
49827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               c_state_out_len--;
49837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cs_next_out++;
49847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cs_avail_out--;
49857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
49867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s_state_out_len_eq_one:
49877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            {
49887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               if (cs_avail_out == 0) {
49897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  c_state_out_len = 1; goto return_notr;
49907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               };
49917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
49927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
49937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cs_next_out++;
49947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               cs_avail_out--;
49957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            }
49967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
49977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* Only caused by corrupt data stream? */
49987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (c_nblock_used > s_save_nblockPP)
49997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return True;
50007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* can a new run be started? */
50027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (c_nblock_used == s_save_nblockPP) {
50037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            c_state_out_len = 0; goto return_notr;
50047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         };
50057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         c_state_out_ch = c_k0;
50067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
50077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != c_k0) {
50087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            c_k0 = k1; goto s_state_out_len_eq_one;
50097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         };
50107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (c_nblock_used == s_save_nblockPP)
50117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            goto s_state_out_len_eq_one;
50127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         c_state_out_len = 2;
50147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
50157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (c_nblock_used == s_save_nblockPP) continue;
50167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
50177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         c_state_out_len = 3;
50197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
50207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (c_nblock_used == s_save_nblockPP) continue;
50217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
50227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
50247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         c_state_out_len = ((Int32)k1) + 4;
50257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_FAST_C(c_k0); c_nblock_used++;
50267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
50277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return_notr:
50297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      total_out_lo32_old = s->strm->total_out_lo32;
50307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
50317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->strm->total_out_lo32 < total_out_lo32_old)
50327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->strm->total_out_hi32++;
50337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* save */
50357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->calculatedBlockCRC = c_calculatedBlockCRC;
50367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->state_out_ch       = c_state_out_ch;
50377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->state_out_len      = c_state_out_len;
50387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->nblock_used        = c_nblock_used;
50397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->k0                 = c_k0;
50407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->tt                 = c_tt;
50417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->tPos               = c_tPos;
50427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->next_out     = cs_next_out;
50437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      s->strm->avail_out    = cs_avail_out;
50447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* end save */
50457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
50467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return False;
50477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
50487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
50527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* Return  True iff data corruption is discovered.
50537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Returns False if there is no problem.
50547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj*/
50557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
50567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBool unRLE_obuf_to_output_SMALL ( DState* s )
50577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
50587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar k1;
50597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->blockRandomised) {
50617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
50637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* try to finish existing run */
50647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (True) {
50657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->strm->avail_out == 0) return False;
50667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->state_out_len == 0) break;
50677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
50687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
50697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->state_out_len--;
50707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->next_out++;
50717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->avail_out--;
50727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->total_out_lo32++;
50737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
50747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
50757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* can a new run be started? */
50777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) return False;
50787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* Only caused by corrupt data stream? */
50807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used > s->save_nblock+1)
50817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return True;
50827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 1;
50847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_ch = s->k0;
50857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
50867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
50877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
50887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
50897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 2;
50917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
50927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
50937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
50947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
50957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
50967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 3;
50977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
50987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
50997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
51007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
51017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
51037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
51047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = ((Int32)k1) + 4;
51057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
51067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
51077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
51087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
51107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
51127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* try to finish existing run */
51137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         while (True) {
51147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->strm->avail_out == 0) return False;
51157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->state_out_len == 0) break;
51167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
51177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
51187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->state_out_len--;
51197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->next_out++;
51207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->avail_out--;
51217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->strm->total_out_lo32++;
51227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
51237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
51247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* can a new run be started? */
51267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) return False;
51277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         /* Only caused by corrupt data stream? */
51297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used > s->save_nblock+1)
51307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return True;
51317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 1;
51337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_ch = s->k0;
51347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
51367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
51377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 2;
51397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
51417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
51427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = 3;
51447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
51467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
51477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         s->state_out_len = ((Int32)k1) + 4;
51507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ_GET_SMALL(s->k0); s->nblock_used++;
51517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
51527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
51547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
51557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
51587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
51597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
51607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Bool    corrupt;
51617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   DState* s;
51627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
51637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s = strm->state;
51647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
51657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
51667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
51677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
51687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
51697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->state == BZ_X_OUTPUT) {
51707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->smallDecompress)
51717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
51727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            corrupt = unRLE_obuf_to_output_FAST  ( s );
51737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (corrupt) return BZ_DATA_ERROR;
51747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
51757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
51767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->verbosity >= 3)
51777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
51787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          s->calculatedBlockCRC );
51797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->verbosity >= 2) VPrintf0 ( "]" );
51807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->calculatedBlockCRC != s->storedBlockCRC)
51817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               return BZ_DATA_ERROR;
51827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->calculatedCombinedCRC
51837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               = (s->calculatedCombinedCRC << 1) |
51847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    (s->calculatedCombinedCRC >> 31);
51857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
51867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            s->state = BZ_X_BLKHDR_1;
51877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
51887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return BZ_OK;
51897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
51907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
51917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (s->state >= BZ_X_MAGIC_1) {
51927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         Int32 r = BZ2_decompress ( s );
51937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (r == BZ_STREAM_END) {
51947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->verbosity >= 3)
51957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
51967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          s->storedCombinedCRC, s->calculatedCombinedCRC );
51977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
51987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               return BZ_DATA_ERROR;
51997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            return r;
52007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
52017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (s->state != BZ_X_OUTPUT) return r;
52027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
52037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
52047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   AssertH ( 0, 6001 );
52067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return 0;  /*NOTREACHED*/
52087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
52097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
52127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
52137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
52147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   DState* s;
52157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
52167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   s = strm->state;
52177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
52187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
52197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->tt   != NULL) BZFREE(s->tt);
52217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->ll16 != NULL) BZFREE(s->ll16);
52227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (s->ll4  != NULL) BZFREE(s->ll4);
52237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZFREE(strm->state);
52257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm->state = NULL;
52267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OK;
52287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
52297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_NO_STDIO
52327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
52337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- File I/O stuff                              ---*/
52347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
52357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define BZ_SETERR(eee)                    \
52377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{                                         \
52387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzerror != NULL) *bzerror = eee;   \
52397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf != NULL) bzf->lastErr = eee;   \
52407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
52417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjtypedef
52437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   struct {
52447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      FILE*     handle;
52457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Char      buf[BZ_MAX_UNUSED];
52467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32     bufN;
52477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool      writing;
52487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bz_stream strm;
52497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Int32     lastErr;
52507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      Bool      initialisedOk;
52517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
52527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile;
52537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------*/
52567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic Bool myfeof ( FILE* f )
52577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
52587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 c = fgetc ( f );
52597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (c == EOF) return True;
52607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ungetc ( c, f );
52617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return False;
52627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
52637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
52667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZFILE* BZ_API(BZ2_bzWriteOpen)
52677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    ( int*  bzerror,
52687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      FILE* f,
52697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      int   blockSize100k,
52707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      int   verbosity,
52717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                      int   workFactor )
52727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
52737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   ret;
52747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile* bzf = NULL;
52757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
52777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (f == NULL ||
52797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (blockSize100k < 1 || blockSize100k > 9) ||
52807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (workFactor < 0 || workFactor > 250) ||
52817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (verbosity < 0 || verbosity > 4))
52827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
52837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ferror(f))
52857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
52867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf = malloc ( sizeof(bzFile) );
52887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf == NULL)
52897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
52907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
52917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
52927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->initialisedOk = False;
52937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->bufN          = 0;
52947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->handle        = f;
52957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->writing       = True;
52967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.bzalloc  = NULL;
52977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.bzfree   = NULL;
52987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.opaque   = NULL;
52997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (workFactor == 0) workFactor = 30;
53017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
53027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                              verbosity, workFactor );
53037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret != BZ_OK)
53047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
53057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.avail_in = 0;
53077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->initialisedOk = True;
53087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return bzf;
53097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
53107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
53147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ_API(BZ2_bzWrite)
53157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             ( int*    bzerror,
53167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               BZFILE* b,
53177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               void*   buf,
53187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               int     len )
53197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
53207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32 n, n2, ret;
53217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile* bzf = (bzFile*)b;
53227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
53247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf == NULL || buf == NULL || len < 0)
53257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
53267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (!(bzf->writing))
53277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
53287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ferror(bzf->handle))
53297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
53307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (len == 0)
53327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_OK); return; };
53337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.avail_in = len;
53357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.next_in  = buf;
53367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
53387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bzf->strm.avail_out = BZ_MAX_UNUSED;
53397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bzf->strm.next_out = bzf->buf;
53407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
53417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ret != BZ_RUN_OK)
53427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(ret); return; };
53437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
53457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
53467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
53477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       n, bzf->handle );
53487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (n != n2 || ferror(bzf->handle))
53497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            { BZ_SETERR(BZ_IO_ERROR); return; };
53507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
53517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (bzf->strm.avail_in == 0)
53537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(BZ_OK); return; };
53547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
53557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
53567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
53597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ_API(BZ2_bzWriteClose)
53607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  ( int*          bzerror,
53617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    BZFILE*       b,
53627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    int           abandon,
53637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    unsigned int* nbytes_in,
53647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    unsigned int* nbytes_out )
53657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
53667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzWriteClose64 ( bzerror, b, abandon,
53677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                        nbytes_in, NULL, nbytes_out, NULL );
53687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
53697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ_API(BZ2_bzWriteClose64)
53727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                  ( int*          bzerror,
53737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    BZFILE*       b,
53747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    int           abandon,
53757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    unsigned int* nbytes_in_lo32,
53767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    unsigned int* nbytes_in_hi32,
53777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    unsigned int* nbytes_out_lo32,
53787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                    unsigned int* nbytes_out_hi32 )
53797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
53807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   n, n2, ret;
53817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile* bzf = (bzFile*)b;
53827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf == NULL)
53847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_OK); return; };
53857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (!(bzf->writing))
53867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
53877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ferror(bzf->handle))
53887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
53897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
53917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
53927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
53937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
53947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
53957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if ((!abandon) && bzf->lastErr == BZ_OK) {
53967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      while (True) {
53977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         bzf->strm.avail_out = BZ_MAX_UNUSED;
53987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         bzf->strm.next_out = bzf->buf;
53997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
54007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
54017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            { BZ_SETERR(ret); return; };
54027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
54047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
54057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
54067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                          n, bzf->handle );
54077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            if (n != n2 || ferror(bzf->handle))
54087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               { BZ_SETERR(BZ_IO_ERROR); return; };
54097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
54107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (ret == BZ_STREAM_END) break;
54127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
54137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
54147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if ( !abandon && !ferror ( bzf->handle ) ) {
54167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fflush ( bzf->handle );
54177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ferror(bzf->handle))
54187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(BZ_IO_ERROR); return; };
54197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
54207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_in_lo32 != NULL)
54227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
54237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_in_hi32 != NULL)
54247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
54257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_out_lo32 != NULL)
54267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
54277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (nbytes_out_hi32 != NULL)
54287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
54297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
54317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzCompressEnd ( &(bzf->strm) );
54327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   free ( bzf );
54337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
54347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
54377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZFILE* BZ_API(BZ2_bzReadOpen)
54387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                   ( int*  bzerror,
54397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     FILE* f,
54407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     int   verbosity,
54417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     int   small,
54427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     void* unused,
54437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     int   nUnused )
54447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
54457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile* bzf = NULL;
54467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int     ret;
54477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
54497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (f == NULL ||
54517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (small != 0 && small != 1) ||
54527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (verbosity < 0 || verbosity > 4) ||
54537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (unused == NULL && nUnused != 0) ||
54547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
54557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
54567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ferror(f))
54587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
54597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf = malloc ( sizeof(bzFile) );
54617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf == NULL)
54627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
54637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
54657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->initialisedOk = False;
54677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->handle        = f;
54687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->bufN          = 0;
54697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->writing       = False;
54707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.bzalloc  = NULL;
54717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.bzfree   = NULL;
54727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.opaque   = NULL;
54737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (nUnused > 0) {
54757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
54767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      unused = ((void*)( 1 + ((UChar*)(unused))  ));
54777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nUnused--;
54787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
54797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
54817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret != BZ_OK)
54827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
54837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.avail_in = bzf->bufN;
54857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.next_in  = bzf->buf;
54867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->initialisedOk = True;
54887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return bzf;
54897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
54907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
54937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
54947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
54957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile* bzf = (bzFile*)b;
54967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
54977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
54987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf == NULL)
54997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_OK); return; };
55007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf->writing)
55027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
55037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf->initialisedOk)
55057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
55067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   free ( bzf );
55077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
55087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
55117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzRead)
55127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           ( int*    bzerror,
55137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             BZFILE* b,
55147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             void*   buf,
55157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             int     len )
55167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
55177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Int32   n, ret;
55187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile* bzf = (bzFile*)b;
55197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
55217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf == NULL || buf == NULL || len < 0)
55237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
55247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf->writing)
55267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
55277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (len == 0)
55297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_OK); return 0; };
55307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.avail_out = len;
55327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzf->strm.next_out = buf;
55337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (True) {
55357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ferror(bzf->handle))
55377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(BZ_IO_ERROR); return 0; };
55387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
55407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         n = fread ( bzf->buf, sizeof(UChar),
55417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     BZ_MAX_UNUSED, bzf->handle );
55427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (ferror(bzf->handle))
55437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            { BZ_SETERR(BZ_IO_ERROR); return 0; };
55447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         bzf->bufN = n;
55457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         bzf->strm.avail_in = bzf->bufN;
55467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         bzf->strm.next_in = bzf->buf;
55477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
55487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ret = BZ2_bzDecompress ( &(bzf->strm) );
55507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ret != BZ_OK && ret != BZ_STREAM_END)
55527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(ret); return 0; };
55537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ret == BZ_OK && myfeof(bzf->handle) &&
55557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
55567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
55577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (ret == BZ_STREAM_END)
55597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(BZ_STREAM_END);
55607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           return len - bzf->strm.avail_out; };
55617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (bzf->strm.avail_out == 0)
55627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         { BZ_SETERR(BZ_OK); return len; };
55637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
55657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return 0; /*not reached*/
55677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
55687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
55717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ_API(BZ2_bzReadGetUnused)
55727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                     ( int*    bzerror,
55737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       BZFILE* b,
55747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       void**  unused,
55757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                       int*    nUnused )
55767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
55777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bzFile* bzf = (bzFile*)b;
55787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf == NULL)
55797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
55807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzf->lastErr != BZ_STREAM_END)
55817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
55827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (unused == NULL || nUnused == NULL)
55837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
55847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ_SETERR(BZ_OK);
55867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   *nUnused = bzf->strm.avail_in;
55877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   *unused = bzf->strm.next_in;
55887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
55897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
55907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
55937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- Misc convenience stuff                      ---*/
55947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
55957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
55967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
55977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzBuffToBuffCompress)
55987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                         ( char*         dest,
55997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           unsigned int* destLen,
56007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           char*         source,
56017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           unsigned int  sourceLen,
56027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           int           blockSize100k,
56037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           int           verbosity,
56047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           int           workFactor )
56057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
56067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bz_stream strm;
56077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int ret;
56087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (dest == NULL || destLen == NULL ||
56107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       source == NULL ||
56117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       blockSize100k < 1 || blockSize100k > 9 ||
56127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       verbosity < 0 || verbosity > 4 ||
56137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       workFactor < 0 || workFactor > 250)
56147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return BZ_PARAM_ERROR;
56157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (workFactor == 0) workFactor = 30;
56177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.bzalloc = NULL;
56187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.bzfree = NULL;
56197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.opaque = NULL;
56207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret = BZ2_bzCompressInit ( &strm, blockSize100k,
56227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                              verbosity, workFactor );
56237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret != BZ_OK) return ret;
56247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.next_in = source;
56267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.next_out = dest;
56277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.avail_in = sourceLen;
56287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.avail_out = *destLen;
56297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
56317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret == BZ_FINISH_OK) goto output_overflow;
56327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret != BZ_STREAM_END) goto errhandler;
56337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* normal termination */
56357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   *destLen -= strm.avail_out;
56367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzCompressEnd ( &strm );
56377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OK;
56387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   output_overflow:
56407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzCompressEnd ( &strm );
56417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OUTBUFF_FULL;
56427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   errhandler:
56447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzCompressEnd ( &strm );
56457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return ret;
56467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
56477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
56507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzBuffToBuffDecompress)
56517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                           ( char*         dest,
56527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             unsigned int* destLen,
56537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             char*         source,
56547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             unsigned int  sourceLen,
56557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             int           small,
56567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             int           verbosity )
56577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
56587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   bz_stream strm;
56597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int ret;
56607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (dest == NULL || destLen == NULL ||
56627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       source == NULL ||
56637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       (small != 0 && small != 1) ||
56647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       verbosity < 0 || verbosity > 4)
56657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          return BZ_PARAM_ERROR;
56667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.bzalloc = NULL;
56687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.bzfree = NULL;
56697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.opaque = NULL;
56707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
56717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret != BZ_OK) return ret;
56727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.next_in = source;
56747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.next_out = dest;
56757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.avail_in = sourceLen;
56767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strm.avail_out = *destLen;
56777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   ret = BZ2_bzDecompress ( &strm );
56797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret == BZ_OK) goto output_overflow_or_eof;
56807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (ret != BZ_STREAM_END) goto errhandler;
56817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* normal termination */
56837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   *destLen -= strm.avail_out;
56847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzDecompressEnd ( &strm );
56857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_OK;
56867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   output_overflow_or_eof:
56887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (strm.avail_out > 0) {
56897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ2_bzDecompressEnd ( &strm );
56907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return BZ_UNEXPECTED_EOF;
56917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
56927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ2_bzDecompressEnd ( &strm );
56937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return BZ_OUTBUFF_FULL;
56947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   };
56957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
56967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   errhandler:
56977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzDecompressEnd ( &strm );
56987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return ret;
56997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
57007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
57037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
57047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   Code contributed by Yoshioka Tsuneo
57057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
57067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   to support better zlib compatibility.
57077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   This code is not _officially_ part of libbzip2 (yet);
57087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   I haven't tested it, documented it, or considered the
57097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   threading-safeness of it.
57107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   If this code breaks, please contact both Yoshioka and me.
57117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
57127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
57137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
57157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
57167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return version like "0.9.0c".
57177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
57187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjconst char * BZ_API(BZ2_bzlibVersion)(void)
57197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
57207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return BZ_VERSION;
57217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
57227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifndef BZ_NO_STDIO
57257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
57267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
57287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   include <fcntl.h>
57297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   include <io.h>
57307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
57317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#else
57327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#   define SET_BINARY_MODE(file)
57337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
57347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic
57357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZFILE * bzopen_or_bzdopen
57367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ( const char *path,   /* no use when bzdopen */
57377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 int fd,             /* no use when bzdopen */
57387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 const char *mode,
57397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 int open_mode)      /* bzopen: 0, bzdopen:1 */
57407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
57417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int    bzerr;
57427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   char   unused[BZ_MAX_UNUSED];
57437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int    blockSize100k = 9;
57447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int    writing       = 0;
57457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   char   mode2[10]     = "";
57467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   FILE   *fp           = NULL;
57477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZFILE *bzfp         = NULL;
57487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int    verbosity     = 0;
57497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int    workFactor    = 30;
57507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int    smallMode     = 0;
57517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int    nUnused       = 0;
57527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (mode == NULL) return NULL;
57547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   while (*mode) {
57557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      switch (*mode) {
57567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 'r':
57577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         writing = 0; break;
57587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 'w':
57597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         writing = 1; break;
57607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 's':
57617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         smallMode = 1; break;
57627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      default:
57637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (isdigit((int)(*mode))) {
57647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            blockSize100k = *mode-BZ_HDR_0;
57657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
57667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
57677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      mode++;
57687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
57697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strcat(mode2, writing ? "w" : "r" );
57707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   strcat(mode2,"b");   /* binary mode */
57717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (open_mode==0) {
57737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (path==NULL || strcmp(path,"")==0) {
57747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        fp = (writing ? stdout : stdin);
57757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        SET_BINARY_MODE(fp);
57767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } else {
57777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        fp = fopen(path,mode2);
57787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
57797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
57807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#ifdef BZ_STRICT_ANSI
57817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fp = NULL;
57827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#else
57837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fp = fdopen(fd,mode2);
57847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
57857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
57867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (fp == NULL) return NULL;
57877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
57887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (writing) {
57897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      /* Guard against total chaos and anarchy -- JRS */
57907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (blockSize100k < 1) blockSize100k = 1;
57917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (blockSize100k > 9) blockSize100k = 9;
57927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
57937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                             verbosity,workFactor);
57947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
57957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
57967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                            unused,nUnused);
57977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
57987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzfp == NULL) {
57997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (fp != stdin && fp != stdout) fclose(fp);
58007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return NULL;
58017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
58027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return bzfp;
58037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
58047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
58077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
58087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   open file for read or write.
58097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ex) bzopen("file","w9")
58107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case path="" or NULL => use stdin or stdout.
58117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
58127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZFILE * BZ_API(BZ2_bzopen)
58137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ( const char *path,
58147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 const char *mode )
58157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
58167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
58177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
58187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
58217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjBZFILE * BZ_API(BZ2_bzdopen)
58227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj               ( int fd,
58237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                 const char *mode )
58247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
58257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
58267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
58277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
58307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
58317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
58327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int bzerr, nread;
58337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
58347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nread = BZ2_bzRead(&bzerr,b,buf,len);
58357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
58367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return nread;
58377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   } else {
58387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return -1;
58397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
58407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
58417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
58447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
58457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
58467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int bzerr;
58477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   BZ2_bzWrite(&bzerr,b,buf,len);
58497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if(bzerr == BZ_OK){
58507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return len;
58517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }else{
58527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      return -1;
58537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
58547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
58557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
58587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint BZ_API(BZ2_bzflush) (BZFILE *b)
58597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
58607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* do nothing now... */
58617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return 0;
58627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
58637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
58667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid BZ_API(BZ2_bzclose) (BZFILE* b)
58677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
58687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int bzerr;
58697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   FILE *fp = ((bzFile *)b)->handle;
58707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (b==NULL) {return;}
58727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if(((bzFile*)b)->writing){
58737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
58747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if(bzerr != BZ_OK){
58757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
58767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
58777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }else{
58787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      BZ2_bzReadClose(&bzerr,b);
58797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
58807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if(fp!=stdin && fp!=stdout){
58817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      fclose(fp);
58827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
58837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
58847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
58867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*---------------------------------------------------*/
58877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--
58887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return last error code
58897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj--*/
58907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic char *bzerrorstrings[] = {
58917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       "OK"
58927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"SEQUENCE_ERROR"
58937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"PARAM_ERROR"
58947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"MEM_ERROR"
58957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"DATA_ERROR"
58967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"DATA_ERROR_MAGIC"
58977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"IO_ERROR"
58987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"UNEXPECTED_EOF"
58997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"OUTBUFF_FULL"
59007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"CONFIG_ERROR"
59017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj};
59087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjconst char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
59117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
59127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int err = ((bzFile *)b)->lastErr;
59137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if(err>0) err = 0;
59157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   *errnum = err;
59167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return bzerrorstrings[err*-1];
59177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
59187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
59197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
59227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*--- end                                           bzlib.c ---*/
59237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/*-------------------------------------------------------------*/
59247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
59277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/////////////////////////////////////////////////////////////////////
59287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* A test program written to test robustness to decompression of
59317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   corrupted data.  Usage is
59327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       unzcrash filename
59337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   and the program will read the specified file, compress it (in memory),
59347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   and then repeatedly decompress it, each time with a different bit of
59357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   the compressed data inverted, so as to test all possible one-bit errors.
59367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   This should not cause any invalid memory accesses.  If it does,
59377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   I want to know about it!
59387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   p.s.  As you can see from the above description, the process is
59407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   incredibly slow.  A file of size eg 5KB will cause it to run for
59417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   many hours.
59427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj*/
59437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj//#include <stdio.h>
59457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj//#include <assert.h>
59467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj//#include "bzlib.h"
59477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define M_BLOCK 1000000
59497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define M_BLOCK_OUT (M_BLOCK + 1000000)
59527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj char inbuf[M_BLOCK];
59537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj char outbuf[M_BLOCK_OUT];
59547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj char zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
59557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint nIn;
59577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjunsigned int nOut;
59587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjunsigned int nZ;
59597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#if 0
59617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic char *bzerrorstrings[] = {
59627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       "OK"
59637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"SEQUENCE_ERROR"
59647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"PARAM_ERROR"
59657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"MEM_ERROR"
59667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"DATA_ERROR"
59677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"DATA_ERROR_MAGIC"
59687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"IO_ERROR"
59697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"UNEXPECTED_EOF"
59707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"OUTBUFF_FULL"
59717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      ,"???"   /* for future */
59777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj};
59787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
59797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid flip_bit ( int bit )
59817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
59827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int byteno = bit / 8;
59837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int bitno  = bit % 8;
59847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   UChar mask = 1 << bitno;
59857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
59867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   //          byteno, bitno, (int)mask );
59877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   zbuf[byteno] ^= mask;
59887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
59897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
59907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjvoid set_inbuf ( void )
59917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
59927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  inbuf[0] = 0;
59937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "At her sixtieth birthday party, Margaret Thatcher ");
59947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "blew on the cake to light the candles.\n");
59957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "This program, bzip2, the associated library libbzip2, and all\n");
59967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "documentation, are copyright (C) 1996-2004 Julian R Seward.  All\n");
59977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "rights reserved.\n");
59987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
59997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Redistribution and use in source and binary forms, with or without\n");
60007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "modification, are permitted provided that the following conditions\n");
60017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "are met:\n");
60027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "1. Redistributions of source code must retain the above copyright\n");
60047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   notice, this list of conditions and the following disclaimer.\n");
60057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "2. The origin of this software must not be misrepresented; you must\n");
60077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   not claim that you wrote the original software.  If you use this\n");
60087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   software in a product, an acknowledgment in the product\n");
60097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   documentation would be appreciated but is not required.\n");
60107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "3. Altered source versions must be plainly marked as such, and must\n");
60127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   not be misrepresented as being the original software.\n");
60137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "4. The name of the author may not be used to endorse or promote\n");
60157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   products derived from this software without specific prior written\n");
60167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   permission.\n");
60177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n");
60197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n");
60207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n");
60217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n");
60227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n");
60237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n");
60247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n");
60257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n");
60267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n");
60277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n");
60287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n");
60297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "		    GNU GENERAL PUBLIC LICENSE\n");
60727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "		       Version 2, June 1991\n");
60737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, " Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n");
60757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n");
60767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, " Everyone is permitted to copy and distribute verbatim copies\n");
60777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, " of this license document, but changing it is not allowed.\n");
60787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "			    Preamble\n");
60807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  The licenses for most software are designed to take away your\n");
60827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "freedom to share and change it.  By contrast, the GNU General Public\n");
60837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "License is intended to guarantee your freedom to share and change free\n");
60847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "software--to make sure the software is free for all its users.  This\n");
60857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "General Public License applies to most of the Free Software\n");
60867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Foundation's software and to any other program whose authors commit to\n");
60877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "using it.  (Some other Free Software Foundation software is covered by\n");
60887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "the GNU Library General Public License instead.)  You can apply it to\n");
60897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "your programs, too.\n");
60907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  When we speak of free software, we are referring to freedom, not\n");
60927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "price.  Our General Public Licenses are designed to make sure that you\n");
60937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "have the freedom to distribute copies of free software (and charge for\n");
60947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "this service if you wish), that you receive source code or can get it\n");
60957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "if you want it, that you can change the software or use pieces of it\n");
60967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "in new free programs; and that you know you can do these things.\n");
60977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
60987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  To protect your rights, we need to make restrictions that forbid\n");
60997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "anyone to deny you these rights or to ask you to surrender the rights.\n");
61007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "These restrictions translate to certain responsibilities for you if you\n");
61017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "distribute copies of the software, or if you modify it.\n");
61027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  For example, if you distribute copies of such a program, whether\n");
61047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "gratis or for a fee, you must give the recipients all the rights that\n");
61057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "you have.  You must make sure that they, too, receive or can get the\n");
61067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "source code.  And you must show them these terms so they know their\n");
61077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "rights.\n");
61087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  We protect your rights with two steps: (1) copyright the software, and\n");
61107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "(2) offer you this license which gives you legal permission to copy,\n");
61117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "distribute and/or modify the software.\n");
61127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  Also, for each author's protection and ours, we want to make certain\n");
61147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "that everyone understands that there is no warranty for this free\n");
61157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "software.  If the software is modified by someone else and passed on, we\n");
61167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "want its recipients to know that what they have is not the original, so\n");
61177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "that any problems introduced by others will not reflect on the original\n");
61187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "authors' reputations.\n");
61197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  Finally, any free program is threatened constantly by software\n");
61217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "patents.  We wish to avoid the danger that redistributors of a free\n");
61227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "program will individually obtain patent licenses, in effect making the\n");
61237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "program proprietary.  To prevent this, we have made it clear that any\n");
61247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "patent must be licensed for everyone's free use or not licensed at all.\n");
61257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  The precise terms and conditions for copying, distribution and\n");
61277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "modification follow.\n");
61287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "		    GNU GENERAL PUBLIC LICENSE\n");
61307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n");
61317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  0. This License applies to any program or other work which contains\n");
61337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "a notice placed by the copyright holder saying it may be distributed\n");
61347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "under the terms of this General Public License.  The Program, below,\n");
61357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "refers to any such program or work, and a work based on the Program\n");
61367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "means either the Program or any derivative work under copyright law:\n");
61377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "that is to say, a work containing the Program or a portion of it,\n");
61387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "either verbatim or with modifications and/or translated into another\n");
61397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "language.  (Hereinafter, translation is included without limitation in\n");
61407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "the term modification.)  Each licensee is addressed as you.\n");
61417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Activities other than copying, distribution and modification are not\n");
61437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "covered by this License; they are outside its scope.  The act of\n");
61447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "running the Program is not restricted, and the output from the Program\n");
61457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "is covered only if its contents constitute a work based on the\n");
61467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Program (independent of having been made by running the Program).\n");
61477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Whether that is true depends on what the Program does.\n");
61487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  1. You may copy and distribute verbatim copies of the Program's\n");
61507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "source code as you receive it, in any medium, provided that you\n");
61517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "conspicuously and appropriately publish on each copy an appropriate\n");
61527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "copyright notice and disclaimer of warranty; keep intact all the\n");
61537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "notices that refer to this License and to the absence of any warranty;\n");
61547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "and give any other recipients of the Program a copy of this License\n");
61557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "along with the Program.\n");
61567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "You may charge a fee for the physical act of transferring a copy, and\n");
61587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "you may at your option offer warranty protection in exchange for a fee.\n");
61597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  2. You may modify your copy or copies of the Program or any portion\n");
61617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "of it, thus forming a work based on the Program, and copy and\n");
61627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "distribute such modifications or work under the terms of Section 1\n");
61637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "above, provided that you also meet all of these conditions:\n");
61647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    a) You must cause the modified files to carry prominent notices\n");
61667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    stating that you changed the files and the date of any change.\n");
61677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    b) You must cause any work that you distribute or publish, that in\n");
61697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    whole or in part contains or is derived from the Program or any\n");
61707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    part thereof, to be licensed as a whole at no charge to all third\n");
61717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    parties under the terms of this License.\n");
61727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    c) If the modified program normally reads commands interactively\n");
61747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    when run, you must cause it, when started running for such\n");
61757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    interactive use in the most ordinary way, to print or display an\n");
61767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    announcement including an appropriate copyright notice and a\n");
61777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    notice that there is no warranty (or else, saying that you provide\n");
61787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    a warranty) and that users may redistribute the program under\n");
61797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    these conditions, and telling the user how to view a copy of this\n");
61807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    License.  (Exception: if the Program itself is interactive but\n");
61817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    does not normally print such an announcement, your work based on\n");
61827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    the Program is not required to print an announcement.)\n");
61837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "These requirements apply to the modified work as a whole.  If\n");
61857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "identifiable sections of that work are not derived from the Program,\n");
61867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "and can be reasonably considered independent and separate works in\n");
61877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "themselves, then this License, and its terms, do not apply to those\n");
61887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "sections when you distribute them as separate works.  But when you\n");
61897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "distribute the same sections as part of a whole which is a work based\n");
61907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "on the Program, the distribution of the whole must be on the terms of\n");
61917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "this License, whose permissions for other licensees extend to the\n");
61927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "entire whole, and thus to each and every part regardless of who wrote it.\n");
61937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Thus, it is not the intent of this section to claim rights or contest\n");
61957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "your rights to work written entirely by you; rather, the intent is to\n");
61967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "exercise the right to control the distribution of derivative or\n");
61977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "collective works based on the Program.\n");
61987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
61997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "In addition, mere aggregation of another work not based on the Program\n");
62007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "with the Program (or with a work based on the Program) on a volume of\n");
62017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "a storage or distribution medium does not bring the other work under\n");
62027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "the scope of this License.\n");
62037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  3. You may copy and distribute the Program (or a work based on it,\n");
62057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "under Section 2) in object code or executable form under the terms of\n");
62067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Sections 1 and 2 above provided that you also do one of the following:\n");
62077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    a) Accompany it with the complete corresponding machine-readable\n");
62097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    source code, which must be distributed under the terms of Sections\n");
62107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    1 and 2 above on a medium customarily used for software interchange; or,\n");
62117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    b) Accompany it with a written offer, valid for at least three\n");
62137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    years, to give any third party, for a charge no more than your\n");
62147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    cost of physically performing source distribution, a complete\n");
62157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    machine-readable copy of the corresponding source code, to be\n");
62167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    distributed under the terms of Sections 1 and 2 above on a medium\n");
62177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    customarily used for software interchange; or,\n");
62187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    c) Accompany it with the information you received as to the offer\n");
62207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    to distribute corresponding source code.  (This alternative is\n");
62217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    allowed only for noncommercial distribution and only if you\n");
62227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    received the program in object code or executable form with such\n");
62237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    an offer, in accord with Subsection b above.)\n");
62247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "The source code for a work means the preferred form of the work for\n");
62267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "making modifications to it.  For an executable work, complete source\n");
62277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "code means all the source code for all modules it contains, plus any\n");
62287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "associated interface definition files, plus the scripts used to\n");
62297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "control compilation and installation of the executable.  However, as a\n");
62307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "special exception, the source code distributed need not include\n");
62317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "anything that is normally distributed (in either source or binary\n");
62327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "form) with the major components (compiler, kernel, and so on) of the\n");
62337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "operating system on which the executable runs, unless that component\n");
62347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "itself accompanies the executable.\n");
62357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "If distribution of executable or object code is made by offering\n");
62377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "access to copy from a designated place, then offering equivalent\n");
62387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "access to copy the source code from the same place counts as\n");
62397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "distribution of the source code, even though third parties are not\n");
62407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "compelled to copy the source along with the object code.\n");
62417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  4. You may not copy, modify, sublicense, or distribute the Program\n");
62437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "except as expressly provided under this License.  Any attempt\n");
62447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "otherwise to copy, modify, sublicense or distribute the Program is\n");
62457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "void, and will automatically terminate your rights under this License.\n");
62467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "However, parties who have received copies, or rights, from you under\n");
62477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "this License will not have their licenses terminated so long as such\n");
62487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "parties remain in full compliance.\n");
62497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  5. You are not required to accept this License, since you have not\n");
62517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "signed it.  However, nothing else grants you permission to modify or\n");
62527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "distribute the Program or its derivative works.  These actions are\n");
62537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "prohibited by law if you do not accept this License.  Therefore, by\n");
62547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "modifying or distributing the Program (or any work based on the\n");
62557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Program), you indicate your acceptance of this License to do so, and\n");
62567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "all its terms and conditions for copying, distributing or modifying\n");
62577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "the Program or works based on it.\n");
62587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  6. Each time you redistribute the Program (or any work based on the\n");
62607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Program), the recipient automatically receives a license from the\n");
62617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "original licensor to copy, distribute or modify the Program subject to\n");
62627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "these terms and conditions.  You may not impose any further\n");
62637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "restrictions on the recipients' exercise of the rights granted herein.\n");
62647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "You are not responsible for enforcing compliance by third parties to\n");
62657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "this License.\n");
62667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  7. If, as a consequence of a court judgment or allegation of patent\n");
62687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "infringement or for any other reason (not limited to patent issues),\n");
62697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "conditions are imposed on you (whether by court order, agreement or\n");
62707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "otherwise) that contradict the conditions of this License, they do not\n");
62717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "excuse you from the conditions of this License.  If you cannot\n");
62727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "distribute so as to satisfy simultaneously your obligations under this\n");
62737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "License and any other pertinent obligations, then as a consequence you\n");
62747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "may not distribute the Program at all.  For example, if a patent\n");
62757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "license would not permit royalty-free redistribution of the Program by\n");
62767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "all those who receive copies directly or indirectly through you, then\n");
62777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "the only way you could satisfy both it and this License would be to\n");
62787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "refrain entirely from distribution of the Program.\n");
62797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "If any portion of this section is held invalid or unenforceable under\n");
62817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "any particular circumstance, the balance of the section is intended to\n");
62827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "apply and the section as a whole is intended to apply in other\n");
62837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "circumstances.\n");
62847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "It is not the purpose of this section to induce you to infringe any\n");
62867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "patents or other property right claims or to contest validity of any\n");
62877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "such claims; this section has the sole purpose of protecting the\n");
62887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "integrity of the free software distribution system, which is\n");
62897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "implemented by public license practices.  Many people have made\n");
62907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "generous contributions to the wide range of software distributed\n");
62917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "through that system in reliance on consistent application of that\n");
62927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "system; it is up to the author/donor to decide if he or she is willing\n");
62937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "to distribute software through any other system and a licensee cannot\n");
62947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "impose that choice.\n");
62957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "This section is intended to make thoroughly clear what is believed to\n");
62977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "be a consequence of the rest of this License.\n");
62987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
62997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  8. If the distribution and/or use of the Program is restricted in\n");
63007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "certain countries either by patents or by copyrighted interfaces, the\n");
63017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "original copyright holder who places the Program under this License\n");
63027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "may add an explicit geographical distribution limitation excluding\n");
63037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "those countries, so that distribution is permitted only in or among\n");
63047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "countries not thus excluded.  In such case, this License incorporates\n");
63057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "the limitation as if written in the body of this License.\n");
63067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  9. The Free Software Foundation may publish revised and/or new versions\n");
63087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "of the General Public License from time to time.  Such new versions will\n");
63097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "be similar in spirit to the present version, but may differ in detail to\n");
63107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "address new problems or concerns.\n");
63117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Each version is given a distinguishing version number.  If the Program\n");
63137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "specifies a version number of this License which applies to it and any\n");
63147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "later version, you have the option of following the terms and conditions\n");
63157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "either of that version or of any later version published by the Free\n");
63167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Software Foundation.  If the Program does not specify a version number of\n");
63177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "this License, you may choose any version ever published by the Free Software\n");
63187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Foundation.\n");
63197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  10. If you wish to incorporate parts of the Program into other free\n");
63217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "programs whose distribution conditions are different, write to the author\n");
63227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "to ask for permission.  For software which is copyrighted by the Free\n");
63237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Software Foundation, write to the Free Software Foundation; we sometimes\n");
63247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "make exceptions for this.  Our decision will be guided by the two goals\n");
63257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "of preserving the free status of all derivatives of our free software and\n");
63267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "of promoting the sharing and reuse of software generally.\n");
63277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "			    NO WARRANTY\n");
63297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n");
63317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n");
63327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n");
63337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "PROVIDE THE PROGRAM AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n");
63347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n");
63357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n");
63367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n");
63377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n");
63387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "REPAIR OR CORRECTION.\n");
63397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n");
63417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n");
63427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n");
63437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n");
63447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n");
63457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n");
63467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n");
63477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n");
63487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "POSSIBILITY OF SUCH DAMAGES.\n");
63497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "		     END OF TERMS AND CONDITIONS\n");
63517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "	    How to Apply These Terms to Your New Programs\n");
63537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  If you develop a new program, and you want it to be of the greatest\n");
63557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "possible use to the public, the best way to achieve this is to make it\n");
63567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "free software which everyone can redistribute and change under these terms.\n");
63577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  To do so, attach the following notices to the program.  It is safest\n");
63597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "to attach them to the start of each source file to most effectively\n");
63607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "convey the exclusion of warranty; and each file should have at least\n");
63617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "the copyright line and a pointer to where the full notice is found.\n");
63627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    <one line to give the program's name and a brief idea of what it does.>\n");
63647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    Copyright (C) <year>  <name of author>\n");
63657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    This program is free software; you can redistribute it and/or modify\n");
63677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    it under the terms of the GNU General Public License as published by\n");
63687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    the Free Software Foundation; either version 2 of the License, or\n");
63697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    (at your option) any later version.\n");
63707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    This program is distributed in the hope that it will be useful,\n");
63727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
63737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n");
63747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    GNU General Public License for more details.\n");
63757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    You should have received a copy of the GNU General Public License\n");
63777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    along with this program; if not, write to the Free Software\n");
63787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n");
63797cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Also add information on how to contact you by electronic and paper mail.\n");
63827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "If the program is interactive, make it output a short notice like this\n");
63847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "when it starts in an interactive mode:\n");
63857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    Gnomovision version 69, Copyright (C) year  name of author\n");
63877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n");
63887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    This is free software, and you are welcome to redistribute it\n");
63897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "    under certain conditions; type `show c' for details.\n");
63907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "The hypothetical commands `show w' and `show c' should show the appropriate\n");
63927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "parts of the General Public License.  Of course, the commands you use may\n");
63937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "be called something other than `show w' and `show c'; they could even be\n");
63947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "mouse-clicks or menu items--whatever suits your program.\n");
63957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
63967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "You should also get your employer (if you work as a programmer) or your\n");
63977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "school, if any, to sign a copyright disclaimer for the program, if\n");
63987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "necessary.  Here is a sample; alter the names:\n");
63997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
64007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n");
64017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n");
64027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
64037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  <signature of Ty Coon>, 1 April 1989\n");
64047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "  Ty Coon, President of Vice\n");
64057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
64067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "This General Public License does not permit incorporating your program into\n");
64077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "proprietary programs.  If your program is a subroutine library, you may\n");
64087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "consider it more useful to permit linking proprietary applications with the\n");
64097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "library.  If this is what you want to do, use the GNU Library General\n");
64107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "Public License instead of this License.\n");
64117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj  my_strcat(inbuf, "\n");
64137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
64147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
6415d3e4dd9f322e1746ee90fb9363d11654c5101502njn
64167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <stdio.h>
64177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include <assert.h>
64187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj/* For providing services. */
64207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic HWord g_serviceFn ( HWord arg1, HWord arg2 )
64217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
64227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   switch (arg1) {
64237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 0: /* EXIT */
64247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         exit(0);
64257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 1: /* PUTC */
64267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         putchar(arg2);
64277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return 0;
64287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 2: /* MALLOC */
64297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return (HWord)malloc(arg2);
64307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      case 3: /* FREE */
64317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         free((void*)arg2);
64327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         return 0;
64337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      default:
64347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         assert(0);
64357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
64367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
64377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64387cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjstatic char *bzerrorstrings[] = {
64397cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       "OK"
64407cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"SEQUENCE_ERROR"
64417cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"PARAM_ERROR"
64427cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"MEM_ERROR"
64437cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"DATA_ERROR"
64447cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"DATA_ERROR_MAGIC"
64457cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"IO_ERROR"
64467cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"UNEXPECTED_EOF"
64477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"OUTBUFF_FULL"
64487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"CONFIG_ERROR"
64497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"???"   /* for future */
64507cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"???"   /* for future */
64517cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"???"   /* for future */
64527cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"???"   /* for future */
64537cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"???"   /* for future */
64547cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj       ,"???"   /* for future */
64557cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj};
64567cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64577cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#include "../memcheck.h"
64587cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64597cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// If given a cmd line arg, behave as a correctness regtest
64607cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// (run fast and be verbose).  If not, run for a long time
64617cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj// which is what is needed for the performance suite.
64627cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardjint main ( int argc, char** argv )
64637cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj{
64647cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int   r;
64657cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int   bit;
64667cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int   i;
64677cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   int regtest;
64687cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   assert(argc == 1 || argc == 2);
64707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   regtest = argc==2;
64717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   serviceFn = g_serviceFn;
64727cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64737cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   set_inbuf();
64747cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nIn = vex_strlen(inbuf)+1;
64757cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf( "%d bytes read\n", nIn );
64767cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64777cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /* Make inbuf[10] be undefined, so as to check that this source
64787cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      eventually shows up in various places. */
647906bc722457ffe12e056d2f40d0d2f5c8711b541fflorian   (void) VALGRIND_MAKE_MEM_UNDEFINED(&inbuf[10], sizeof(char));
64807cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64817cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (inbuf[10] == 11) vex_printf("foo\n"); else vex_printf("bar\n");
64827cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64837cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   nZ = M_BLOCK;
64847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   r = BZ2_bzBuffToBuffCompress (
64857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj          zbuf, &nZ, inbuf, nIn, 9, 3/*verb*/, 30 );
64867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64877cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   if (r != BZ_OK) {
64887cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     vex_printf("initial compress failed!\n");
64897cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     (*serviceFn)(0,0);
64907cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
64917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf( "%d after compression\n", nZ );
64927cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
64937cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (bit = 0; bit < nZ*8; bit += (bit < 35 ? 1 : (regtest?2377:137))) {
64947cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (regtest)
64957cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         vex_printf( "bit %d  ", bit );
64967cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      flip_bit ( bit );
64977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      nOut = M_BLOCK_OUT;
64987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      r = BZ2_bzBuffToBuffDecompress (
64997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             outbuf, &nOut, zbuf, nZ, 1/*small*/, 0 );
65007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (regtest)
65017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         vex_printf( " %d  %s ", r, bzerrorstrings[-r] );
65027cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
65037cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      if (r != BZ_OK) {
65047cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj	 if (regtest)
65057cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj            vex_printf( "\n" );
65067cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      } else {
65077cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         if (nOut != nIn) {
65087cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           vex_printf(  "nIn/nOut mismatch %d %d\n", nIn, nOut );
65097cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           (*serviceFn)(0,0);
65107cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         } else {
65117cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           for (i = 0; i < nOut; i++)
65127cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj             if (inbuf[i] != outbuf[i]) {
65137cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                vex_printf(  "mismatch at %d\n", i );
65147cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj                (*serviceFn)(0,0);
65157cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           }
65167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj           if (i == nOut) vex_printf( "really ok!\n" );
65177cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         }
65187cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      }
65197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
65207cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj      flip_bit ( bit );
65217cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
65227cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
65237cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#if 0
65247cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   assert (nOut == nIn);
65257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   for (i = 0; i < nOut; i++) {
65267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     if (inbuf[i] != outbuf[i]) {
65277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        vex_printf( "difference at %d !\n", i );
65287cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj        return 1;
65297cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj     }
65307cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   }
65317cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#endif
65327cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj
65337cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   vex_printf( "all ok\n" );
65347cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   (*serviceFn)(0,0);
65357cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   /*NOTREACHED*/
65367cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   return 0;
65377cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj}
6538