Home | History | Annotate | Line # | Download | only in dist
      1  1.5  rillig /*	$NetBSD: bzlib.c,v 1.5 2021/08/27 17:31:48 rillig Exp $	*/
      2  1.1     wiz 
      3  1.1     wiz 
      4  1.1     wiz /*-------------------------------------------------------------*/
      5  1.1     wiz /*--- Library top-level functions.                          ---*/
      6  1.1     wiz /*---                                               bzlib.c ---*/
      7  1.1     wiz /*-------------------------------------------------------------*/
      8  1.1     wiz 
      9  1.1     wiz /* ------------------------------------------------------------------
     10  1.1     wiz    This file is part of bzip2/libbzip2, a program and library for
     11  1.1     wiz    lossless, block-sorting data compression.
     12  1.1     wiz 
     13  1.4    maya    bzip2/libbzip2 version 1.0.8 of 13 July 2019
     14  1.4    maya    Copyright (C) 1996-2019 Julian Seward <jseward (at) acm.org>
     15  1.1     wiz 
     16  1.1     wiz    Please read the WARNING, DISCLAIMER and PATENTS sections in the
     17  1.1     wiz    README file.
     18  1.1     wiz 
     19  1.1     wiz    This program is released under the terms of the license contained
     20  1.1     wiz    in the file LICENSE.
     21  1.1     wiz    ------------------------------------------------------------------ */
     22  1.1     wiz 
     23  1.1     wiz /* CHANGES
     24  1.1     wiz    0.9.0    -- original version.
     25  1.1     wiz    0.9.0a/b -- no changes in this file.
     26  1.1     wiz    0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
     27  1.1     wiz      fixed bzWrite/bzRead to ignore zero-length requests.
     28  1.1     wiz      fixed bzread to correctly handle read requests after EOF.
     29  1.1     wiz      wrong parameter order in call to bzDecompressInit in
     30  1.1     wiz      bzBuffToBuffDecompress.  Fixed.
     31  1.1     wiz */
     32  1.1     wiz 
     33  1.1     wiz #include "bzlib_private.h"
     34  1.1     wiz 
     35  1.1     wiz 
     36  1.1     wiz /*---------------------------------------------------*/
     37  1.1     wiz /*--- Compression stuff                           ---*/
     38  1.1     wiz /*---------------------------------------------------*/
     39  1.1     wiz 
     40  1.1     wiz 
     41  1.1     wiz /*---------------------------------------------------*/
     42  1.1     wiz #ifndef BZ_NO_STDIO
     43  1.1     wiz void BZ2_bz__AssertH__fail ( int errcode )
     44  1.1     wiz {
     45  1.1     wiz    fprintf(stderr,
     46  1.1     wiz       "\n\nbzip2/libbzip2: internal error number %d.\n"
     47  1.1     wiz       "This is a bug in bzip2/libbzip2, %s.\n"
     48  1.4    maya       "Please report it to: bzip2-devel (at) sourceware.org.  If this happened\n"
     49  1.1     wiz       "when you were using some program which uses libbzip2 as a\n"
     50  1.1     wiz       "component, you should also report this bug to the author(s)\n"
     51  1.1     wiz       "of that program.  Please make an effort to report this bug;\n"
     52  1.1     wiz       "timely and accurate bug reports eventually lead to higher\n"
     53  1.4    maya       "quality software.  Thanks.\n\n",
     54  1.1     wiz       errcode,
     55  1.1     wiz       BZ2_bzlibVersion()
     56  1.1     wiz    );
     57  1.1     wiz 
     58  1.1     wiz    if (errcode == 1007) {
     59  1.1     wiz    fprintf(stderr,
     60  1.1     wiz       "\n*** A special note about internal error number 1007 ***\n"
     61  1.1     wiz       "\n"
     62  1.1     wiz       "Experience suggests that a common cause of i.e. 1007\n"
     63  1.1     wiz       "is unreliable memory or other hardware.  The 1007 assertion\n"
     64  1.1     wiz       "just happens to cross-check the results of huge numbers of\n"
     65  1.1     wiz       "memory reads/writes, and so acts (unintendedly) as a stress\n"
     66  1.1     wiz       "test of your memory system.\n"
     67  1.1     wiz       "\n"
     68  1.1     wiz       "I suggest the following: try compressing the file again,\n"
     69  1.1     wiz       "possibly monitoring progress in detail with the -vv flag.\n"
     70  1.1     wiz       "\n"
     71  1.1     wiz       "* If the error cannot be reproduced, and/or happens at different\n"
     72  1.1     wiz       "  points in compression, you may have a flaky memory system.\n"
     73  1.1     wiz       "  Try a memory-test program.  I have used Memtest86\n"
     74  1.1     wiz       "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
     75  1.1     wiz       "  Memtest86 tests memory much more thorougly than your BIOSs\n"
     76  1.1     wiz       "  power-on test, and may find failures that the BIOS doesn't.\n"
     77  1.1     wiz       "\n"
     78  1.1     wiz       "* If the error can be repeatably reproduced, this is a bug in\n"
     79  1.1     wiz       "  bzip2, and I would very much like to hear about it.  Please\n"
     80  1.1     wiz       "  let me know, and, ideally, save a copy of the file causing the\n"
     81  1.1     wiz       "  problem -- without which I will be unable to investigate it.\n"
     82  1.1     wiz       "\n"
     83  1.1     wiz    );
     84  1.1     wiz    }
     85  1.1     wiz 
     86  1.1     wiz    exit(3);
     87  1.1     wiz }
     88  1.1     wiz #endif
     89  1.1     wiz 
     90  1.1     wiz 
     91  1.1     wiz /*---------------------------------------------------*/
     92  1.1     wiz static
     93  1.1     wiz int bz_config_ok ( void )
     94  1.1     wiz {
     95  1.1     wiz    if (sizeof(int)   != 4) return 0;
     96  1.1     wiz    if (sizeof(short) != 2) return 0;
     97  1.1     wiz    if (sizeof(char)  != 1) return 0;
     98  1.1     wiz    return 1;
     99  1.1     wiz }
    100  1.1     wiz 
    101  1.1     wiz 
    102  1.1     wiz /*---------------------------------------------------*/
    103  1.1     wiz static
    104  1.1     wiz void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
    105  1.1     wiz {
    106  1.1     wiz    void* v = malloc ( items * size );
    107  1.1     wiz    return v;
    108  1.1     wiz }
    109  1.1     wiz 
    110  1.1     wiz static
    111  1.1     wiz void default_bzfree ( void* opaque, void* addr )
    112  1.1     wiz {
    113  1.1     wiz    if (addr != NULL) free ( addr );
    114  1.1     wiz }
    115  1.1     wiz 
    116  1.1     wiz 
    117  1.1     wiz /*---------------------------------------------------*/
    118  1.1     wiz static
    119  1.1     wiz void prepare_new_block ( EState* s )
    120  1.1     wiz {
    121  1.1     wiz    Int32 i;
    122  1.1     wiz    s->nblock = 0;
    123  1.1     wiz    s->numZ = 0;
    124  1.1     wiz    s->state_out_pos = 0;
    125  1.1     wiz    BZ_INITIALISE_CRC ( s->blockCRC );
    126  1.1     wiz    for (i = 0; i < 256; i++) s->inUse[i] = False;
    127  1.1     wiz    s->blockNo++;
    128  1.1     wiz }
    129  1.1     wiz 
    130  1.1     wiz 
    131  1.1     wiz /*---------------------------------------------------*/
    132  1.1     wiz static
    133  1.1     wiz void init_RL ( EState* s )
    134  1.1     wiz {
    135  1.1     wiz    s->state_in_ch  = 256;
    136  1.1     wiz    s->state_in_len = 0;
    137  1.1     wiz }
    138  1.1     wiz 
    139  1.1     wiz 
    140  1.1     wiz static
    141  1.1     wiz Bool isempty_RL ( EState* s )
    142  1.1     wiz {
    143  1.1     wiz    if (s->state_in_ch < 256 && s->state_in_len > 0)
    144  1.1     wiz       return False; else
    145  1.1     wiz       return True;
    146  1.1     wiz }
    147  1.1     wiz 
    148  1.1     wiz 
    149  1.1     wiz /*---------------------------------------------------*/
    150  1.1     wiz int BZ_API(BZ2_bzCompressInit)
    151  1.1     wiz                     ( bz_stream* strm,
    152  1.1     wiz                      int        blockSize100k,
    153  1.1     wiz                      int        verbosity,
    154  1.1     wiz                      int        workFactor )
    155  1.1     wiz {
    156  1.1     wiz    Int32   n;
    157  1.1     wiz    EState* s;
    158  1.1     wiz 
    159  1.1     wiz    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
    160  1.1     wiz 
    161  1.1     wiz    if (strm == NULL ||
    162  1.1     wiz        blockSize100k < 1 || blockSize100k > 9 ||
    163  1.1     wiz        workFactor < 0 || workFactor > 250)
    164  1.1     wiz      return BZ_PARAM_ERROR;
    165  1.1     wiz 
    166  1.1     wiz    if (workFactor == 0) workFactor = 30;
    167  1.1     wiz    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
    168  1.1     wiz    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
    169  1.1     wiz 
    170  1.1     wiz    s = BZALLOC( sizeof(EState) );
    171  1.1     wiz    if (s == NULL) return BZ_MEM_ERROR;
    172  1.1     wiz    s->strm = strm;
    173  1.1     wiz 
    174  1.1     wiz    s->arr1 = NULL;
    175  1.1     wiz    s->arr2 = NULL;
    176  1.1     wiz    s->ftab = NULL;
    177  1.1     wiz 
    178  1.1     wiz    n       = 100000 * blockSize100k;
    179  1.1     wiz    s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
    180  1.1     wiz    s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
    181  1.1     wiz    s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
    182  1.1     wiz 
    183  1.1     wiz    if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
    184  1.1     wiz       if (s->arr1 != NULL) BZFREE(s->arr1);
    185  1.1     wiz       if (s->arr2 != NULL) BZFREE(s->arr2);
    186  1.1     wiz       if (s->ftab != NULL) BZFREE(s->ftab);
    187  1.1     wiz       if (s       != NULL) BZFREE(s);
    188  1.1     wiz       return BZ_MEM_ERROR;
    189  1.1     wiz    }
    190  1.1     wiz 
    191  1.1     wiz    s->blockNo           = 0;
    192  1.1     wiz    s->state             = BZ_S_INPUT;
    193  1.1     wiz    s->mode              = BZ_M_RUNNING;
    194  1.1     wiz    s->combinedCRC       = 0;
    195  1.1     wiz    s->blockSize100k     = blockSize100k;
    196  1.1     wiz    s->nblockMAX         = 100000 * blockSize100k - 19;
    197  1.1     wiz    s->verbosity         = verbosity;
    198  1.1     wiz    s->workFactor        = workFactor;
    199  1.1     wiz 
    200  1.1     wiz    s->block             = (UChar*)s->arr2;
    201  1.1     wiz    s->mtfv              = (UInt16*)s->arr1;
    202  1.1     wiz    s->zbits             = NULL;
    203  1.1     wiz    s->ptr               = (UInt32*)s->arr1;
    204  1.1     wiz 
    205  1.1     wiz    strm->state          = s;
    206  1.1     wiz    strm->total_in_lo32  = 0;
    207  1.1     wiz    strm->total_in_hi32  = 0;
    208  1.1     wiz    strm->total_out_lo32 = 0;
    209  1.1     wiz    strm->total_out_hi32 = 0;
    210  1.1     wiz    init_RL ( s );
    211  1.1     wiz    prepare_new_block ( s );
    212  1.1     wiz    return BZ_OK;
    213  1.1     wiz }
    214  1.1     wiz 
    215  1.1     wiz 
    216  1.1     wiz /*---------------------------------------------------*/
    217  1.1     wiz static
    218  1.1     wiz void add_pair_to_block ( EState* s )
    219  1.1     wiz {
    220  1.1     wiz    Int32 i;
    221  1.1     wiz    UChar ch = (UChar)(s->state_in_ch);
    222  1.1     wiz    for (i = 0; i < s->state_in_len; i++) {
    223  1.1     wiz       BZ_UPDATE_CRC( s->blockCRC, ch );
    224  1.1     wiz    }
    225  1.1     wiz    s->inUse[s->state_in_ch] = True;
    226  1.1     wiz    switch (s->state_in_len) {
    227  1.1     wiz       case 1:
    228  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    229  1.1     wiz          break;
    230  1.1     wiz       case 2:
    231  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    232  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    233  1.1     wiz          break;
    234  1.1     wiz       case 3:
    235  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    236  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    237  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    238  1.1     wiz          break;
    239  1.1     wiz       default:
    240  1.1     wiz          s->inUse[s->state_in_len-4] = True;
    241  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    242  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    243  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    244  1.1     wiz          s->block[s->nblock] = (UChar)ch; s->nblock++;
    245  1.1     wiz          s->block[s->nblock] = ((UChar)(s->state_in_len-4));
    246  1.1     wiz          s->nblock++;
    247  1.1     wiz          break;
    248  1.1     wiz    }
    249  1.1     wiz }
    250  1.1     wiz 
    251  1.1     wiz 
    252  1.1     wiz /*---------------------------------------------------*/
    253  1.1     wiz static
    254  1.1     wiz void flush_RL ( EState* s )
    255  1.1     wiz {
    256  1.1     wiz    if (s->state_in_ch < 256) add_pair_to_block ( s );
    257  1.1     wiz    init_RL ( s );
    258  1.1     wiz }
    259  1.1     wiz 
    260  1.1     wiz 
    261  1.1     wiz /*---------------------------------------------------*/
    262  1.1     wiz #define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
    263  1.1     wiz {                                                 \
    264  1.1     wiz    UInt32 zchh = (UInt32)(zchh0);                 \
    265  1.1     wiz    /*-- fast track the common case --*/           \
    266  1.1     wiz    if (zchh != zs->state_in_ch &&                 \
    267  1.1     wiz        zs->state_in_len == 1) {                   \
    268  1.1     wiz       UChar ch = (UChar)(zs->state_in_ch);        \
    269  1.1     wiz       BZ_UPDATE_CRC( zs->blockCRC, ch );          \
    270  1.1     wiz       zs->inUse[zs->state_in_ch] = True;          \
    271  1.1     wiz       zs->block[zs->nblock] = (UChar)ch;          \
    272  1.1     wiz       zs->nblock++;                               \
    273  1.1     wiz       zs->state_in_ch = zchh;                     \
    274  1.1     wiz    }                                              \
    275  1.1     wiz    else                                           \
    276  1.1     wiz    /*-- general, uncommon cases --*/              \
    277  1.1     wiz    if (zchh != zs->state_in_ch ||                 \
    278  1.1     wiz       zs->state_in_len == 255) {                  \
    279  1.1     wiz       if (zs->state_in_ch < 256)                  \
    280  1.1     wiz          add_pair_to_block ( zs );                \
    281  1.1     wiz       zs->state_in_ch = zchh;                     \
    282  1.1     wiz       zs->state_in_len = 1;                       \
    283  1.1     wiz    } else {                                       \
    284  1.1     wiz       zs->state_in_len++;                         \
    285  1.1     wiz    }                                              \
    286  1.1     wiz }
    287  1.1     wiz 
    288  1.1     wiz 
    289  1.1     wiz /*---------------------------------------------------*/
    290  1.1     wiz static
    291  1.1     wiz Bool copy_input_until_stop ( EState* s )
    292  1.1     wiz {
    293  1.1     wiz    Bool progress_in = False;
    294  1.1     wiz 
    295  1.1     wiz    if (s->mode == BZ_M_RUNNING) {
    296  1.1     wiz 
    297  1.1     wiz       /*-- fast track the common case --*/
    298  1.1     wiz       while (True) {
    299  1.1     wiz          /*-- block full? --*/
    300  1.1     wiz          if (s->nblock >= s->nblockMAX) break;
    301  1.1     wiz          /*-- no input? --*/
    302  1.1     wiz          if (s->strm->avail_in == 0) break;
    303  1.1     wiz          progress_in = True;
    304  1.1     wiz          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
    305  1.1     wiz          s->strm->next_in++;
    306  1.1     wiz          s->strm->avail_in--;
    307  1.1     wiz          s->strm->total_in_lo32++;
    308  1.1     wiz          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
    309  1.1     wiz       }
    310  1.1     wiz 
    311  1.1     wiz    } else {
    312  1.1     wiz 
    313  1.1     wiz       /*-- general, uncommon case --*/
    314  1.1     wiz       while (True) {
    315  1.1     wiz          /*-- block full? --*/
    316  1.1     wiz          if (s->nblock >= s->nblockMAX) break;
    317  1.1     wiz          /*-- no input? --*/
    318  1.1     wiz          if (s->strm->avail_in == 0) break;
    319  1.1     wiz          /*-- flush/finish end? --*/
    320  1.1     wiz          if (s->avail_in_expect == 0) break;
    321  1.1     wiz          progress_in = True;
    322  1.1     wiz          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
    323  1.1     wiz          s->strm->next_in++;
    324  1.1     wiz          s->strm->avail_in--;
    325  1.1     wiz          s->strm->total_in_lo32++;
    326  1.1     wiz          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
    327  1.1     wiz          s->avail_in_expect--;
    328  1.1     wiz       }
    329  1.1     wiz    }
    330  1.1     wiz    return progress_in;
    331  1.1     wiz }
    332  1.1     wiz 
    333  1.1     wiz 
    334  1.1     wiz /*---------------------------------------------------*/
    335  1.1     wiz static
    336  1.1     wiz Bool copy_output_until_stop ( EState* s )
    337  1.1     wiz {
    338  1.1     wiz    Bool progress_out = False;
    339  1.1     wiz 
    340  1.1     wiz    while (True) {
    341  1.1     wiz 
    342  1.1     wiz       /*-- no output space? --*/
    343  1.1     wiz       if (s->strm->avail_out == 0) break;
    344  1.1     wiz 
    345  1.1     wiz       /*-- block done? --*/
    346  1.1     wiz       if (s->state_out_pos >= s->numZ) break;
    347  1.1     wiz 
    348  1.1     wiz       progress_out = True;
    349  1.1     wiz       *(s->strm->next_out) = s->zbits[s->state_out_pos];
    350  1.1     wiz       s->state_out_pos++;
    351  1.1     wiz       s->strm->avail_out--;
    352  1.1     wiz       s->strm->next_out++;
    353  1.1     wiz       s->strm->total_out_lo32++;
    354  1.1     wiz       if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
    355  1.1     wiz    }
    356  1.1     wiz 
    357  1.1     wiz    return progress_out;
    358  1.1     wiz }
    359  1.1     wiz 
    360  1.1     wiz 
    361  1.1     wiz /*---------------------------------------------------*/
    362  1.1     wiz static
    363  1.1     wiz Bool handle_compress ( bz_stream* strm )
    364  1.1     wiz {
    365  1.1     wiz    Bool progress_in  = False;
    366  1.1     wiz    Bool progress_out = False;
    367  1.1     wiz    EState* s = strm->state;
    368  1.1     wiz 
    369  1.1     wiz    while (True) {
    370  1.1     wiz 
    371  1.1     wiz       if (s->state == BZ_S_OUTPUT) {
    372  1.1     wiz          progress_out |= copy_output_until_stop ( s );
    373  1.1     wiz          if (s->state_out_pos < s->numZ) break;
    374  1.1     wiz          if (s->mode == BZ_M_FINISHING &&
    375  1.1     wiz              s->avail_in_expect == 0 &&
    376  1.1     wiz              isempty_RL(s)) break;
    377  1.1     wiz          prepare_new_block ( s );
    378  1.1     wiz          s->state = BZ_S_INPUT;
    379  1.1     wiz          if (s->mode == BZ_M_FLUSHING &&
    380  1.1     wiz              s->avail_in_expect == 0 &&
    381  1.1     wiz              isempty_RL(s)) break;
    382  1.1     wiz       }
    383  1.1     wiz 
    384  1.1     wiz       if (s->state == BZ_S_INPUT) {
    385  1.1     wiz          progress_in |= copy_input_until_stop ( s );
    386  1.1     wiz          if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
    387  1.1     wiz             flush_RL ( s );
    388  1.1     wiz             BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
    389  1.1     wiz             s->state = BZ_S_OUTPUT;
    390  1.1     wiz          }
    391  1.1     wiz          else
    392  1.1     wiz          if (s->nblock >= s->nblockMAX) {
    393  1.1     wiz             BZ2_compressBlock ( s, False );
    394  1.1     wiz             s->state = BZ_S_OUTPUT;
    395  1.1     wiz          }
    396  1.1     wiz          else
    397  1.1     wiz          if (s->strm->avail_in == 0) {
    398  1.1     wiz             break;
    399  1.1     wiz          }
    400  1.1     wiz       }
    401  1.1     wiz 
    402  1.1     wiz    }
    403  1.1     wiz 
    404  1.1     wiz    return progress_in || progress_out;
    405  1.1     wiz }
    406  1.1     wiz 
    407  1.1     wiz 
    408  1.1     wiz /*---------------------------------------------------*/
    409  1.1     wiz int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
    410  1.1     wiz {
    411  1.1     wiz    Bool progress;
    412  1.1     wiz    EState* s;
    413  1.1     wiz    if (strm == NULL) return BZ_PARAM_ERROR;
    414  1.1     wiz    s = strm->state;
    415  1.1     wiz    if (s == NULL) return BZ_PARAM_ERROR;
    416  1.1     wiz    if (s->strm != strm) return BZ_PARAM_ERROR;
    417  1.1     wiz 
    418  1.1     wiz    preswitch:
    419  1.1     wiz    switch (s->mode) {
    420  1.1     wiz 
    421  1.1     wiz       case BZ_M_IDLE:
    422  1.1     wiz          return BZ_SEQUENCE_ERROR;
    423  1.1     wiz 
    424  1.1     wiz       case BZ_M_RUNNING:
    425  1.1     wiz          if (action == BZ_RUN) {
    426  1.1     wiz             progress = handle_compress ( strm );
    427  1.1     wiz             return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
    428  1.1     wiz          }
    429  1.1     wiz          else
    430  1.1     wiz 	 if (action == BZ_FLUSH) {
    431  1.1     wiz             s->avail_in_expect = strm->avail_in;
    432  1.1     wiz             s->mode = BZ_M_FLUSHING;
    433  1.1     wiz             goto preswitch;
    434  1.1     wiz          }
    435  1.1     wiz          else
    436  1.1     wiz          if (action == BZ_FINISH) {
    437  1.1     wiz             s->avail_in_expect = strm->avail_in;
    438  1.1     wiz             s->mode = BZ_M_FINISHING;
    439  1.1     wiz             goto preswitch;
    440  1.1     wiz          }
    441  1.1     wiz          else
    442  1.1     wiz             return BZ_PARAM_ERROR;
    443  1.1     wiz 
    444  1.1     wiz       case BZ_M_FLUSHING:
    445  1.1     wiz          if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
    446  1.1     wiz          if (s->avail_in_expect != s->strm->avail_in)
    447  1.1     wiz             return BZ_SEQUENCE_ERROR;
    448  1.1     wiz          progress = handle_compress ( strm );
    449  1.1     wiz          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
    450  1.1     wiz              s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
    451  1.1     wiz          s->mode = BZ_M_RUNNING;
    452  1.1     wiz          return BZ_RUN_OK;
    453  1.1     wiz 
    454  1.1     wiz       case BZ_M_FINISHING:
    455  1.1     wiz          if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
    456  1.1     wiz          if (s->avail_in_expect != s->strm->avail_in)
    457  1.1     wiz             return BZ_SEQUENCE_ERROR;
    458  1.1     wiz          progress = handle_compress ( strm );
    459  1.1     wiz          if (!progress) return BZ_SEQUENCE_ERROR;
    460  1.1     wiz          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
    461  1.1     wiz              s->state_out_pos < s->numZ) return BZ_FINISH_OK;
    462  1.1     wiz          s->mode = BZ_M_IDLE;
    463  1.1     wiz          return BZ_STREAM_END;
    464  1.1     wiz    }
    465  1.1     wiz    return BZ_OK; /*--not reached--*/
    466  1.1     wiz }
    467  1.1     wiz 
    468  1.1     wiz 
    469  1.1     wiz /*---------------------------------------------------*/
    470  1.1     wiz int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
    471  1.1     wiz {
    472  1.1     wiz    EState* s;
    473  1.1     wiz    if (strm == NULL) return BZ_PARAM_ERROR;
    474  1.1     wiz    s = strm->state;
    475  1.1     wiz    if (s == NULL) return BZ_PARAM_ERROR;
    476  1.1     wiz    if (s->strm != strm) return BZ_PARAM_ERROR;
    477  1.1     wiz 
    478  1.1     wiz    if (s->arr1 != NULL) BZFREE(s->arr1);
    479  1.1     wiz    if (s->arr2 != NULL) BZFREE(s->arr2);
    480  1.1     wiz    if (s->ftab != NULL) BZFREE(s->ftab);
    481  1.1     wiz    BZFREE(strm->state);
    482  1.1     wiz 
    483  1.1     wiz    strm->state = NULL;
    484  1.1     wiz 
    485  1.1     wiz    return BZ_OK;
    486  1.1     wiz }
    487  1.1     wiz 
    488  1.1     wiz 
    489  1.1     wiz /*---------------------------------------------------*/
    490  1.1     wiz /*--- Decompression stuff                         ---*/
    491  1.1     wiz /*---------------------------------------------------*/
    492  1.1     wiz 
    493  1.1     wiz /*---------------------------------------------------*/
    494  1.1     wiz int BZ_API(BZ2_bzDecompressInit)
    495  1.1     wiz                      ( bz_stream* strm,
    496  1.1     wiz                        int        verbosity,
    497  1.1     wiz                        int        small )
    498  1.1     wiz {
    499  1.1     wiz    DState* s;
    500  1.1     wiz 
    501  1.1     wiz    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
    502  1.1     wiz 
    503  1.1     wiz    if (strm == NULL) return BZ_PARAM_ERROR;
    504  1.1     wiz    if (small != 0 && small != 1) return BZ_PARAM_ERROR;
    505  1.1     wiz    if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
    506  1.1     wiz 
    507  1.1     wiz    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
    508  1.1     wiz    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
    509  1.1     wiz 
    510  1.1     wiz    s = BZALLOC( sizeof(DState) );
    511  1.1     wiz    if (s == NULL) return BZ_MEM_ERROR;
    512  1.1     wiz    s->strm                  = strm;
    513  1.1     wiz    strm->state              = s;
    514  1.1     wiz    s->state                 = BZ_X_MAGIC_1;
    515  1.1     wiz    s->bsLive                = 0;
    516  1.1     wiz    s->bsBuff                = 0;
    517  1.1     wiz    s->calculatedCombinedCRC = 0;
    518  1.1     wiz    strm->total_in_lo32      = 0;
    519  1.1     wiz    strm->total_in_hi32      = 0;
    520  1.1     wiz    strm->total_out_lo32     = 0;
    521  1.1     wiz    strm->total_out_hi32     = 0;
    522  1.1     wiz    s->smallDecompress       = (Bool)small;
    523  1.1     wiz    s->ll4                   = NULL;
    524  1.1     wiz    s->ll16                  = NULL;
    525  1.1     wiz    s->tt                    = NULL;
    526  1.1     wiz    s->currBlockNo           = 0;
    527  1.1     wiz    s->verbosity             = verbosity;
    528  1.1     wiz 
    529  1.1     wiz    return BZ_OK;
    530  1.1     wiz }
    531  1.1     wiz 
    532  1.1     wiz 
    533  1.1     wiz /*---------------------------------------------------*/
    534  1.1     wiz /* Return  True iff data corruption is discovered.
    535  1.1     wiz    Returns False if there is no problem.
    536  1.1     wiz */
    537  1.1     wiz static
    538  1.1     wiz Bool unRLE_obuf_to_output_FAST ( DState* s )
    539  1.1     wiz {
    540  1.1     wiz    UChar k1;
    541  1.1     wiz 
    542  1.1     wiz    if (s->blockRandomised) {
    543  1.1     wiz 
    544  1.1     wiz       while (True) {
    545  1.1     wiz          /* try to finish existing run */
    546  1.1     wiz          while (True) {
    547  1.1     wiz             if (s->strm->avail_out == 0) return False;
    548  1.1     wiz             if (s->state_out_len == 0) break;
    549  1.1     wiz             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
    550  1.1     wiz             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
    551  1.1     wiz             s->state_out_len--;
    552  1.1     wiz             s->strm->next_out++;
    553  1.1     wiz             s->strm->avail_out--;
    554  1.1     wiz             s->strm->total_out_lo32++;
    555  1.1     wiz             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
    556  1.1     wiz          }
    557  1.1     wiz 
    558  1.1     wiz          /* can a new run be started? */
    559  1.1     wiz          if (s->nblock_used == s->save_nblock+1) return False;
    560  1.1     wiz 
    561  1.1     wiz          /* Only caused by corrupt data stream? */
    562  1.1     wiz          if (s->nblock_used > s->save_nblock+1)
    563  1.1     wiz             return True;
    564  1.1     wiz 
    565  1.1     wiz          s->state_out_len = 1;
    566  1.1     wiz          s->state_out_ch = s->k0;
    567  1.1     wiz          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
    568  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    569  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    570  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    571  1.1     wiz 
    572  1.1     wiz          s->state_out_len = 2;
    573  1.1     wiz          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
    574  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    575  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    576  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    577  1.1     wiz 
    578  1.1     wiz          s->state_out_len = 3;
    579  1.1     wiz          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
    580  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    581  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    582  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    583  1.1     wiz 
    584  1.1     wiz          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
    585  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    586  1.1     wiz          s->state_out_len = ((Int32)k1) + 4;
    587  1.1     wiz          BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
    588  1.1     wiz          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
    589  1.1     wiz       }
    590  1.1     wiz 
    591  1.1     wiz    } else {
    592  1.1     wiz 
    593  1.1     wiz       /* restore */
    594  1.1     wiz       UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
    595  1.1     wiz       UChar         c_state_out_ch       = s->state_out_ch;
    596  1.1     wiz       Int32         c_state_out_len      = s->state_out_len;
    597  1.1     wiz       Int32         c_nblock_used        = s->nblock_used;
    598  1.1     wiz       Int32         c_k0                 = s->k0;
    599  1.1     wiz       UInt32*       c_tt                 = s->tt;
    600  1.1     wiz       UInt32        c_tPos               = s->tPos;
    601  1.1     wiz       char*         cs_next_out          = s->strm->next_out;
    602  1.1     wiz       unsigned int  cs_avail_out         = s->strm->avail_out;
    603  1.1     wiz       Int32         ro_blockSize100k     = s->blockSize100k;
    604  1.1     wiz       /* end restore */
    605  1.1     wiz 
    606  1.1     wiz       UInt32       avail_out_INIT = cs_avail_out;
    607  1.1     wiz       Int32        s_save_nblockPP = s->save_nblock+1;
    608  1.1     wiz       unsigned int total_out_lo32_old;
    609  1.1     wiz 
    610  1.1     wiz       while (True) {
    611  1.1     wiz 
    612  1.1     wiz          /* try to finish existing run */
    613  1.1     wiz          if (c_state_out_len > 0) {
    614  1.1     wiz             while (True) {
    615  1.1     wiz                if (cs_avail_out == 0) goto return_notr;
    616  1.1     wiz                if (c_state_out_len == 1) break;
    617  1.1     wiz                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
    618  1.1     wiz                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
    619  1.1     wiz                c_state_out_len--;
    620  1.1     wiz                cs_next_out++;
    621  1.1     wiz                cs_avail_out--;
    622  1.1     wiz             }
    623  1.1     wiz             s_state_out_len_eq_one:
    624  1.1     wiz             {
    625  1.1     wiz                if (cs_avail_out == 0) {
    626  1.1     wiz                   c_state_out_len = 1; goto return_notr;
    627  1.1     wiz                };
    628  1.1     wiz                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
    629  1.1     wiz                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
    630  1.1     wiz                cs_next_out++;
    631  1.1     wiz                cs_avail_out--;
    632  1.1     wiz             }
    633  1.1     wiz          }
    634  1.1     wiz          /* Only caused by corrupt data stream? */
    635  1.1     wiz          if (c_nblock_used > s_save_nblockPP)
    636  1.1     wiz             return True;
    637  1.1     wiz 
    638  1.1     wiz          /* can a new run be started? */
    639  1.1     wiz          if (c_nblock_used == s_save_nblockPP) {
    640  1.1     wiz             c_state_out_len = 0; goto return_notr;
    641  1.1     wiz          };
    642  1.1     wiz          c_state_out_ch = c_k0;
    643  1.1     wiz          BZ_GET_FAST_C(k1); c_nblock_used++;
    644  1.1     wiz          if (k1 != c_k0) {
    645  1.1     wiz             c_k0 = k1; goto s_state_out_len_eq_one;
    646  1.1     wiz          };
    647  1.1     wiz          if (c_nblock_used == s_save_nblockPP)
    648  1.1     wiz             goto s_state_out_len_eq_one;
    649  1.1     wiz 
    650  1.1     wiz          c_state_out_len = 2;
    651  1.1     wiz          BZ_GET_FAST_C(k1); c_nblock_used++;
    652  1.1     wiz          if (c_nblock_used == s_save_nblockPP) continue;
    653  1.1     wiz          if (k1 != c_k0) { c_k0 = k1; continue; };
    654  1.1     wiz 
    655  1.1     wiz          c_state_out_len = 3;
    656  1.1     wiz          BZ_GET_FAST_C(k1); c_nblock_used++;
    657  1.1     wiz          if (c_nblock_used == s_save_nblockPP) continue;
    658  1.1     wiz          if (k1 != c_k0) { c_k0 = k1; continue; };
    659  1.1     wiz 
    660  1.1     wiz          BZ_GET_FAST_C(k1); c_nblock_used++;
    661  1.1     wiz          c_state_out_len = ((Int32)k1) + 4;
    662  1.1     wiz          BZ_GET_FAST_C(c_k0); c_nblock_used++;
    663  1.1     wiz       }
    664  1.1     wiz 
    665  1.1     wiz       return_notr:
    666  1.1     wiz       total_out_lo32_old = s->strm->total_out_lo32;
    667  1.1     wiz       s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
    668  1.1     wiz       if (s->strm->total_out_lo32 < total_out_lo32_old)
    669  1.1     wiz          s->strm->total_out_hi32++;
    670  1.1     wiz 
    671  1.1     wiz       /* save */
    672  1.1     wiz       s->calculatedBlockCRC = c_calculatedBlockCRC;
    673  1.1     wiz       s->state_out_ch       = c_state_out_ch;
    674  1.1     wiz       s->state_out_len      = c_state_out_len;
    675  1.1     wiz       s->nblock_used        = c_nblock_used;
    676  1.1     wiz       s->k0                 = c_k0;
    677  1.1     wiz       s->tt                 = c_tt;
    678  1.1     wiz       s->tPos               = c_tPos;
    679  1.1     wiz       s->strm->next_out     = cs_next_out;
    680  1.1     wiz       s->strm->avail_out    = cs_avail_out;
    681  1.1     wiz       /* end save */
    682  1.1     wiz    }
    683  1.1     wiz    return False;
    684  1.1     wiz }
    685  1.1     wiz 
    686  1.1     wiz 
    687  1.1     wiz 
    688  1.1     wiz /*---------------------------------------------------*/
    689  1.1     wiz __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
    690  1.1     wiz {
    691  1.1     wiz    Int32 nb, na, mid;
    692  1.1     wiz    nb = 0;
    693  1.1     wiz    na = 256;
    694  1.1     wiz    do {
    695  1.1     wiz       mid = (nb + na) >> 1;
    696  1.1     wiz       if (indx >= cftab[mid]) nb = mid; else na = mid;
    697  1.1     wiz    }
    698  1.1     wiz    while (na - nb != 1);
    699  1.1     wiz    return nb;
    700  1.1     wiz }
    701  1.1     wiz 
    702  1.1     wiz 
    703  1.1     wiz /*---------------------------------------------------*/
    704  1.1     wiz /* Return  True iff data corruption is discovered.
    705  1.1     wiz    Returns False if there is no problem.
    706  1.1     wiz */
    707  1.1     wiz static
    708  1.1     wiz Bool unRLE_obuf_to_output_SMALL ( DState* s )
    709  1.1     wiz {
    710  1.1     wiz    UChar k1;
    711  1.1     wiz 
    712  1.1     wiz    if (s->blockRandomised) {
    713  1.1     wiz 
    714  1.1     wiz       while (True) {
    715  1.1     wiz          /* try to finish existing run */
    716  1.1     wiz          while (True) {
    717  1.1     wiz             if (s->strm->avail_out == 0) return False;
    718  1.1     wiz             if (s->state_out_len == 0) break;
    719  1.1     wiz             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
    720  1.1     wiz             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
    721  1.1     wiz             s->state_out_len--;
    722  1.1     wiz             s->strm->next_out++;
    723  1.1     wiz             s->strm->avail_out--;
    724  1.1     wiz             s->strm->total_out_lo32++;
    725  1.1     wiz             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
    726  1.1     wiz          }
    727  1.1     wiz 
    728  1.1     wiz          /* can a new run be started? */
    729  1.1     wiz          if (s->nblock_used == s->save_nblock+1) return False;
    730  1.1     wiz 
    731  1.1     wiz          /* Only caused by corrupt data stream? */
    732  1.1     wiz          if (s->nblock_used > s->save_nblock+1)
    733  1.1     wiz             return True;
    734  1.1     wiz 
    735  1.1     wiz          s->state_out_len = 1;
    736  1.1     wiz          s->state_out_ch = s->k0;
    737  1.1     wiz          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
    738  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    739  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    740  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    741  1.1     wiz 
    742  1.1     wiz          s->state_out_len = 2;
    743  1.1     wiz          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
    744  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    745  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    746  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    747  1.1     wiz 
    748  1.1     wiz          s->state_out_len = 3;
    749  1.1     wiz          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
    750  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    751  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    752  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    753  1.1     wiz 
    754  1.1     wiz          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
    755  1.1     wiz          k1 ^= BZ_RAND_MASK; s->nblock_used++;
    756  1.1     wiz          s->state_out_len = ((Int32)k1) + 4;
    757  1.1     wiz          BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
    758  1.1     wiz          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
    759  1.1     wiz       }
    760  1.1     wiz 
    761  1.1     wiz    } else {
    762  1.1     wiz 
    763  1.1     wiz       while (True) {
    764  1.1     wiz          /* try to finish existing run */
    765  1.1     wiz          while (True) {
    766  1.1     wiz             if (s->strm->avail_out == 0) return False;
    767  1.1     wiz             if (s->state_out_len == 0) break;
    768  1.1     wiz             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
    769  1.1     wiz             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
    770  1.1     wiz             s->state_out_len--;
    771  1.1     wiz             s->strm->next_out++;
    772  1.1     wiz             s->strm->avail_out--;
    773  1.1     wiz             s->strm->total_out_lo32++;
    774  1.1     wiz             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
    775  1.1     wiz          }
    776  1.1     wiz 
    777  1.1     wiz          /* can a new run be started? */
    778  1.1     wiz          if (s->nblock_used == s->save_nblock+1) return False;
    779  1.1     wiz 
    780  1.1     wiz          /* Only caused by corrupt data stream? */
    781  1.1     wiz          if (s->nblock_used > s->save_nblock+1)
    782  1.1     wiz             return True;
    783  1.1     wiz 
    784  1.1     wiz          s->state_out_len = 1;
    785  1.1     wiz          s->state_out_ch = s->k0;
    786  1.1     wiz          BZ_GET_SMALL(k1); s->nblock_used++;
    787  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    788  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    789  1.1     wiz 
    790  1.1     wiz          s->state_out_len = 2;
    791  1.1     wiz          BZ_GET_SMALL(k1); s->nblock_used++;
    792  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    793  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    794  1.1     wiz 
    795  1.1     wiz          s->state_out_len = 3;
    796  1.1     wiz          BZ_GET_SMALL(k1); s->nblock_used++;
    797  1.1     wiz          if (s->nblock_used == s->save_nblock+1) continue;
    798  1.1     wiz          if (k1 != s->k0) { s->k0 = k1; continue; };
    799  1.1     wiz 
    800  1.1     wiz          BZ_GET_SMALL(k1); s->nblock_used++;
    801  1.1     wiz          s->state_out_len = ((Int32)k1) + 4;
    802  1.1     wiz          BZ_GET_SMALL(s->k0); s->nblock_used++;
    803  1.1     wiz       }
    804  1.1     wiz 
    805  1.1     wiz    }
    806  1.1     wiz }
    807  1.1     wiz 
    808  1.1     wiz 
    809  1.1     wiz /*---------------------------------------------------*/
    810  1.1     wiz int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
    811  1.1     wiz {
    812  1.1     wiz    Bool    corrupt;
    813  1.1     wiz    DState* s;
    814  1.1     wiz    if (strm == NULL) return BZ_PARAM_ERROR;
    815  1.1     wiz    s = strm->state;
    816  1.1     wiz    if (s == NULL) return BZ_PARAM_ERROR;
    817  1.1     wiz    if (s->strm != strm) return BZ_PARAM_ERROR;
    818  1.1     wiz 
    819  1.1     wiz    while (True) {
    820  1.1     wiz       if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
    821  1.1     wiz       if (s->state == BZ_X_OUTPUT) {
    822  1.1     wiz          if (s->smallDecompress)
    823  1.1     wiz             corrupt = unRLE_obuf_to_output_SMALL ( s ); else
    824  1.1     wiz             corrupt = unRLE_obuf_to_output_FAST  ( s );
    825  1.1     wiz          if (corrupt) return BZ_DATA_ERROR;
    826  1.1     wiz          if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
    827  1.1     wiz             BZ_FINALISE_CRC ( s->calculatedBlockCRC );
    828  1.1     wiz             if (s->verbosity >= 3)
    829  1.1     wiz                VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
    830  1.1     wiz                           s->calculatedBlockCRC );
    831  1.1     wiz             if (s->verbosity >= 2) VPrintf0 ( "]" );
    832  1.1     wiz             if (s->calculatedBlockCRC != s->storedBlockCRC)
    833  1.1     wiz                return BZ_DATA_ERROR;
    834  1.1     wiz             s->calculatedCombinedCRC
    835  1.1     wiz                = (s->calculatedCombinedCRC << 1) |
    836  1.1     wiz                     (s->calculatedCombinedCRC >> 31);
    837  1.1     wiz             s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
    838  1.1     wiz             s->state = BZ_X_BLKHDR_1;
    839  1.1     wiz          } else {
    840  1.1     wiz             return BZ_OK;
    841  1.1     wiz          }
    842  1.1     wiz       }
    843  1.1     wiz       if (s->state >= BZ_X_MAGIC_1) {
    844  1.1     wiz          Int32 r = BZ2_decompress ( s );
    845  1.1     wiz          if (r == BZ_STREAM_END) {
    846  1.1     wiz             if (s->verbosity >= 3)
    847  1.1     wiz                VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
    848  1.1     wiz                           s->storedCombinedCRC, s->calculatedCombinedCRC );
    849  1.1     wiz             if (s->calculatedCombinedCRC != s->storedCombinedCRC)
    850  1.1     wiz                return BZ_DATA_ERROR;
    851  1.1     wiz             return r;
    852  1.1     wiz          }
    853  1.1     wiz          if (s->state != BZ_X_OUTPUT) return r;
    854  1.1     wiz       }
    855  1.1     wiz    }
    856  1.1     wiz 
    857  1.1     wiz    AssertH ( 0, 6001 );
    858  1.1     wiz 
    859  1.1     wiz    return 0;  /*NOTREACHED*/
    860  1.1     wiz }
    861  1.1     wiz 
    862  1.1     wiz 
    863  1.1     wiz /*---------------------------------------------------*/
    864  1.1     wiz int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
    865  1.1     wiz {
    866  1.1     wiz    DState* s;
    867  1.1     wiz    if (strm == NULL) return BZ_PARAM_ERROR;
    868  1.1     wiz    s = strm->state;
    869  1.1     wiz    if (s == NULL) return BZ_PARAM_ERROR;
    870  1.1     wiz    if (s->strm != strm) return BZ_PARAM_ERROR;
    871  1.1     wiz 
    872  1.1     wiz    if (s->tt   != NULL) BZFREE(s->tt);
    873  1.1     wiz    if (s->ll16 != NULL) BZFREE(s->ll16);
    874  1.1     wiz    if (s->ll4  != NULL) BZFREE(s->ll4);
    875  1.1     wiz 
    876  1.1     wiz    BZFREE(strm->state);
    877  1.1     wiz    strm->state = NULL;
    878  1.1     wiz 
    879  1.1     wiz    return BZ_OK;
    880  1.1     wiz }
    881  1.1     wiz 
    882  1.1     wiz 
    883  1.1     wiz #ifndef BZ_NO_STDIO
    884  1.1     wiz /*---------------------------------------------------*/
    885  1.1     wiz /*--- File I/O stuff                              ---*/
    886  1.1     wiz /*---------------------------------------------------*/
    887  1.1     wiz 
    888  1.1     wiz #define BZ_SETERR(eee)                    \
    889  1.1     wiz {                                         \
    890  1.1     wiz    if (bzerror != NULL) *bzerror = eee;   \
    891  1.1     wiz    if (bzf != NULL) bzf->lastErr = eee;   \
    892  1.1     wiz }
    893  1.1     wiz 
    894  1.1     wiz typedef
    895  1.1     wiz    struct {
    896  1.1     wiz       FILE*     handle;
    897  1.1     wiz       Char      buf[BZ_MAX_UNUSED];
    898  1.1     wiz       Int32     bufN;
    899  1.1     wiz       Bool      writing;
    900  1.1     wiz       bz_stream strm;
    901  1.1     wiz       Int32     lastErr;
    902  1.1     wiz       Bool      initialisedOk;
    903  1.1     wiz    }
    904  1.1     wiz    bzFile;
    905  1.1     wiz 
    906  1.1     wiz 
    907  1.1     wiz /*---------------------------------------------*/
    908  1.1     wiz static Bool myfeof ( FILE* f )
    909  1.1     wiz {
    910  1.1     wiz    Int32 c = fgetc ( f );
    911  1.1     wiz    if (c == EOF) return True;
    912  1.1     wiz    ungetc ( c, f );
    913  1.1     wiz    return False;
    914  1.1     wiz }
    915  1.1     wiz 
    916  1.1     wiz 
    917  1.1     wiz /*---------------------------------------------------*/
    918  1.1     wiz BZFILE* BZ_API(BZ2_bzWriteOpen)
    919  1.1     wiz                     ( int*  bzerror,
    920  1.1     wiz                       FILE* f,
    921  1.1     wiz                       int   blockSize100k,
    922  1.1     wiz                       int   verbosity,
    923  1.1     wiz                       int   workFactor )
    924  1.1     wiz {
    925  1.1     wiz    Int32   ret;
    926  1.1     wiz    bzFile* bzf = NULL;
    927  1.1     wiz 
    928  1.1     wiz    BZ_SETERR(BZ_OK);
    929  1.1     wiz 
    930  1.1     wiz    if (f == NULL ||
    931  1.1     wiz        (blockSize100k < 1 || blockSize100k > 9) ||
    932  1.1     wiz        (workFactor < 0 || workFactor > 250) ||
    933  1.1     wiz        (verbosity < 0 || verbosity > 4))
    934  1.1     wiz       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
    935  1.1     wiz 
    936  1.1     wiz    if (ferror(f))
    937  1.1     wiz       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
    938  1.1     wiz 
    939  1.1     wiz    bzf = malloc ( sizeof(bzFile) );
    940  1.1     wiz    if (bzf == NULL)
    941  1.1     wiz       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
    942  1.1     wiz 
    943  1.1     wiz    BZ_SETERR(BZ_OK);
    944  1.1     wiz    bzf->initialisedOk = False;
    945  1.1     wiz    bzf->bufN          = 0;
    946  1.1     wiz    bzf->handle        = f;
    947  1.1     wiz    bzf->writing       = True;
    948  1.1     wiz    bzf->strm.bzalloc  = NULL;
    949  1.1     wiz    bzf->strm.bzfree   = NULL;
    950  1.1     wiz    bzf->strm.opaque   = NULL;
    951  1.1     wiz 
    952  1.1     wiz    if (workFactor == 0) workFactor = 30;
    953  1.1     wiz    ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
    954  1.1     wiz                               verbosity, workFactor );
    955  1.1     wiz    if (ret != BZ_OK)
    956  1.1     wiz       { BZ_SETERR(ret); free(bzf); return NULL; };
    957  1.1     wiz 
    958  1.1     wiz    bzf->strm.avail_in = 0;
    959  1.1     wiz    bzf->initialisedOk = True;
    960  1.1     wiz    return bzf;
    961  1.1     wiz }
    962  1.1     wiz 
    963  1.1     wiz 
    964  1.1     wiz 
    965  1.1     wiz /*---------------------------------------------------*/
    966  1.1     wiz void BZ_API(BZ2_bzWrite)
    967  1.1     wiz              ( int*    bzerror,
    968  1.1     wiz                BZFILE* b,
    969  1.1     wiz                void*   buf,
    970  1.1     wiz                int     len )
    971  1.1     wiz {
    972  1.1     wiz    Int32 n, n2, ret;
    973  1.1     wiz    bzFile* bzf = (bzFile*)b;
    974  1.1     wiz 
    975  1.1     wiz    BZ_SETERR(BZ_OK);
    976  1.1     wiz    if (bzf == NULL || buf == NULL || len < 0)
    977  1.1     wiz       { BZ_SETERR(BZ_PARAM_ERROR); return; };
    978  1.1     wiz    if (!(bzf->writing))
    979  1.1     wiz       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
    980  1.1     wiz    if (ferror(bzf->handle))
    981  1.1     wiz       { BZ_SETERR(BZ_IO_ERROR); return; };
    982  1.1     wiz 
    983  1.1     wiz    if (len == 0)
    984  1.1     wiz       { BZ_SETERR(BZ_OK); return; };
    985  1.1     wiz 
    986  1.1     wiz    bzf->strm.avail_in = len;
    987  1.1     wiz    bzf->strm.next_in  = buf;
    988  1.1     wiz 
    989  1.1     wiz    while (True) {
    990  1.1     wiz       bzf->strm.avail_out = BZ_MAX_UNUSED;
    991  1.1     wiz       bzf->strm.next_out = bzf->buf;
    992  1.1     wiz       ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
    993  1.1     wiz       if (ret != BZ_RUN_OK)
    994  1.1     wiz          { BZ_SETERR(ret); return; };
    995  1.1     wiz 
    996  1.1     wiz       if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
    997  1.1     wiz          n = BZ_MAX_UNUSED - bzf->strm.avail_out;
    998  1.1     wiz          n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
    999  1.1     wiz                        n, bzf->handle );
   1000  1.1     wiz          if (n != n2 || ferror(bzf->handle))
   1001  1.1     wiz             { BZ_SETERR(BZ_IO_ERROR); return; };
   1002  1.1     wiz       }
   1003  1.1     wiz 
   1004  1.1     wiz       if (bzf->strm.avail_in == 0)
   1005  1.1     wiz          { BZ_SETERR(BZ_OK); return; };
   1006  1.1     wiz    }
   1007  1.1     wiz }
   1008  1.1     wiz 
   1009  1.1     wiz 
   1010  1.1     wiz /*---------------------------------------------------*/
   1011  1.1     wiz void BZ_API(BZ2_bzWriteClose)
   1012  1.1     wiz                   ( int*          bzerror,
   1013  1.1     wiz                     BZFILE*       b,
   1014  1.1     wiz                     int           abandon,
   1015  1.1     wiz                     unsigned int* nbytes_in,
   1016  1.1     wiz                     unsigned int* nbytes_out )
   1017  1.1     wiz {
   1018  1.1     wiz    BZ2_bzWriteClose64 ( bzerror, b, abandon,
   1019  1.1     wiz                         nbytes_in, NULL, nbytes_out, NULL );
   1020  1.1     wiz }
   1021  1.1     wiz 
   1022  1.1     wiz 
   1023  1.1     wiz void BZ_API(BZ2_bzWriteClose64)
   1024  1.1     wiz                   ( int*          bzerror,
   1025  1.1     wiz                     BZFILE*       b,
   1026  1.1     wiz                     int           abandon,
   1027  1.1     wiz                     unsigned int* nbytes_in_lo32,
   1028  1.1     wiz                     unsigned int* nbytes_in_hi32,
   1029  1.1     wiz                     unsigned int* nbytes_out_lo32,
   1030  1.1     wiz                     unsigned int* nbytes_out_hi32 )
   1031  1.1     wiz {
   1032  1.1     wiz    Int32   n, n2, ret;
   1033  1.1     wiz    bzFile* bzf = (bzFile*)b;
   1034  1.1     wiz 
   1035  1.1     wiz    if (bzf == NULL)
   1036  1.1     wiz       { BZ_SETERR(BZ_OK); return; };
   1037  1.1     wiz    if (!(bzf->writing))
   1038  1.1     wiz       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
   1039  1.1     wiz    if (ferror(bzf->handle))
   1040  1.1     wiz       { BZ_SETERR(BZ_IO_ERROR); return; };
   1041  1.1     wiz 
   1042  1.1     wiz    if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
   1043  1.1     wiz    if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
   1044  1.1     wiz    if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
   1045  1.1     wiz    if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
   1046  1.1     wiz 
   1047  1.1     wiz    if ((!abandon) && bzf->lastErr == BZ_OK) {
   1048  1.1     wiz       while (True) {
   1049  1.1     wiz          bzf->strm.avail_out = BZ_MAX_UNUSED;
   1050  1.1     wiz          bzf->strm.next_out = bzf->buf;
   1051  1.1     wiz          ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
   1052  1.1     wiz          if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
   1053  1.1     wiz             { BZ_SETERR(ret); return; };
   1054  1.1     wiz 
   1055  1.1     wiz          if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
   1056  1.1     wiz             n = BZ_MAX_UNUSED - bzf->strm.avail_out;
   1057  1.1     wiz             n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
   1058  1.1     wiz                           n, bzf->handle );
   1059  1.1     wiz             if (n != n2 || ferror(bzf->handle))
   1060  1.1     wiz                { BZ_SETERR(BZ_IO_ERROR); return; };
   1061  1.1     wiz          }
   1062  1.1     wiz 
   1063  1.1     wiz          if (ret == BZ_STREAM_END) break;
   1064  1.1     wiz       }
   1065  1.1     wiz    }
   1066  1.1     wiz 
   1067  1.1     wiz    if ( !abandon && !ferror ( bzf->handle ) ) {
   1068  1.1     wiz       fflush ( bzf->handle );
   1069  1.1     wiz       if (ferror(bzf->handle))
   1070  1.1     wiz          { BZ_SETERR(BZ_IO_ERROR); return; };
   1071  1.1     wiz    }
   1072  1.1     wiz 
   1073  1.1     wiz    if (nbytes_in_lo32 != NULL)
   1074  1.1     wiz       *nbytes_in_lo32 = bzf->strm.total_in_lo32;
   1075  1.1     wiz    if (nbytes_in_hi32 != NULL)
   1076  1.1     wiz       *nbytes_in_hi32 = bzf->strm.total_in_hi32;
   1077  1.1     wiz    if (nbytes_out_lo32 != NULL)
   1078  1.1     wiz       *nbytes_out_lo32 = bzf->strm.total_out_lo32;
   1079  1.1     wiz    if (nbytes_out_hi32 != NULL)
   1080  1.1     wiz       *nbytes_out_hi32 = bzf->strm.total_out_hi32;
   1081  1.1     wiz 
   1082  1.1     wiz    BZ_SETERR(BZ_OK);
   1083  1.1     wiz    BZ2_bzCompressEnd ( &(bzf->strm) );
   1084  1.1     wiz    free ( bzf );
   1085  1.1     wiz }
   1086  1.1     wiz 
   1087  1.1     wiz 
   1088  1.1     wiz /*---------------------------------------------------*/
   1089  1.1     wiz BZFILE* BZ_API(BZ2_bzReadOpen)
   1090  1.1     wiz                    ( int*  bzerror,
   1091  1.1     wiz                      FILE* f,
   1092  1.1     wiz                      int   verbosity,
   1093  1.1     wiz                      int   small,
   1094  1.1     wiz                      void* unused,
   1095  1.1     wiz                      int   nUnused )
   1096  1.1     wiz {
   1097  1.1     wiz    bzFile* bzf = NULL;
   1098  1.1     wiz    int     ret;
   1099  1.1     wiz 
   1100  1.1     wiz    BZ_SETERR(BZ_OK);
   1101  1.1     wiz 
   1102  1.1     wiz    if (f == NULL ||
   1103  1.1     wiz        (small != 0 && small != 1) ||
   1104  1.1     wiz        (verbosity < 0 || verbosity > 4) ||
   1105  1.1     wiz        (unused == NULL && nUnused != 0) ||
   1106  1.1     wiz        (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
   1107  1.1     wiz       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
   1108  1.1     wiz 
   1109  1.1     wiz    if (ferror(f))
   1110  1.1     wiz       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
   1111  1.1     wiz 
   1112  1.1     wiz    bzf = malloc ( sizeof(bzFile) );
   1113  1.1     wiz    if (bzf == NULL)
   1114  1.1     wiz       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
   1115  1.1     wiz 
   1116  1.1     wiz    BZ_SETERR(BZ_OK);
   1117  1.1     wiz 
   1118  1.1     wiz    bzf->initialisedOk = False;
   1119  1.1     wiz    bzf->handle        = f;
   1120  1.1     wiz    bzf->bufN          = 0;
   1121  1.1     wiz    bzf->writing       = False;
   1122  1.1     wiz    bzf->strm.bzalloc  = NULL;
   1123  1.1     wiz    bzf->strm.bzfree   = NULL;
   1124  1.1     wiz    bzf->strm.opaque   = NULL;
   1125  1.1     wiz 
   1126  1.1     wiz    while (nUnused > 0) {
   1127  1.1     wiz       bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
   1128  1.1     wiz       unused = ((void*)( 1 + ((UChar*)(unused))  ));
   1129  1.1     wiz       nUnused--;
   1130  1.1     wiz    }
   1131  1.1     wiz 
   1132  1.1     wiz    ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
   1133  1.1     wiz    if (ret != BZ_OK)
   1134  1.1     wiz       { BZ_SETERR(ret); free(bzf); return NULL; };
   1135  1.1     wiz 
   1136  1.1     wiz    bzf->strm.avail_in = bzf->bufN;
   1137  1.1     wiz    bzf->strm.next_in  = bzf->buf;
   1138  1.1     wiz 
   1139  1.1     wiz    bzf->initialisedOk = True;
   1140  1.1     wiz    return bzf;
   1141  1.1     wiz }
   1142  1.1     wiz 
   1143  1.1     wiz 
   1144  1.1     wiz /*---------------------------------------------------*/
   1145  1.1     wiz void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
   1146  1.1     wiz {
   1147  1.1     wiz    bzFile* bzf = (bzFile*)b;
   1148  1.1     wiz 
   1149  1.1     wiz    BZ_SETERR(BZ_OK);
   1150  1.1     wiz    if (bzf == NULL)
   1151  1.1     wiz       { BZ_SETERR(BZ_OK); return; };
   1152  1.1     wiz 
   1153  1.1     wiz    if (bzf->writing)
   1154  1.1     wiz       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
   1155  1.1     wiz 
   1156  1.1     wiz    if (bzf->initialisedOk)
   1157  1.1     wiz       (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
   1158  1.1     wiz    free ( bzf );
   1159  1.1     wiz }
   1160  1.1     wiz 
   1161  1.1     wiz 
   1162  1.1     wiz /*---------------------------------------------------*/
   1163  1.1     wiz int BZ_API(BZ2_bzRead)
   1164  1.1     wiz            ( int*    bzerror,
   1165  1.1     wiz              BZFILE* b,
   1166  1.1     wiz              void*   buf,
   1167  1.1     wiz              int     len )
   1168  1.1     wiz {
   1169  1.1     wiz    Int32   n, ret;
   1170  1.1     wiz    bzFile* bzf = (bzFile*)b;
   1171  1.1     wiz 
   1172  1.1     wiz    BZ_SETERR(BZ_OK);
   1173  1.1     wiz 
   1174  1.1     wiz    if (bzf == NULL || buf == NULL || len < 0)
   1175  1.1     wiz       { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
   1176  1.1     wiz 
   1177  1.1     wiz    if (bzf->writing)
   1178  1.1     wiz       { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
   1179  1.1     wiz 
   1180  1.1     wiz    if (len == 0)
   1181  1.1     wiz       { BZ_SETERR(BZ_OK); return 0; };
   1182  1.1     wiz 
   1183  1.1     wiz    bzf->strm.avail_out = len;
   1184  1.1     wiz    bzf->strm.next_out = buf;
   1185  1.1     wiz 
   1186  1.1     wiz    while (True) {
   1187  1.1     wiz 
   1188  1.1     wiz       if (ferror(bzf->handle))
   1189  1.1     wiz          { BZ_SETERR(BZ_IO_ERROR); return 0; };
   1190  1.1     wiz 
   1191  1.1     wiz       if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
   1192  1.1     wiz          n = fread ( bzf->buf, sizeof(UChar),
   1193  1.1     wiz                      BZ_MAX_UNUSED, bzf->handle );
   1194  1.1     wiz          if (ferror(bzf->handle))
   1195  1.1     wiz             { BZ_SETERR(BZ_IO_ERROR); return 0; };
   1196  1.1     wiz          bzf->bufN = n;
   1197  1.1     wiz          bzf->strm.avail_in = bzf->bufN;
   1198  1.1     wiz          bzf->strm.next_in = bzf->buf;
   1199  1.1     wiz       }
   1200  1.1     wiz 
   1201  1.1     wiz       ret = BZ2_bzDecompress ( &(bzf->strm) );
   1202  1.1     wiz 
   1203  1.1     wiz       if (ret != BZ_OK && ret != BZ_STREAM_END)
   1204  1.1     wiz          { BZ_SETERR(ret); return 0; };
   1205  1.1     wiz 
   1206  1.1     wiz       if (ret == BZ_OK && myfeof(bzf->handle) &&
   1207  1.1     wiz           bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
   1208  1.1     wiz          { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
   1209  1.1     wiz 
   1210  1.1     wiz       if (ret == BZ_STREAM_END)
   1211  1.1     wiz          { BZ_SETERR(BZ_STREAM_END);
   1212  1.1     wiz            return len - bzf->strm.avail_out; };
   1213  1.1     wiz       if (bzf->strm.avail_out == 0)
   1214  1.1     wiz          { BZ_SETERR(BZ_OK); return len; };
   1215  1.1     wiz 
   1216  1.1     wiz    }
   1217  1.1     wiz 
   1218  1.1     wiz    return 0; /*not reached*/
   1219  1.1     wiz }
   1220  1.1     wiz 
   1221  1.1     wiz 
   1222  1.1     wiz /*---------------------------------------------------*/
   1223  1.1     wiz void BZ_API(BZ2_bzReadGetUnused)
   1224  1.1     wiz                      ( int*    bzerror,
   1225  1.1     wiz                        BZFILE* b,
   1226  1.1     wiz                        void**  unused,
   1227  1.1     wiz                        int*    nUnused )
   1228  1.1     wiz {
   1229  1.1     wiz    bzFile* bzf = (bzFile*)b;
   1230  1.1     wiz    if (bzf == NULL)
   1231  1.1     wiz       { BZ_SETERR(BZ_PARAM_ERROR); return; };
   1232  1.1     wiz    if (bzf->lastErr != BZ_STREAM_END)
   1233  1.1     wiz       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
   1234  1.1     wiz    if (unused == NULL || nUnused == NULL)
   1235  1.1     wiz       { BZ_SETERR(BZ_PARAM_ERROR); return; };
   1236  1.1     wiz 
   1237  1.1     wiz    BZ_SETERR(BZ_OK);
   1238  1.1     wiz    *nUnused = bzf->strm.avail_in;
   1239  1.1     wiz    *unused = bzf->strm.next_in;
   1240  1.1     wiz }
   1241  1.1     wiz #endif
   1242  1.1     wiz 
   1243  1.1     wiz 
   1244  1.1     wiz /*---------------------------------------------------*/
   1245  1.1     wiz /*--- Misc convenience stuff                      ---*/
   1246  1.1     wiz /*---------------------------------------------------*/
   1247  1.1     wiz 
   1248  1.1     wiz /*---------------------------------------------------*/
   1249  1.1     wiz int BZ_API(BZ2_bzBuffToBuffCompress)
   1250  1.1     wiz                          ( char*         dest,
   1251  1.1     wiz                            unsigned int* destLen,
   1252  1.1     wiz                            char*         source,
   1253  1.1     wiz                            unsigned int  sourceLen,
   1254  1.1     wiz                            int           blockSize100k,
   1255  1.1     wiz                            int           verbosity,
   1256  1.1     wiz                            int           workFactor )
   1257  1.1     wiz {
   1258  1.1     wiz    bz_stream strm;
   1259  1.1     wiz    int ret;
   1260  1.1     wiz 
   1261  1.1     wiz    if (dest == NULL || destLen == NULL ||
   1262  1.1     wiz        source == NULL ||
   1263  1.1     wiz        blockSize100k < 1 || blockSize100k > 9 ||
   1264  1.1     wiz        verbosity < 0 || verbosity > 4 ||
   1265  1.1     wiz        workFactor < 0 || workFactor > 250)
   1266  1.1     wiz       return BZ_PARAM_ERROR;
   1267  1.1     wiz 
   1268  1.1     wiz    if (workFactor == 0) workFactor = 30;
   1269  1.1     wiz    strm.bzalloc = NULL;
   1270  1.1     wiz    strm.bzfree = NULL;
   1271  1.1     wiz    strm.opaque = NULL;
   1272  1.1     wiz    ret = BZ2_bzCompressInit ( &strm, blockSize100k,
   1273  1.1     wiz                               verbosity, workFactor );
   1274  1.1     wiz    if (ret != BZ_OK) return ret;
   1275  1.1     wiz 
   1276  1.1     wiz    strm.next_in = source;
   1277  1.1     wiz    strm.next_out = dest;
   1278  1.1     wiz    strm.avail_in = sourceLen;
   1279  1.1     wiz    strm.avail_out = *destLen;
   1280  1.1     wiz 
   1281  1.1     wiz    ret = BZ2_bzCompress ( &strm, BZ_FINISH );
   1282  1.1     wiz    if (ret == BZ_FINISH_OK) goto output_overflow;
   1283  1.1     wiz    if (ret != BZ_STREAM_END) goto errhandler;
   1284  1.1     wiz 
   1285  1.1     wiz    /* normal termination */
   1286  1.1     wiz    *destLen -= strm.avail_out;
   1287  1.1     wiz    BZ2_bzCompressEnd ( &strm );
   1288  1.1     wiz    return BZ_OK;
   1289  1.1     wiz 
   1290  1.1     wiz    output_overflow:
   1291  1.1     wiz    BZ2_bzCompressEnd ( &strm );
   1292  1.1     wiz    return BZ_OUTBUFF_FULL;
   1293  1.1     wiz 
   1294  1.1     wiz    errhandler:
   1295  1.1     wiz    BZ2_bzCompressEnd ( &strm );
   1296  1.1     wiz    return ret;
   1297  1.1     wiz }
   1298  1.1     wiz 
   1299  1.1     wiz 
   1300  1.1     wiz /*---------------------------------------------------*/
   1301  1.1     wiz int BZ_API(BZ2_bzBuffToBuffDecompress)
   1302  1.1     wiz                            ( char*         dest,
   1303  1.1     wiz                              unsigned int* destLen,
   1304  1.1     wiz                              char*         source,
   1305  1.1     wiz                              unsigned int  sourceLen,
   1306  1.1     wiz                              int           small,
   1307  1.1     wiz                              int           verbosity )
   1308  1.1     wiz {
   1309  1.1     wiz    bz_stream strm;
   1310  1.1     wiz    int ret;
   1311  1.1     wiz 
   1312  1.1     wiz    if (dest == NULL || destLen == NULL ||
   1313  1.1     wiz        source == NULL ||
   1314  1.1     wiz        (small != 0 && small != 1) ||
   1315  1.1     wiz        verbosity < 0 || verbosity > 4)
   1316  1.1     wiz           return BZ_PARAM_ERROR;
   1317  1.1     wiz 
   1318  1.1     wiz    strm.bzalloc = NULL;
   1319  1.1     wiz    strm.bzfree = NULL;
   1320  1.1     wiz    strm.opaque = NULL;
   1321  1.1     wiz    ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
   1322  1.1     wiz    if (ret != BZ_OK) return ret;
   1323  1.1     wiz 
   1324  1.1     wiz    strm.next_in = source;
   1325  1.1     wiz    strm.next_out = dest;
   1326  1.1     wiz    strm.avail_in = sourceLen;
   1327  1.1     wiz    strm.avail_out = *destLen;
   1328  1.1     wiz 
   1329  1.1     wiz    ret = BZ2_bzDecompress ( &strm );
   1330  1.1     wiz    if (ret == BZ_OK) goto output_overflow_or_eof;
   1331  1.1     wiz    if (ret != BZ_STREAM_END) goto errhandler;
   1332  1.1     wiz 
   1333  1.1     wiz    /* normal termination */
   1334  1.1     wiz    *destLen -= strm.avail_out;
   1335  1.1     wiz    BZ2_bzDecompressEnd ( &strm );
   1336  1.1     wiz    return BZ_OK;
   1337  1.1     wiz 
   1338  1.1     wiz    output_overflow_or_eof:
   1339  1.1     wiz    if (strm.avail_out > 0) {
   1340  1.1     wiz       BZ2_bzDecompressEnd ( &strm );
   1341  1.1     wiz       return BZ_UNEXPECTED_EOF;
   1342  1.1     wiz    } else {
   1343  1.1     wiz       BZ2_bzDecompressEnd ( &strm );
   1344  1.1     wiz       return BZ_OUTBUFF_FULL;
   1345  1.1     wiz    };
   1346  1.1     wiz 
   1347  1.1     wiz    errhandler:
   1348  1.1     wiz    BZ2_bzDecompressEnd ( &strm );
   1349  1.1     wiz    return ret;
   1350  1.1     wiz }
   1351  1.1     wiz 
   1352  1.1     wiz 
   1353  1.1     wiz /*---------------------------------------------------*/
   1354  1.1     wiz /*--
   1355  1.1     wiz    Code contributed by Yoshioka Tsuneo (tsuneo (at) rr.iij4u.or.jp)
   1356  1.1     wiz    to support better zlib compatibility.
   1357  1.1     wiz    This code is not _officially_ part of libbzip2 (yet);
   1358  1.1     wiz    I haven't tested it, documented it, or considered the
   1359  1.1     wiz    threading-safeness of it.
   1360  1.1     wiz    If this code breaks, please contact both Yoshioka and me.
   1361  1.1     wiz --*/
   1362  1.1     wiz /*---------------------------------------------------*/
   1363  1.1     wiz 
   1364  1.1     wiz /*---------------------------------------------------*/
   1365  1.1     wiz /*--
   1366  1.1     wiz    return version like "0.9.5d, 4-Sept-1999".
   1367  1.1     wiz --*/
   1368  1.1     wiz const char * BZ_API(BZ2_bzlibVersion)(void)
   1369  1.1     wiz {
   1370  1.1     wiz    return BZ_VERSION;
   1371  1.1     wiz }
   1372  1.1     wiz 
   1373  1.1     wiz 
   1374  1.1     wiz #ifndef BZ_NO_STDIO
   1375  1.1     wiz /*---------------------------------------------------*/
   1376  1.1     wiz 
   1377  1.1     wiz #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
   1378  1.1     wiz #   include <fcntl.h>
   1379  1.1     wiz #   include <io.h>
   1380  1.1     wiz #   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
   1381  1.1     wiz #else
   1382  1.1     wiz #   define SET_BINARY_MODE(file)
   1383  1.1     wiz #endif
   1384  1.1     wiz static
   1385  1.1     wiz BZFILE * bzopen_or_bzdopen
   1386  1.1     wiz                ( const char *path,   /* no use when bzdopen */
   1387  1.1     wiz                  int fd,             /* no use when bzdopen */
   1388  1.1     wiz                  const char *mode,
   1389  1.1     wiz                  int open_mode)      /* bzopen: 0, bzdopen:1 */
   1390  1.1     wiz {
   1391  1.1     wiz    int    bzerr;
   1392  1.1     wiz    char   unused[BZ_MAX_UNUSED];
   1393  1.1     wiz    int    blockSize100k = 9;
   1394  1.1     wiz    int    writing       = 0;
   1395  1.1     wiz    char   mode2[10]     = "";
   1396  1.1     wiz    FILE   *fp           = NULL;
   1397  1.1     wiz    BZFILE *bzfp         = NULL;
   1398  1.1     wiz    int    verbosity     = 0;
   1399  1.1     wiz    int    workFactor    = 30;
   1400  1.1     wiz    int    smallMode     = 0;
   1401  1.1     wiz    int    nUnused       = 0;
   1402  1.1     wiz 
   1403  1.1     wiz    if (mode == NULL) return NULL;
   1404  1.1     wiz    while (*mode) {
   1405  1.1     wiz       switch (*mode) {
   1406  1.1     wiz       case 'r':
   1407  1.1     wiz          writing = 0; break;
   1408  1.1     wiz       case 'w':
   1409  1.1     wiz          writing = 1; break;
   1410  1.1     wiz       case 's':
   1411  1.1     wiz          smallMode = 1; break;
   1412  1.1     wiz       default:
   1413  1.5  rillig          if (isdigit((UChar)(*mode))) {
   1414  1.1     wiz             blockSize100k = *mode-BZ_HDR_0;
   1415  1.1     wiz          }
   1416  1.1     wiz       }
   1417  1.1     wiz       mode++;
   1418  1.1     wiz    }
   1419  1.1     wiz    strcat(mode2, writing ? "w" : "r" );
   1420  1.1     wiz    strcat(mode2,"b");   /* binary mode */
   1421  1.1     wiz 
   1422  1.1     wiz    if (open_mode==0) {
   1423  1.1     wiz       if (path==NULL || strcmp(path,"")==0) {
   1424  1.1     wiz         fp = (writing ? stdout : stdin);
   1425  1.1     wiz         SET_BINARY_MODE(fp);
   1426  1.1     wiz       } else {
   1427  1.1     wiz         fp = fopen(path,mode2);
   1428  1.1     wiz       }
   1429  1.1     wiz    } else {
   1430  1.1     wiz #ifdef BZ_STRICT_ANSI
   1431  1.1     wiz       fp = NULL;
   1432  1.1     wiz #else
   1433  1.1     wiz       fp = fdopen(fd,mode2);
   1434  1.1     wiz #endif
   1435  1.1     wiz    }
   1436  1.1     wiz    if (fp == NULL) return NULL;
   1437  1.1     wiz 
   1438  1.1     wiz    if (writing) {
   1439  1.1     wiz       /* Guard against total chaos and anarchy -- JRS */
   1440  1.1     wiz       if (blockSize100k < 1) blockSize100k = 1;
   1441  1.1     wiz       if (blockSize100k > 9) blockSize100k = 9;
   1442  1.1     wiz       bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
   1443  1.1     wiz                              verbosity,workFactor);
   1444  1.1     wiz    } else {
   1445  1.1     wiz       bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
   1446  1.1     wiz                             unused,nUnused);
   1447  1.1     wiz    }
   1448  1.1     wiz    if (bzfp == NULL) {
   1449  1.1     wiz       if (fp != stdin && fp != stdout) fclose(fp);
   1450  1.1     wiz       return NULL;
   1451  1.1     wiz    }
   1452  1.1     wiz    return bzfp;
   1453  1.1     wiz }
   1454  1.1     wiz 
   1455  1.1     wiz 
   1456  1.1     wiz /*---------------------------------------------------*/
   1457  1.1     wiz /*--
   1458  1.1     wiz    open file for read or write.
   1459  1.1     wiz       ex) bzopen("file","w9")
   1460  1.1     wiz       case path="" or NULL => use stdin or stdout.
   1461  1.1     wiz --*/
   1462  1.1     wiz BZFILE * BZ_API(BZ2_bzopen)
   1463  1.1     wiz                ( const char *path,
   1464  1.1     wiz                  const char *mode )
   1465  1.1     wiz {
   1466  1.1     wiz    return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
   1467  1.1     wiz }
   1468  1.1     wiz 
   1469  1.1     wiz 
   1470  1.1     wiz /*---------------------------------------------------*/
   1471  1.1     wiz BZFILE * BZ_API(BZ2_bzdopen)
   1472  1.1     wiz                ( int fd,
   1473  1.1     wiz                  const char *mode )
   1474  1.1     wiz {
   1475  1.1     wiz    return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
   1476  1.1     wiz }
   1477  1.1     wiz 
   1478  1.1     wiz 
   1479  1.1     wiz /*---------------------------------------------------*/
   1480  1.1     wiz int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
   1481  1.1     wiz {
   1482  1.1     wiz    int bzerr, nread;
   1483  1.1     wiz    if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
   1484  1.1     wiz    nread = BZ2_bzRead(&bzerr,b,buf,len);
   1485  1.1     wiz    if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
   1486  1.1     wiz       return nread;
   1487  1.1     wiz    } else {
   1488  1.1     wiz       return -1;
   1489  1.1     wiz    }
   1490  1.1     wiz }
   1491  1.1     wiz 
   1492  1.1     wiz 
   1493  1.1     wiz /*---------------------------------------------------*/
   1494  1.1     wiz int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
   1495  1.1     wiz {
   1496  1.1     wiz    int bzerr;
   1497  1.1     wiz 
   1498  1.1     wiz    BZ2_bzWrite(&bzerr,b,buf,len);
   1499  1.1     wiz    if(bzerr == BZ_OK){
   1500  1.1     wiz       return len;
   1501  1.1     wiz    }else{
   1502  1.1     wiz       return -1;
   1503  1.1     wiz    }
   1504  1.1     wiz }
   1505  1.1     wiz 
   1506  1.1     wiz 
   1507  1.1     wiz /*---------------------------------------------------*/
   1508  1.1     wiz int BZ_API(BZ2_bzflush) (BZFILE *b)
   1509  1.1     wiz {
   1510  1.1     wiz    /* do nothing now... */
   1511  1.1     wiz    return 0;
   1512  1.1     wiz }
   1513  1.1     wiz 
   1514  1.1     wiz 
   1515  1.1     wiz /*---------------------------------------------------*/
   1516  1.1     wiz void BZ_API(BZ2_bzclose) (BZFILE* b)
   1517  1.1     wiz {
   1518  1.1     wiz    int bzerr;
   1519  1.1     wiz    FILE *fp;
   1520  1.1     wiz 
   1521  1.1     wiz    if (b==NULL) {return;}
   1522  1.1     wiz    fp = ((bzFile *)b)->handle;
   1523  1.1     wiz    if(((bzFile*)b)->writing){
   1524  1.1     wiz       BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
   1525  1.1     wiz       if(bzerr != BZ_OK){
   1526  1.1     wiz          BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
   1527  1.1     wiz       }
   1528  1.1     wiz    }else{
   1529  1.1     wiz       BZ2_bzReadClose(&bzerr,b);
   1530  1.1     wiz    }
   1531  1.1     wiz    if(fp!=stdin && fp!=stdout){
   1532  1.1     wiz       fclose(fp);
   1533  1.1     wiz    }
   1534  1.1     wiz }
   1535  1.1     wiz 
   1536  1.1     wiz 
   1537  1.1     wiz /*---------------------------------------------------*/
   1538  1.1     wiz /*--
   1539  1.1     wiz    return last error code
   1540  1.1     wiz --*/
   1541  1.1     wiz static const char *bzerrorstrings[] = {
   1542  1.1     wiz        "OK"
   1543  1.1     wiz       ,"SEQUENCE_ERROR"
   1544  1.1     wiz       ,"PARAM_ERROR"
   1545  1.1     wiz       ,"MEM_ERROR"
   1546  1.1     wiz       ,"DATA_ERROR"
   1547  1.1     wiz       ,"DATA_ERROR_MAGIC"
   1548  1.1     wiz       ,"IO_ERROR"
   1549  1.1     wiz       ,"UNEXPECTED_EOF"
   1550  1.1     wiz       ,"OUTBUFF_FULL"
   1551  1.1     wiz       ,"CONFIG_ERROR"
   1552  1.1     wiz       ,"???"   /* for future */
   1553  1.1     wiz       ,"???"   /* for future */
   1554  1.1     wiz       ,"???"   /* for future */
   1555  1.1     wiz       ,"???"   /* for future */
   1556  1.1     wiz       ,"???"   /* for future */
   1557  1.1     wiz       ,"???"   /* for future */
   1558  1.1     wiz };
   1559  1.1     wiz 
   1560  1.1     wiz 
   1561  1.1     wiz const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
   1562  1.1     wiz {
   1563  1.1     wiz    int err = ((bzFile *)b)->lastErr;
   1564  1.1     wiz 
   1565  1.1     wiz    if(err>0) err = 0;
   1566  1.1     wiz    *errnum = err;
   1567  1.1     wiz    return bzerrorstrings[err*-1];
   1568  1.1     wiz }
   1569  1.1     wiz #endif
   1570  1.1     wiz 
   1571  1.1     wiz 
   1572  1.1     wiz /*-------------------------------------------------------------*/
   1573  1.1     wiz /*--- end                                           bzlib.c ---*/
   1574  1.1     wiz /*-------------------------------------------------------------*/
   1575