19f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_NO_STDIO
39f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
69f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Private header file for the library.                  ---*/
79f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                       bzlib_private.h ---*/
89f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
99f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef _BZLIB_PRIVATE_H
669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define _BZLIB_PRIVATE_H
679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#include <stdlib.h>
699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_NO_STDIO
719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#include <stdio.h>
729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#include <ctype.h>
739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#include <string.h>
749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Public header file for the library.                   ---*/
799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                               bzlib.h ---*/
809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
1019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
1029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
1049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
1059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
1069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
1209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
1219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
1229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
1249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
1259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
1269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
1279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
1289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
1299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
1309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
1319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
1329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
1349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
1359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef _BZLIB_H
1389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define _BZLIB_H
1399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifdef __cplusplus
1419f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern "C" {
1429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
1439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RUN               0
1459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_FLUSH             1
1469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_FINISH            2
1479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_OK                0
1499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RUN_OK            1
1509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_FLUSH_OK          2
1519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_FINISH_OK         3
1529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_STREAM_END        4
1539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_SEQUENCE_ERROR    (-1)
1549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_PARAM_ERROR       (-2)
1559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_MEM_ERROR         (-3)
1569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_DATA_ERROR        (-4)
1579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_DATA_ERROR_MAGIC  (-5)
1589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_IO_ERROR          (-6)
1599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_UNEXPECTED_EOF    (-7)
1609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_OUTBUFF_FULL      (-8)
1619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_CONFIG_ERROR      (-9)
1629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1639f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef
1649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   struct {
1659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      char *next_in;
1669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int avail_in;
1679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int total_in_lo32;
1689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int total_in_hi32;
1699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      char *next_out;
1719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int avail_out;
1729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int total_out_lo32;
1739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int total_out_hi32;
1749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void *state;
1769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void *(*bzalloc)(void *,int,int);
1789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void (*bzfree)(void *,void *);
1799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void *opaque;
1809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
1819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bz_stream;
1829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_IMPORT
1859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_EXPORT
1869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
1879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_NO_STDIO
1899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Need a definitition for FILE */
1909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#include <stdio.h>
1919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
1929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
1939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifdef _WIN32
1949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   include <windows.h>
1959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   ifdef small
1969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* windows.h define small to char */
1979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#      undef small
1989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   endif
1999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   ifdef BZ_EXPORT
2009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define BZ_API(func) WINAPI func
2019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define BZ_EXTERN extern
2029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   else
2039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* import windows dll dynamically */
2049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define BZ_API(func) (WINAPI * func)
2059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define BZ_EXTERN
2069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   endif
2079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#else
2089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define BZ_API(func) func
2099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define BZ_EXTERN extern
2109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
2119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Core (low-level) library functions --*/
2149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2159f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
2169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream* strm,
2179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int        blockSize100k,
2189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int        verbosity,
2199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int        workFactor
2209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2229f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzCompress) (
2239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream* strm,
2249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int action
2259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2279f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
2289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream* strm
2299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2319f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
2329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream *strm,
2339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int       verbosity,
2349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int       small
2359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2379f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzDecompress) (
2389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream* strm
2399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2419f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
2429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream *strm
2439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- High(er) level library functions --*/
2489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_NO_STDIO
2509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_MAX_UNUSED 5000
2519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2529f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef void BZFILE;
2539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2549f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
2559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*  bzerror,
2569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      FILE* f,
2579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int   verbosity,
2589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int   small,
2599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void* unused,
2609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int   nUnused
2619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2639f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN void BZ_API(BZ2_bzReadClose) (
2649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*    bzerror,
2659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b
2669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2689f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
2699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*    bzerror,
2709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b,
2719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void**  unused,
2729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*    nUnused
2739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2759f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzRead) (
2769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*    bzerror,
2779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b,
2789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void*   buf,
2799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int     len
2809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2829f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
2839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*  bzerror,
2849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      FILE* f,
2859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int   blockSize100k,
2869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int   verbosity,
2879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int   workFactor
2889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2909f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN void BZ_API(BZ2_bzWrite) (
2919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*    bzerror,
2929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b,
2939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void*   buf,
2949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int     len
2959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
2969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
2979f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
2989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*          bzerror,
2999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE*       b,
3009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int           abandon,
3019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* nbytes_in,
3029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* nbytes_out
3039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3059f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
3069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int*          bzerror,
3079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE*       b,
3089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int           abandon,
3099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* nbytes_in_lo32,
3109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* nbytes_in_hi32,
3119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* nbytes_out_lo32,
3129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* nbytes_out_hi32
3139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
3159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Utility functions --*/
3189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3199f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
3209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      char*         dest,
3219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* destLen,
3229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      char*         source,
3239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int  sourceLen,
3249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int           blockSize100k,
3259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int           verbosity,
3269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int           workFactor
3279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3299f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
3309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      char*         dest,
3319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int* destLen,
3329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      char*         source,
3339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int  sourceLen,
3349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int           small,
3359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int           verbosity
3369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
3409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Code contributed by Yoshioka Tsuneo
3419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
3429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   to support better zlib compatibility.
3439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   This code is not _officially_ part of libbzip2 (yet);
3449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   I haven't tested it, documented it, or considered the
3459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   threading-safeness of it.
3469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   If this code breaks, please contact both Yoshioka and me.
3479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
3489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3499f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
3509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void
3519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_NO_STDIO
3549f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
3559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      const char *path,
3569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      const char *mode
3579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3599f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
3609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int        fd,
3619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      const char *mode
3629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3649f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzread) (
3659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b,
3669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void* buf,
3679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int len
3689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3709f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzwrite) (
3719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b,
3729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      void*   buf,
3739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int     len
3749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3769f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN int BZ_API(BZ2_bzflush) (
3779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b
3789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3809f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN void BZ_API(BZ2_bzclose) (
3819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE* b
3829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3849f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ_EXTERN const char * BZ_API(BZ2_bzerror) (
3859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZFILE *b,
3869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      int    *errnum
3879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   );
3889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
3899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifdef __cplusplus
3919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
3929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
3939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
3959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
3969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
3979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                           bzlib.h ---*/
3989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
3999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- General stuff. --*/
4049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_VERSION  "1.0.3, 17-Oct-2004"
4069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4079f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef char            Char;
4089f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef unsigned char   Bool;
4099f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef unsigned char   UChar;
4109f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef int             Int32;
4119f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef unsigned int    UInt32;
4129f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef short           Int16;
4139f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef unsigned short  UInt16;
4149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define True  ((Bool)1)
4169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define False ((Bool)0)
4179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef __GNUC__
4199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define __inline__  /* */
4209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
4219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_NO_STDIO
4239f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void BZ2_bz__AssertH__fail ( int errcode );
4249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define AssertH(cond,errcode) \
4259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
4269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#if BZ_DEBUG
4279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define AssertD(cond,msg) \
4289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { if (!(cond)) {       \
4299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fprintf ( stderr,   \
4309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
4319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      exit(1); \
4329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }}
4339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#else
4349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define AssertD(cond,msg) /* */
4359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
4369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VPrintf0(zf) \
4379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   fprintf(stderr,zf)
4389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VPrintf1(zf,za1) \
4399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   fprintf(stderr,zf,za1)
4409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VPrintf2(zf,za1,za2) \
4419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   fprintf(stderr,zf,za1,za2)
4429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VPrintf3(zf,za1,za2,za3) \
4439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   fprintf(stderr,zf,za1,za2,za3)
4449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VPrintf4(zf,za1,za2,za3,za4) \
4459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   fprintf(stderr,zf,za1,za2,za3,za4)
4469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
4479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   fprintf(stderr,zf,za1,za2,za3,za4,za5)
4489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#else
4499f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void bz_internal_error ( int errcode );
4509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define AssertH(cond,errcode) \
4519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { if (!(cond)) bz_internal_error ( errcode ); }
4529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define AssertD(cond,msg) /* */
4539dc4cf77abb447418edba303d29c7cb0b4361a27sewardj#define VPrintf0(zf) \
4546ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf(zf)
4559dc4cf77abb447418edba303d29c7cb0b4361a27sewardj#define VPrintf1(zf,za1) \
4566ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf(zf,za1)
4579dc4cf77abb447418edba303d29c7cb0b4361a27sewardj#define VPrintf2(zf,za1,za2) \
4586ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf(zf,za1,za2)
4599dc4cf77abb447418edba303d29c7cb0b4361a27sewardj#define VPrintf3(zf,za1,za2,za3) \
4606ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf(zf,za1,za2,za3)
4619dc4cf77abb447418edba303d29c7cb0b4361a27sewardj#define VPrintf4(zf,za1,za2,za3,za4) \
4626ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf(zf,za1,za2,za3,za4)
4639dc4cf77abb447418edba303d29c7cb0b4361a27sewardj#define VPrintf5(zf,za1,za2,za3,za4,za5) \
4646ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf(zf,za1,za2,za3,za4,za5)
4659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
4669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
4699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
4709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Header bytes. --*/
4739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_HDR_B 0x42   /* 'B' */
4759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_HDR_Z 0x5a   /* 'Z' */
4769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_HDR_h 0x68   /* 'h' */
4779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_HDR_0 0x30   /* '0' */
4789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Constants for the back end. --*/
4809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_MAX_ALPHA_SIZE 258
4829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_MAX_CODE_LEN    23
4839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RUNA 0
4859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RUNB 1
4869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_N_GROUPS 6
4889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_G_SIZE   50
4899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_N_ITERS  4
4909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
4929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Stuff for randomising repetitive blocks. --*/
4969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4979f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern Int32 BZ2_rNums[512];
4989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
4999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RAND_DECLS                          \
5009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 rNToGo;                               \
5019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 rTPos                                 \
5029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RAND_INIT_MASK                      \
5049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->rNToGo = 0;                              \
5059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->rTPos  = 0                               \
5069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
5089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_RAND_UPD_MASK                       \
5109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->rNToGo == 0) {                       \
5119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->rNToGo = BZ2_rNums[s->rTPos];         \
5129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->rTPos++;                              \
5139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->rTPos == 512) s->rTPos = 0;       \
5149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                           \
5159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->rNToGo--;
5169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Stuff for doing CRCs. --*/
5209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5219f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern UInt32 BZ2_crc32Table[256];
5229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_INITIALISE_CRC(crcVar)              \
5249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                              \
5259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   crcVar = 0xffffffffL;                       \
5269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
5279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_FINALISE_CRC(crcVar)                \
5299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                              \
5309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   crcVar = ~(crcVar);                         \
5319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
5329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_UPDATE_CRC(crcVar,cha)              \
5349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                              \
5359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   crcVar = (crcVar << 8) ^                    \
5369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ2_crc32Table[(crcVar >> 24) ^    \
5379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           ((UChar)cha)];      \
5389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
5399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- States and modes for compression. --*/
5439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_M_IDLE      1
5459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_M_RUNNING   2
5469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_M_FLUSHING  3
5479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_M_FINISHING 4
5489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_S_OUTPUT    1
5509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_S_INPUT     2
5519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_N_RADIX 2
5539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_N_QSORT 12
5549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_N_SHELL 18
5559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
5569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Structure holding all the compression-side stuff. --*/
5619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5629f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef
5639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   struct {
5649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* pointer back to the struct bz_stream */
5659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream* strm;
5669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* mode this stream is in, and whether inputting */
5689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* or outputting data */
5699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    mode;
5709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    state;
5719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* remembers avail_in when flush/finish requested */
5739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   avail_in_expect;
5749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* for doing the block sorting */
5769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32*  arr1;
5779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32*  arr2;
5789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32*  ftab;
5799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    origPtr;
5809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* aliases for arr1 and arr2 */
5829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32*  ptr;
5839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar*   block;
5849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt16*  mtfv;
5859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar*   zbits;
5869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* for deciding when to use the fallback sorting algorithm */
5889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    workFactor;
5899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* run-length-encoding of the input */
5919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   state_in_ch;
5929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    state_in_len;
5939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ_RAND_DECLS;
5949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
5959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* input and output limits and current posns */
5969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    nblock;
5979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    nblockMAX;
5989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    numZ;
5999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    state_out_pos;
6009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* map of bytes used in block */
6029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    nInUse;
6039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool     inUse[256];
6049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    unseqToSeq[256];
6059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* the buffer for bit stream creation */
6079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   bsBuff;
6089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    bsLive;
6099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* block and combined CRCs */
6119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   blockCRC;
6129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   combinedCRC;
6139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* misc administratium */
6159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    verbosity;
6169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    blockNo;
6179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    blockSize100k;
6189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* stuff for coding the MTF values */
6209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    nMTF;
6219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
6229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    selector   [BZ_MAX_SELECTORS];
6239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
6249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
6269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
6279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
6289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* second dimension: only 3 needed; 4 makes index calculations faster */
6299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
6309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
6329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   EState;
6339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- externs for compression. --*/
6379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6389f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void
6399f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_blockSort ( EState* );
6409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6419f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void
6429f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_compressBlock ( EState*, Bool );
6439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6449f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void
6459f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_bsInitWrite ( EState* );
6469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6479f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void
6489f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
6499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6509f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void
6519f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
6529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- states for decompression. --*/
6569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_IDLE        1
6589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_OUTPUT      2
6599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
6609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MAGIC_1     10
6619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MAGIC_2     11
6629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MAGIC_3     12
6639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MAGIC_4     13
6649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BLKHDR_1    14
6659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BLKHDR_2    15
6669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BLKHDR_3    16
6679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BLKHDR_4    17
6689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BLKHDR_5    18
6699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BLKHDR_6    19
6709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BCRC_1      20
6719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BCRC_2      21
6729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BCRC_3      22
6739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_BCRC_4      23
6749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_RANDBIT     24
6759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ORIGPTR_1   25
6769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ORIGPTR_2   26
6779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ORIGPTR_3   27
6789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MAPPING_1   28
6799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MAPPING_2   29
6809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_SELECTOR_1  30
6819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_SELECTOR_2  31
6829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_SELECTOR_3  32
6839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_CODING_1    33
6849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_CODING_2    34
6859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_CODING_3    35
6869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MTF_1       36
6879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MTF_2       37
6889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MTF_3       38
6899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MTF_4       39
6909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MTF_5       40
6919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_MTF_6       41
6929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ENDHDR_2    42
6939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ENDHDR_3    43
6949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ENDHDR_4    44
6959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ENDHDR_5    45
6969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_ENDHDR_6    46
6979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_CCRC_1      47
6989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_CCRC_2      48
6999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_CCRC_3      49
7009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_X_CCRC_4      50
7019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Constants for the fast MTF decoder. --*/
7059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define MTFA_SIZE 4096
7079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define MTFL_SIZE 16
7089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Structure holding all the decompression-side stuff. --*/
7129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7139f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef
7149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   struct {
7159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* pointer back to the struct bz_stream */
7169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream* strm;
7179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* state indicator for this stream */
7199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    state;
7209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* for doing the final run-length decoding */
7229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    state_out_ch;
7239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    state_out_len;
7249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool     blockRandomised;
7259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ_RAND_DECLS;
7269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* the buffer for bit stream reading */
7289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   bsBuff;
7299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    bsLive;
7309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* misc administratium */
7329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    blockSize100k;
7339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool     smallDecompress;
7349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    currBlockNo;
7359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    verbosity;
7369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* for undoing the Burrows-Wheeler transform */
7389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    origPtr;
7399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   tPos;
7409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    k0;
7419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    unzftab[256];
7429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    nblock_used;
7439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    cftab[257];
7449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    cftabCopy[257];
7459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* for undoing the Burrows-Wheeler transform (FAST) */
7479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   *tt;
7489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* for undoing the Burrows-Wheeler transform (SMALL) */
7509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt16   *ll16;
7519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    *ll4;
7529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* stored and calculated CRCs */
7549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   storedBlockCRC;
7559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   storedCombinedCRC;
7569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   calculatedBlockCRC;
7579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32   calculatedCombinedCRC;
7589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* map of bytes used in block */
7609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    nInUse;
7619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool     inUse[256];
7629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool     inUse16[16];
7639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    seqToUnseq[256];
7649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* for decoding the MTF values */
7669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    mtfa   [MTFA_SIZE];
7679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    mtfbase[256 / MTFL_SIZE];
7689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    selector   [BZ_MAX_SELECTORS];
7699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    selectorMtf[BZ_MAX_SELECTORS];
7709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
7759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    minLens[BZ_N_GROUPS];
7769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
7779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* save area for scalars in the main decompress code */
7789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_i;
7799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_j;
7809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_t;
7819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_alphaSize;
7829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_nGroups;
7839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_nSelectors;
7849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_EOB;
7859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_groupNo;
7869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_groupPos;
7879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_nextSym;
7889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_nblockMAX;
7899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_nblock;
7909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_es;
7919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_N;
7929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_curr;
7939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_zt;
7949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_zn;
7959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_zvec;
7969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_zj;
7979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_gSel;
7989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32    save_gMinlen;
7999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32*   save_gLimit;
8009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32*   save_gBase;
8019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32*   save_gPerm;
8029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
8049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   DState;
8059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- Macros for decompression. --*/
8099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_GET_FAST(cccc)                     \
8119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    s->tPos = s->tt[s->tPos];                 \
8129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    cccc = (UChar)(s->tPos & 0xff);           \
8139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    s->tPos >>= 8;
8149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_GET_FAST_C(cccc)                   \
8169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    c_tPos = c_tt[c_tPos];                    \
8179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    cccc = (UChar)(c_tPos & 0xff);            \
8189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    c_tPos >>= 8;
8199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define SET_LL4(i,n)                                          \
8219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { if (((i) & 0x1) == 0)                                    \
8229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
8239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
8249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
8259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define GET_LL4(i)                             \
8279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
8289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define SET_LL(i,n)                          \
8309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
8319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     SET_LL4(i, n >> 16);                    \
8329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
8339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define GET_LL(i) \
8359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
8369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_GET_SMALL(cccc)                            \
8389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
8399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->tPos = GET_LL(s->tPos);
8409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- externs for decompression. --*/
8439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8449f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern Int32
8459f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_indexIntoF ( Int32, Int32* );
8469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8479f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern Int32
8489f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_decompress ( DState* );
8499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8509f12f3ca9afc762f2e659179860c08d36e30f30fsewardjextern void
8519f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
8529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           Int32,  Int32, Int32 );
8539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
8569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
8599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifdef BZ_NO_STDIO
8619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef NULL
8629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define NULL 0
8639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
8649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
8659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
8689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                   bzlib_private.h ---*/
8699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
8709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Something which has the same size as void* on the host.  That is,
8739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   it is 32 bits on a 32-bit host and 64 bits on a 64-bit host, and so
8749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   it can safely be coerced to and from a pointer type on the host
8759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   machine. */
8769f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef  unsigned long HWord;
8779f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef  char          HChar;
8789f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef  signed int    Int;
8799f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef  unsigned int  UInt;
8809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8819f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef    signed long long int   Long;
8829f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef  unsigned long long int   ULong;
8839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
8869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
8879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj//#include "/home/sewardj/VEX/trunk/pub/libvex_basictypes.h"
8899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8909f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic HWord (*serviceFn)(HWord,HWord) = 0;
8919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
8939f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic char* my_strcpy ( char* dest, const char* src )
8949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
8959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   char* dest_orig = dest;
8969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (*src) *dest++ = *src++;
8979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   *dest = 0;
8989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return dest_orig;
8999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9019f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic void* my_memcpy ( void *dest, const void *src, int sz )
9029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
9039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   const char *s = (const char *)src;
9049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   char *d = (char *)dest;
9059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (sz--)
9079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      *d++ = *s++;
9089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return dest;
9109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9129f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic void* my_memmove( void *dst, const void *src, unsigned int len )
9139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
9149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    register char *d;
9159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    register char *s;
9169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    if ( dst > src ) {
9179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        d = (char *)dst + len - 1;
9189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        s = (char *)src + len - 1;
9199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        while ( len >= 4 ) {
9209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d-- = *s--;
9219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d-- = *s--;
9229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d-- = *s--;
9239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d-- = *s--;
9249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            len -= 4;
9259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        }
9269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        while ( len-- ) {
9279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d-- = *s--;
9289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        }
9299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    } else if ( dst < src ) {
9309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        d = (char *)dst;
9319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        s = (char *)src;
9329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        while ( len >= 4 ) {
9339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d++ = *s++;
9349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d++ = *s++;
9359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d++ = *s++;
9369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d++ = *s++;
9379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            len -= 4;
9389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        }
9399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        while ( len-- ) {
9409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *d++ = *s++;
9419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        }
9429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    }
9439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    return dst;
9449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9469f12f3ca9afc762f2e659179860c08d36e30f30fsewardjchar* my_strcat ( char* dest, const char* src )
9479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
9489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   char* dest_orig = dest;
9499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (*dest) dest++;
9509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (*src) *dest++ = *src++;
9519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   *dest = 0;
9529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return dest_orig;
9539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
9579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9586ded3895778c796f141ae0324862c4bd4b021a6fcerionstatic void vexxx_log_bytes ( char* p, int n )
9599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
9609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int i;
9619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < n; i++)
9629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      (*serviceFn)( 1, (int)p[i] );
9639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------------*/
9666ded3895778c796f141ae0324862c4bd4b021a6fcerion/*--- vexxx_printf                                        ---*/
9679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------------*/
9689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* This should be the only <...> include in the entire VEX library.
9706ded3895778c796f141ae0324862c4bd4b021a6fcerion   New code for vexxx_util.c should go above this point. */
9719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#include <stdarg.h>
9729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9736ded3895778c796f141ae0324862c4bd4b021a6fcerionstatic HChar vexxx_toupper ( HChar c )
9749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
9759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c >= 'a' && c <= 'z')
9769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return c + ('A' - 'a');
9779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   else
9789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return c;
9799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9816ded3895778c796f141ae0324862c4bd4b021a6fcerionstatic Int vexxx_strlen ( const HChar* str )
9829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
9839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int i = 0;
9849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (str[i] != 0) i++;
9859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return i;
9869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
9886ded3895778c796f141ae0324862c4bd4b021a6fcerionBool vexxx_streq ( const HChar* s1, const HChar* s2 )
9899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
9909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
9919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (*s1 == 0 && *s2 == 0)
9929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         return True;
9939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (*s1 != *s2)
9949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         return False;
9959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1++;
9969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s2++;
9979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
9989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
9999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Some flags.  */
10019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VG_MSG_SIGNED    1 /* The value is signed. */
10029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VG_MSG_ZJUSTIFY  2 /* Must justify with '0'. */
10039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VG_MSG_LJUSTIFY  4 /* Must justify on the left. */
10049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VG_MSG_PAREN     8 /* Parenthesize if present (for %y) */
10059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define VG_MSG_COMMA    16 /* Add commas to numbers (for %d, %u) */
10069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Copy a string into the buffer. */
10089f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic UInt
10099f12f3ca9afc762f2e659179860c08d36e30f30fsewardjmyvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
10109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                Bool capitalise )
10119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
10126ded3895778c796f141ae0324862c4bd4b021a6fcerion#  define MAYBE_TOUPPER(ch) (capitalise ? vexxx_toupper(ch) : (ch))
10139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt ret = 0;
10149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int i, extra;
10156ded3895778c796f141ae0324862c4bd4b021a6fcerion   Int len = vexxx_strlen(str);
10169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (width == 0) {
10189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ret += len;
10199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < len; i++)
10209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         send(MAYBE_TOUPPER(str[i]));
10219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return ret;
10229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
10239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (len > width) {
10259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ret += width;
10269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < width; i++)
10279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         send(MAYBE_TOUPPER(str[i]));
10289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return ret;
10299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
10309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   extra = width - len;
10329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (flags & VG_MSG_LJUSTIFY) {
10339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ret += extra;
10349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < extra; i++)
10359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         send(' ');
10369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
10379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret += len;
10389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < len; i++)
10399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      send(MAYBE_TOUPPER(str[i]));
10409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (!(flags & VG_MSG_LJUSTIFY)) {
10419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ret += extra;
10429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < extra; i++)
10439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         send(' ');
10449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
10459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#  undef MAYBE_TOUPPER
10479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return ret;
10499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
10509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Write P into the buffer according to these args:
10529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj *  If SIGN is true, p is a signed.
10539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj *  BASE is the base.
10549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj *  If WITH_ZERO is true, '0' must be added.
10559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj *  WIDTH is the width of the field.
10569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj */
10579f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic UInt
10589f12f3ca9afc762f2e659179860c08d36e30f30fsewardjmyvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
10599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
10609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   HChar buf[40];
10619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int   ind = 0;
10629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int   i, nc = 0;
10639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool  neg = False;
10649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   HChar *digits = "0123456789ABCDEF";
10659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt  ret = 0;
10669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt  p = (UInt)pL;
10679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (base < 2 || base > 16)
10699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return ret;
10709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
10729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      p   = - (Int)p;
10739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      neg = True;
10749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
10759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (p == 0)
10779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      buf[ind++] = '0';
10789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   else {
10799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (p > 0) {
10809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if ((flags & VG_MSG_COMMA) && 10 == base &&
10819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             0 == (ind-nc) % 3 && 0 != ind)
10829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         {
10839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            buf[ind++] = ',';
10849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            nc++;
10859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
10869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         buf[ind++] = digits[p % base];
10879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         p /= base;
10889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
10899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
10909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (neg)
10929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      buf[ind++] = '-';
10939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
10949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
10959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for(; ind < width; ind++) {
10969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	//vassert(ind < 39);
10979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         buf[ind] = ((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
10989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
10999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
11009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
11019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* Reverse copy to buffer.  */
11029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret += ind;
11039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = ind -1; i >= 0; i--) {
11049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      send(buf[i]);
11059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
11069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
11079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for(; ind < width; ind++) {
11089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 ret++;
11099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         send(' ');  // Never pad with zeroes on RHS -- changes the value!
11109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
11129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return ret;
11139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
11149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
11159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
11169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* A simple vprintf().  */
11179f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
11189f12f3ca9afc762f2e659179860c08d36e30f30fsewardjUInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
11199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
11209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt ret = 0;
11219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int i;
11229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int flags;
11239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int width;
11249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool is_long;
11259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
11269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* We assume that vargs has already been initialised by the
11279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      caller, using va_start, and that the caller will similarly
11289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      clean up with va_end.
11299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   */
11309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
11319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; format[i] != 0; i++) {
11329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (format[i] != '%') {
11339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         send(format[i]);
11349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 ret++;
11359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         continue;
11369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i++;
11389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* A '%' has been found.  Ignore a trailing %. */
11399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (format[i] == 0)
11409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         break;
11419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (format[i] == '%') {
11429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* `%%' is replaced by `%'. */
11439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         send('%');
11449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 ret++;
11459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         continue;
11469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      flags = 0;
11489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      is_long = False;
11499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      width = 0; /* length of the field. */
11509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (format[i] == '(') {
11519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 flags |= VG_MSG_PAREN;
11529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 i++;
11539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* If ',' follows '%', commas will be inserted. */
11559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (format[i] == ',') {
11569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         flags |= VG_MSG_COMMA;
11579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i++;
11589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* If '-' follows '%', justify on the left. */
11609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (format[i] == '-') {
11619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         flags |= VG_MSG_LJUSTIFY;
11629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i++;
11639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* If '0' follows '%', pads will be inserted. */
11659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (format[i] == '0') {
11669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         flags |= VG_MSG_ZJUSTIFY;
11679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i++;
11689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* Compute the field length. */
11709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (format[i] >= '0' && format[i] <= '9') {
11719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         width *= 10;
11729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         width += format[i++] - '0';
11739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (format[i] == 'l') {
11759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i++;
11769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         is_long = True;
11779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
11789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
11799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      switch (format[i]) {
11809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         case 'd': /* %d */
11819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            flags |= VG_MSG_SIGNED;
11829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (is_long)
11839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ret += myvprintf_int64(send, flags, 10, width,
11849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj				      (ULong)(va_arg (vargs, Long)));
11859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            else
11869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ret += myvprintf_int64(send, flags, 10, width,
11879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj				      (ULong)(va_arg (vargs, Int)));
11889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
11899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         case 'u': /* %u */
11909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (is_long)
11919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ret += myvprintf_int64(send, flags, 10, width,
11929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj				      (ULong)(va_arg (vargs, ULong)));
11939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            else
11949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ret += myvprintf_int64(send, flags, 10, width,
11959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj				      (ULong)(va_arg (vargs, UInt)));
11969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
11979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         case 'p': /* %p */
11989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	    ret += 2;
11999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            send('0');
12009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            send('x');
12019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ret += myvprintf_int64(send, flags, 16, width,
12029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj				   (ULong)((HWord)va_arg (vargs, void *)));
12039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
12049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         case 'x': /* %x */
12059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (is_long)
12069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ret += myvprintf_int64(send, flags, 16, width,
12079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj				      (ULong)(va_arg (vargs, ULong)));
12089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            else
12099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ret += myvprintf_int64(send, flags, 16, width,
12109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj				      (ULong)(va_arg (vargs, UInt)));
12119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
12129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         case 'c': /* %c */
12139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	    ret++;
12149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            send((va_arg (vargs, int)));
12159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
12169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         case 's': case 'S': { /* %s */
12179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            char *str = va_arg (vargs, char *);
12189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (str == (char*) 0) str = "(null)";
12199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ret += myvprintf_str(send, flags, width, str,
12209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                 (format[i]=='S'));
12219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
12229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 }
12239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#        if 0
12249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 case 'y': { /* %y - print symbol */
12259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	    Addr a = va_arg(vargs, Addr);
12269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
122775d774c08397be8076934c514e12fa36811eb880florian            HChar *name;
122875d774c08397be8076934c514e12fa36811eb880florian	    if (VG_(get_fnname_w_offset)(a, &name)) {
122975d774c08397be8076934c514e12fa36811eb880florian               HChar buf[1 + VG_strlen(name) + 1 + 1];
12309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	       if (flags & VG_MSG_PAREN) {
123175d774c08397be8076934c514e12fa36811eb880florian                  VG_(sprintf)(str, "(%s)", name):
123275d774c08397be8076934c514e12fa36811eb880florian	       } else {
123375d774c08397be8076934c514e12fa36811eb880florian                  VG_(sprintf)(str, "%s", name):
123475d774c08397be8076934c514e12fa36811eb880florian               }
12359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	       ret += myvprintf_str(send, flags, width, buf, 0);
12369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	    }
12379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	    break;
12389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 }
12399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#        endif
12409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         default:
12419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
12429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
12439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
12449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return ret;
12459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
12469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* A general replacement for printf().  Note that only low-level
12499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   debugging info should be sent via here.  The official route is to
12509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   to use vg_message().  This interface is deprecated.
12519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj*/
12529f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic HChar myprintf_buf[1000];
12539f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic Int   n_myprintf_buf;
12549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12559f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic void add_to_myprintf_buf ( HChar c )
12569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
12579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
12586ded3895778c796f141ae0324862c4bd4b021a6fcerion      (*vexxx_log_bytes)( myprintf_buf, vexxx_strlen(myprintf_buf) );
12599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      n_myprintf_buf = 0;
12609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      myprintf_buf[n_myprintf_buf] = 0;
12619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
12629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   myprintf_buf[n_myprintf_buf++] = c;
12639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   myprintf_buf[n_myprintf_buf] = 0;
12649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
12659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12666ded3895778c796f141ae0324862c4bd4b021a6fcerionstatic UInt vexxx_printf ( const char *format, ... )
12679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
12689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt ret;
12699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   va_list vargs;
12709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   va_start(vargs,format);
12719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   n_myprintf_buf = 0;
12739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   myprintf_buf[n_myprintf_buf] = 0;
12749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
12759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (n_myprintf_buf > 0) {
12776ded3895778c796f141ae0324862c4bd4b021a6fcerion      (*vexxx_log_bytes)( myprintf_buf, n_myprintf_buf );
12789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
12799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   va_end(vargs);
12819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return ret;
12839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
12849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------------------*/
12866ded3895778c796f141ae0324862c4bd4b021a6fcerion/*--- end                                          vexxx_util.c ---*/
12879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------------------*/
12889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
12919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
12929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
12939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
12949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
12969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
12979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Decompression machinery                               ---*/
12989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                          decompress.c ---*/
12999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
13009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
13029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
13039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
13049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
13069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
13089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
13099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
13109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
13129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
13139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
13159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
13169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
13179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
13189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
13209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
13219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
13239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
13249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
13259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
13279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
13329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
13339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
13349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
13359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
13399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
13409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
13419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
13439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
13449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
13459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
13469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
13479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
13489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
13499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
13509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
13519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
13539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
13549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
13599f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
13609f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid makeMaps_d ( DState* s )
13619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
13629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 i;
13639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->nInUse = 0;
13649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < 256; i++)
13659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->inUse[i]) {
13669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->seqToUnseq[s->nInUse] = i;
13679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->nInUse++;
13689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
13699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
13709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
13739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define RETURN(rrr)                               \
13749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { retVal = rrr; goto save_state_and_return; };
13759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
13769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define GET_BITS(lll,vvv,nnn)                     \
13779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   case lll: s->state = lll;                      \
13789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {                                 \
13799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->bsLive >= nnn) {                     \
13809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         UInt32 v;                                \
13819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         v = (s->bsBuff >>                        \
13829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
13839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->bsLive -= nnn;                        \
13849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         vvv = v;                                 \
13859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         break;                                   \
13869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }                                           \
13879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
13889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->bsBuff                                   \
13899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         = (s->bsBuff << 8) |                     \
13909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj           ((UInt32)                              \
13919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj              (*((UChar*)(s->strm->next_in))));   \
13929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->bsLive += 8;                             \
13939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->next_in++;                         \
13949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->avail_in--;                        \
13959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->total_in_lo32++;                   \
13969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->strm->total_in_lo32 == 0)            \
13979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->total_in_hi32++;                \
13989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
13999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define GET_UCHAR(lll,uuu)                        \
14019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   GET_BITS(lll,uuu,8)
14029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define GET_BIT(lll,uuu)                          \
14049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   GET_BITS(lll,uuu,1)
14059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
14079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define GET_MTF_VAL(label1,label2,lval)           \
14089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                                 \
14099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (groupPos == 0) {                           \
14109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      groupNo++;                                  \
14119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (groupNo >= nSelectors)                  \
14129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         RETURN(BZ_DATA_ERROR);                   \
14139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      groupPos = BZ_G_SIZE;                       \
14149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gSel = s->selector[groupNo];                \
14159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gMinlen = s->minLens[gSel];                 \
14169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gLimit = &(s->limit[gSel][0]);              \
14179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gPerm = &(s->perm[gSel][0]);                \
14189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gBase = &(s->base[gSel][0]);                \
14199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                              \
14209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   groupPos--;                                    \
14219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zn = gMinlen;                                  \
14229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   GET_BITS(label1, zvec, zn);                    \
14239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (1) {                                    \
14249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (zn > 20 /* the longest code */)         \
14259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         RETURN(BZ_DATA_ERROR);                   \
14269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (zvec <= gLimit[zn]) break;              \
14279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zn++;                                       \
14289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_BIT(label2, zj);                        \
14299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zvec = (zvec << 1) | zj;                    \
14309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   };                                             \
14319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (zvec - gBase[zn] < 0                       \
14329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
14339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      RETURN(BZ_DATA_ERROR);                      \
14349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   lval = gPerm[zvec - gBase[zn]];                \
14359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
14369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
14409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
14419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
14429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nb, na, mid;
14439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nb = 0;
14449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   na = 256;
14459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   do {
14469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mid = (nb + na) >> 1;
14479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (indx >= cftab[mid]) nb = mid; else na = mid;
14489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
14499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (na - nb != 1);
14509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return nb;
14519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
14529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
14549f12f3ca9afc762f2e659179860c08d36e30f30fsewardjInt32 BZ2_decompress ( DState* s )
14559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
14569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar      uc;
14579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32      retVal;
14589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32      minLen, maxLen;
14599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bz_stream* strm = s->strm;
14609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* stuff that needs to be saved/restored */
14629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  i;
14639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  j;
14649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  t;
14659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  alphaSize;
14669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  nGroups;
14679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  nSelectors;
14689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  EOB;
14699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  groupNo;
14709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  groupPos;
14719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  nextSym;
14729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  nblockMAX;
14739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  nblock;
14749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  es;
14759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  N;
14769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  curr;
14779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  zt;
14789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  zn;
14799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  zvec;
14809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  zj;
14819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  gSel;
14829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  gMinlen;
14839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32* gLimit;
14849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32* gBase;
14859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32* gPerm;
14869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
14879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->state == BZ_X_MAGIC_1) {
14889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*initialise the save area*/
14899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_i           = 0;
14909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_j           = 0;
14919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_t           = 0;
14929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_alphaSize   = 0;
14939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_nGroups     = 0;
14949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_nSelectors  = 0;
14959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_EOB         = 0;
14969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_groupNo     = 0;
14979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_groupPos    = 0;
14989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_nextSym     = 0;
14999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_nblockMAX   = 0;
15009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_nblock      = 0;
15019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_es          = 0;
15029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_N           = 0;
15039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_curr        = 0;
15049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_zt          = 0;
15059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_zn          = 0;
15069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_zvec        = 0;
15079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_zj          = 0;
15089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_gSel        = 0;
15099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_gMinlen     = 0;
15109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_gLimit      = NULL;
15119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_gBase       = NULL;
15129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->save_gPerm       = NULL;
15139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
15149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*restore from the save area*/
15169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i           = s->save_i;
15179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   j           = s->save_j;
15189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   t           = s->save_t;
15199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   alphaSize   = s->save_alphaSize;
15209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nGroups     = s->save_nGroups;
15219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nSelectors  = s->save_nSelectors;
15229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   EOB         = s->save_EOB;
15239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   groupNo     = s->save_groupNo;
15249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   groupPos    = s->save_groupPos;
15259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nextSym     = s->save_nextSym;
15269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nblockMAX   = s->save_nblockMAX;
15279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nblock      = s->save_nblock;
15289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   es          = s->save_es;
15299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   N           = s->save_N;
15309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   curr        = s->save_curr;
15319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zt          = s->save_zt;
15329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zn          = s->save_zn;
15339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zvec        = s->save_zvec;
15349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zj          = s->save_zj;
15359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   gSel        = s->save_gSel;
15369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   gMinlen     = s->save_gMinlen;
15379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   gLimit      = s->save_gLimit;
15389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   gBase       = s->save_gBase;
15399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   gPerm       = s->save_gPerm;
15409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   retVal = BZ_OK;
15429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   switch (s->state) {
15449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_MAGIC_1, uc);
15469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
15479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_MAGIC_2, uc);
15499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
15509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_MAGIC_3, uc)
15529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
15539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
15559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->blockSize100k < (BZ_HDR_0 + 1) ||
15569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
15579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->blockSize100k -= BZ_HDR_0;
15589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->smallDecompress) {
15609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
15619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->ll4  = BZALLOC(
15629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
15639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   );
15649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
15659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } else {
15669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
15679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
15689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
15699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BLKHDR_1, uc);
15719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc == 0x17) goto endhdr_2;
15739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
15749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BLKHDR_2, uc);
15759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
15769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BLKHDR_3, uc);
15779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
15789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BLKHDR_4, uc);
15799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
15809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BLKHDR_5, uc);
15819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
15829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BLKHDR_6, uc);
15839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
15849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->currBlockNo++;
15869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->verbosity >= 2)
15879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
15889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedBlockCRC = 0;
15909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BCRC_1, uc);
15919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
15929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BCRC_2, uc);
15939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
15949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BCRC_3, uc);
15959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
15969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_BCRC_4, uc);
15979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
15989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
15999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
16009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->origPtr = 0;
16029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
16039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
16049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
16059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
16069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
16079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
16089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->origPtr < 0)
16109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         RETURN(BZ_DATA_ERROR);
16119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->origPtr > 10 + 100000*s->blockSize100k)
16129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         RETURN(BZ_DATA_ERROR);
16139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--- Receive the mapping table ---*/
16159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < 16; i++) {
16169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         GET_BIT(BZ_X_MAPPING_1, uc);
16179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (uc == 1)
16189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->inUse16[i] = True; else
16199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->inUse16[i] = False;
16209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
16219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < 256; i++) s->inUse[i] = False;
16239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < 16; i++)
16259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->inUse16[i])
16269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            for (j = 0; j < 16; j++) {
16279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               GET_BIT(BZ_X_MAPPING_2, uc);
16289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (uc == 1) s->inUse[i * 16 + j] = True;
16299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
16309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      makeMaps_d ( s );
16319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
16329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      alphaSize = s->nInUse+2;
16339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--- Now the selectors ---*/
16359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
16369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
16379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
16389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
16399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < nSelectors; i++) {
16409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = 0;
16419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (True) {
16429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            GET_BIT(BZ_X_SELECTOR_3, uc);
16439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (uc == 0) break;
16449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j++;
16459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
16469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
16479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->selectorMtf[i] = j;
16489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
16499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--- Undo the MTF values for the selectors. ---*/
16519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      {
16529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         UChar pos[BZ_N_GROUPS], tmp, v;
16539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (v = 0; v < nGroups; v++) pos[v] = v;
16549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = 0; i < nSelectors; i++) {
16569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            v = s->selectorMtf[i];
16579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            tmp = pos[v];
16589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (v > 0) { pos[v] = pos[v-1]; v--; }
16599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            pos[0] = tmp;
16609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->selector[i] = tmp;
16619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
16629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
16639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--- Now the coding tables ---*/
16659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (t = 0; t < nGroups; t++) {
16669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         GET_BITS(BZ_X_CODING_1, curr, 5);
16679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = 0; i < alphaSize; i++) {
16689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (True) {
16699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
16709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               GET_BIT(BZ_X_CODING_2, uc);
16719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (uc == 0) break;
16729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               GET_BIT(BZ_X_CODING_3, uc);
16739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (uc == 0) curr++; else curr--;
16749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
16759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->len[t][i] = curr;
16769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
16779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
16789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--- Create the Huffman decoding tables ---*/
16809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (t = 0; t < nGroups; t++) {
16819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         minLen = 32;
16829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         maxLen = 0;
16839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = 0; i < alphaSize; i++) {
16849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
16859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->len[t][i] < minLen) minLen = s->len[t][i];
16869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
16879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ2_hbCreateDecodeTables (
16889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            &(s->limit[t][0]),
16899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            &(s->base[t][0]),
16909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            &(s->perm[t][0]),
16919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            &(s->len[t][0]),
16929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            minLen, maxLen, alphaSize
16939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         );
16949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->minLens[t] = minLen;
16959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
16969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--- Now the MTF values ---*/
16989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
16999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      EOB      = s->nInUse+1;
17009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nblockMAX = 100000 * s->blockSize100k;
17019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      groupNo  = -1;
17029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      groupPos = 0;
17039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
17059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- MTF init --*/
17079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      {
17089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Int32 ii, jj, kk;
17099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         kk = MTFA_SIZE-1;
17109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
17119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
17129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
17139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               kk--;
17149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
17159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->mtfbase[ii] = kk + 1;
17169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
17179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
17189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- end MTF init --*/
17199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nblock = 0;
17219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
17229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
17249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (nextSym == EOB) break;
17269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
17289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            es = -1;
17309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            N = 1;
17319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            do {
17329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
17339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
17349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               N = N * 2;
17359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
17369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
17379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
17389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            es++;
17409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
17419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->unzftab[uc] += es;
17429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->smallDecompress)
17449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               while (es > 0) {
17459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
17469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->ll16[nblock] = (UInt16)uc;
17479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  nblock++;
17489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  es--;
17499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               }
17509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            else
17519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               while (es > 0) {
17529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
17539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->tt[nblock] = (UInt32)uc;
17549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  nblock++;
17559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  es--;
17569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               };
17579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            continue;
17599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
17619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
17639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            /*-- uc = MTF ( nextSym-1 ) --*/
17659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            {
17669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               Int32 ii, jj, kk, pp, lno, off;
17679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               UInt32 nn;
17689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               nn = (UInt32)(nextSym - 1);
17699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
17709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (nn < MTFL_SIZE) {
17719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  /* avoid general-case expense */
17729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  pp = s->mtfbase[0];
17739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  uc = s->mtfa[pp+nn];
17749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  while (nn > 3) {
17759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     Int32 z = pp+nn;
17769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
17779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
17789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
17799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
17809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     nn -= 4;
17819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  }
17829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  while (nn > 0) {
17839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
17849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  };
17859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->mtfa[pp] = uc;
17869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               } else {
17879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  /* general case */
17889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  lno = nn / MTFL_SIZE;
17899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  off = nn % MTFL_SIZE;
17909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  pp = s->mtfbase[lno] + off;
17919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  uc = s->mtfa[pp];
17929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  while (pp > s->mtfbase[lno]) {
17939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfa[pp] = s->mtfa[pp-1]; pp--;
17949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  };
17959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->mtfbase[lno]++;
17969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  while (lno > 0) {
17979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfbase[lno]--;
17989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s->mtfa[s->mtfbase[lno]]
17999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
18009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     lno--;
18019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  }
18029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->mtfbase[0]--;
18039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->mtfa[s->mtfbase[0]] = uc;
18049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  if (s->mtfbase[0] == 0) {
18059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     kk = MTFA_SIZE-1;
18069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
18079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
18089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
18099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           kk--;
18109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                        }
18119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                        s->mtfbase[ii] = kk + 1;
18129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     }
18139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  }
18149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               }
18159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
18169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            /*-- end uc = MTF ( nextSym-1 ) --*/
18179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->unzftab[s->seqToUnseq[uc]]++;
18199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->smallDecompress)
18209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
18219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
18229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            nblock++;
18239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
18259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            continue;
18269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
18279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
18289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* Now we know what nblock is, we can do a better sanity
18309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         check on s->origPtr.
18319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      */
18329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->origPtr < 0 || s->origPtr >= nblock)
18339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         RETURN(BZ_DATA_ERROR);
18349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- Set up cftab to facilitate generation of T^(-1) --*/
18369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->cftab[0] = 0;
18379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
18389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
18399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i <= 256; i++) {
18409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
18419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            /* s->cftab[i] can legitimately be == nblock */
18429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            RETURN(BZ_DATA_ERROR);
18439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
18449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
18459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->state_out_len = 0;
18479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->state_out_ch  = 0;
18489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
18499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->state = BZ_X_OUTPUT;
18509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
18519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->smallDecompress) {
18539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- Make a copy of cftab, used in generation of T --*/
18559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
18569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- compute the T vector --*/
18589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = 0; i < nblock; i++) {
18599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            uc = (UChar)(s->ll16[i]);
18609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            SET_LL(i, s->cftabCopy[uc]);
18619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->cftabCopy[uc]++;
18629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
18639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- Compute T^(-1) by pointer reversal on T --*/
18659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i = s->origPtr;
18669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = GET_LL(i);
18679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         do {
18689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            Int32 tmp = GET_LL(j);
18699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            SET_LL(j, i);
18709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            i = j;
18719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j = tmp;
18729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
18739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (i != s->origPtr);
18749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->tPos = s->origPtr;
18769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->nblock_used = 0;
18779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->blockRandomised) {
18789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_RAND_INIT_MASK;
18799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
18809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
18819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
18829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_GET_SMALL(s->k0); s->nblock_used++;
18839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
18849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } else {
18869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- compute the T^(-1) vector --*/
18889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = 0; i < nblock; i++) {
18899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            uc = (UChar)(s->tt[i] & 0xff);
18909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->tt[s->cftab[uc]] |= (i << 8);
18919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->cftab[uc]++;
18929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
18939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
18949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->tPos = s->tt[s->origPtr] >> 8;
18959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->nblock_used = 0;
18969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->blockRandomised) {
18979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_RAND_INIT_MASK;
18989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
18999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
19009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
19019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_GET_FAST(s->k0); s->nblock_used++;
19029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
19039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
19059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      RETURN(BZ_OK);
19079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj    endhdr_2:
19119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ENDHDR_2, uc);
19139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
19149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ENDHDR_3, uc);
19159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
19169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ENDHDR_4, uc);
19179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
19189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ENDHDR_5, uc);
19199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
19209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_ENDHDR_6, uc);
19219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
19229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedCombinedCRC = 0;
19249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_CCRC_1, uc);
19259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_CCRC_2, uc);
19279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_CCRC_3, uc);
19299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      GET_UCHAR(BZ_X_CCRC_4, uc);
19319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
19329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->state = BZ_X_IDLE;
19349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      RETURN(BZ_STREAM_END);
19359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      default: AssertH ( False, 4001 );
19379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
19389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH ( False, 4002 );
19409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   save_state_and_return:
19429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_i           = i;
19449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_j           = j;
19459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_t           = t;
19469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_alphaSize   = alphaSize;
19479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_nGroups     = nGroups;
19489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_nSelectors  = nSelectors;
19499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_EOB         = EOB;
19509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_groupNo     = groupNo;
19519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_groupPos    = groupPos;
19529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_nextSym     = nextSym;
19539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_nblockMAX   = nblockMAX;
19549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_nblock      = nblock;
19559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_es          = es;
19569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_N           = N;
19579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_curr        = curr;
19589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_zt          = zt;
19599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_zn          = zn;
19609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_zvec        = zvec;
19619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_zj          = zj;
19629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_gSel        = gSel;
19639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_gMinlen     = gMinlen;
19649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_gLimit      = gLimit;
19659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_gBase       = gBase;
19669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->save_gPerm       = gPerm;
19679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return retVal;
19699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
19709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
19739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                      decompress.c ---*/
19749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
19759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
19779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Block sorting machinery                               ---*/
19789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                           blocksort.c ---*/
19799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
19809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
19829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
19839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
19849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
19869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
19889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
19899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
19909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
19929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
19939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
19959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
19969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
19979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
19989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
19999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
20009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
20019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
20039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
20049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
20059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
20199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
20209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
20219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
20239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
20249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
20259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
20269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
20279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
20289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
20299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
20309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
20319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
20339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  To get some idea how the block sorting algorithms in this file
20359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  work, read my paper
20369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     On the Performance of BWT Sorting Algorithms
20379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  in Proceedings of the IEEE Data Compression Conference 2000,
20389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
20399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  file implements the algorithm called  cache  in the paper.
20409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
20419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
20459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Fallback O(N log(N)^2) sorting        ---*/
20469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- algorithm, for repetitive blocks      ---*/
20479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
20489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
20509f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
20519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj__inline__
20529f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid fallbackSimpleSort ( UInt32* fmap,
20539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          UInt32* eclass,
20549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          Int32   lo,
20559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          Int32   hi )
20569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
20579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 i, j, tmp;
20589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt32 ec_tmp;
20599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (lo == hi) return;
20619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (hi - lo > 3) {
20639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for ( i = hi-4; i >= lo; i-- ) {
20649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         tmp = fmap[i];
20659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ec_tmp = eclass[tmp];
20669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
20679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            fmap[j-4] = fmap[j];
20689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fmap[j-4] = tmp;
20699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
20709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
20719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for ( i = hi-1; i >= lo; i-- ) {
20739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      tmp = fmap[i];
20749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ec_tmp = eclass[tmp];
20759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
20769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fmap[j-1] = fmap[j];
20779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fmap[j-1] = tmp;
20789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
20799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
20809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
20839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define fswap(zz1, zz2) \
20849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
20859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define fvswap(zzp1, zzp2, zzn)       \
20879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                     \
20889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 yyp1 = (zzp1);               \
20899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 yyp2 = (zzp2);               \
20909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 yyn  = (zzn);                \
20919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (yyn > 0) {                  \
20929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fswap(fmap[yyp1], fmap[yyp2]);  \
20939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      yyp1++; yyp2++; yyn--;          \
20949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                  \
20959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
20969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
20989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define fmin(a,b) ((a) < (b)) ? (a) : (b)
20999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define fpush(lz,hz) { stackLo[sp] = lz; \
21019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       stackHi[sp] = hz; \
21029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       sp++; }
21039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define fpop(lz,hz) { sp--;              \
21059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      lz = stackLo[sp];  \
21069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      hz = stackHi[sp]; }
21079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define FALLBACK_QSORT_SMALL_THRESH 10
21099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define FALLBACK_QSORT_STACK_SIZE   100
21109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21129f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
21139f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid fallbackQSort3 ( UInt32* fmap,
21149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      UInt32* eclass,
21159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      Int32   loSt,
21169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      Int32   hiSt )
21179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
21189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 unLo, unHi, ltLo, gtHi, n, m;
21199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 sp, lo, hi;
21209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt32 med, r, r3;
21219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
21229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
21239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   r = 0;
21259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   sp = 0;
21279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   fpush ( loSt, hiSt );
21289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (sp > 0) {
21309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
21329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fpop ( lo, hi );
21349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
21359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fallbackSimpleSort ( fmap, eclass, lo, hi );
21369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         continue;
21379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
21389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* Random partitioning.  Median of 3 sometimes fails to
21409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         avoid bad cases.  Median of 9 seems to help but
21419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         looks rather expensive.  This too seems to work but
21429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         is cheaper.  Guidance for the magic constants
21439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         7621 and 32768 is taken from Sedgewick's algorithms
21449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         book, chapter 35.
21459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      */
21469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      r = ((r * 7621) + 1) % 32768;
21479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      r3 = r % 3;
21489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (r3 == 0) med = eclass[fmap[lo]]; else
21499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
21509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   med = eclass[fmap[hi]];
21519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unLo = ltLo = lo;
21539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unHi = gtHi = hi;
21549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (1) {
21569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (1) {
21579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (unLo > unHi) break;
21589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            n = (Int32)eclass[fmap[unLo]] - (Int32)med;
21599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n == 0) {
21609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               fswap(fmap[unLo], fmap[ltLo]);
21619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ltLo++; unLo++;
21629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               continue;
21639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            };
21649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n > 0) break;
21659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            unLo++;
21669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
21679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (1) {
21689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (unLo > unHi) break;
21699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            n = (Int32)eclass[fmap[unHi]] - (Int32)med;
21709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n == 0) {
21719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               fswap(fmap[unHi], fmap[gtHi]);
21729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               gtHi--; unHi--;
21739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               continue;
21749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            };
21759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n < 0) break;
21769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            unHi--;
21779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
21789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (unLo > unHi) break;
21799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
21809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
21819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
21839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (gtHi < ltLo) continue;
21859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
21879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
21889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      n = lo + unLo - ltLo - 1;
21909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      m = hi - (gtHi - unHi) + 1;
21919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
21929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (n - lo > hi - m) {
21939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fpush ( lo, n );
21949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fpush ( m, hi );
21959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } else {
21969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fpush ( m, hi );
21979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fpush ( lo, n );
21989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
21999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
22009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
22019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef fmin
22039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef fpush
22049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef fpop
22059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef fswap
22069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef fvswap
22079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef FALLBACK_QSORT_SMALL_THRESH
22089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef FALLBACK_QSORT_STACK_SIZE
22099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
22129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Pre:
22139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nblock > 0
22149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      eclass exists for [0 .. nblock-1]
22159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
22169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr exists for [0 .. nblock-1]
22179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Post:
22199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ((UChar*)eclass) [0 .. nblock-1] holds block
22209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      All other areas of eclass destroyed
22219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fmap [0 .. nblock-1] holds sorted order
22229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bhtab [ 0 .. 2+(nblock/32) ] destroyed
22239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj*/
22249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
22269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
22279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
22289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define      WORD_BH(zz)  bhtab[(zz) >> 5]
22299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
22309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22319f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
22329f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid fallbackSort ( UInt32* fmap,
22339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    UInt32* eclass,
22349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    UInt32* bhtab,
22359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    Int32   nblock,
22369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    Int32   verb )
22379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
22389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 ftab[257];
22399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 ftabCopy[256];
22409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 H, i, j, k, l, r, cc, cc1;
22419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nNotDone;
22429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nBhtab;
22439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar* eclass8 = (UChar*)eclass;
22449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--
22469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Initial 1-char radix sort to generate
22479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      initial fmap and initial BH bits.
22489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   --*/
22499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (verb >= 4)
22509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      VPrintf0 ( "        bucket sorting ...\n" );
22519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < 257;    i++) ftab[i] = 0;
22529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
22539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
22549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
22559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < nblock; i++) {
22579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = eclass8[i];
22589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      k = ftab[j] - 1;
22599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[j] = k;
22609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fmap[k] = i;
22619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
22629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nBhtab = 2 + (nblock / 32);
22649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
22659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < 256; i++) SET_BH(ftab[i]);
22669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--
22689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Inductively refine the buckets.  Kind-of an
22699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      "exponential radix sort" (!), inspired by the
22709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Manber-Myers suffix array construction algorithm.
22719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   --*/
22729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- set sentinel bits for block-end detection --*/
22749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < 32; i++) {
22759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      SET_BH(nblock + 2*i);
22769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      CLEAR_BH(nblock + 2*i + 1);
22779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
22789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- the log(N) loop --*/
22809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   H = 1;
22819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (1) {
22829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (verb >= 4)
22849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf1 ( "        depth %6d has ", H );
22859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = 0;
22879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < nblock; i++) {
22889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (ISSET_BH(i)) j = i;
22899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k = fmap[i] - H; if (k < 0) k += nblock;
22909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         eclass[k] = j;
22919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
22929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nNotDone = 0;
22949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      r = -1;
22959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (1) {
22969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
22979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 /*-- find the next non-singleton bucket --*/
22989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k = r + 1;
22999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
23009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (ISSET_BH(k)) {
23019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (WORD_BH(k) == 0xffffffff) k += 32;
23029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (ISSET_BH(k)) k++;
23039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
23049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         l = k - 1;
23059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (l >= nblock) break;
23069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
23079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (!ISSET_BH(k)) {
23089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (WORD_BH(k) == 0x00000000) k += 32;
23099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (!ISSET_BH(k)) k++;
23109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
23119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         r = k - 1;
23129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (r >= nblock) break;
23139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- now [l, r] bracket current bucket --*/
23159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (r > l) {
23169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            nNotDone += (r - l + 1);
23179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            fallbackQSort3 ( fmap, eclass, l, r );
23189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            /*-- scan bucket and generate header bits-- */
23209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            cc = -1;
23219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            for (i = l; i <= r; i++) {
23229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cc1 = eclass[fmap[i]];
23239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (cc != cc1) { SET_BH(i); cc = cc1; };
23249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
23259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
23269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
23279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (verb >= 4)
23299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf1 ( "%6d unresolved strings\n", nNotDone );
23309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      H *= 2;
23329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (H > nblock || nNotDone == 0) break;
23339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
23349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--
23369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Reconstruct the original block in
23379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      eclass8 [0 .. nblock-1], since the
23389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      previous phase destroyed it.
23399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   --*/
23409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (verb >= 4)
23419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      VPrintf0 ( "        reconstructing block ...\n" );
23429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   j = 0;
23439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < nblock; i++) {
23449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (ftabCopy[j] == 0) j++;
23459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftabCopy[j]--;
23469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      eclass8[fmap[i]] = (UChar)j;
23479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
23489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH ( j < 256, 1005 );
23499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
23509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef       SET_BH
23529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef     CLEAR_BH
23539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef     ISSET_BH
23549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef      WORD_BH
23559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef UNALIGNED_BH
23569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
23599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- The main, O(N^2 log(N)) sorting       ---*/
23609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- algorithm.  Faster for "normal"       ---*/
23619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- non-repetitive blocks.                ---*/
23629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
23639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
23659f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
23669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj__inline__
23679f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBool mainGtU ( UInt32  i1,
23689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               UInt32  i2,
23699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               UChar*  block,
23709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               UInt16* quadrant,
23719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               UInt32  nblock,
23729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               Int32*  budget )
23739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
23749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  k;
23759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar  c1, c2;
23769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt16 s1, s2;
23779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
23789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertD ( i1 != i2, "mainGtU" );
23799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 1 */
23809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
23819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
23829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
23839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 2 */
23849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
23859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
23869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
23879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 3 */
23889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
23899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
23909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
23919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 4 */
23929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
23939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
23949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
23959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 5 */
23969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
23979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
23989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
23999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 6 */
24009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
24019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
24029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
24039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 7 */
24049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
24059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
24069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
24079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 8 */
24089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
24099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
24109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
24119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 9 */
24129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
24139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
24149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
24159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 10 */
24169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
24179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
24189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
24199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 11 */
24209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
24219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
24229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
24239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* 12 */
24249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   c1 = block[i1]; c2 = block[i2];
24259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c1 != c2) return (c1 > c2);
24269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i1++; i2++;
24279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
24289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   k = nblock + 8;
24299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
24309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   do {
24319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 1 */
24329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 2 */
24389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 3 */
24449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 4 */
24509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 5 */
24569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 6 */
24629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 7 */
24689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 8 */
24749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      c1 = block[i1]; c2 = block[i2];
24759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (c1 != c2) return (c1 > c2);
24769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s1 = quadrant[i1]; s2 = quadrant[i2];
24779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s1 != s2) return (s1 > s2);
24789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i1++; i2++;
24799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
24809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (i1 >= nblock) i1 -= nblock;
24819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (i2 >= nblock) i2 -= nblock;
24829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
24839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      k -= 8;
24849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      (*budget)--;
24859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
24869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (k >= 0);
24879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
24889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return False;
24899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
24909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
24919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
24929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
24939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
24949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Knuth's increments seem to work better
24959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   than Incerpi-Sedgewick here.  Possibly
24969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   because the number of elems to sort is
24979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   usually small, typically <= 20.
24989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
24999f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
25009f12f3ca9afc762f2e659179860c08d36e30f30fsewardjInt32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
25019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   9841, 29524, 88573, 265720,
25029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   797161, 2391484 };
25039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25049f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
25059f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid mainSimpleSort ( UInt32* ptr,
25069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      UChar*  block,
25079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      UInt16* quadrant,
25089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      Int32   nblock,
25099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      Int32   lo,
25109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      Int32   hi,
25119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      Int32   d,
25129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      Int32*  budget )
25139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
25149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 i, j, h, bigN, hp;
25159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt32 v;
25169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bigN = hi - lo + 1;
25189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bigN < 2) return;
25199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   hp = 0;
25219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (incs[hp] < bigN) hp++;
25229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   hp--;
25239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (; hp >= 0; hp--) {
25259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      h = incs[hp];
25269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i = lo + h;
25289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
25299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- copy 1 --*/
25319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (i > hi) break;
25329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         v = ptr[i];
25339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = i;
25349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while ( mainGtU (
25359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
25369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 ) ) {
25379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ptr[j] = ptr[j-h];
25389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j = j - h;
25399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (j <= (lo + h - 1)) break;
25409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
25419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ptr[j] = v;
25429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i++;
25439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- copy 2 --*/
25459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (i > hi) break;
25469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         v = ptr[i];
25479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = i;
25489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while ( mainGtU (
25499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
25509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 ) ) {
25519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ptr[j] = ptr[j-h];
25529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j = j - h;
25539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (j <= (lo + h - 1)) break;
25549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
25559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ptr[j] = v;
25569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i++;
25579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- copy 3 --*/
25599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (i > hi) break;
25609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         v = ptr[i];
25619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = i;
25629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while ( mainGtU (
25639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    ptr[j-h]+d, v+d, block, quadrant, nblock, budget
25649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 ) ) {
25659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ptr[j] = ptr[j-h];
25669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j = j - h;
25679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (j <= (lo + h - 1)) break;
25689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
25699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ptr[j] = v;
25709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         i++;
25719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (*budget < 0) return;
25739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
25749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
25759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
25769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
25799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
25809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   The following is an implementation of
25819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   an elegant 3-way quicksort for strings,
25829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   described in a paper "Fast Algorithms for
25839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Sorting and Searching Strings", by Robert
25849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Sedgewick and Jon L. Bentley.
25859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
25869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define mswap(zz1, zz2) \
25889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
25899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
25909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define mvswap(zzp1, zzp2, zzn)       \
25919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                     \
25929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 yyp1 = (zzp1);               \
25939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 yyp2 = (zzp2);               \
25949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 yyn  = (zzn);                \
25959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (yyn > 0) {                  \
25969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mswap(ptr[yyp1], ptr[yyp2]);    \
25979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      yyp1++; yyp2++; yyn--;          \
25989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                  \
25999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
26009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26019f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
26029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj__inline__
26039f12f3ca9afc762f2e659179860c08d36e30f30fsewardjUChar mmed3 ( UChar a, UChar b, UChar c )
26049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
26059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar t;
26069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (a > b) { t = a; a = b; b = t; };
26079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (b > c) {
26089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      b = c;
26099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (a > b) b = a;
26109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
26119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return b;
26129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
26139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define mmin(a,b) ((a) < (b)) ? (a) : (b)
26159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
26179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          stackHi[sp] = hz; \
26189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          stackD [sp] = dz; \
26199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          sp++; }
26209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define mpop(lz,hz,dz) { sp--;             \
26229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         lz = stackLo[sp]; \
26239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         hz = stackHi[sp]; \
26249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         dz = stackD [sp]; }
26259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define mnextsize(az) (nextHi[az]-nextLo[az])
26289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define mnextswap(az,bz)                                        \
26309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   { Int32 tz;                                                  \
26319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
26329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
26339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
26349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define MAIN_QSORT_SMALL_THRESH 20
26379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
26389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define MAIN_QSORT_STACK_SIZE 100
26399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26409f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
26419f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid mainQSort3 ( UInt32* ptr,
26429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  UChar*  block,
26439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  UInt16* quadrant,
26449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  Int32   nblock,
26459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  Int32   loSt,
26469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  Int32   hiSt,
26479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  Int32   dSt,
26489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  Int32*  budget )
26499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
26509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 unLo, unHi, ltLo, gtHi, n, m, med;
26519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 sp, lo, hi, d;
26529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 stackLo[MAIN_QSORT_STACK_SIZE];
26549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 stackHi[MAIN_QSORT_STACK_SIZE];
26559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 stackD [MAIN_QSORT_STACK_SIZE];
26569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nextLo[3];
26589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nextHi[3];
26599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nextD [3];
26609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   sp = 0;
26629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   mpush ( loSt, hiSt, dSt );
26639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (sp > 0) {
26659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
26679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mpop ( lo, hi, d );
26699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
26709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          d > MAIN_QSORT_DEPTH_THRESH) {
26719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
26729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (*budget < 0) return;
26739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         continue;
26749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
26759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      med = (Int32)
26779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            mmed3 ( block[ptr[ lo         ]+d],
26789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    block[ptr[ hi         ]+d],
26799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    block[ptr[ (lo+hi)>>1 ]+d] );
26809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unLo = ltLo = lo;
26829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unHi = gtHi = hi;
26839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
26849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
26859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (True) {
26869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (unLo > unHi) break;
26879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            n = ((Int32)block[ptr[unLo]+d]) - med;
26889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n == 0) {
26899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               mswap(ptr[unLo], ptr[ltLo]);
26909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ltLo++; unLo++; continue;
26919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            };
26929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n >  0) break;
26939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            unLo++;
26949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
26959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (True) {
26969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (unLo > unHi) break;
26979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            n = ((Int32)block[ptr[unHi]+d]) - med;
26989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n == 0) {
26999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               mswap(ptr[unHi], ptr[gtHi]);
27009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               gtHi--; unHi--; continue;
27019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            };
27029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n <  0) break;
27039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            unHi--;
27049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
27059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (unLo > unHi) break;
27069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
27079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
27089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertD ( unHi == unLo-1, "mainQSort3(2)" );
27109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (gtHi < ltLo) {
27129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         mpush(lo, hi, d+1 );
27139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         continue;
27149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
27159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
27179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
27189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      n = lo + unLo - ltLo - 1;
27209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      m = hi - (gtHi - unHi) + 1;
27219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
27239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
27249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
27259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
27279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
27289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
27299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
27319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
27329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mpush (nextLo[0], nextHi[0], nextD[0]);
27349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mpush (nextLo[1], nextHi[1], nextD[1]);
27359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mpush (nextLo[2], nextHi[2], nextD[2]);
27369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
27379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
27389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef mswap
27409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef mvswap
27419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef mpush
27429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef mpop
27439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef mmin
27449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef mnextsize
27459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef mnextswap
27469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef MAIN_QSORT_SMALL_THRESH
27479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef MAIN_QSORT_DEPTH_THRESH
27489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef MAIN_QSORT_STACK_SIZE
27499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
27529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Pre:
27539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nblock > N_OVERSHOOT
27549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
27559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ((UChar*)block32) [0 .. nblock-1] holds block
27569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr exists for [0 .. nblock-1]
27579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Post:
27599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ((UChar*)block32) [0 .. nblock-1] holds block
27609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      All other areas of block32 destroyed
27619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab [0 .. 65536 ] destroyed
27629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr [0 .. nblock-1] holds sorted order
27639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (*budget < 0), sorting was abandoned
27649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj*/
27659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
27679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define SETMASK (1 << 21)
27689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define CLEARMASK (~(SETMASK))
27699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27709f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
27719f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid mainSort ( UInt32* ptr,
27729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                UChar*  block,
27739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                UInt16* quadrant,
27749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                UInt32* ftab,
27759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                Int32   nblock,
27769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                Int32   verb,
27779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                Int32*  budget )
27789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
27799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  i, j, k, ss, sb;
27809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  runningOrder[256];
27819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool   bigDone[256];
27829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  copyStart[256];
27839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  copyEnd  [256];
27849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar  c1;
27859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  numQSorted;
27869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt16 s;
27879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
27889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- set up the 2-byte frequency table --*/
27909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 65536; i >= 0; i--) ftab[i] = 0;
27919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
27929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   j = block[0] << 8;
27939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i = nblock-1;
27949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (; i >= 3; i -= 4) {
27959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      quadrant[i] = 0;
27969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
27979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[j]++;
27989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      quadrant[i-1] = 0;
27999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
28009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[j]++;
28019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      quadrant[i-2] = 0;
28029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
28039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[j]++;
28049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      quadrant[i-3] = 0;
28059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
28069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[j]++;
28079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
28089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (; i >= 0; i--) {
28099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      quadrant[i] = 0;
28109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = (j >> 8) | ( ((UInt16)block[i]) << 8);
28119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[j]++;
28129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
28139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- (emphasises close relationship of block & quadrant) --*/
28159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < BZ_N_OVERSHOOT; i++) {
28169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      block   [nblock+i] = block[i];
28179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      quadrant[nblock+i] = 0;
28189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
28199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
28219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- Complete the initial radix sort --*/
28239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
28249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s = block[0] << 8;
28269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   i = nblock-1;
28279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (; i >= 3; i -= 4) {
28289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s = (s >> 8) | (block[i] << 8);
28299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = ftab[s] -1;
28309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[s] = j;
28319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr[j] = i;
28329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s = (s >> 8) | (block[i-1] << 8);
28339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = ftab[s] -1;
28349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[s] = j;
28359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr[j] = i-1;
28369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s = (s >> 8) | (block[i-2] << 8);
28379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = ftab[s] -1;
28389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[s] = j;
28399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr[j] = i-2;
28409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s = (s >> 8) | (block[i-3] << 8);
28419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = ftab[s] -1;
28429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[s] = j;
28439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr[j] = i-3;
28449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
28459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (; i >= 0; i--) {
28469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s = (s >> 8) | (block[i] << 8);
28479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = ftab[s] -1;
28489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab[s] = j;
28499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ptr[j] = i;
28509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
28519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--
28539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Now ftab contains the first loc of every small bucket.
28549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Calculate the running order, from smallest to largest
28559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      big bucket.
28569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   --*/
28579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i <= 255; i++) {
28589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bigDone     [i] = False;
28599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      runningOrder[i] = i;
28609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
28619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   {
28639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32 vv;
28649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32 h = 1;
28659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      do h = 3 * h + 1; while (h <= 256);
28669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      do {
28679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         h = h / 3;
28689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = h; i <= 255; i++) {
28699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            vv = runningOrder[i];
28709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j = i;
28719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
28729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               runningOrder[j] = runningOrder[j-h];
28739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               j = j - h;
28749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (j <= (h - 1)) goto zero;
28759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
28769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            zero:
28779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            runningOrder[j] = vv;
28789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
28799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } while (h != 1);
28809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
28819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--
28839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      The main sorting loop.
28849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   --*/
28859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   numQSorted = 0;
28879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i <= 255; i++) {
28899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--
28919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Process big buckets, starting with the least full.
28929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Basically this is a 3-step process in which we call
28939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         mainQSort3 to sort the small buckets [ss, j], but
28949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         also make a big effort to avoid the calls if we can.
28959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      --*/
28969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ss = runningOrder[i];
28979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
28989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--
28999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Step 1:
29009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Complete the big bucket [ss] by quicksorting
29019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         any unsorted small buckets [ss, j], for j != ss.
29029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Hopefully previous pointer-scanning phases have already
29039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         completed many of the small buckets [ss, j], so
29049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         we don't have to sort them at all.
29059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      --*/
29069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (j = 0; j <= 255; j++) {
29079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (j != ss) {
29089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            sb = (ss << 8) + j;
29099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if ( ! (ftab[sb] & SETMASK) ) {
29109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               Int32 lo = ftab[sb]   & CLEARMASK;
29119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
29129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (hi > lo) {
29139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  if (verb >= 4)
29149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     VPrintf4 ( "        qsort [0x%x, 0x%x]   "
29159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                "done %d   this %d\n",
29169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                ss, j, numQSorted, hi - lo + 1 );
29179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  mainQSort3 (
29189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     ptr, block, quadrant, nblock,
29199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     lo, hi, BZ_N_RADIX, budget
29209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  );
29219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  numQSorted += (hi - lo + 1);
29229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  if (*budget < 0) return;
29239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               }
29249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
29259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ftab[sb] |= SETMASK;
29269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
29279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
29289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH ( !bigDone[ss], 1006 );
29309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--
29329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Step 2:
29339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Now scan this big bucket [ss] so as to synthesise the
29349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         sorted order for small buckets [t, ss] for all t,
29359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         including, magically, the bucket [ss,ss] too.
29369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         This will avoid doing Real Work in subsequent Step 1's.
29379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      --*/
29389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      {
29399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (j = 0; j <= 255; j++) {
29409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
29419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
29429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
29439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
29449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            k = ptr[j]-1; if (k < 0) k += nblock;
29459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            c1 = block[k];
29469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (!bigDone[c1])
29479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ptr[ copyStart[c1]++ ] = k;
29489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
29499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
29509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            k = ptr[j]-1; if (k < 0) k += nblock;
29519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            c1 = block[k];
29529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (!bigDone[c1])
29539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ptr[ copyEnd[c1]-- ] = k;
29549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
29559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
29569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH ( (copyStart[ss]-1 == copyEnd[ss])
29589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                ||
29599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
29609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   Necessity for this case is demonstrated by compressing
29619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   a sequence of approximately 48.5 million of character
29629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   251; 1.0.0/1.0.1 will then die here. */
29639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
29649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                1007 )
29659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
29679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--
29699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Step 3:
29709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         The [ss] big bucket is now done.  Record this fact,
29719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         and update the quadrant descriptors.  Remember to
29729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         update quadrants in the overshoot area too, if
29739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         necessary.  The "if (i < 255)" test merely skips
29749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         this updating for the last bucket processed, since
29759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         updating for the last bucket is pointless.
29769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         The quadrant array provides a way to incrementally
29789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         cache sort orderings, as they appear, so as to
29799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         make subsequent comparisons in fullGtU() complete
29809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         faster.  For repetitive blocks this makes a big
29819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         difference (but not big enough to be able to avoid
29829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         the fallback sorting mechanism, exponential radix sort).
29839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         The precise meaning is: at all times:
29859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            for 0 <= i < nblock and 0 <= j <= nblock
29879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if block[i] != block[j],
29899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               then the relative values of quadrant[i] and
29919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    quadrant[j] are meaningless.
29929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               else {
29949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  if quadrant[i] < quadrant[j]
29959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     then the string starting at i lexicographically
29969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     precedes the string starting at j
29979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
29989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  else if quadrant[i] > quadrant[j]
29999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     then the string starting at j lexicographically
30009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     precedes the string starting at i
30019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  else
30039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     the relative ordering of the strings starting
30049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     at i and j has not yet been determined.
30059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               }
30069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      --*/
30079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bigDone[ss] = True;
30089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (i < 255) {
30109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
30119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
30129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Int32 shifts   = 0;
30139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while ((bbSize >> shifts) > 65534) shifts++;
30159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (j = bbSize-1; j >= 0; j--) {
30179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            Int32 a2update     = ptr[bbStart + j];
30189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            UInt16 qVal        = (UInt16)(j >> shifts);
30199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            quadrant[a2update] = qVal;
30209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (a2update < BZ_N_OVERSHOOT)
30219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               quadrant[a2update + nblock] = qVal;
30229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
30239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
30249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
30259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
30279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (verb >= 4)
30299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
30309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 nblock, numQSorted, nblock - numQSorted );
30319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
30329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef BIGFREQ
30349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef SETMASK
30359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#undef CLEARMASK
30369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
30399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Pre:
30409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nblock > 0
30419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
30429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ((UChar*)arr2)  [0 .. nblock-1] holds block
30439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      arr1 exists for [0 .. nblock-1]
30449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Post:
30469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ((UChar*)arr2) [0 .. nblock-1] holds block
30479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      All other areas of block destroyed
30489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ftab [ 0 .. 65536 ] destroyed
30499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      arr1 [0 .. nblock-1] holds sorted order
30509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj*/
30519f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ2_blockSort ( EState* s )
30529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
30539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt32* ptr    = s->ptr;
30549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar*  block  = s->block;
30559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt32* ftab   = s->ftab;
30569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   nblock = s->nblock;
30579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   verb   = s->verbosity;
30589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   wfact  = s->workFactor;
30599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt16* quadrant;
30609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   budget;
30619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   budgetInit;
30629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   i;
30639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30649dc4cf77abb447418edba303d29c7cb0b4361a27sewardj   if (nblock < /* 10000 */1000 ) {
30659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
30669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
30679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* Calculate the location for quadrant, remembering to get
30689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         the alignment right.  Assumes that &(block[0]) is at least
30699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         2-byte aligned -- this should be ok since block is really
30709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         the first section of arr2.
30719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      */
30729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      i = nblock+BZ_N_OVERSHOOT;
30739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (i & 1) i++;
30749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      quadrant = (UInt16*)(&(block[i]));
30759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* (wfact-1) / 3 puts the default-factor-30
30779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         transition point at very roughly the same place as
30789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         with v0.1 and v0.9.0.
30799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Not that it particularly matters any more, since the
30809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         resulting compressed stream is now the same regardless
30819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         of whether or not we use the main sort or fallback sort.
30829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      */
30839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (wfact < 1  ) wfact = 1;
30849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (wfact > 100) wfact = 100;
30859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      budgetInit = nblock * ((wfact-1) / 3);
30869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      budget = budgetInit;
30879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
30889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
30899dc4cf77abb447418edba303d29c7cb0b4361a27sewardj      if (0 && verb >= 3)
30909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
30919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    budgetInit - budget,
30929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    nblock,
30939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    (float)(budgetInit - budget) /
30949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    (float)(nblock==0 ? 1 : nblock) );
30959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (budget < 0) {
30969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (verb >= 2)
30979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            VPrintf0 ( "    too repetitive; using fallback"
30989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       " sorting algorithm\n" );
30999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
31009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
31019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
31029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->origPtr = -1;
31049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < s->nblock; i++)
31059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ptr[i] == 0)
31069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { s->origPtr = i; break; };
31079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH( s->origPtr != -1, 1003 );
31099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
31109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
31139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                       blocksort.c ---*/
31149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
31159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
31179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Huffman coding low-level stuff                        ---*/
31189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                             huffman.c ---*/
31199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
31209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
31229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
31239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
31249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
31269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
31289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
31299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
31309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
31329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
31339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
31359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
31369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
31379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
31389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
31409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
31419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
31439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
31449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
31459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
31479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
31509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
31599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
31609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
31619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
31639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
31649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
31659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
31669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
31679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
31689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
31699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
31709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
31719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
31739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
31749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
31789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
31799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
31809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
31819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define ADDWEIGHTS(zw1,zw2)                           \
31839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
31849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
31859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define UPHEAP(z)                                     \
31879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                                     \
31889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 zz, tmp;                                     \
31899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zz = z; tmp = heap[zz];                            \
31909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
31919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      heap[zz] = heap[zz >> 1];                       \
31929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zz >>= 1;                                       \
31939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                                  \
31949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   heap[zz] = tmp;                                    \
31959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
31969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
31979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define DOWNHEAP(z)                                   \
31989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                                     \
31999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 zz, yy, tmp;                                 \
32009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zz = z; tmp = heap[zz];                            \
32019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {                                     \
32029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      yy = zz << 1;                                   \
32039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (yy > nHeap) break;                          \
32049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (yy < nHeap &&                               \
32059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          weight[heap[yy+1]] < weight[heap[yy]])      \
32069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         yy++;                                        \
32079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (weight[tmp] < weight[heap[yy]]) break;      \
32089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      heap[zz] = heap[yy];                            \
32099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zz = yy;                                        \
32109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                                  \
32119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   heap[zz] = tmp;                                    \
32129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
32139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
32169f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ2_hbMakeCodeLengths ( UChar *len,
32179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             Int32 *freq,
32189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             Int32 alphaSize,
32199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             Int32 maxLen )
32209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
32219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--
32229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Nodes and heap entries run from 1.  Entry 0
32239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for both the heap and nodes is a sentinel.
32249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   --*/
32259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nNodes, nHeap, n1, n2, i, j, k;
32269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool  tooLong;
32279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
32299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
32309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
32319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < alphaSize; i++)
32339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
32349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
32369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nNodes = alphaSize;
32389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nHeap = 0;
32399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      heap[0] = 0;
32419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      weight[0] = 0;
32429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      parent[0] = -2;
32439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 1; i <= alphaSize; i++) {
32459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         parent[i] = -1;
32469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         nHeap++;
32479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         heap[nHeap] = i;
32489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         UPHEAP(nHeap);
32499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
32509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
32529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (nHeap > 1) {
32549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
32559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
32569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         nNodes++;
32579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         parent[n1] = parent[n2] = nNodes;
32589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
32599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         parent[nNodes] = -1;
32609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         nHeap++;
32619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         heap[nHeap] = nNodes;
32629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         UPHEAP(nHeap);
32639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
32649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
32669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      tooLong = False;
32689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 1; i <= alphaSize; i++) {
32699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = 0;
32709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k = i;
32719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (parent[k] >= 0) { k = parent[k]; j++; }
32729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         len[i-1] = j;
32739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (j > maxLen) tooLong = True;
32749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
32759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (! tooLong) break;
32779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* 17 Oct 04: keep-going condition for the following loop used
32799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         to be 'i < alphaSize', which missed the last element,
32809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         theoretically leading to the possibility of the compressor
32819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         looping.  However, this count-scaling step is only needed if
32829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         one of the generated Huffman code words is longer than
32839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         maxLen, which up to and including version 1.0.2 was 20 bits,
32849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         which is extremely unlikely.  In version 1.0.3 maxLen was
32859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         changed to 17 bits, which has minimal effect on compression
32869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ratio, but does mean this scaling step is used from time to
32879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         time, enough to verify that it works.
32889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         This means that bzip2-1.0.3 and later will only produce
32909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Huffman codes with a maximum length of 17 bits.  However, in
32919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         order to preserve backwards compatibility with bitstreams
32929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         produced by versions pre-1.0.3, the decompressor must still
32939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         handle lengths of up to 20. */
32949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
32959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 1; i <= alphaSize; i++) {
32969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = weight[i] >> 8;
32979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = 1 + (j / 2);
32989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         weight[i] = j << 8;
32999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
33009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
33019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
33029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
33059f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ2_hbAssignCodes ( Int32 *code,
33069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         UChar *length,
33079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         Int32 minLen,
33089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         Int32 maxLen,
33099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         Int32 alphaSize )
33109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
33119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 n, vec, i;
33129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   vec = 0;
33149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (n = minLen; n <= maxLen; n++) {
33159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < alphaSize; i++)
33169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (length[i] == n) { code[i] = vec; vec++; };
33179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      vec <<= 1;
33189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
33199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
33209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
33239f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ2_hbCreateDecodeTables ( Int32 *limit,
33249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                Int32 *base,
33259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                Int32 *perm,
33269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                UChar *length,
33279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                Int32 minLen,
33289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                Int32 maxLen,
33299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                Int32 alphaSize )
33309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
33319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 pp, i, j, vec;
33329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   pp = 0;
33349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = minLen; i <= maxLen; i++)
33359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (j = 0; j < alphaSize; j++)
33369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (length[j] == i) { perm[pp] = j; pp++; };
33379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
33399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
33409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
33429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
33449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   vec = 0;
33459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = minLen; i <= maxLen; i++) {
33479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      vec += (base[i+1] - base[i]);
33489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      limit[i] = vec-1;
33499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      vec <<= 1;
33509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
33519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = minLen + 1; i <= maxLen; i++)
33529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      base[i] = ((limit[i-1] + 1) << 1) - base[i];
33539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
33549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
33579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                         huffman.c ---*/
33589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
33599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
33619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Compression machinery (not incl block sorting)        ---*/
33629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                            compress.c ---*/
33639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
33649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
33669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
33679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
33689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
33709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
33729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
33739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
33749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
33769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
33779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
33799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
33809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
33819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
33829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
33849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
33859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
33879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
33889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
33899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
33909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
33919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
33949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
33969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
34039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
34049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
34059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
34079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
34089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
34099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
34109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
34119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
34129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
34139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
34149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
34159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
34179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
34189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
34209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   CHANGES
34219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ~~~~~~~
34229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0.9.0 -- original version.
34239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0.9.0a/b -- no changes in this file.
34259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0.9.0c
34279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      * changed setting of nGroups in sendMTFValues() so as to
34289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        do a bit better on small files
34299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
34309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Bit stream I/O                              ---*/
34359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34389f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ2_bsInitWrite ( EState* s )
34399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
34409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->bsLive = 0;
34419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->bsBuff = 0;
34429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
34439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34469f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
34479f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid bsFinishWrite ( EState* s )
34489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
34499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (s->bsLive > 0) {
34509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
34519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->numZ++;
34529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->bsBuff <<= 8;
34539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->bsLive -= 8;
34549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
34559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
34569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define bsNEEDW(nz)                           \
34609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                             \
34619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (s->bsLive >= 8) {                   \
34629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->zbits[s->numZ]                       \
34639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         = (UChar)(s->bsBuff >> 24);          \
34649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->numZ++;                              \
34659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->bsBuff <<= 8;                        \
34669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->bsLive -= 8;                         \
34679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                          \
34689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
34699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34729f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
34739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj__inline__
34749f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid bsW ( EState* s, Int32 n, UInt32 v )
34759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
34769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsNEEDW ( n );
34779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->bsBuff |= (v << (32 - s->bsLive - n));
34789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->bsLive += n;
34799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
34809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34839f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
34849f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid bsPutUInt32 ( EState* s, UInt32 u )
34859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
34869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsW ( s, 8, (u >> 24) & 0xffL );
34879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsW ( s, 8, (u >> 16) & 0xffL );
34889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsW ( s, 8, (u >>  8) & 0xffL );
34899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsW ( s, 8,  u        & 0xffL );
34909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
34919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
34939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
34949f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
34959f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid bsPutUChar ( EState* s, UChar c )
34969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
34979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsW( s, 8, (UInt32)c );
34989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
34999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
35029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- The back end proper                         ---*/
35039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
35049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
35069f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
35079f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid makeMaps_e ( EState* s )
35089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
35099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 i;
35109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->nInUse = 0;
35119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < 256; i++)
35129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->inUse[i]) {
35139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->unseqToSeq[i] = s->nInUse;
35149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->nInUse++;
35159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
35169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
35179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
35209f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
35219f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid generateMTFValues ( EState* s )
35229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
35239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar   yy[256];
35249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   i, j;
35259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   zPend;
35269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   wr;
35279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   EOB;
35289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*
35309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      After sorting (eg, here),
35319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
35329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         and
35339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
35349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         holds the original block data.
35359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      The first thing to do is generate the MTF values,
35379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      and put them in
35389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
35399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Because there are strictly fewer or equal MTF values
35409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      than block values, ptr values in this area are overwritten
35419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      with MTF values only when they are no longer needed.
35429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      The final compressed bitstream is generated into the
35449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      area starting at
35459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         (UChar*) (&((UChar*)s->arr2)[s->nblock])
35469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      These storage aliases are set up in bzCompressInit(),
35489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      except for the last one, which is arranged in
35499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      compressBlock().
35509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   */
35519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt32* ptr   = s->ptr;
35529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar* block  = s->block;
35539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt16* mtfv  = s->mtfv;
35549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   makeMaps_e ( s );
35569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   EOB = s->nInUse+1;
35579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
35599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   wr = 0;
35619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zPend = 0;
35629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
35639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < s->nblock; i++) {
35659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar ll_i;
35669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertD ( wr <= i, "generateMTFValues(1)" );
35679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      j = ptr[i]-1; if (j < 0) j += s->nblock;
35689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ll_i = s->unseqToSeq[block[j]];
35699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
35709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (yy[0] == ll_i) {
35729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         zPend++;
35739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } else {
35749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
35759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (zPend > 0) {
35769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            zPend--;
35779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (True) {
35789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (zPend & 1) {
35799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  mtfv[wr] = BZ_RUNB; wr++;
35809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->mtfFreq[BZ_RUNB]++;
35819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               } else {
35829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  mtfv[wr] = BZ_RUNA; wr++;
35839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->mtfFreq[BZ_RUNA]++;
35849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               }
35859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (zPend < 2) break;
35869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               zPend = (zPend - 2) / 2;
35879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            };
35889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            zPend = 0;
35899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
35909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         {
35919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            register UChar  rtmp;
35929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            register UChar* ryy_j;
35939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            register UChar  rll_i;
35949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            rtmp  = yy[1];
35959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            yy[1] = yy[0];
35969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ryy_j = &(yy[1]);
35979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            rll_i = ll_i;
35989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while ( rll_i != rtmp ) {
35999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               register UChar rtmp2;
36009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ryy_j++;
36019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               rtmp2  = rtmp;
36029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               rtmp   = *ryy_j;
36039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               *ryy_j = rtmp2;
36049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            };
36059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            yy[0] = rtmp;
36069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j = ryy_j - &(yy[0]);
36079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
36089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
36099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
36119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
36129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (zPend > 0) {
36149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zPend--;
36159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
36169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (zPend & 1) {
36179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            mtfv[wr] = BZ_RUNB; wr++;
36189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->mtfFreq[BZ_RUNB]++;
36199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
36209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            mtfv[wr] = BZ_RUNA; wr++;
36219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->mtfFreq[BZ_RUNA]++;
36229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
36239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (zPend < 2) break;
36249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         zPend = (zPend - 2) / 2;
36259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      };
36269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zPend = 0;
36279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
36289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
36309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->nMTF = wr;
36329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
36339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
36369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_LESSER_ICOST  0
36379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_GREATER_ICOST 15
36389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36399f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
36409f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid sendMTFValues ( EState* s )
36419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
36429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
36439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
36449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 nGroups, nBytes;
36459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--
36479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
36489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   is a global since the decoder also needs it.
36499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
36519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
36529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   are also globals only used in this proc.
36539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Made global to keep stack frame size small.
36549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   --*/
36559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt16 cost[BZ_N_GROUPS];
36589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32  fave[BZ_N_GROUPS];
36599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt16* mtfv = s->mtfv;
36619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->verbosity >= 3)
36639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
36649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                "%d+2 syms in use\n",
36659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                s->nblock, s->nMTF, s->nInUse );
36669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   alphaSize = s->nInUse+2;
36689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (t = 0; t < BZ_N_GROUPS; t++)
36699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (v = 0; v < alphaSize; v++)
36709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->len[t][v] = BZ_GREATER_ICOST;
36719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- Decide how many coding tables to use ---*/
36739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH ( s->nMTF > 0, 3001 );
36749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->nMTF < 200)  nGroups = 2; else
36759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->nMTF < 600)  nGroups = 3; else
36769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->nMTF < 1200) nGroups = 4; else
36779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->nMTF < 2400) nGroups = 5; else
36789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       nGroups = 6;
36799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- Generate an initial set of coding tables ---*/
36819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   {
36829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32 nPart, remF, tFreq, aFreq;
36839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nPart = nGroups;
36859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      remF  = s->nMTF;
36869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gs = 0;
36879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (nPart > 0) {
36889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         tFreq = remF / nPart;
36899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ge = gs-1;
36909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         aFreq = 0;
36919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (aFreq < tFreq && ge < alphaSize-1) {
36929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ge++;
36939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            aFreq += s->mtfFreq[ge];
36949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
36959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
36969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (ge > gs
36979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             && nPart != nGroups && nPart != 1
36989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             && ((nGroups-nPart) % 2 == 1)) {
36999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            aFreq -= s->mtfFreq[ge];
37009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            ge--;
37019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
37029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37039dc4cf77abb447418edba303d29c7cb0b4361a27sewardj         if (0 && s->verbosity >= 3)
37049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            VPrintf5( "      initial group %d, [%d .. %d], "
37059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      "has %d syms (%4.1f%%)\n",
37069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      nPart, gs, ge, aFreq,
37079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
37089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (v = 0; v < alphaSize; v++)
37109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (v >= gs && v <= ge)
37119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
37129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               s->len[nPart-1][v] = BZ_GREATER_ICOST;
37139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         nPart--;
37159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         gs = ge+1;
37169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         remF -= aFreq;
37179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
37189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
37199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*---
37219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Iterate up to BZ_N_ITERS times to improve the tables.
37229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ---*/
37239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (iter = 0; iter < BZ_N_ITERS; iter++) {
37249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (t = 0; t < nGroups; t++) fave[t] = 0;
37269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (t = 0; t < nGroups; t++)
37289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (v = 0; v < alphaSize; v++)
37299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->rfreq[t][v] = 0;
37309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*---
37329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        Set up an auxiliary length table which is used to fast-track
37339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	the common case (nGroups == 6).
37349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ---*/
37359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (nGroups == 6) {
37369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (v = 0; v < alphaSize; v++) {
37379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
37389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
37399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
37409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 }
37419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
37429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nSelectors = 0;
37449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      totc = 0;
37459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gs = 0;
37469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
37479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*--- Set group start & end marks. --*/
37499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (gs >= s->nMTF) break;
37509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ge = gs + BZ_G_SIZE - 1;
37519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (ge >= s->nMTF) ge = s->nMTF-1;
37529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*--
37549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            Calculate the cost of this group as coded
37559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            by each of the coding tables.
37569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         --*/
37579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (t = 0; t < nGroups; t++) cost[t] = 0;
37589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (nGroups == 6 && 50 == ge-gs+1) {
37609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            /*--- fast track the common case ---*/
37619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            register UInt32 cost01, cost23, cost45;
37629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            register UInt16 icv;
37639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            cost01 = cost23 = cost45 = 0;
37649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#           define BZ_ITER(nn)                \
37669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               icv = mtfv[gs+(nn)];           \
37679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cost01 += s->len_pack[icv][0]; \
37689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cost23 += s->len_pack[icv][1]; \
37699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cost45 += s->len_pack[icv][2]; \
37709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
37729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
37739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
37749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
37759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
37769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
37779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
37789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
37799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
37809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
37819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#           undef BZ_ITER
37839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
37859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
37869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
37879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
37899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	    /*--- slow version which correctly handles all situations ---*/
37909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            for (i = gs; i <= ge; i++) {
37919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               UInt16 icv = mtfv[i];
37929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
37939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
37949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
37959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
37969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*--
37979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            Find the coding table which is best for this group,
37989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            and record its identity in the selector table.
37999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         --*/
38009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         bc = 999999999; bt = -1;
38019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (t = 0; t < nGroups; t++)
38029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (cost[t] < bc) { bc = cost[t]; bt = t; };
38039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         totc += bc;
38049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         fave[bt]++;
38059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->selector[nSelectors] = bt;
38069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         nSelectors++;
38079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*--
38099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            Increment the symbol frequencies for the selected table.
38109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          --*/
38119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (nGroups == 6 && 50 == ge-gs+1) {
38129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            /*--- fast track the common case ---*/
38139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
38159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
38179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
38189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
38199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
38209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
38219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
38229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
38239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
38249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
38259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
38269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#           undef BZ_ITUR
38289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
38309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	    /*--- slow version which correctly handles all situations ---*/
38319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            for (i = gs; i <= ge; i++)
38329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               s->rfreq[bt][ mtfv[i] ]++;
38339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
38349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         gs = ge+1;
38369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
38379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->verbosity >= 3) {
38389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf2 ( "      pass %d: size is %d, grp uses are ",
38399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   iter+1, totc/8 );
38409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (t = 0; t < nGroups; t++)
38419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            VPrintf1 ( "%d ", fave[t] );
38429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf0 ( "\n" );
38439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
38449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--
38469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        Recompute the tables based on the accumulated frequencies.
38479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      --*/
38489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
38499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         comment in huffman.c for details. */
38509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (t = 0; t < nGroups; t++)
38519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
38529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                                 alphaSize, 17 /*20*/ );
38539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
38549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH( nGroups < 8, 3002 );
38579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH( nSelectors < 32768 &&
38589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
38599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            3003 );
38609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- Compute MTF values for the selectors. ---*/
38639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   {
38649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
38659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < nGroups; i++) pos[i] = i;
38669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < nSelectors; i++) {
38679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ll_i = s->selector[i];
38689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         j = 0;
38699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         tmp = pos[j];
38709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while ( ll_i != tmp ) {
38719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            j++;
38729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            tmp2 = tmp;
38739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            tmp = pos[j];
38749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            pos[j] = tmp2;
38759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         };
38769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         pos[0] = tmp;
38779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->selectorMtf[i] = j;
38789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
38799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   };
38809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- Assign actual codes for the tables. --*/
38829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (t = 0; t < nGroups; t++) {
38839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      minLen = 32;
38849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      maxLen = 0;
38859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < alphaSize; i++) {
38869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
38879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->len[t][i] < minLen) minLen = s->len[t][i];
38889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
38899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
38909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH ( !(minLen < 1),  3005 );
38919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
38929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          minLen, maxLen, alphaSize );
38939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
38949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
38959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- Transmit the mapping table. ---*/
38969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   {
38979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool inUse16[16];
38989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < 16; i++) {
38999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          inUse16[i] = False;
39009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          for (j = 0; j < 16; j++)
39019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             if (s->inUse[i * 16 + j]) inUse16[i] = True;
39029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
39039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nBytes = s->numZ;
39059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < 16; i++)
39069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
39079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < 16; i++)
39099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (inUse16[i])
39109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            for (j = 0; j < 16; j++) {
39119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
39129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
39139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->verbosity >= 3)
39159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
39169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
39179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- Now the selectors. ---*/
39199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nBytes = s->numZ;
39209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsW ( s, 3, nGroups );
39219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bsW ( s, 15, nSelectors );
39229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < nSelectors; i++) {
39239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
39249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsW(s,1,0);
39259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
39269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->verbosity >= 3)
39279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      VPrintf1( "selectors %d, ", s->numZ-nBytes );
39289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- Now the coding tables. ---*/
39309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nBytes = s->numZ;
39319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (t = 0; t < nGroups; t++) {
39339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32 curr = s->len[t][0];
39349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsW ( s, 5, curr );
39359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      for (i = 0; i < alphaSize; i++) {
39369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
39379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
39389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         bsW ( s, 1, 0 );
39399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
39409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
39419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->verbosity >= 3)
39439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
39449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*--- And finally, the block data proper ---*/
39469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nBytes = s->numZ;
39479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   selCtr = 0;
39489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   gs = 0;
39499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
39509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (gs >= s->nMTF) break;
39519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ge = gs + BZ_G_SIZE - 1;
39529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ge >= s->nMTF) ge = s->nMTF-1;
39539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      AssertH ( s->selector[selCtr] < nGroups, 3006 );
39549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (nGroups == 6 && 50 == ge-gs+1) {
39569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            /*--- fast track the common case ---*/
39579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            UInt16 mtfv_i;
39589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            UChar* s_len_sel_selCtr
39599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               = &(s->len[s->selector[selCtr]][0]);
39609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            Int32* s_code_sel_selCtr
39619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               = &(s->code[s->selector[selCtr]][0]);
39629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#           define BZ_ITAH(nn)                      \
39649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               mtfv_i = mtfv[gs+(nn)];              \
39659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               bsW ( s,                             \
39669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s_len_sel_selCtr[mtfv_i],      \
39679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     s_code_sel_selCtr[mtfv_i] )
39689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
39709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
39719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
39729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
39739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
39749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
39759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
39769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
39779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
39789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
39799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#           undef BZ_ITAH
39819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } else {
39839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 /*--- slow version which correctly handles all situations ---*/
39849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         for (i = gs; i <= ge; i++) {
39859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            bsW ( s,
39869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->len  [s->selector[selCtr]] [mtfv[i]],
39879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  s->code [s->selector[selCtr]] [mtfv[i]] );
39889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
39899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
39909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      gs = ge+1;
39939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      selCtr++;
39949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
39959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH( selCtr == nSelectors, 3007 );
39969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
39979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->verbosity >= 3)
39989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      VPrintf1( "codes %d\n", s->numZ-nBytes );
39999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
40009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
40039f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ2_compressBlock ( EState* s, Bool is_last_block )
40049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
40059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->nblock > 0) {
40069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ_FINALISE_CRC ( s->blockCRC );
40089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
40099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->combinedCRC ^= s->blockCRC;
40109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->blockNo > 1) s->numZ = 0;
40119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->verbosity >= 2)
40139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf4( "    block %d: crc = 0x%08x, "
40149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   "combined CRC = 0x%08x, size = %d\n",
40159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
40169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ2_blockSort ( s );
40189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
40199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
40219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- If this is the first block, create the stream header. --*/
40239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->blockNo == 1) {
40249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ2_bsInitWrite ( s );
40259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, BZ_HDR_B );
40269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, BZ_HDR_Z );
40279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, BZ_HDR_h );
40289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
40299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
40309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->nblock > 0) {
40329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
40349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
40359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
40369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- Now the block's CRC, so it is in a known place. --*/
40389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUInt32 ( s, s->blockCRC );
40399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*--
40419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Now a single bit indicating (non-)randomisation.
40429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         As of version 0.9.5, we use a better sorting algorithm
40439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         which makes randomisation unnecessary.  So always set
40449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         the randomised bit to 'no'.  Of course, the decoder
40459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         still needs to be able to handle randomised blocks
40469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         so as to maintain backwards compatibility with
40479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         older versions of bzip2.
40489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      --*/
40499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsW(s,1,0);
40509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsW ( s, 24, s->origPtr );
40529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      generateMTFValues ( s );
40539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      sendMTFValues ( s );
40549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
40559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- If this is the last block, add the stream trailer. --*/
40589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (is_last_block) {
40599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
40619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
40629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
40639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsPutUInt32 ( s, s->combinedCRC );
40649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->verbosity >= 2)
40659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
40669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bsFinishWrite ( s );
40679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
40689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
40699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
40729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                        compress.c ---*/
40739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
40749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
40779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Table for randomising repetitive blocks               ---*/
40789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                           randtable.c ---*/
40799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
40809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
40829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
40839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
40849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
40869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
40889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
40899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
40909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
40929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
40939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
40959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
40969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
40979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
40989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
40999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
41009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
41019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
41039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
41049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
41059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
41079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
41089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
41109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
41199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
41209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
41219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
41239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
41249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
41259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
41269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
41279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
41289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
41299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
41309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
41319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
41339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
41349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
41399f12f3ca9afc762f2e659179860c08d36e30f30fsewardjInt32 BZ2_rNums[512] = {
41409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
41419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
41429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
41439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
41449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
41459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
41469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
41479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
41489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
41499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
41509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
41519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
41529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
41539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
41549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
41559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
41569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
41579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
41589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
41599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
41609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
41619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
41629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
41639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
41649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
41659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
41669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
41679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
41689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
41699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
41709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
41719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
41729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
41739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
41749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
41759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
41769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
41779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
41789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
41799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
41809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
41819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
41829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
41839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
41849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
41859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
41869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
41879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
41889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
41899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
41909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
41919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   936, 638
41929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj};
41939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
41969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                       randtable.c ---*/
41979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
41989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
41999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
42009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Table for doing CRCs                                  ---*/
42019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                            crctable.c ---*/
42029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
42039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
42059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
42069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
42079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
42099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
42119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
42129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
42139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
42159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
42169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
42189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
42199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
42209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
42219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
42239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
42249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
42269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
42279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
42289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
42309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
42339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
42429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
42439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
42449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
42469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
42479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
42489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
42499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
42509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
42519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
42529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
42539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
42549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
42569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
42579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
42639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  I think this is an implementation of the AUTODIN-II,
42649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
42659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  from code by Rob Warnock, in Section 51 of the
42669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  comp.compression FAQ.
42679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
42689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42699f12f3ca9afc762f2e659179860c08d36e30f30fsewardjUInt32 BZ2_crc32Table[256] = {
42709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- Ugly, innit? --*/
42729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
42739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
42749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
42759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
42769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
42779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
42789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
42799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
42809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
42819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
42829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
42839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
42849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
42859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
42869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
42879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
42889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
42899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
42909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
42919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
42929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
42939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
42949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
42959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
42969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
42979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
42989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
42999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
43009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
43019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
43029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
43039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
43049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
43059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
43069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
43079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
43089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
43099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
43109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
43119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
43129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
43139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
43149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
43159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
43169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
43179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
43189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
43199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
43209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
43219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
43229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
43239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
43249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
43259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
43269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
43279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
43289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
43299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
43309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
43319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
43329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
43339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
43349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
43359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
43369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
43379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj};
43389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
43419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                        crctable.c ---*/
43429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
43439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
43459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Library top-level functions.                          ---*/
43469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---                                               bzlib.c ---*/
43479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
43489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
43509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This file is a part of bzip2 and/or libbzip2, a program and
43519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  library for lossless, block-sorting data compression.
43529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
43549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Redistribution and use in source and binary forms, with or without
43569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  modification, are permitted provided that the following conditions
43579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  are met:
43589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  1. Redistributions of source code must retain the above copyright
43609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     notice, this list of conditions and the following disclaimer.
43619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  2. The origin of this software must not be misrepresented; you must
43639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not claim that you wrote the original software.  If you use this
43649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     software in a product, an acknowledgment in the product
43659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     documentation would be appreciated but is not required.
43669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  3. Altered source versions must be plainly marked as such, and must
43689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     not be misrepresented as being the original software.
43699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  4. The name of the author may not be used to endorse or promote
43719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     products derived from this software without specific prior written
43729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     permission.
43739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
43759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
43789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
43829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  Julian Seward, Cambridge, UK.
43879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  jseward@bzip.org
43889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  bzip2/libbzip2 version 1.0 of 21 March 2000
43899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
43909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  This program is based on (at least) the work of:
43919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Mike Burrows
43929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     David Wheeler
43939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Peter Fenwick
43949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Alistair Moffat
43959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Radford Neal
43969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Ian H. Witten
43979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Robert Sedgewick
43989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     Jon L. Bentley
43999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  For more information on these sources, see the manual.
44019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
44029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
44049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   CHANGES
44059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ~~~~~~~
44069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0.9.0 -- original version.
44079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0.9.0a/b -- no changes in this file.
44099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   0.9.0c
44119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      * made zero-length BZ_FLUSH work correctly in bzCompress().
44129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      * fixed bzWrite/bzRead to ignore zero-length requests.
44139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      * fixed bzread to correctly handle read requests after EOF.
44149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      * wrong parameter order in call to bzDecompressInit in
44159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        bzBuffToBuffDecompress.  Fixed.
44169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
44179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Compression stuff                           ---*/
44229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44269f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ2_bz__AssertH__fail ( int errcode )
44279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44286ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf("BZ2_bz__AssertH__fail(%d) called, exiting\n", errcode);
44299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (*serviceFn)(0,0);
44309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44329f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid bz_internal_error ( int errcode )
44339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44346ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf("bz_internal_error called, exiting\n", errcode);
44359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (*serviceFn)(0,0);
44369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44399f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
44409f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint bz_config_ok ( void )
44419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (sizeof(int)   != 4) return 0;
44439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (sizeof(short) != 2) return 0;
44449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (sizeof(char)  != 1) return 0;
44459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return 1;
44469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44509f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
44519f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid* default_bzalloc ( void* opaque, Int32 items, Int32 size )
44529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   void* v = (void*) (*serviceFn)(2, items * size );
44549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return v;
44559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44579f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
44589f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid default_bzfree ( void* opaque, void* addr )
44599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (addr != NULL) (*serviceFn)( 3, (HWord)addr );
44619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44659f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
44669f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid prepare_new_block ( EState* s )
44679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 i;
44699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->nblock = 0;
44709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->numZ = 0;
44719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->state_out_pos = 0;
44729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_INITIALISE_CRC ( s->blockCRC );
44739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < 256; i++) s->inUse[i] = False;
44749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->blockNo++;
44759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44799f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
44809f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid init_RL ( EState* s )
44819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->state_in_ch  = 256;
44839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->state_in_len = 0;
44849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44879f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
44889f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBool isempty_RL ( EState* s )
44899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
44909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->state_in_ch < 256 && s->state_in_len > 0)
44919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return False; else
44929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return True;
44939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
44949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
44969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
44979f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzCompressInit)
44989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    ( bz_stream* strm,
44999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     int        blockSize100k,
45009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     int        verbosity,
45019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     int        workFactor )
45029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
45039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   n;
45049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   EState* s;
45059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
45079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm == NULL ||
45099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       blockSize100k < 1 || blockSize100k > 9 ||
45109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       workFactor < 0 || workFactor > 250)
45119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     return BZ_PARAM_ERROR;
45129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (workFactor == 0) workFactor = 30;
45149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
45159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
45169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s = BZALLOC( sizeof(EState) );
45189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s == NULL) return BZ_MEM_ERROR;
45199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->strm = strm;
45209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->arr1 = NULL;
45229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->arr2 = NULL;
45239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->ftab = NULL;
45249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   n       = 100000 * blockSize100k;
45269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
45279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
45289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
45299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
45319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->arr1 != NULL) BZFREE(s->arr1);
45329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->arr2 != NULL) BZFREE(s->arr2);
45339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->ftab != NULL) BZFREE(s->ftab);
45349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s       != NULL) BZFREE(s);
45359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return BZ_MEM_ERROR;
45369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
45379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->blockNo           = 0;
45399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->state             = BZ_S_INPUT;
45409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->mode              = BZ_M_RUNNING;
45419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->combinedCRC       = 0;
45429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->blockSize100k     = blockSize100k;
45439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->nblockMAX         = 100000 * blockSize100k - 19;
45449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->verbosity         = verbosity;
45459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->workFactor        = workFactor;
45469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->block             = (UChar*)s->arr2;
45489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->mtfv              = (UInt16*)s->arr1;
45499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->zbits             = NULL;
45509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->ptr               = (UInt32*)s->arr1;
45519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->state          = s;
45539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_in_lo32  = 0;
45549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_in_hi32  = 0;
45559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_out_lo32 = 0;
45569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_out_hi32 = 0;
45579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   init_RL ( s );
45589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   prepare_new_block ( s );
45599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OK;
45609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
45619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
45649f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
45659f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid add_pair_to_block ( EState* s )
45669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
45679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 i;
45689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar ch = (UChar)(s->state_in_ch);
45699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < s->state_in_len; i++) {
45709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ_UPDATE_CRC( s->blockCRC, ch );
45719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
45729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->inUse[s->state_in_ch] = True;
45739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   switch (s->state_in_len) {
45749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case 1:
45759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         break;
45779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case 2:
45789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         break;
45819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case 3:
45829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         break;
45869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      default:
45879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->inUse[s->state_in_len-4] = True;
45889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = (UChar)ch; s->nblock++;
45929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
45939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->nblock++;
45949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         break;
45959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
45969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
45979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
45999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
46009f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
46019f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid flush_RL ( EState* s )
46029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
46039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->state_in_ch < 256) add_pair_to_block ( s );
46049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   init_RL ( s );
46059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
46069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
46099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
46109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                                 \
46119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UInt32 zchh = (UInt32)(zchh0);                 \
46129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- fast track the common case --*/           \
46139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (zchh != zs->state_in_ch &&                 \
46149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       zs->state_in_len == 1) {                   \
46159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar ch = (UChar)(zs->state_in_ch);        \
46169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
46179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->inUse[zs->state_in_ch] = True;          \
46189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->block[zs->nblock] = (UChar)ch;          \
46199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->nblock++;                               \
46209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->state_in_ch = zchh;                     \
46219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                              \
46229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   else                                           \
46239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /*-- general, uncommon cases --*/              \
46249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (zchh != zs->state_in_ch ||                 \
46259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->state_in_len == 255) {                  \
46269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (zs->state_in_ch < 256)                  \
46279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         add_pair_to_block ( zs );                \
46289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->state_in_ch = zchh;                     \
46299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->state_in_len = 1;                       \
46309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {                                       \
46319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      zs->state_in_len++;                         \
46329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }                                              \
46339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
46349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
46379f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
46389f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBool copy_input_until_stop ( EState* s )
46399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
46409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool progress_in = False;
46419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->mode == BZ_M_RUNNING) {
46439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- fast track the common case --*/
46459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
46469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- block full? --*/
46479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock >= s->nblockMAX) break;
46489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- no input? --*/
46499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->strm->avail_in == 0) break;
46509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         progress_in = True;
46519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
46529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->next_in++;
46539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->avail_in--;
46549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->total_in_lo32++;
46559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
46569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
46579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
46599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- general, uncommon case --*/
46619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
46629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- block full? --*/
46639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock >= s->nblockMAX) break;
46649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- no input? --*/
46659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->strm->avail_in == 0) break;
46669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /*-- flush/finish end? --*/
46679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->avail_in_expect == 0) break;
46689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         progress_in = True;
46699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
46709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->next_in++;
46719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->avail_in--;
46729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->total_in_lo32++;
46739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
46749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->avail_in_expect--;
46759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
46769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
46779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return progress_in;
46789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
46799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
46829f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
46839f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBool copy_output_until_stop ( EState* s )
46849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
46859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool progress_out = False;
46869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
46889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- no output space? --*/
46909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->strm->avail_out == 0) break;
46919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /*-- block done? --*/
46939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->state_out_pos >= s->numZ) break;
46949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
46959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      progress_out = True;
46969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      *(s->strm->next_out) = s->zbits[s->state_out_pos];
46979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->state_out_pos++;
46989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->avail_out--;
46999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->next_out++;
47009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->total_out_lo32++;
47019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
47029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
47039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return progress_out;
47059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
47069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
47099f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
47109f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBool handle_compress ( bz_stream* strm )
47119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
47129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool progress_in  = False;
47139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool progress_out = False;
47149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   EState* s = strm->state;
47159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
47179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->state == BZ_S_OUTPUT) {
47199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         progress_out |= copy_output_until_stop ( s );
47209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->state_out_pos < s->numZ) break;
47219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->mode == BZ_M_FINISHING &&
47229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             s->avail_in_expect == 0 &&
47239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             isempty_RL(s)) break;
47249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         prepare_new_block ( s );
47259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state = BZ_S_INPUT;
47269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->mode == BZ_M_FLUSHING &&
47279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             s->avail_in_expect == 0 &&
47289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             isempty_RL(s)) break;
47299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
47309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->state == BZ_S_INPUT) {
47329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         progress_in |= copy_input_until_stop ( s );
47339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
47349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            flush_RL ( s );
47359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
47369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->state = BZ_S_OUTPUT;
47379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
47389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         else
47399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock >= s->nblockMAX) {
47409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ2_compressBlock ( s, False );
47419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->state = BZ_S_OUTPUT;
47429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
47439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         else
47449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->strm->avail_in == 0) {
47459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            break;
47469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
47479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
47489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
47509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return progress_in || progress_out;
47529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
47539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
47569f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
47579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
47589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool progress;
47599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   EState* s;
47609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
47619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s = strm->state;
47629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
47639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
47649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   preswitch:
47669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   switch (s->mode) {
47679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case BZ_M_IDLE:
47699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         return BZ_SEQUENCE_ERROR;
47709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case BZ_M_RUNNING:
47729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (action == BZ_RUN) {
47739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            progress = handle_compress ( strm );
47749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
47759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
47769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         else
47779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj	 if (action == BZ_FLUSH) {
47789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->avail_in_expect = strm->avail_in;
47799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->mode = BZ_M_FLUSHING;
47809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            goto preswitch;
47819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
47829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         else
47839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (action == BZ_FINISH) {
47849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->avail_in_expect = strm->avail_in;
47859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->mode = BZ_M_FINISHING;
47869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            goto preswitch;
47879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
47889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         else
47899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return BZ_PARAM_ERROR;
47909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
47919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case BZ_M_FLUSHING:
47929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
47939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->avail_in_expect != s->strm->avail_in)
47949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return BZ_SEQUENCE_ERROR;
47959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         progress = handle_compress ( strm );
47969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
47979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
47989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->mode = BZ_M_RUNNING;
47999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         return BZ_RUN_OK;
48009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case BZ_M_FINISHING:
48029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
48039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->avail_in_expect != s->strm->avail_in)
48049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return BZ_SEQUENCE_ERROR;
48059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         progress = handle_compress ( strm );
48069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (!progress) return BZ_SEQUENCE_ERROR;
48079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
48089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
48099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->mode = BZ_M_IDLE;
48109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         return BZ_STREAM_END;
48119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
48129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OK; /*--not reached--*/
48139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
48149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
48179f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
48189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
48199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   EState* s;
48209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
48219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s = strm->state;
48229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
48239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
48249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->arr1 != NULL) BZFREE(s->arr1);
48269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->arr2 != NULL) BZFREE(s->arr2);
48279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->ftab != NULL) BZFREE(s->ftab);
48289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZFREE(strm->state);
48299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->state = NULL;
48319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OK;
48339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
48349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
48379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Decompression stuff                         ---*/
48389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
48399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
48419f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzDecompressInit)
48429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     ( bz_stream* strm,
48439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       int        verbosity,
48449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       int        small )
48459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
48469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   DState* s;
48479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
48499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
48519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
48529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
48539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
48559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
48569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s = BZALLOC( sizeof(DState) );
48589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s == NULL) return BZ_MEM_ERROR;
48599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->strm                  = strm;
48609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->state              = s;
48619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->state                 = BZ_X_MAGIC_1;
48629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->bsLive                = 0;
48639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->bsBuff                = 0;
48649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->calculatedCombinedCRC = 0;
48659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_in_lo32      = 0;
48669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_in_hi32      = 0;
48679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_out_lo32     = 0;
48689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->total_out_hi32     = 0;
48699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->smallDecompress       = (Bool)small;
48709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->ll4                   = NULL;
48719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->ll16                  = NULL;
48729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->tt                    = NULL;
48739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->currBlockNo           = 0;
48749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s->verbosity             = verbosity;
48759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OK;
48779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
48789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
48819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Return  True iff data corruption is discovered.
48829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Returns False if there is no problem.
48839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj*/
48849f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
48859f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBool unRLE_obuf_to_output_FAST ( DState* s )
48869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
48879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar k1;
48889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->blockRandomised) {
48909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
48919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
48929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* try to finish existing run */
48939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (True) {
48949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->strm->avail_out == 0) return False;
48959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->state_out_len == 0) break;
48969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
48979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
48989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->state_out_len--;
48999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->next_out++;
49009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->avail_out--;
49019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->total_out_lo32++;
49029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
49039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
49049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* can a new run be started? */
49069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) return False;
49079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* Only caused by corrupt data stream? */
49099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used > s->save_nblock+1)
49109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return True;
49119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 1;
49139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_ch = s->k0;
49149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
49179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
49189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 2;
49209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
49239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
49249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 3;
49269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
49299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
49309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
49329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
49339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = ((Int32)k1) + 4;
49349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
49359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
49369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
49379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
49399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* restore */
49419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
49429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UChar         c_state_out_ch       = s->state_out_ch;
49439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32         c_state_out_len      = s->state_out_len;
49449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32         c_nblock_used        = s->nblock_used;
49459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32         c_k0                 = s->k0;
49469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32*       c_tt                 = s->tt;
49479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32        c_tPos               = s->tPos;
49489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      char*         cs_next_out          = s->strm->next_out;
49499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int  cs_avail_out         = s->strm->avail_out;
49509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* end restore */
49519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      UInt32       avail_out_INIT = cs_avail_out;
49539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32        s_save_nblockPP = s->save_nblock+1;
49549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unsigned int total_out_lo32_old;
49559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
49579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* try to finish existing run */
49599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (c_state_out_len > 0) {
49609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            while (True) {
49619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (cs_avail_out == 0) goto return_notr;
49629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (c_state_out_len == 1) break;
49639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
49649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
49659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               c_state_out_len--;
49669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cs_next_out++;
49679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cs_avail_out--;
49689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
49699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s_state_out_len_eq_one:
49709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            {
49719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               if (cs_avail_out == 0) {
49729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  c_state_out_len = 1; goto return_notr;
49739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               };
49749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
49759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
49769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cs_next_out++;
49779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               cs_avail_out--;
49789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            }
49799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
49809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* Only caused by corrupt data stream? */
49819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (c_nblock_used > s_save_nblockPP)
49829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return True;
49839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* can a new run be started? */
49859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (c_nblock_used == s_save_nblockPP) {
49869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            c_state_out_len = 0; goto return_notr;
49879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         };
49889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         c_state_out_ch = c_k0;
49899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
49909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != c_k0) {
49919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            c_k0 = k1; goto s_state_out_len_eq_one;
49929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         };
49939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (c_nblock_used == s_save_nblockPP)
49949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            goto s_state_out_len_eq_one;
49959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
49969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         c_state_out_len = 2;
49979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
49989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (c_nblock_used == s_save_nblockPP) continue;
49999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
50009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         c_state_out_len = 3;
50029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
50039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (c_nblock_used == s_save_nblockPP) continue;
50049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != c_k0) { c_k0 = k1; continue; };
50059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST_C(k1); c_nblock_used++;
50079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         c_state_out_len = ((Int32)k1) + 4;
50089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_FAST_C(c_k0); c_nblock_used++;
50099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
50109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return_notr:
50129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      total_out_lo32_old = s->strm->total_out_lo32;
50139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
50149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->strm->total_out_lo32 < total_out_lo32_old)
50159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->strm->total_out_hi32++;
50169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* save */
50189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->calculatedBlockCRC = c_calculatedBlockCRC;
50199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->state_out_ch       = c_state_out_ch;
50209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->state_out_len      = c_state_out_len;
50219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->nblock_used        = c_nblock_used;
50229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->k0                 = c_k0;
50239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->tt                 = c_tt;
50249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->tPos               = c_tPos;
50259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->next_out     = cs_next_out;
50269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      s->strm->avail_out    = cs_avail_out;
50279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* end save */
50289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
50299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return False;
50309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
50319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
50359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* Return  True iff data corruption is discovered.
50369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Returns False if there is no problem.
50379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj*/
50389f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
50399f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBool unRLE_obuf_to_output_SMALL ( DState* s )
50409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
50419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   UChar k1;
50429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->blockRandomised) {
50449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
50469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* try to finish existing run */
50479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (True) {
50489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->strm->avail_out == 0) return False;
50499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->state_out_len == 0) break;
50509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
50519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
50529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->state_out_len--;
50539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->next_out++;
50549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->avail_out--;
50559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->total_out_lo32++;
50569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
50579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
50589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* can a new run be started? */
50609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) return False;
50619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* Only caused by corrupt data stream? */
50639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used > s->save_nblock+1)
50649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return True;
50659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 1;
50679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_ch = s->k0;
50689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
50699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
50709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
50719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
50729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 2;
50749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
50759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
50769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
50779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
50789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 3;
50809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
50819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
50829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
50839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
50849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
50869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         k1 ^= BZ_RAND_MASK; s->nblock_used++;
50879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = ((Int32)k1) + 4;
50889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
50899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
50909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
50919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
50939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
50949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
50959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* try to finish existing run */
50969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         while (True) {
50979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->strm->avail_out == 0) return False;
50989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->state_out_len == 0) break;
50999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
51009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
51019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->state_out_len--;
51029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->next_out++;
51039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->avail_out--;
51049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->strm->total_out_lo32++;
51059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
51069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
51079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* can a new run be started? */
51099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) return False;
51109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         /* Only caused by corrupt data stream? */
51129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used > s->save_nblock+1)
51139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return True;
51149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 1;
51169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_ch = s->k0;
51179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
51199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
51209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 2;
51229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
51249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
51259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = 3;
51279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1) continue;
51299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (k1 != s->k0) { s->k0 = k1; continue; };
51309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(k1); s->nblock_used++;
51329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         s->state_out_len = ((Int32)k1) + 4;
51339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ_GET_SMALL(s->k0); s->nblock_used++;
51349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
51359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
51379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
51389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
51419f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
51429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
51439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Bool    corrupt;
51449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   DState* s;
51459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
51469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s = strm->state;
51479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
51489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
51499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
51519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
51529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->state == BZ_X_OUTPUT) {
51539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->smallDecompress)
51549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
51559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            corrupt = unRLE_obuf_to_output_FAST  ( s );
51569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (corrupt) return BZ_DATA_ERROR;
51579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
51589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
51599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->verbosity >= 3)
51609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
51619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          s->calculatedBlockCRC );
51629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->verbosity >= 2) VPrintf0 ( "]" );
51639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->calculatedBlockCRC != s->storedBlockCRC)
51649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               return BZ_DATA_ERROR;
51659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->calculatedCombinedCRC
51669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               = (s->calculatedCombinedCRC << 1) |
51679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    (s->calculatedCombinedCRC >> 31);
51689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
51699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            s->state = BZ_X_BLKHDR_1;
51709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
51719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return BZ_OK;
51729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
51739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
51749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (s->state >= BZ_X_MAGIC_1) {
51759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         Int32 r = BZ2_decompress ( s );
51769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (r == BZ_STREAM_END) {
51779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->verbosity >= 3)
51789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
51799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          s->storedCombinedCRC, s->calculatedCombinedCRC );
51809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
51819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               return BZ_DATA_ERROR;
51829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            return r;
51839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
51849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (s->state != BZ_X_OUTPUT) return r;
51859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
51869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
51879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   AssertH ( 0, 6001 );
51899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return 0;  /*NOTREACHED*/
51919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
51929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
51949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
51959f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
51969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
51979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   DState* s;
51989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm == NULL) return BZ_PARAM_ERROR;
51999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   s = strm->state;
52009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s == NULL) return BZ_PARAM_ERROR;
52019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->strm != strm) return BZ_PARAM_ERROR;
52029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->tt   != NULL) BZFREE(s->tt);
52049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->ll16 != NULL) BZFREE(s->ll16);
52059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (s->ll4  != NULL) BZFREE(s->ll4);
52069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZFREE(strm->state);
52089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm->state = NULL;
52099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OK;
52119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
52129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_NO_STDIO
52159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
52169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- File I/O stuff                              ---*/
52179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
52189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define BZ_SETERR(eee)                    \
52209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{                                         \
52219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzerror != NULL) *bzerror = eee;   \
52229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf != NULL) bzf->lastErr = eee;   \
52239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
52249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52259f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef
52269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   struct {
52279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      FILE*     handle;
52289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Char      buf[BZ_MAX_UNUSED];
52299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32     bufN;
52309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool      writing;
52319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bz_stream strm;
52329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Int32     lastErr;
52339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      Bool      initialisedOk;
52349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
52359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile;
52369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------*/
52399f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic Bool myfeof ( FILE* f )
52409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
52419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 c = fgetc ( f );
52429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (c == EOF) return True;
52439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ungetc ( c, f );
52449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return False;
52459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
52469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
52499f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZFILE* BZ_API(BZ2_bzWriteOpen)
52509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    ( int*  bzerror,
52519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      FILE* f,
52529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      int   blockSize100k,
52539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      int   verbosity,
52549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                      int   workFactor )
52559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
52569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   ret;
52579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile* bzf = NULL;
52589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
52609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (f == NULL ||
52629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (blockSize100k < 1 || blockSize100k > 9) ||
52639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (workFactor < 0 || workFactor > 250) ||
52649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (verbosity < 0 || verbosity > 4))
52659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
52669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ferror(f))
52689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
52699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf = malloc ( sizeof(bzFile) );
52719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf == NULL)
52729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
52739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
52759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->initialisedOk = False;
52769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->bufN          = 0;
52779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->handle        = f;
52789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->writing       = True;
52799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.bzalloc  = NULL;
52809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.bzfree   = NULL;
52819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.opaque   = NULL;
52829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (workFactor == 0) workFactor = 30;
52849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
52859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                              verbosity, workFactor );
52869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret != BZ_OK)
52879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
52889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.avail_in = 0;
52909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->initialisedOk = True;
52919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return bzf;
52929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
52939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
52969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
52979f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ_API(BZ2_bzWrite)
52989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             ( int*    bzerror,
52999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               BZFILE* b,
53009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               void*   buf,
53019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               int     len )
53029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
53039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32 n, n2, ret;
53049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile* bzf = (bzFile*)b;
53059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
53079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf == NULL || buf == NULL || len < 0)
53089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
53099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (!(bzf->writing))
53109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
53119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ferror(bzf->handle))
53129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
53139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (len == 0)
53159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_OK); return; };
53169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.avail_in = len;
53189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.next_in  = buf;
53199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
53219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bzf->strm.avail_out = BZ_MAX_UNUSED;
53229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bzf->strm.next_out = bzf->buf;
53239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
53249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ret != BZ_RUN_OK)
53259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(ret); return; };
53269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
53289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
53299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
53309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       n, bzf->handle );
53319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (n != n2 || ferror(bzf->handle))
53329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            { BZ_SETERR(BZ_IO_ERROR); return; };
53339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
53349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (bzf->strm.avail_in == 0)
53369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(BZ_OK); return; };
53379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
53389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
53399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
53429f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ_API(BZ2_bzWriteClose)
53439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  ( int*          bzerror,
53449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    BZFILE*       b,
53459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    int           abandon,
53469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    unsigned int* nbytes_in,
53479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    unsigned int* nbytes_out )
53489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
53499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzWriteClose64 ( bzerror, b, abandon,
53509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                        nbytes_in, NULL, nbytes_out, NULL );
53519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
53529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53549f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ_API(BZ2_bzWriteClose64)
53559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                  ( int*          bzerror,
53569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    BZFILE*       b,
53579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    int           abandon,
53589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    unsigned int* nbytes_in_lo32,
53599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    unsigned int* nbytes_in_hi32,
53609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    unsigned int* nbytes_out_lo32,
53619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                    unsigned int* nbytes_out_hi32 )
53629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
53639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   n, n2, ret;
53649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile* bzf = (bzFile*)b;
53659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf == NULL)
53679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_OK); return; };
53689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (!(bzf->writing))
53699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
53709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ferror(bzf->handle))
53719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_IO_ERROR); return; };
53729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
53749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
53759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
53769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
53779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if ((!abandon) && bzf->lastErr == BZ_OK) {
53799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      while (True) {
53809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         bzf->strm.avail_out = BZ_MAX_UNUSED;
53819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         bzf->strm.next_out = bzf->buf;
53829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
53839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
53849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            { BZ_SETERR(ret); return; };
53859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
53879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
53889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
53899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                          n, bzf->handle );
53909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            if (n != n2 || ferror(bzf->handle))
53919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               { BZ_SETERR(BZ_IO_ERROR); return; };
53929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
53939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (ret == BZ_STREAM_END) break;
53959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
53969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
53979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
53989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if ( !abandon && !ferror ( bzf->handle ) ) {
53999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fflush ( bzf->handle );
54009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ferror(bzf->handle))
54019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(BZ_IO_ERROR); return; };
54029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
54039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_in_lo32 != NULL)
54059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
54069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_in_hi32 != NULL)
54079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
54089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_out_lo32 != NULL)
54099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
54109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (nbytes_out_hi32 != NULL)
54119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
54129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
54149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzCompressEnd ( &(bzf->strm) );
54159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   free ( bzf );
54169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
54179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
54209f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZFILE* BZ_API(BZ2_bzReadOpen)
54219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                   ( int*  bzerror,
54229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     FILE* f,
54239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     int   verbosity,
54249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     int   small,
54259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     void* unused,
54269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     int   nUnused )
54279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
54289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile* bzf = NULL;
54299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int     ret;
54309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
54329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (f == NULL ||
54349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (small != 0 && small != 1) ||
54359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (verbosity < 0 || verbosity > 4) ||
54369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (unused == NULL && nUnused != 0) ||
54379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
54389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
54399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ferror(f))
54419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
54429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf = malloc ( sizeof(bzFile) );
54449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf == NULL)
54459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
54469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
54489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->initialisedOk = False;
54509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->handle        = f;
54519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->bufN          = 0;
54529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->writing       = False;
54539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.bzalloc  = NULL;
54549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.bzfree   = NULL;
54559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.opaque   = NULL;
54569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (nUnused > 0) {
54589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
54599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      unused = ((void*)( 1 + ((UChar*)(unused))  ));
54609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nUnused--;
54619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
54629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
54649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret != BZ_OK)
54659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(ret); free(bzf); return NULL; };
54669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.avail_in = bzf->bufN;
54689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.next_in  = bzf->buf;
54699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->initialisedOk = True;
54719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return bzf;
54729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
54739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
54769f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
54779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
54789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile* bzf = (bzFile*)b;
54799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
54819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf == NULL)
54829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_OK); return; };
54839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf->writing)
54859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
54869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf->initialisedOk)
54889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
54899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   free ( bzf );
54909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
54919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
54939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
54949f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzRead)
54959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj           ( int*    bzerror,
54969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             BZFILE* b,
54979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             void*   buf,
54989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             int     len )
54999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
55009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Int32   n, ret;
55019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile* bzf = (bzFile*)b;
55029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
55049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf == NULL || buf == NULL || len < 0)
55069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
55079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf->writing)
55099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
55109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (len == 0)
55129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_OK); return 0; };
55139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.avail_out = len;
55159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzf->strm.next_out = buf;
55169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (True) {
55189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ferror(bzf->handle))
55209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(BZ_IO_ERROR); return 0; };
55219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
55239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         n = fread ( bzf->buf, sizeof(UChar),
55249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     BZ_MAX_UNUSED, bzf->handle );
55259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (ferror(bzf->handle))
55269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            { BZ_SETERR(BZ_IO_ERROR); return 0; };
55279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         bzf->bufN = n;
55289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         bzf->strm.avail_in = bzf->bufN;
55299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         bzf->strm.next_in = bzf->buf;
55309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
55319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ret = BZ2_bzDecompress ( &(bzf->strm) );
55339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ret != BZ_OK && ret != BZ_STREAM_END)
55359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(ret); return 0; };
55369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ret == BZ_OK && myfeof(bzf->handle) &&
55389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
55399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
55409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (ret == BZ_STREAM_END)
55429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(BZ_STREAM_END);
55439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj           return len - bzf->strm.avail_out; };
55449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (bzf->strm.avail_out == 0)
55459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         { BZ_SETERR(BZ_OK); return len; };
55469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
55489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return 0; /*not reached*/
55509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
55519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
55549f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ_API(BZ2_bzReadGetUnused)
55559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                     ( int*    bzerror,
55569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       BZFILE* b,
55579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       void**  unused,
55589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                       int*    nUnused )
55599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
55609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bzFile* bzf = (bzFile*)b;
55619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf == NULL)
55629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
55639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzf->lastErr != BZ_STREAM_END)
55649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
55659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (unused == NULL || nUnused == NULL)
55669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      { BZ_SETERR(BZ_PARAM_ERROR); return; };
55679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ_SETERR(BZ_OK);
55699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   *nUnused = bzf->strm.avail_in;
55709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   *unused = bzf->strm.next_in;
55719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
55729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
55739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
55769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- Misc convenience stuff                      ---*/
55779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
55789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
55809f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzBuffToBuffCompress)
55819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                         ( char*         dest,
55829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           unsigned int* destLen,
55839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           char*         source,
55849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           unsigned int  sourceLen,
55859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           int           blockSize100k,
55869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           int           verbosity,
55879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           int           workFactor )
55889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
55899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bz_stream strm;
55909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int ret;
55919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (dest == NULL || destLen == NULL ||
55939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       source == NULL ||
55949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       blockSize100k < 1 || blockSize100k > 9 ||
55959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       verbosity < 0 || verbosity > 4 ||
55969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       workFactor < 0 || workFactor > 250)
55979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return BZ_PARAM_ERROR;
55989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
55999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (workFactor == 0) workFactor = 30;
56009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.bzalloc = NULL;
56019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.bzfree = NULL;
56029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.opaque = NULL;
56039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret = BZ2_bzCompressInit ( &strm, blockSize100k,
56049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                              verbosity, workFactor );
56059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret != BZ_OK) return ret;
56069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.next_in = source;
56089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.next_out = dest;
56099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.avail_in = sourceLen;
56109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.avail_out = *destLen;
56119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
56139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret == BZ_FINISH_OK) goto output_overflow;
56149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret != BZ_STREAM_END) goto errhandler;
56159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* normal termination */
56179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   *destLen -= strm.avail_out;
56189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzCompressEnd ( &strm );
56199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OK;
56209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   output_overflow:
56229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzCompressEnd ( &strm );
56239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OUTBUFF_FULL;
56249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   errhandler:
56269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzCompressEnd ( &strm );
56279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return ret;
56289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
56299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
56329f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzBuffToBuffDecompress)
56339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                           ( char*         dest,
56349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             unsigned int* destLen,
56359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             char*         source,
56369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             unsigned int  sourceLen,
56379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             int           small,
56389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             int           verbosity )
56399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
56409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   bz_stream strm;
56419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int ret;
56429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (dest == NULL || destLen == NULL ||
56449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       source == NULL ||
56459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       (small != 0 && small != 1) ||
56469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       verbosity < 0 || verbosity > 4)
56479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj          return BZ_PARAM_ERROR;
56489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.bzalloc = NULL;
56509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.bzfree = NULL;
56519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.opaque = NULL;
56529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
56539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret != BZ_OK) return ret;
56549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.next_in = source;
56569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.next_out = dest;
56579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.avail_in = sourceLen;
56589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strm.avail_out = *destLen;
56599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   ret = BZ2_bzDecompress ( &strm );
56619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret == BZ_OK) goto output_overflow_or_eof;
56629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (ret != BZ_STREAM_END) goto errhandler;
56639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* normal termination */
56659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   *destLen -= strm.avail_out;
56669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzDecompressEnd ( &strm );
56679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_OK;
56689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   output_overflow_or_eof:
56709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (strm.avail_out > 0) {
56719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ2_bzDecompressEnd ( &strm );
56729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return BZ_UNEXPECTED_EOF;
56739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
56749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ2_bzDecompressEnd ( &strm );
56759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return BZ_OUTBUFF_FULL;
56769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   };
56779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   errhandler:
56799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzDecompressEnd ( &strm );
56809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return ret;
56819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
56829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
56859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
56869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   Code contributed by Yoshioka Tsuneo
56879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
56889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   to support better zlib compatibility.
56899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   This code is not _officially_ part of libbzip2 (yet);
56909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   I haven't tested it, documented it, or considered the
56919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   threading-safeness of it.
56929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   If this code breaks, please contact both Yoshioka and me.
56939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
56949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
56959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
56969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
56979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
56989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return version like "0.9.0c".
56999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
57009f12f3ca9afc762f2e659179860c08d36e30f30fsewardjconst char * BZ_API(BZ2_bzlibVersion)(void)
57019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
57029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return BZ_VERSION;
57039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
57049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifndef BZ_NO_STDIO
57079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
57089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
57109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   include <fcntl.h>
57119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   include <io.h>
57129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
57139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#else
57149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#   define SET_BINARY_MODE(file)
57159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
57169f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic
57179f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZFILE * bzopen_or_bzdopen
57189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ( const char *path,   /* no use when bzdopen */
57199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 int fd,             /* no use when bzdopen */
57209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 const char *mode,
57219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 int open_mode)      /* bzopen: 0, bzdopen:1 */
57229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
57239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int    bzerr;
57249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   char   unused[BZ_MAX_UNUSED];
57259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int    blockSize100k = 9;
57269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int    writing       = 0;
57279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   char   mode2[10]     = "";
57289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   FILE   *fp           = NULL;
57299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZFILE *bzfp         = NULL;
57309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int    verbosity     = 0;
57319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int    workFactor    = 30;
57329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int    smallMode     = 0;
57339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int    nUnused       = 0;
57349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (mode == NULL) return NULL;
57369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   while (*mode) {
57379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      switch (*mode) {
57389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case 'r':
57399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         writing = 0; break;
57409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case 'w':
57419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         writing = 1; break;
57429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case 's':
57439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         smallMode = 1; break;
57449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      default:
57459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (isdigit((int)(*mode))) {
57469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj            blockSize100k = *mode-BZ_HDR_0;
57479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
57489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
57499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      mode++;
57509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
57519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strcat(mode2, writing ? "w" : "r" );
57529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   strcat(mode2,"b");   /* binary mode */
57539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (open_mode==0) {
57559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (path==NULL || strcmp(path,"")==0) {
57569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        fp = (writing ? stdout : stdin);
57579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        SET_BINARY_MODE(fp);
57589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } else {
57599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        fp = fopen(path,mode2);
57609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
57619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
57629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#ifdef BZ_STRICT_ANSI
57639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fp = NULL;
57649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#else
57659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fp = fdopen(fd,mode2);
57669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
57679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
57689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (fp == NULL) return NULL;
57699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (writing) {
57719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      /* Guard against total chaos and anarchy -- JRS */
57729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (blockSize100k < 1) blockSize100k = 1;
57739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (blockSize100k > 9) blockSize100k = 9;
57749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
57759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                             verbosity,workFactor);
57769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
57779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
57789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                            unused,nUnused);
57799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
57809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzfp == NULL) {
57819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (fp != stdin && fp != stdout) fclose(fp);
57829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return NULL;
57839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
57849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return bzfp;
57859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
57869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
57889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
57899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
57909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   open file for read or write.
57919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ex) bzopen("file","w9")
57929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      case path="" or NULL => use stdin or stdout.
57939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
57949f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZFILE * BZ_API(BZ2_bzopen)
57959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ( const char *path,
57969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 const char *mode )
57979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
57989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
57999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
58009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
58039f12f3ca9afc762f2e659179860c08d36e30f30fsewardjBZFILE * BZ_API(BZ2_bzdopen)
58049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj               ( int fd,
58059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                 const char *mode )
58069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
58079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
58089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
58099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
58129f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
58139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
58149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int bzerr, nread;
58159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
58169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nread = BZ2_bzRead(&bzerr,b,buf,len);
58179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
58189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return nread;
58199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   } else {
58209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return -1;
58219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
58229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
58239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
58269f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
58279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
58289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int bzerr;
58299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   BZ2_bzWrite(&bzerr,b,buf,len);
58319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if(bzerr == BZ_OK){
58329f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return len;
58339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }else{
58349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      return -1;
58359f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
58369f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
58379f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58399f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
58409f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint BZ_API(BZ2_bzflush) (BZFILE *b)
58419f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
58429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   /* do nothing now... */
58439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return 0;
58449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
58459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
58489f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid BZ_API(BZ2_bzclose) (BZFILE* b)
58499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
58509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int bzerr;
58519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   FILE *fp = ((bzFile *)b)->handle;
58529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (b==NULL) {return;}
58549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if(((bzFile*)b)->writing){
58559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
58569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if(bzerr != BZ_OK){
58579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
58589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
58599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }else{
58609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      BZ2_bzReadClose(&bzerr,b);
58619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
58629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if(fp!=stdin && fp!=stdout){
58639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      fclose(fp);
58649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
58659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
58669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*---------------------------------------------------*/
58699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--
58709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return last error code
58719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj--*/
58729f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic char *bzerrorstrings[] = {
58739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       "OK"
58749f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"SEQUENCE_ERROR"
58759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"PARAM_ERROR"
58769f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"MEM_ERROR"
58779f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"DATA_ERROR"
58789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"DATA_ERROR_MAGIC"
58799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"IO_ERROR"
58809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"UNEXPECTED_EOF"
58819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"OUTBUFF_FULL"
58829f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"CONFIG_ERROR"
58839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
58849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
58859f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
58869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
58879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
58889f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
58899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj};
58909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58929f12f3ca9afc762f2e659179860c08d36e30f30fsewardjconst char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
58939f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
58949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int err = ((bzFile *)b)->lastErr;
58959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
58969f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if(err>0) err = 0;
58979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   *errnum = err;
58989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   return bzerrorstrings[err*-1];
58999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
59009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
59019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
59049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*--- end                                           bzlib.c ---*/
59059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/*-------------------------------------------------------------*/
59069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59079f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
59099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/////////////////////////////////////////////////////////////////////
59109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj/* A test program written to test robustness to decompression of
59139f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   corrupted data.  Usage is
59149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       unzcrash filename
59159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   and the program will read the specified file, compress it (in memory),
59169f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   and then repeatedly decompress it, each time with a different bit of
59179f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   the compressed data inverted, so as to test all possible one-bit errors.
59189f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   This should not cause any invalid memory accesses.  If it does,
59199f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   I want to know about it!
59209f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59219f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   p.s.  As you can see from the above description, the process is
59229f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   incredibly slow.  A file of size eg 5KB will cause it to run for
59239f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   many hours.
59249f12f3ca9afc762f2e659179860c08d36e30f30fsewardj*/
59259f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59269f12f3ca9afc762f2e659179860c08d36e30f30fsewardj//#include <stdio.h>
59279f12f3ca9afc762f2e659179860c08d36e30f30fsewardj//#include <assert.h>
59289f12f3ca9afc762f2e659179860c08d36e30f30fsewardj//#include "bzlib.h"
59299f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59309f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define M_BLOCK 1000000
59319f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59329f12f3ca9afc762f2e659179860c08d36e30f30fsewardjtypedef unsigned char uchar;
59339f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59349f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#define M_BLOCK_OUT (M_BLOCK + 1000000)
59359f12f3ca9afc762f2e659179860c08d36e30f30fsewardjuchar inbuf[M_BLOCK];
59369f12f3ca9afc762f2e659179860c08d36e30f30fsewardjuchar outbuf[M_BLOCK_OUT];
59379f12f3ca9afc762f2e659179860c08d36e30f30fsewardjuchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
59389f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59399f12f3ca9afc762f2e659179860c08d36e30f30fsewardjint nIn, nOut, nZ;
59409f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59419f12f3ca9afc762f2e659179860c08d36e30f30fsewardjstatic char *bzerrorstrings[] = {
59429f12f3ca9afc762f2e659179860c08d36e30f30fsewardj       "OK"
59439f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"SEQUENCE_ERROR"
59449f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"PARAM_ERROR"
59459f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"MEM_ERROR"
59469f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"DATA_ERROR"
59479f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"DATA_ERROR_MAGIC"
59489f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"IO_ERROR"
59499f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"UNEXPECTED_EOF"
59509f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"OUTBUFF_FULL"
59519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
59529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
59539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
59549f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
59559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
59569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      ,"???"   /* for future */
59579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj};
59589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59599f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid flip_bit ( int bit )
59609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
59619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int byteno = bit / 8;
59629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int bitno  = bit % 8;
59639f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   uchar mask = 1 << bitno;
59649f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
59659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   //          byteno, bitno, (int)mask );
59669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   zbuf[byteno] ^= mask;
59679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
59689f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
59699f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid set_inbuf ( void )
59709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
59719f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  inbuf[0] = 0;
59729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj  my_strcat(inbuf, "At her sixtieth birthday party, Margaret Thatcher ");
59739dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "blew on the cake to light the candles.\n");
59749dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "This program, bzip2, the associated library libbzip2, and all\n");
59759dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "documentation, are copyright (C) 1996-2004 Julian R Seward.  All\n");
59769dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "rights reserved.\n");
59779dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "\n");
59789dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "Redistribution and use in source and binary forms, with or without\n");
59799dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "modification, are permitted provided that the following conditions\n");
59809dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "are met:\n");
59819dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "\n");
59829dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "1. Redistributions of source code must retain the above copyright\n");
59839dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "   notice, this list of conditions and the following disclaimer.\n");
59849dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "\n");
59859dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "2. The origin of this software must not be misrepresented; you must\n");
59869dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "   not claim that you wrote the original software.  If you use this\n");
59879dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "   software in a product, an acknowledgment in the product\n");
59889dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "   documentation would be appreciated but is not required.\n");
59899dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "\n");
59909dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "3. Altered source versions must be plainly marked as such, and must\n");
59919dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "   not be misrepresented as being the original software.\n");
59929dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "\n");
59939dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "4. The name of the author may not be used to endorse or promote\n");
59949dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "   products derived from this software without specific prior written\n");
59959dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "   permission.\n");
59969dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "\n");
59979dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n");
59989dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n");
59999dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n");
60009dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n");
60019dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n");
60029dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n");
60039dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n");
60049dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n");
60059dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n");
60069dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n");
60079dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n");
60089dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60099dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60109dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60119dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60129dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60139dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60149dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60159dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60169dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60179dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60189dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60199dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60209dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60219dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60229dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60239dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60249dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60259dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60269dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60279dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60289dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60299dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60309dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60319dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60329dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60339dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60349dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60359dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60369dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60379dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60389dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60399dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60409dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60419dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60429dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60439dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60449dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60459dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60469dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60479dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60489dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60499dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
60509dc4cf77abb447418edba303d29c7cb0b4361a27sewardj  my_strcat(inbuf, "\n");
60519f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
60529f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60539f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60549f12f3ca9afc762f2e659179860c08d36e30f30fsewardjvoid entry ( HWord(*service)(HWord,HWord) )
60559f12f3ca9afc762f2e659179860c08d36e30f30fsewardj{
60569f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int   r;
60579f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int   bit;
60589f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   int   i;
60599f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60609f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   serviceFn = service;
60619f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60629f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   set_inbuf();
60636ded3895778c796f141ae0324862c4bd4b021a6fcerion   nIn = vexxx_strlen(inbuf)+1;
60646ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf( "%d bytes read\n", nIn );
60659f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60669f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   nZ = M_BLOCK;
60679f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   r = BZ2_bzBuffToBuffCompress (
60689dc4cf77abb447418edba303d29c7cb0b4361a27sewardj          zbuf, &nZ, inbuf, nIn, 9, 4/*verb*/, 30 );
60699f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60709f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   if (r != BZ_OK) {
60716ded3895778c796f141ae0324862c4bd4b021a6fcerion     vexxx_printf("initial compress failed!\n");
60729f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     (*serviceFn)(0,0);
60739f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
60746ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf( "%d after compression\n", nZ );
60759f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60769dc4cf77abb447418edba303d29c7cb0b4361a27sewardj   for (bit = 0; bit < nZ*8; bit += (bit < 35 ? 1 : 377)) {
60776ded3895778c796f141ae0324862c4bd4b021a6fcerion      vexxx_printf( "bit %d  ", bit );
60789f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      flip_bit ( bit );
60799f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      nOut = M_BLOCK_OUT;
60809f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      r = BZ2_bzBuffToBuffDecompress (
60819f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             outbuf, &nOut, zbuf, nZ, 1/*small*/, 0 );
60826ded3895778c796f141ae0324862c4bd4b021a6fcerion      vexxx_printf( " %d  %s ", r, bzerrorstrings[-r] );
60839f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
60849f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      if (r != BZ_OK) {
60856ded3895778c796f141ae0324862c4bd4b021a6fcerion         vexxx_printf( "\n" );
60869f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      } else {
60879f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         if (nOut != nIn) {
60886ded3895778c796f141ae0324862c4bd4b021a6fcerion           vexxx_printf(  "nIn/nOut mismatch %d %d\n", nIn, nOut );
60899f12f3ca9afc762f2e659179860c08d36e30f30fsewardj           (*serviceFn)(0,0);
60909f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         } else {
60919f12f3ca9afc762f2e659179860c08d36e30f30fsewardj           for (i = 0; i < nOut; i++)
60929f12f3ca9afc762f2e659179860c08d36e30f30fsewardj             if (inbuf[i] != outbuf[i]) {
60936ded3895778c796f141ae0324862c4bd4b021a6fcerion                vexxx_printf(  "mismatch at %d\n", i );
60949f12f3ca9afc762f2e659179860c08d36e30f30fsewardj                (*serviceFn)(0,0);
60959f12f3ca9afc762f2e659179860c08d36e30f30fsewardj           }
60966ded3895778c796f141ae0324862c4bd4b021a6fcerion           if (i == nOut) vexxx_printf( "really ok!\n" );
60979f12f3ca9afc762f2e659179860c08d36e30f30fsewardj         }
60989f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      }
60999f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
61009f12f3ca9afc762f2e659179860c08d36e30f30fsewardj      flip_bit ( bit );
61019f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
61029f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
61039f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#if 0
61049f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   assert (nOut == nIn);
61059f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   for (i = 0; i < nOut; i++) {
61069f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     if (inbuf[i] != outbuf[i]) {
61076ded3895778c796f141ae0324862c4bd4b021a6fcerion        vexxx_printf( "difference at %d !\n", i );
61089f12f3ca9afc762f2e659179860c08d36e30f30fsewardj        return 1;
61099f12f3ca9afc762f2e659179860c08d36e30f30fsewardj     }
61109f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   }
61119f12f3ca9afc762f2e659179860c08d36e30f30fsewardj#endif
61129f12f3ca9afc762f2e659179860c08d36e30f30fsewardj
61136ded3895778c796f141ae0324862c4bd4b021a6fcerion   vexxx_printf( "all ok\n" );
61149f12f3ca9afc762f2e659179860c08d36e30f30fsewardj   (*serviceFn)(0,0);
61159f12f3ca9afc762f2e659179860c08d36e30f30fsewardj}
6116