Blame bzlib.c

Packit 71fd91
Packit 71fd91
/*-------------------------------------------------------------*/
Packit 71fd91
/*--- Library top-level functions.                          ---*/
Packit 71fd91
/*---                                               bzlib.c ---*/
Packit 71fd91
/*-------------------------------------------------------------*/
Packit 71fd91
Packit 71fd91
/* ------------------------------------------------------------------
Packit 71fd91
   This file is part of bzip2/libbzip2, a program and library for
Packit 71fd91
   lossless, block-sorting data compression.
Packit 71fd91
Packit 71fd91
   bzip2/libbzip2 version 1.0.6 of 6 September 2010
Packit 71fd91
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Packit 71fd91
Packit 71fd91
   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
Packit 71fd91
   README file.
Packit 71fd91
Packit 71fd91
   This program is released under the terms of the license contained
Packit 71fd91
   in the file LICENSE.
Packit 71fd91
   ------------------------------------------------------------------ */
Packit 71fd91
Packit 71fd91
/* CHANGES
Packit 71fd91
   0.9.0    -- original version.
Packit 71fd91
   0.9.0a/b -- no changes in this file.
Packit 71fd91
   0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
Packit 71fd91
     fixed bzWrite/bzRead to ignore zero-length requests.
Packit 71fd91
     fixed bzread to correctly handle read requests after EOF.
Packit 71fd91
     wrong parameter order in call to bzDecompressInit in
Packit 71fd91
     bzBuffToBuffDecompress.  Fixed.
Packit 71fd91
*/
Packit 71fd91
Packit 71fd91
#include "bzlib_private.h"
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--- Compression stuff                           ---*/
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
#ifndef BZ_NO_STDIO
Packit 71fd91
void BZ2_bz__AssertH__fail ( int errcode )
Packit 71fd91
{
Packit 71fd91
   fprintf(stderr, 
Packit 71fd91
      "\n\nbzip2/libbzip2: internal error number %d.\n"
Packit 71fd91
      "This is a bug in bzip2/libbzip2, %s.\n"
Packit 71fd91
      "Please report it to me at: jseward@bzip.org.  If this happened\n"
Packit 71fd91
      "when you were using some program which uses libbzip2 as a\n"
Packit 71fd91
      "component, you should also report this bug to the author(s)\n"
Packit 71fd91
      "of that program.  Please make an effort to report this bug;\n"
Packit 71fd91
      "timely and accurate bug reports eventually lead to higher\n"
Packit 71fd91
      "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
Packit 71fd91
      errcode,
Packit 71fd91
      BZ2_bzlibVersion()
Packit 71fd91
   );
Packit 71fd91
Packit 71fd91
   if (errcode == 1007) {
Packit 71fd91
   fprintf(stderr,
Packit 71fd91
      "\n*** A special note about internal error number 1007 ***\n"
Packit 71fd91
      "\n"
Packit 71fd91
      "Experience suggests that a common cause of i.e. 1007\n"
Packit 71fd91
      "is unreliable memory or other hardware.  The 1007 assertion\n"
Packit 71fd91
      "just happens to cross-check the results of huge numbers of\n"
Packit 71fd91
      "memory reads/writes, and so acts (unintendedly) as a stress\n"
Packit 71fd91
      "test of your memory system.\n"
Packit 71fd91
      "\n"
Packit 71fd91
      "I suggest the following: try compressing the file again,\n"
Packit 71fd91
      "possibly monitoring progress in detail with the -vv flag.\n"
Packit 71fd91
      "\n"
Packit 71fd91
      "* If the error cannot be reproduced, and/or happens at different\n"
Packit 71fd91
      "  points in compression, you may have a flaky memory system.\n"
Packit 71fd91
      "  Try a memory-test program.  I have used Memtest86\n"
Packit 71fd91
      "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
Packit 71fd91
      "  Memtest86 tests memory much more thorougly than your BIOSs\n"
Packit 71fd91
      "  power-on test, and may find failures that the BIOS doesn't.\n"
Packit 71fd91
      "\n"
Packit 71fd91
      "* If the error can be repeatably reproduced, this is a bug in\n"
Packit 71fd91
      "  bzip2, and I would very much like to hear about it.  Please\n"
Packit 71fd91
      "  let me know, and, ideally, save a copy of the file causing the\n"
Packit 71fd91
      "  problem -- without which I will be unable to investigate it.\n"
Packit 71fd91
      "\n"
Packit 71fd91
   );
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   exit(3);
Packit 71fd91
}
Packit 71fd91
#endif
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
int bz_config_ok ( void )
Packit 71fd91
{
Packit 71fd91
   if (sizeof(int)   != 4) return 0;
Packit 71fd91
   if (sizeof(short) != 2) return 0;
Packit 71fd91
   if (sizeof(char)  != 1) return 0;
Packit 71fd91
   return 1;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
Packit 71fd91
{
Packit 71fd91
   void* v = malloc ( items * size );
Packit 71fd91
   return v;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
static
Packit 71fd91
void default_bzfree ( void* opaque, void* addr )
Packit 71fd91
{
Packit 71fd91
   if (addr != NULL) free ( addr );
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
void prepare_new_block ( EState* s )
Packit 71fd91
{
Packit 71fd91
   Int32 i;
Packit 71fd91
   s->nblock = 0;
Packit 71fd91
   s->numZ = 0;
Packit 71fd91
   s->state_out_pos = 0;
Packit 71fd91
   BZ_INITIALISE_CRC ( s->blockCRC );
Packit 71fd91
   for (i = 0; i < 256; i++) s->inUse[i] = False;
Packit 71fd91
   s->blockNo++;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
void init_RL ( EState* s )
Packit 71fd91
{
Packit 71fd91
   s->state_in_ch  = 256;
Packit 71fd91
   s->state_in_len = 0;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
static
Packit 71fd91
Bool isempty_RL ( EState* s )
Packit 71fd91
{
Packit 71fd91
   if (s->state_in_ch < 256 && s->state_in_len > 0)
Packit 71fd91
      return False; else
Packit 71fd91
      return True;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzCompressInit) 
Packit 71fd91
                    ( bz_stream* strm, 
Packit 71fd91
                     int        blockSize100k,
Packit 71fd91
                     int        verbosity,
Packit 71fd91
                     int        workFactor )
Packit 71fd91
{
Packit 71fd91
   Int32   n;
Packit 71fd91
   EState* s;
Packit 71fd91
Packit 71fd91
   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
Packit 71fd91
Packit 71fd91
   if (strm == NULL || 
Packit 71fd91
       blockSize100k < 1 || blockSize100k > 9 ||
Packit 71fd91
       workFactor < 0 || workFactor > 250)
Packit 71fd91
     return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   if (workFactor == 0) workFactor = 30;
Packit 71fd91
   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
Packit 71fd91
   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
Packit 71fd91
Packit 71fd91
   s = BZALLOC( sizeof(EState) );
Packit 71fd91
   if (s == NULL) return BZ_MEM_ERROR;
Packit 71fd91
   s->strm = strm;
Packit 71fd91
Packit 71fd91
   s->arr1 = NULL;
Packit 71fd91
   s->arr2 = NULL;
Packit 71fd91
   s->ftab = NULL;
Packit 71fd91
Packit 71fd91
   n       = 100000 * blockSize100k;
Packit 71fd91
   s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
Packit 71fd91
   s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
Packit 71fd91
   s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
Packit 71fd91
Packit 71fd91
   if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
Packit 71fd91
      if (s->arr1 != NULL) BZFREE(s->arr1);
Packit 71fd91
      if (s->arr2 != NULL) BZFREE(s->arr2);
Packit 71fd91
      if (s->ftab != NULL) BZFREE(s->ftab);
Packit 71fd91
      if (s       != NULL) BZFREE(s);
Packit 71fd91
      return BZ_MEM_ERROR;
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   s->blockNo           = 0;
Packit 71fd91
   s->state             = BZ_S_INPUT;
Packit 71fd91
   s->mode              = BZ_M_RUNNING;
Packit 71fd91
   s->combinedCRC       = 0;
Packit 71fd91
   s->blockSize100k     = blockSize100k;
Packit 71fd91
   s->nblockMAX         = 100000 * blockSize100k - 19;
Packit 71fd91
   s->verbosity         = verbosity;
Packit 71fd91
   s->workFactor        = workFactor;
Packit 71fd91
Packit 71fd91
   s->block             = (UChar*)s->arr2;
Packit 71fd91
   s->mtfv              = (UInt16*)s->arr1;
Packit 71fd91
   s->zbits             = NULL;
Packit 71fd91
   s->ptr               = (UInt32*)s->arr1;
Packit 71fd91
Packit 71fd91
   strm->state          = s;
Packit 71fd91
   strm->total_in_lo32  = 0;
Packit 71fd91
   strm->total_in_hi32  = 0;
Packit 71fd91
   strm->total_out_lo32 = 0;
Packit 71fd91
   strm->total_out_hi32 = 0;
Packit 71fd91
   init_RL ( s );
Packit 71fd91
   prepare_new_block ( s );
Packit 71fd91
   return BZ_OK;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
void add_pair_to_block ( EState* s )
Packit 71fd91
{
Packit 71fd91
   Int32 i;
Packit 71fd91
   UChar ch = (UChar)(s->state_in_ch);
Packit 71fd91
   for (i = 0; i < s->state_in_len; i++) {
Packit 71fd91
      BZ_UPDATE_CRC( s->blockCRC, ch );
Packit 71fd91
   }
Packit 71fd91
   s->inUse[s->state_in_ch] = True;
Packit 71fd91
   switch (s->state_in_len) {
Packit 71fd91
      case 1:
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         break;
Packit 71fd91
      case 2:
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         break;
Packit 71fd91
      case 3:
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         break;
Packit 71fd91
      default:
Packit 71fd91
         s->inUse[s->state_in_len-4] = True;
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         s->block[s->nblock] = (UChar)ch; s->nblock++;
Packit 71fd91
         s->block[s->nblock] = ((UChar)(s->state_in_len-4));
Packit 71fd91
         s->nblock++;
Packit 71fd91
         break;
Packit 71fd91
   }
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
void flush_RL ( EState* s )
Packit 71fd91
{
Packit 71fd91
   if (s->state_in_ch < 256) add_pair_to_block ( s );
Packit 71fd91
   init_RL ( s );
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
#define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
Packit 71fd91
{                                                 \
Packit 71fd91
   UInt32 zchh = (UInt32)(zchh0);                 \
Packit 71fd91
   /*-- fast track the common case --*/           \
Packit 71fd91
   if (zchh != zs->state_in_ch &&                 \
Packit 71fd91
       zs->state_in_len == 1) {                   \
Packit 71fd91
      UChar ch = (UChar)(zs->state_in_ch);        \
Packit 71fd91
      BZ_UPDATE_CRC( zs->blockCRC, ch );          \
Packit 71fd91
      zs->inUse[zs->state_in_ch] = True;          \
Packit 71fd91
      zs->block[zs->nblock] = (UChar)ch;          \
Packit 71fd91
      zs->nblock++;                               \
Packit 71fd91
      zs->state_in_ch = zchh;                     \
Packit 71fd91
   }                                              \
Packit 71fd91
   else                                           \
Packit 71fd91
   /*-- general, uncommon cases --*/              \
Packit 71fd91
   if (zchh != zs->state_in_ch ||                 \
Packit 71fd91
      zs->state_in_len == 255) {                  \
Packit 71fd91
      if (zs->state_in_ch < 256)                  \
Packit 71fd91
         add_pair_to_block ( zs );                \
Packit 71fd91
      zs->state_in_ch = zchh;                     \
Packit 71fd91
      zs->state_in_len = 1;                       \
Packit 71fd91
   } else {                                       \
Packit 71fd91
      zs->state_in_len++;                         \
Packit 71fd91
   }                                              \
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
Bool copy_input_until_stop ( EState* s )
Packit 71fd91
{
Packit 71fd91
   Bool progress_in = False;
Packit 71fd91
Packit 71fd91
   if (s->mode == BZ_M_RUNNING) {
Packit 71fd91
Packit 71fd91
      /*-- fast track the common case --*/
Packit 71fd91
      while (True) {
Packit 71fd91
         /*-- block full? --*/
Packit 71fd91
         if (s->nblock >= s->nblockMAX) break;
Packit 71fd91
         /*-- no input? --*/
Packit 71fd91
         if (s->strm->avail_in == 0) break;
Packit 71fd91
         progress_in = True;
Packit 71fd91
         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
Packit 71fd91
         s->strm->next_in++;
Packit 71fd91
         s->strm->avail_in--;
Packit 71fd91
         s->strm->total_in_lo32++;
Packit 71fd91
         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
   } else {
Packit 71fd91
Packit 71fd91
      /*-- general, uncommon case --*/
Packit 71fd91
      while (True) {
Packit 71fd91
         /*-- block full? --*/
Packit 71fd91
         if (s->nblock >= s->nblockMAX) break;
Packit 71fd91
         /*-- no input? --*/
Packit 71fd91
         if (s->strm->avail_in == 0) break;
Packit 71fd91
         /*-- flush/finish end? --*/
Packit 71fd91
         if (s->avail_in_expect == 0) break;
Packit 71fd91
         progress_in = True;
Packit 71fd91
         ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
Packit 71fd91
         s->strm->next_in++;
Packit 71fd91
         s->strm->avail_in--;
Packit 71fd91
         s->strm->total_in_lo32++;
Packit 71fd91
         if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
Packit 71fd91
         s->avail_in_expect--;
Packit 71fd91
      }
Packit 71fd91
   }
Packit 71fd91
   return progress_in;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
Bool copy_output_until_stop ( EState* s )
Packit 71fd91
{
Packit 71fd91
   Bool progress_out = False;
Packit 71fd91
Packit 71fd91
   while (True) {
Packit 71fd91
Packit 71fd91
      /*-- no output space? --*/
Packit 71fd91
      if (s->strm->avail_out == 0) break;
Packit 71fd91
Packit 71fd91
      /*-- block done? --*/
Packit 71fd91
      if (s->state_out_pos >= s->numZ) break;
Packit 71fd91
Packit 71fd91
      progress_out = True;
Packit 71fd91
      *(s->strm->next_out) = s->zbits[s->state_out_pos];
Packit 71fd91
      s->state_out_pos++;
Packit 71fd91
      s->strm->avail_out--;
Packit 71fd91
      s->strm->next_out++;
Packit 71fd91
      s->strm->total_out_lo32++;
Packit 71fd91
      if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   return progress_out;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
Bool handle_compress ( bz_stream* strm )
Packit 71fd91
{
Packit 71fd91
   Bool progress_in  = False;
Packit 71fd91
   Bool progress_out = False;
Packit 71fd91
   EState* s = strm->state;
Packit 71fd91
   
Packit 71fd91
   while (True) {
Packit 71fd91
Packit 71fd91
      if (s->state == BZ_S_OUTPUT) {
Packit 71fd91
         progress_out |= copy_output_until_stop ( s );
Packit 71fd91
         if (s->state_out_pos < s->numZ) break;
Packit 71fd91
         if (s->mode == BZ_M_FINISHING && 
Packit 71fd91
             s->avail_in_expect == 0 &&
Packit 71fd91
             isempty_RL(s)) break;
Packit 71fd91
         prepare_new_block ( s );
Packit 71fd91
         s->state = BZ_S_INPUT;
Packit 71fd91
         if (s->mode == BZ_M_FLUSHING && 
Packit 71fd91
             s->avail_in_expect == 0 &&
Packit 71fd91
             isempty_RL(s)) break;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      if (s->state == BZ_S_INPUT) {
Packit 71fd91
         progress_in |= copy_input_until_stop ( s );
Packit 71fd91
         if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
Packit 71fd91
            flush_RL ( s );
Packit 71fd91
            BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
Packit 71fd91
            s->state = BZ_S_OUTPUT;
Packit 71fd91
         }
Packit 71fd91
         else
Packit 71fd91
         if (s->nblock >= s->nblockMAX) {
Packit 71fd91
            BZ2_compressBlock ( s, False );
Packit 71fd91
            s->state = BZ_S_OUTPUT;
Packit 71fd91
         }
Packit 71fd91
         else
Packit 71fd91
         if (s->strm->avail_in == 0) {
Packit 71fd91
            break;
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   return progress_in || progress_out;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
Packit 71fd91
{
Packit 71fd91
   Bool progress;
Packit 71fd91
   EState* s;
Packit 71fd91
   if (strm == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   s = strm->state;
Packit 71fd91
   if (s == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   if (s->strm != strm) return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   preswitch:
Packit 71fd91
   switch (s->mode) {
Packit 71fd91
Packit 71fd91
      case BZ_M_IDLE:
Packit 71fd91
         return BZ_SEQUENCE_ERROR;
Packit 71fd91
Packit 71fd91
      case BZ_M_RUNNING:
Packit 71fd91
         if (action == BZ_RUN) {
Packit 71fd91
            progress = handle_compress ( strm );
Packit 71fd91
            return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
Packit 71fd91
         } 
Packit 71fd91
         else
Packit 71fd91
	 if (action == BZ_FLUSH) {
Packit 71fd91
            s->avail_in_expect = strm->avail_in;
Packit 71fd91
            s->mode = BZ_M_FLUSHING;
Packit 71fd91
            goto preswitch;
Packit 71fd91
         }
Packit 71fd91
         else
Packit 71fd91
         if (action == BZ_FINISH) {
Packit 71fd91
            s->avail_in_expect = strm->avail_in;
Packit 71fd91
            s->mode = BZ_M_FINISHING;
Packit 71fd91
            goto preswitch;
Packit 71fd91
         }
Packit 71fd91
         else 
Packit 71fd91
            return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
      case BZ_M_FLUSHING:
Packit 71fd91
         if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
Packit 71fd91
         if (s->avail_in_expect != s->strm->avail_in) 
Packit 71fd91
            return BZ_SEQUENCE_ERROR;
Packit 71fd91
         progress = handle_compress ( strm );
Packit 71fd91
         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
Packit 71fd91
             s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
Packit 71fd91
         s->mode = BZ_M_RUNNING;
Packit 71fd91
         return BZ_RUN_OK;
Packit 71fd91
Packit 71fd91
      case BZ_M_FINISHING:
Packit 71fd91
         if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
Packit 71fd91
         if (s->avail_in_expect != s->strm->avail_in) 
Packit 71fd91
            return BZ_SEQUENCE_ERROR;
Packit 71fd91
         progress = handle_compress ( strm );
Packit 71fd91
         if (!progress) return BZ_SEQUENCE_ERROR;
Packit 71fd91
         if (s->avail_in_expect > 0 || !isempty_RL(s) ||
Packit 71fd91
             s->state_out_pos < s->numZ) return BZ_FINISH_OK;
Packit 71fd91
         s->mode = BZ_M_IDLE;
Packit 71fd91
         return BZ_STREAM_END;
Packit 71fd91
   }
Packit 71fd91
   return BZ_OK; /*--not reached--*/
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
Packit 71fd91
{
Packit 71fd91
   EState* s;
Packit 71fd91
   if (strm == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   s = strm->state;
Packit 71fd91
   if (s == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   if (s->strm != strm) return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   if (s->arr1 != NULL) BZFREE(s->arr1);
Packit 71fd91
   if (s->arr2 != NULL) BZFREE(s->arr2);
Packit 71fd91
   if (s->ftab != NULL) BZFREE(s->ftab);
Packit 71fd91
   BZFREE(strm->state);
Packit 71fd91
Packit 71fd91
   strm->state = NULL;   
Packit 71fd91
Packit 71fd91
   return BZ_OK;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--- Decompression stuff                         ---*/
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzDecompressInit) 
Packit 71fd91
                     ( bz_stream* strm, 
Packit 71fd91
                       int        verbosity,
Packit 71fd91
                       int        small )
Packit 71fd91
{
Packit 71fd91
   DState* s;
Packit 71fd91
Packit 71fd91
   if (!bz_config_ok()) return BZ_CONFIG_ERROR;
Packit 71fd91
Packit 71fd91
   if (strm == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   if (small != 0 && small != 1) return BZ_PARAM_ERROR;
Packit 71fd91
   if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
Packit 71fd91
   if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
Packit 71fd91
Packit 71fd91
   s = BZALLOC( sizeof(DState) );
Packit 71fd91
   if (s == NULL) return BZ_MEM_ERROR;
Packit 71fd91
   s->strm                  = strm;
Packit 71fd91
   strm->state              = s;
Packit 71fd91
   s->state                 = BZ_X_MAGIC_1;
Packit 71fd91
   s->bsLive                = 0;
Packit 71fd91
   s->bsBuff                = 0;
Packit 71fd91
   s->calculatedCombinedCRC = 0;
Packit 71fd91
   strm->total_in_lo32      = 0;
Packit 71fd91
   strm->total_in_hi32      = 0;
Packit 71fd91
   strm->total_out_lo32     = 0;
Packit 71fd91
   strm->total_out_hi32     = 0;
Packit 71fd91
   s->smallDecompress       = (Bool)small;
Packit 71fd91
   s->ll4                   = NULL;
Packit 71fd91
   s->ll16                  = NULL;
Packit 71fd91
   s->tt                    = NULL;
Packit 71fd91
   s->currBlockNo           = 0;
Packit 71fd91
   s->verbosity             = verbosity;
Packit 71fd91
Packit 71fd91
   return BZ_OK;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/* Return  True iff data corruption is discovered.
Packit 71fd91
   Returns False if there is no problem.
Packit 71fd91
*/
Packit 71fd91
static
Packit 71fd91
Bool unRLE_obuf_to_output_FAST ( DState* s )
Packit 71fd91
{
Packit 71fd91
   UChar k1;
Packit 71fd91
Packit 71fd91
   if (s->blockRandomised) {
Packit 71fd91
Packit 71fd91
      while (True) {
Packit 71fd91
         /* try to finish existing run */
Packit 71fd91
         while (True) {
Packit 71fd91
            if (s->strm->avail_out == 0) return False;
Packit 71fd91
            if (s->state_out_len == 0) break;
Packit 71fd91
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
Packit 71fd91
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
Packit 71fd91
            s->state_out_len--;
Packit 71fd91
            s->strm->next_out++;
Packit 71fd91
            s->strm->avail_out--;
Packit 71fd91
            s->strm->total_out_lo32++;
Packit 71fd91
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
Packit 71fd91
         }
Packit 71fd91
Packit 71fd91
         /* can a new run be started? */
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) return False;
Packit 71fd91
               
Packit 71fd91
         /* Only caused by corrupt data stream? */
Packit 71fd91
         if (s->nblock_used > s->save_nblock+1)
Packit 71fd91
            return True;
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 1;
Packit 71fd91
         s->state_out_ch = s->k0;
Packit 71fd91
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 2;
Packit 71fd91
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 3;
Packit 71fd91
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         s->state_out_len = ((Int32)k1) + 4;
Packit 71fd91
         BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
Packit 71fd91
         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
   } else {
Packit 71fd91
Packit 71fd91
      /* restore */
Packit 71fd91
      UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
Packit 71fd91
      UChar         c_state_out_ch       = s->state_out_ch;
Packit 71fd91
      Int32         c_state_out_len      = s->state_out_len;
Packit 71fd91
      Int32         c_nblock_used        = s->nblock_used;
Packit 71fd91
      Int32         c_k0                 = s->k0;
Packit 71fd91
      UInt32*       c_tt                 = s->tt;
Packit 71fd91
      UInt32        c_tPos               = s->tPos;
Packit 71fd91
      char*         cs_next_out          = s->strm->next_out;
Packit 71fd91
      unsigned int  cs_avail_out         = s->strm->avail_out;
Packit 71fd91
      Int32         ro_blockSize100k     = s->blockSize100k;
Packit 71fd91
      /* end restore */
Packit 71fd91
Packit 71fd91
      UInt32       avail_out_INIT = cs_avail_out;
Packit 71fd91
      Int32        s_save_nblockPP = s->save_nblock+1;
Packit 71fd91
      unsigned int total_out_lo32_old;
Packit 71fd91
Packit 71fd91
      while (True) {
Packit 71fd91
Packit 71fd91
         /* try to finish existing run */
Packit 71fd91
         if (c_state_out_len > 0) {
Packit 71fd91
            while (True) {
Packit 71fd91
               if (cs_avail_out == 0) goto return_notr;
Packit 71fd91
               if (c_state_out_len == 1) break;
Packit 71fd91
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
Packit 71fd91
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
Packit 71fd91
               c_state_out_len--;
Packit 71fd91
               cs_next_out++;
Packit 71fd91
               cs_avail_out--;
Packit 71fd91
            }
Packit 71fd91
            s_state_out_len_eq_one:
Packit 71fd91
            {
Packit 71fd91
               if (cs_avail_out == 0) { 
Packit 71fd91
                  c_state_out_len = 1; goto return_notr;
Packit 71fd91
               };
Packit 71fd91
               *( (UChar*)(cs_next_out) ) = c_state_out_ch;
Packit 71fd91
               BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
Packit 71fd91
               cs_next_out++;
Packit 71fd91
               cs_avail_out--;
Packit 71fd91
            }
Packit 71fd91
         }   
Packit 71fd91
         /* Only caused by corrupt data stream? */
Packit 71fd91
         if (c_nblock_used > s_save_nblockPP)
Packit 71fd91
            return True;
Packit 71fd91
Packit 71fd91
         /* can a new run be started? */
Packit 71fd91
         if (c_nblock_used == s_save_nblockPP) {
Packit 71fd91
            c_state_out_len = 0; goto return_notr;
Packit 71fd91
         };   
Packit 71fd91
         c_state_out_ch = c_k0;
Packit 71fd91
         BZ_GET_FAST_C(k1); c_nblock_used++;
Packit 71fd91
         if (k1 != c_k0) { 
Packit 71fd91
            c_k0 = k1; goto s_state_out_len_eq_one; 
Packit 71fd91
         };
Packit 71fd91
         if (c_nblock_used == s_save_nblockPP) 
Packit 71fd91
            goto s_state_out_len_eq_one;
Packit 71fd91
   
Packit 71fd91
         c_state_out_len = 2;
Packit 71fd91
         BZ_GET_FAST_C(k1); c_nblock_used++;
Packit 71fd91
         if (c_nblock_used == s_save_nblockPP) continue;
Packit 71fd91
         if (k1 != c_k0) { c_k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         c_state_out_len = 3;
Packit 71fd91
         BZ_GET_FAST_C(k1); c_nblock_used++;
Packit 71fd91
         if (c_nblock_used == s_save_nblockPP) continue;
Packit 71fd91
         if (k1 != c_k0) { c_k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         BZ_GET_FAST_C(k1); c_nblock_used++;
Packit 71fd91
         c_state_out_len = ((Int32)k1) + 4;
Packit 71fd91
         BZ_GET_FAST_C(c_k0); c_nblock_used++;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      return_notr:
Packit 71fd91
      total_out_lo32_old = s->strm->total_out_lo32;
Packit 71fd91
      s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
Packit 71fd91
      if (s->strm->total_out_lo32 < total_out_lo32_old)
Packit 71fd91
         s->strm->total_out_hi32++;
Packit 71fd91
Packit 71fd91
      /* save */
Packit 71fd91
      s->calculatedBlockCRC = c_calculatedBlockCRC;
Packit 71fd91
      s->state_out_ch       = c_state_out_ch;
Packit 71fd91
      s->state_out_len      = c_state_out_len;
Packit 71fd91
      s->nblock_used        = c_nblock_used;
Packit 71fd91
      s->k0                 = c_k0;
Packit 71fd91
      s->tt                 = c_tt;
Packit 71fd91
      s->tPos               = c_tPos;
Packit 71fd91
      s->strm->next_out     = cs_next_out;
Packit 71fd91
      s->strm->avail_out    = cs_avail_out;
Packit 71fd91
      /* end save */
Packit 71fd91
   }
Packit 71fd91
   return False;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
Packit 71fd91
{
Packit 71fd91
   Int32 nb, na, mid;
Packit 71fd91
   nb = 0;
Packit 71fd91
   na = 256;
Packit 71fd91
   do {
Packit 71fd91
      mid = (nb + na) >> 1;
Packit 71fd91
      if (indx >= cftab[mid]) nb = mid; else na = mid;
Packit 71fd91
   }
Packit 71fd91
   while (na - nb != 1);
Packit 71fd91
   return nb;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/* Return  True iff data corruption is discovered.
Packit 71fd91
   Returns False if there is no problem.
Packit 71fd91
*/
Packit 71fd91
static
Packit 71fd91
Bool unRLE_obuf_to_output_SMALL ( DState* s )
Packit 71fd91
{
Packit 71fd91
   UChar k1;
Packit 71fd91
Packit 71fd91
   if (s->blockRandomised) {
Packit 71fd91
Packit 71fd91
      while (True) {
Packit 71fd91
         /* try to finish existing run */
Packit 71fd91
         while (True) {
Packit 71fd91
            if (s->strm->avail_out == 0) return False;
Packit 71fd91
            if (s->state_out_len == 0) break;
Packit 71fd91
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
Packit 71fd91
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
Packit 71fd91
            s->state_out_len--;
Packit 71fd91
            s->strm->next_out++;
Packit 71fd91
            s->strm->avail_out--;
Packit 71fd91
            s->strm->total_out_lo32++;
Packit 71fd91
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
Packit 71fd91
         }
Packit 71fd91
   
Packit 71fd91
         /* can a new run be started? */
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) return False;
Packit 71fd91
Packit 71fd91
         /* Only caused by corrupt data stream? */
Packit 71fd91
         if (s->nblock_used > s->save_nblock+1)
Packit 71fd91
            return True;
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 1;
Packit 71fd91
         s->state_out_ch = s->k0;
Packit 71fd91
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 2;
Packit 71fd91
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 3;
Packit 71fd91
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
Packit 71fd91
         k1 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
         s->state_out_len = ((Int32)k1) + 4;
Packit 71fd91
         BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
Packit 71fd91
         s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
   } else {
Packit 71fd91
Packit 71fd91
      while (True) {
Packit 71fd91
         /* try to finish existing run */
Packit 71fd91
         while (True) {
Packit 71fd91
            if (s->strm->avail_out == 0) return False;
Packit 71fd91
            if (s->state_out_len == 0) break;
Packit 71fd91
            *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
Packit 71fd91
            BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
Packit 71fd91
            s->state_out_len--;
Packit 71fd91
            s->strm->next_out++;
Packit 71fd91
            s->strm->avail_out--;
Packit 71fd91
            s->strm->total_out_lo32++;
Packit 71fd91
            if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
Packit 71fd91
         }
Packit 71fd91
   
Packit 71fd91
         /* can a new run be started? */
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) return False;
Packit 71fd91
Packit 71fd91
         /* Only caused by corrupt data stream? */
Packit 71fd91
         if (s->nblock_used > s->save_nblock+1)
Packit 71fd91
            return True;
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 1;
Packit 71fd91
         s->state_out_ch = s->k0;
Packit 71fd91
         BZ_GET_SMALL(k1); s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 2;
Packit 71fd91
         BZ_GET_SMALL(k1); s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         s->state_out_len = 3;
Packit 71fd91
         BZ_GET_SMALL(k1); s->nblock_used++;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1) continue;
Packit 71fd91
         if (k1 != s->k0) { s->k0 = k1; continue; };
Packit 71fd91
   
Packit 71fd91
         BZ_GET_SMALL(k1); s->nblock_used++;
Packit 71fd91
         s->state_out_len = ((Int32)k1) + 4;
Packit 71fd91
         BZ_GET_SMALL(s->k0); s->nblock_used++;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
   }
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
Packit 71fd91
{
Packit 71fd91
   Bool    corrupt;
Packit 71fd91
   DState* s;
Packit 71fd91
   if (strm == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   s = strm->state;
Packit 71fd91
   if (s == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   if (s->strm != strm) return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   while (True) {
Packit 71fd91
      if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
Packit 71fd91
      if (s->state == BZ_X_OUTPUT) {
Packit 71fd91
         if (s->smallDecompress)
Packit 71fd91
            corrupt = unRLE_obuf_to_output_SMALL ( s ); else
Packit 71fd91
            corrupt = unRLE_obuf_to_output_FAST  ( s );
Packit 71fd91
         if (corrupt) return BZ_DATA_ERROR;
Packit 71fd91
         if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
Packit 71fd91
            BZ_FINALISE_CRC ( s->calculatedBlockCRC );
Packit 71fd91
            if (s->verbosity >= 3) 
Packit 71fd91
               VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
Packit 71fd91
                          s->calculatedBlockCRC );
Packit 71fd91
            if (s->verbosity >= 2) VPrintf0 ( "]" );
Packit 71fd91
            if (s->calculatedBlockCRC != s->storedBlockCRC)
Packit 71fd91
               return BZ_DATA_ERROR;
Packit 71fd91
            s->calculatedCombinedCRC 
Packit 71fd91
               = (s->calculatedCombinedCRC << 1) | 
Packit 71fd91
                    (s->calculatedCombinedCRC >> 31);
Packit 71fd91
            s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
Packit 71fd91
            s->state = BZ_X_BLKHDR_1;
Packit 71fd91
         } else {
Packit 71fd91
            return BZ_OK;
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
      if (s->state >= BZ_X_MAGIC_1) {
Packit 71fd91
         Int32 r = BZ2_decompress ( s );
Packit 71fd91
         if (r == BZ_STREAM_END) {
Packit 71fd91
            if (s->verbosity >= 3)
Packit 71fd91
               VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
Packit 71fd91
                          s->storedCombinedCRC, s->calculatedCombinedCRC );
Packit 71fd91
            if (s->calculatedCombinedCRC != s->storedCombinedCRC)
Packit 71fd91
               return BZ_DATA_ERROR;
Packit 71fd91
            return r;
Packit 71fd91
         }
Packit 71fd91
         if (s->state != BZ_X_OUTPUT) return r;
Packit 71fd91
      }
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   AssertH ( 0, 6001 );
Packit 71fd91
Packit 71fd91
   return 0;  /*NOTREACHED*/
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
Packit 71fd91
{
Packit 71fd91
   DState* s;
Packit 71fd91
   if (strm == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   s = strm->state;
Packit 71fd91
   if (s == NULL) return BZ_PARAM_ERROR;
Packit 71fd91
   if (s->strm != strm) return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   if (s->tt   != NULL) BZFREE(s->tt);
Packit 71fd91
   if (s->ll16 != NULL) BZFREE(s->ll16);
Packit 71fd91
   if (s->ll4  != NULL) BZFREE(s->ll4);
Packit 71fd91
Packit 71fd91
   BZFREE(strm->state);
Packit 71fd91
   strm->state = NULL;
Packit 71fd91
Packit 71fd91
   return BZ_OK;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
#ifndef BZ_NO_STDIO
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--- File I/O stuff                              ---*/
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
Packit 71fd91
#define BZ_SETERR(eee)                    \
Packit 71fd91
{                                         \
Packit 71fd91
   if (bzerror != NULL) *bzerror = eee;   \
Packit 71fd91
   if (bzf != NULL) bzf->lastErr = eee;   \
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
typedef 
Packit 71fd91
   struct {
Packit 71fd91
      FILE*     handle;
Packit 71fd91
      Char      buf[BZ_MAX_UNUSED];
Packit 71fd91
      Int32     bufN;
Packit 71fd91
      Bool      writing;
Packit 71fd91
      bz_stream strm;
Packit 71fd91
      Int32     lastErr;
Packit 71fd91
      Bool      initialisedOk;
Packit 71fd91
   }
Packit 71fd91
   bzFile;
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------*/
Packit 71fd91
static Bool myfeof ( FILE* f )
Packit 71fd91
{
Packit 71fd91
   Int32 c = fgetc ( f );
Packit 71fd91
   if (c == EOF) return True;
Packit 71fd91
   ungetc ( c, f );
Packit 71fd91
   return False;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
BZFILE* BZ_API(BZ2_bzWriteOpen) 
Packit 71fd91
                    ( int*  bzerror,      
Packit 71fd91
                      FILE* f, 
Packit 71fd91
                      int   blockSize100k, 
Packit 71fd91
                      int   verbosity,
Packit 71fd91
                      int   workFactor )
Packit 71fd91
{
Packit 71fd91
   Int32   ret;
Packit 71fd91
   bzFile* bzf = NULL;
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
Packit 71fd91
   if (f == NULL ||
Packit 71fd91
       (blockSize100k < 1 || blockSize100k > 9) ||
Packit 71fd91
       (workFactor < 0 || workFactor > 250) ||
Packit 71fd91
       (verbosity < 0 || verbosity > 4))
Packit 71fd91
      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
Packit 71fd91
Packit 71fd91
   if (ferror(f))
Packit 71fd91
      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
Packit 71fd91
Packit 71fd91
   bzf = malloc ( sizeof(bzFile) );
Packit 71fd91
   if (bzf == NULL)
Packit 71fd91
      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
   bzf->initialisedOk = False;
Packit 71fd91
   bzf->bufN          = 0;
Packit 71fd91
   bzf->handle        = f;
Packit 71fd91
   bzf->writing       = True;
Packit 71fd91
   bzf->strm.bzalloc  = NULL;
Packit 71fd91
   bzf->strm.bzfree   = NULL;
Packit 71fd91
   bzf->strm.opaque   = NULL;
Packit 71fd91
Packit 71fd91
   if (workFactor == 0) workFactor = 30;
Packit 71fd91
   ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
Packit 71fd91
                              verbosity, workFactor );
Packit 71fd91
   if (ret != BZ_OK)
Packit 71fd91
      { BZ_SETERR(ret); free(bzf); return NULL; };
Packit 71fd91
Packit 71fd91
   bzf->strm.avail_in = 0;
Packit 71fd91
   bzf->initialisedOk = True;
Packit 71fd91
   return bzf;   
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
void BZ_API(BZ2_bzWrite)
Packit 71fd91
             ( int*    bzerror, 
Packit 71fd91
               BZFILE* b, 
Packit 71fd91
               void*   buf, 
Packit 71fd91
               int     len )
Packit 71fd91
{
Packit 71fd91
   Int32 n, n2, ret;
Packit 71fd91
   bzFile* bzf = (bzFile*)b;
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
   if (bzf == NULL || buf == NULL || len < 0)
Packit 71fd91
      { BZ_SETERR(BZ_PARAM_ERROR); return; };
Packit 71fd91
   if (!(bzf->writing))
Packit 71fd91
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
Packit 71fd91
   if (ferror(bzf->handle))
Packit 71fd91
      { BZ_SETERR(BZ_IO_ERROR); return; };
Packit 71fd91
Packit 71fd91
   if (len == 0)
Packit 71fd91
      { BZ_SETERR(BZ_OK); return; };
Packit 71fd91
Packit 71fd91
   bzf->strm.avail_in = len;
Packit 71fd91
   bzf->strm.next_in  = buf;
Packit 71fd91
Packit 71fd91
   while (True) {
Packit 71fd91
      bzf->strm.avail_out = BZ_MAX_UNUSED;
Packit 71fd91
      bzf->strm.next_out = bzf->buf;
Packit 71fd91
      ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
Packit 71fd91
      if (ret != BZ_RUN_OK)
Packit 71fd91
         { BZ_SETERR(ret); return; };
Packit 71fd91
Packit 71fd91
      if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
Packit 71fd91
         n = BZ_MAX_UNUSED - bzf->strm.avail_out;
Packit 71fd91
         n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
Packit 71fd91
                       n, bzf->handle );
Packit 71fd91
         if (n != n2 || ferror(bzf->handle))
Packit 71fd91
            { BZ_SETERR(BZ_IO_ERROR); return; };
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      if (bzf->strm.avail_in == 0)
Packit 71fd91
         { BZ_SETERR(BZ_OK); return; };
Packit 71fd91
   }
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
void BZ_API(BZ2_bzWriteClose)
Packit 71fd91
                  ( int*          bzerror, 
Packit 71fd91
                    BZFILE*       b, 
Packit 71fd91
                    int           abandon,
Packit 71fd91
                    unsigned int* nbytes_in,
Packit 71fd91
                    unsigned int* nbytes_out )
Packit 71fd91
{
Packit 71fd91
   BZ2_bzWriteClose64 ( bzerror, b, abandon, 
Packit 71fd91
                        nbytes_in, NULL, nbytes_out, NULL );
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
void BZ_API(BZ2_bzWriteClose64)
Packit 71fd91
                  ( int*          bzerror, 
Packit 71fd91
                    BZFILE*       b, 
Packit 71fd91
                    int           abandon,
Packit 71fd91
                    unsigned int* nbytes_in_lo32,
Packit 71fd91
                    unsigned int* nbytes_in_hi32,
Packit 71fd91
                    unsigned int* nbytes_out_lo32,
Packit 71fd91
                    unsigned int* nbytes_out_hi32 )
Packit 71fd91
{
Packit 71fd91
   Int32   n, n2, ret;
Packit 71fd91
   bzFile* bzf = (bzFile*)b;
Packit 71fd91
Packit 71fd91
   if (bzf == NULL)
Packit 71fd91
      { BZ_SETERR(BZ_OK); return; };
Packit 71fd91
   if (!(bzf->writing))
Packit 71fd91
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
Packit 71fd91
   if (ferror(bzf->handle))
Packit 71fd91
      { BZ_SETERR(BZ_IO_ERROR); return; };
Packit 71fd91
Packit 71fd91
   if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
Packit 71fd91
   if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
Packit 71fd91
   if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
Packit 71fd91
   if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
Packit 71fd91
Packit 71fd91
   if ((!abandon) && bzf->lastErr == BZ_OK) {
Packit 71fd91
      while (True) {
Packit 71fd91
         bzf->strm.avail_out = BZ_MAX_UNUSED;
Packit 71fd91
         bzf->strm.next_out = bzf->buf;
Packit 71fd91
         ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
Packit 71fd91
         if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
Packit 71fd91
            { BZ_SETERR(ret); return; };
Packit 71fd91
Packit 71fd91
         if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
Packit 71fd91
            n = BZ_MAX_UNUSED - bzf->strm.avail_out;
Packit 71fd91
            n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
Packit 71fd91
                          n, bzf->handle );
Packit 71fd91
            if (n != n2 || ferror(bzf->handle))
Packit 71fd91
               { BZ_SETERR(BZ_IO_ERROR); return; };
Packit 71fd91
         }
Packit 71fd91
Packit 71fd91
         if (ret == BZ_STREAM_END) break;
Packit 71fd91
      }
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   if ( !abandon && !ferror ( bzf->handle ) ) {
Packit 71fd91
      fflush ( bzf->handle );
Packit 71fd91
      if (ferror(bzf->handle))
Packit 71fd91
         { BZ_SETERR(BZ_IO_ERROR); return; };
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   if (nbytes_in_lo32 != NULL)
Packit 71fd91
      *nbytes_in_lo32 = bzf->strm.total_in_lo32;
Packit 71fd91
   if (nbytes_in_hi32 != NULL)
Packit 71fd91
      *nbytes_in_hi32 = bzf->strm.total_in_hi32;
Packit 71fd91
   if (nbytes_out_lo32 != NULL)
Packit 71fd91
      *nbytes_out_lo32 = bzf->strm.total_out_lo32;
Packit 71fd91
   if (nbytes_out_hi32 != NULL)
Packit 71fd91
      *nbytes_out_hi32 = bzf->strm.total_out_hi32;
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
   BZ2_bzCompressEnd ( &(bzf->strm) );
Packit 71fd91
   free ( bzf );
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
BZFILE* BZ_API(BZ2_bzReadOpen) 
Packit 71fd91
                   ( int*  bzerror, 
Packit 71fd91
                     FILE* f, 
Packit 71fd91
                     int   verbosity,
Packit 71fd91
                     int   small,
Packit 71fd91
                     void* unused,
Packit 71fd91
                     int   nUnused )
Packit 71fd91
{
Packit 71fd91
   bzFile* bzf = NULL;
Packit 71fd91
   int     ret;
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
Packit 71fd91
   if (f == NULL || 
Packit 71fd91
       (small != 0 && small != 1) ||
Packit 71fd91
       (verbosity < 0 || verbosity > 4) ||
Packit 71fd91
       (unused == NULL && nUnused != 0) ||
Packit 71fd91
       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
Packit 71fd91
      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
Packit 71fd91
Packit 71fd91
   if (ferror(f))
Packit 71fd91
      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
Packit 71fd91
Packit 71fd91
   bzf = malloc ( sizeof(bzFile) );
Packit 71fd91
   if (bzf == NULL) 
Packit 71fd91
      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
Packit 71fd91
   bzf->initialisedOk = False;
Packit 71fd91
   bzf->handle        = f;
Packit 71fd91
   bzf->bufN          = 0;
Packit 71fd91
   bzf->writing       = False;
Packit 71fd91
   bzf->strm.bzalloc  = NULL;
Packit 71fd91
   bzf->strm.bzfree   = NULL;
Packit 71fd91
   bzf->strm.opaque   = NULL;
Packit 71fd91
   
Packit 71fd91
   while (nUnused > 0) {
Packit 71fd91
      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
Packit 71fd91
      unused = ((void*)( 1 + ((UChar*)(unused))  ));
Packit 71fd91
      nUnused--;
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
Packit 71fd91
   if (ret != BZ_OK)
Packit 71fd91
      { BZ_SETERR(ret); free(bzf); return NULL; };
Packit 71fd91
Packit 71fd91
   bzf->strm.avail_in = bzf->bufN;
Packit 71fd91
   bzf->strm.next_in  = bzf->buf;
Packit 71fd91
Packit 71fd91
   bzf->initialisedOk = True;
Packit 71fd91
   return bzf;   
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
Packit 71fd91
{
Packit 71fd91
   bzFile* bzf = (bzFile*)b;
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
   if (bzf == NULL)
Packit 71fd91
      { BZ_SETERR(BZ_OK); return; };
Packit 71fd91
Packit 71fd91
   if (bzf->writing)
Packit 71fd91
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
Packit 71fd91
Packit 71fd91
   if (bzf->initialisedOk)
Packit 71fd91
      (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
Packit 71fd91
   free ( bzf );
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzRead) 
Packit 71fd91
           ( int*    bzerror, 
Packit 71fd91
             BZFILE* b, 
Packit 71fd91
             void*   buf, 
Packit 71fd91
             int     len )
Packit 71fd91
{
Packit 71fd91
   Int32   n, ret;
Packit 71fd91
   bzFile* bzf = (bzFile*)b;
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
Packit 71fd91
   if (bzf == NULL || buf == NULL || len < 0)
Packit 71fd91
      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
Packit 71fd91
Packit 71fd91
   if (bzf->writing)
Packit 71fd91
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
Packit 71fd91
Packit 71fd91
   if (len == 0)
Packit 71fd91
      { BZ_SETERR(BZ_OK); return 0; };
Packit 71fd91
Packit 71fd91
   bzf->strm.avail_out = len;
Packit 71fd91
   bzf->strm.next_out = buf;
Packit 71fd91
Packit 71fd91
   while (True) {
Packit 71fd91
Packit 71fd91
      if (ferror(bzf->handle)) 
Packit 71fd91
         { BZ_SETERR(BZ_IO_ERROR); return 0; };
Packit 71fd91
Packit 71fd91
      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
Packit 71fd91
         n = fread ( bzf->buf, sizeof(UChar), 
Packit 71fd91
                     BZ_MAX_UNUSED, bzf->handle );
Packit 71fd91
         if (ferror(bzf->handle))
Packit 71fd91
            { BZ_SETERR(BZ_IO_ERROR); return 0; };
Packit 71fd91
         bzf->bufN = n;
Packit 71fd91
         bzf->strm.avail_in = bzf->bufN;
Packit 71fd91
         bzf->strm.next_in = bzf->buf;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      ret = BZ2_bzDecompress ( &(bzf->strm) );
Packit 71fd91
Packit 71fd91
      if (ret != BZ_OK && ret != BZ_STREAM_END)
Packit 71fd91
         { BZ_SETERR(ret); return 0; };
Packit 71fd91
Packit 71fd91
      if (ret == BZ_OK && myfeof(bzf->handle) && 
Packit 71fd91
          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
Packit 71fd91
         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
Packit 71fd91
Packit 71fd91
      if (ret == BZ_STREAM_END)
Packit 71fd91
         { BZ_SETERR(BZ_STREAM_END);
Packit 71fd91
           return len - bzf->strm.avail_out; };
Packit 71fd91
      if (bzf->strm.avail_out == 0)
Packit 71fd91
         { BZ_SETERR(BZ_OK); return len; };
Packit 71fd91
      
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   return 0; /*not reached*/
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
void BZ_API(BZ2_bzReadGetUnused) 
Packit 71fd91
                     ( int*    bzerror, 
Packit 71fd91
                       BZFILE* b, 
Packit 71fd91
                       void**  unused, 
Packit 71fd91
                       int*    nUnused )
Packit 71fd91
{
Packit 71fd91
   bzFile* bzf = (bzFile*)b;
Packit 71fd91
   if (bzf == NULL)
Packit 71fd91
      { BZ_SETERR(BZ_PARAM_ERROR); return; };
Packit 71fd91
   if (bzf->lastErr != BZ_STREAM_END)
Packit 71fd91
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
Packit 71fd91
   if (unused == NULL || nUnused == NULL)
Packit 71fd91
      { BZ_SETERR(BZ_PARAM_ERROR); return; };
Packit 71fd91
Packit 71fd91
   BZ_SETERR(BZ_OK);
Packit 71fd91
   *nUnused = bzf->strm.avail_in;
Packit 71fd91
   *unused = bzf->strm.next_in;
Packit 71fd91
}
Packit 71fd91
#endif
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--- Misc convenience stuff                      ---*/
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzBuffToBuffCompress) 
Packit 71fd91
                         ( char*         dest, 
Packit 71fd91
                           unsigned int* destLen,
Packit 71fd91
                           char*         source, 
Packit 71fd91
                           unsigned int  sourceLen,
Packit 71fd91
                           int           blockSize100k, 
Packit 71fd91
                           int           verbosity, 
Packit 71fd91
                           int           workFactor )
Packit 71fd91
{
Packit 71fd91
   bz_stream strm;
Packit 71fd91
   int ret;
Packit 71fd91
Packit 71fd91
   if (dest == NULL || destLen == NULL || 
Packit 71fd91
       source == NULL ||
Packit 71fd91
       blockSize100k < 1 || blockSize100k > 9 ||
Packit 71fd91
       verbosity < 0 || verbosity > 4 ||
Packit 71fd91
       workFactor < 0 || workFactor > 250) 
Packit 71fd91
      return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   if (workFactor == 0) workFactor = 30;
Packit 71fd91
   strm.bzalloc = NULL;
Packit 71fd91
   strm.bzfree = NULL;
Packit 71fd91
   strm.opaque = NULL;
Packit 71fd91
   ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
Packit 71fd91
                              verbosity, workFactor );
Packit 71fd91
   if (ret != BZ_OK) return ret;
Packit 71fd91
Packit 71fd91
   strm.next_in = source;
Packit 71fd91
   strm.next_out = dest;
Packit 71fd91
   strm.avail_in = sourceLen;
Packit 71fd91
   strm.avail_out = *destLen;
Packit 71fd91
Packit 71fd91
   ret = BZ2_bzCompress ( &strm, BZ_FINISH );
Packit 71fd91
   if (ret == BZ_FINISH_OK) goto output_overflow;
Packit 71fd91
   if (ret != BZ_STREAM_END) goto errhandler;
Packit 71fd91
Packit 71fd91
   /* normal termination */
Packit 71fd91
   *destLen -= strm.avail_out;   
Packit 71fd91
   BZ2_bzCompressEnd ( &strm );
Packit 71fd91
   return BZ_OK;
Packit 71fd91
Packit 71fd91
   output_overflow:
Packit 71fd91
   BZ2_bzCompressEnd ( &strm );
Packit 71fd91
   return BZ_OUTBUFF_FULL;
Packit 71fd91
Packit 71fd91
   errhandler:
Packit 71fd91
   BZ2_bzCompressEnd ( &strm );
Packit 71fd91
   return ret;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzBuffToBuffDecompress) 
Packit 71fd91
                           ( char*         dest, 
Packit 71fd91
                             unsigned int* destLen,
Packit 71fd91
                             char*         source, 
Packit 71fd91
                             unsigned int  sourceLen,
Packit 71fd91
                             int           small,
Packit 71fd91
                             int           verbosity )
Packit 71fd91
{
Packit 71fd91
   bz_stream strm;
Packit 71fd91
   int ret;
Packit 71fd91
Packit 71fd91
   if (dest == NULL || destLen == NULL || 
Packit 71fd91
       source == NULL ||
Packit 71fd91
       (small != 0 && small != 1) ||
Packit 71fd91
       verbosity < 0 || verbosity > 4) 
Packit 71fd91
          return BZ_PARAM_ERROR;
Packit 71fd91
Packit 71fd91
   strm.bzalloc = NULL;
Packit 71fd91
   strm.bzfree = NULL;
Packit 71fd91
   strm.opaque = NULL;
Packit 71fd91
   ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
Packit 71fd91
   if (ret != BZ_OK) return ret;
Packit 71fd91
Packit 71fd91
   strm.next_in = source;
Packit 71fd91
   strm.next_out = dest;
Packit 71fd91
   strm.avail_in = sourceLen;
Packit 71fd91
   strm.avail_out = *destLen;
Packit 71fd91
Packit 71fd91
   ret = BZ2_bzDecompress ( &strm );
Packit 71fd91
   if (ret == BZ_OK) goto output_overflow_or_eof;
Packit 71fd91
   if (ret != BZ_STREAM_END) goto errhandler;
Packit 71fd91
Packit 71fd91
   /* normal termination */
Packit 71fd91
   *destLen -= strm.avail_out;
Packit 71fd91
   BZ2_bzDecompressEnd ( &strm );
Packit 71fd91
   return BZ_OK;
Packit 71fd91
Packit 71fd91
   output_overflow_or_eof:
Packit 71fd91
   if (strm.avail_out > 0) {
Packit 71fd91
      BZ2_bzDecompressEnd ( &strm );
Packit 71fd91
      return BZ_UNEXPECTED_EOF;
Packit 71fd91
   } else {
Packit 71fd91
      BZ2_bzDecompressEnd ( &strm );
Packit 71fd91
      return BZ_OUTBUFF_FULL;
Packit 71fd91
   };      
Packit 71fd91
Packit 71fd91
   errhandler:
Packit 71fd91
   BZ2_bzDecompressEnd ( &strm );
Packit 71fd91
   return ret; 
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--
Packit 71fd91
   Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
Packit 71fd91
   to support better zlib compatibility.
Packit 71fd91
   This code is not _officially_ part of libbzip2 (yet);
Packit 71fd91
   I haven't tested it, documented it, or considered the
Packit 71fd91
   threading-safeness of it.
Packit 71fd91
   If this code breaks, please contact both Yoshioka and me.
Packit 71fd91
--*/
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--
Packit 71fd91
   return version like "0.9.5d, 4-Sept-1999".
Packit 71fd91
--*/
Packit 71fd91
const char * BZ_API(BZ2_bzlibVersion)(void)
Packit 71fd91
{
Packit 71fd91
   return BZ_VERSION;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
#ifndef BZ_NO_STDIO
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
Packit 71fd91
#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
Packit 71fd91
#   include <fcntl.h>
Packit 71fd91
#   include <io.h>
Packit 71fd91
#   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
Packit 71fd91
#else
Packit 71fd91
#   define SET_BINARY_MODE(file)
Packit 71fd91
#endif
Packit 71fd91
static
Packit 71fd91
BZFILE * bzopen_or_bzdopen
Packit 71fd91
               ( const char *path,   /* no use when bzdopen */
Packit 71fd91
                 int fd,             /* no use when bzdopen */
Packit 71fd91
                 const char *mode,
Packit 71fd91
                 int open_mode)      /* bzopen: 0, bzdopen:1 */
Packit 71fd91
{
Packit 71fd91
   int    bzerr;
Packit 71fd91
   char   unused[BZ_MAX_UNUSED];
Packit 71fd91
   int    blockSize100k = 9;
Packit 71fd91
   int    writing       = 0;
Packit 71fd91
   char   mode2[10]     = "";
Packit 71fd91
   FILE   *fp           = NULL;
Packit 71fd91
   BZFILE *bzfp         = NULL;
Packit 71fd91
   int    verbosity     = 0;
Packit 71fd91
   int    workFactor    = 30;
Packit 71fd91
   int    smallMode     = 0;
Packit 71fd91
   int    nUnused       = 0; 
Packit 71fd91
Packit 71fd91
   if (mode == NULL) return NULL;
Packit 71fd91
   while (*mode) {
Packit 71fd91
      switch (*mode) {
Packit 71fd91
      case 'r':
Packit 71fd91
         writing = 0; break;
Packit 71fd91
      case 'w':
Packit 71fd91
         writing = 1; break;
Packit 71fd91
      case 's':
Packit 71fd91
         smallMode = 1; break;
Packit 71fd91
      default:
Packit 71fd91
         if (isdigit((int)(*mode))) {
Packit 71fd91
            blockSize100k = *mode-BZ_HDR_0;
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
      mode++;
Packit 71fd91
   }
Packit 71fd91
   strcat(mode2, writing ? "w" : "r" );
Packit 71fd91
   strcat(mode2,"b");   /* binary mode */
Packit 71fd91
Packit 71fd91
   if (open_mode==0) {
Packit 71fd91
      if (path==NULL || strcmp(path,"")==0) {
Packit 71fd91
        fp = (writing ? stdout : stdin);
Packit 71fd91
        SET_BINARY_MODE(fp);
Packit 71fd91
      } else {
Packit 71fd91
        fp = fopen(path,mode2);
Packit 71fd91
      }
Packit 71fd91
   } else {
Packit 71fd91
#ifdef BZ_STRICT_ANSI
Packit 71fd91
      fp = NULL;
Packit 71fd91
#else
Packit 71fd91
      fp = fdopen(fd,mode2);
Packit 71fd91
#endif
Packit 71fd91
   }
Packit 71fd91
   if (fp == NULL) return NULL;
Packit 71fd91
Packit 71fd91
   if (writing) {
Packit 71fd91
      /* Guard against total chaos and anarchy -- JRS */
Packit 71fd91
      if (blockSize100k < 1) blockSize100k = 1;
Packit 71fd91
      if (blockSize100k > 9) blockSize100k = 9; 
Packit 71fd91
      bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
Packit 71fd91
                             verbosity,workFactor);
Packit 71fd91
   } else {
Packit 71fd91
      bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
Packit 71fd91
                            unused,nUnused);
Packit 71fd91
   }
Packit 71fd91
   if (bzfp == NULL) {
Packit 71fd91
      if (fp != stdin && fp != stdout) fclose(fp);
Packit 71fd91
      return NULL;
Packit 71fd91
   }
Packit 71fd91
   return bzfp;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--
Packit 71fd91
   open file for read or write.
Packit 71fd91
      ex) bzopen("file","w9")
Packit 71fd91
      case path="" or NULL => use stdin or stdout.
Packit 71fd91
--*/
Packit 71fd91
BZFILE * BZ_API(BZ2_bzopen)
Packit 71fd91
               ( const char *path,
Packit 71fd91
                 const char *mode )
Packit 71fd91
{
Packit 71fd91
   return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
BZFILE * BZ_API(BZ2_bzdopen)
Packit 71fd91
               ( int fd,
Packit 71fd91
                 const char *mode )
Packit 71fd91
{
Packit 71fd91
   return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
Packit 71fd91
{
Packit 71fd91
   int bzerr, nread;
Packit 71fd91
   if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
Packit 71fd91
   nread = BZ2_bzRead(&bzerr,b,buf,len);
Packit 71fd91
   if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
Packit 71fd91
      return nread;
Packit 71fd91
   } else {
Packit 71fd91
      return -1;
Packit 71fd91
   }
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
Packit 71fd91
{
Packit 71fd91
   int bzerr;
Packit 71fd91
Packit 71fd91
   BZ2_bzWrite(&bzerr,b,buf,len);
Packit 71fd91
   if(bzerr == BZ_OK){
Packit 71fd91
      return len;
Packit 71fd91
   }else{
Packit 71fd91
      return -1;
Packit 71fd91
   }
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
int BZ_API(BZ2_bzflush) (BZFILE *b)
Packit 71fd91
{
Packit 71fd91
   /* do nothing now... */
Packit 71fd91
   return 0;
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
void BZ_API(BZ2_bzclose) (BZFILE* b)
Packit 71fd91
{
Packit 71fd91
   int bzerr;
Packit 71fd91
   FILE *fp;
Packit 71fd91
   
Packit 71fd91
   if (b==NULL) {return;}
Packit 71fd91
   fp = ((bzFile *)b)->handle;
Packit 71fd91
   if(((bzFile*)b)->writing){
Packit 71fd91
      BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
Packit 71fd91
      if(bzerr != BZ_OK){
Packit 71fd91
         BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
Packit 71fd91
      }
Packit 71fd91
   }else{
Packit 71fd91
      BZ2_bzReadClose(&bzerr,b);
Packit 71fd91
   }
Packit 71fd91
   if(fp!=stdin && fp!=stdout){
Packit 71fd91
      fclose(fp);
Packit 71fd91
   }
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
/*--
Packit 71fd91
   return last error code 
Packit 71fd91
--*/
Packit 71fd91
static const char *bzerrorstrings[] = {
Packit 71fd91
       "OK"
Packit 71fd91
      ,"SEQUENCE_ERROR"
Packit 71fd91
      ,"PARAM_ERROR"
Packit 71fd91
      ,"MEM_ERROR"
Packit 71fd91
      ,"DATA_ERROR"
Packit 71fd91
      ,"DATA_ERROR_MAGIC"
Packit 71fd91
      ,"IO_ERROR"
Packit 71fd91
      ,"UNEXPECTED_EOF"
Packit 71fd91
      ,"OUTBUFF_FULL"
Packit 71fd91
      ,"CONFIG_ERROR"
Packit 71fd91
      ,"???"   /* for future */
Packit 71fd91
      ,"???"   /* for future */
Packit 71fd91
      ,"???"   /* for future */
Packit 71fd91
      ,"???"   /* for future */
Packit 71fd91
      ,"???"   /* for future */
Packit 71fd91
      ,"???"   /* for future */
Packit 71fd91
};
Packit 71fd91
Packit 71fd91
Packit 71fd91
const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
Packit 71fd91
{
Packit 71fd91
   int err = ((bzFile *)b)->lastErr;
Packit 71fd91
Packit 71fd91
   if(err>0) err = 0;
Packit 71fd91
   *errnum = err;
Packit 71fd91
   return bzerrorstrings[err*-1];
Packit 71fd91
}
Packit 71fd91
#endif
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*-------------------------------------------------------------*/
Packit 71fd91
/*--- end                                           bzlib.c ---*/
Packit 71fd91
/*-------------------------------------------------------------*/