ReactOS Fundraising Campaign 2012
 
€ 4,060 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bzlib.c
Go to the documentation of this file.
00001 
00002 /*-------------------------------------------------------------*/
00003 /*--- Library top-level functions.                          ---*/
00004 /*---                                               bzlib.c ---*/
00005 /*-------------------------------------------------------------*/
00006 
00007 /* ------------------------------------------------------------------
00008    This file is part of bzip2/libbzip2, a program and library for
00009    lossless, block-sorting data compression.
00010 
00011    bzip2/libbzip2 version 1.0.6 of 6 September 2010
00012    Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
00013 
00014    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
00015    README file.
00016 
00017    This program is released under the terms of the license contained
00018    in the file LICENSE.
00019    ------------------------------------------------------------------ */
00020 
00021 /* CHANGES
00022    0.9.0    -- original version.
00023    0.9.0a/b -- no changes in this file.
00024    0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
00025      fixed bzWrite/bzRead to ignore zero-length requests.
00026      fixed bzread to correctly handle read requests after EOF.
00027      wrong parameter order in call to bzDecompressInit in
00028      bzBuffToBuffDecompress.  Fixed.
00029 */
00030 
00031 #ifdef BZ_DECOMPRESS_ONLY
00032 #ifndef __NTDRIVER__
00033   #define __NTDRIVER__
00034 #endif
00035 #include <ntddk.h>
00036 #include <debug.h>
00037 #endif
00038 #include "bzlib_private.h"
00039 
00040 
00041 /*---------------------------------------------------*/
00042 /*--- Compression stuff                           ---*/
00043 /*---------------------------------------------------*/
00044 
00045 
00046 /*---------------------------------------------------*/
00047 #ifndef BZ_NO_STDIO
00048 void BZ2_bz__AssertH__fail ( int errcode )
00049 {
00050    fprintf(stderr, 
00051       "\n\nbzip2/libbzip2: internal error number %d.\n"
00052       "This is a bug in bzip2/libbzip2, %s.\n"
00053       "Please report it to me at: jseward@bzip.org.  If this happened\n"
00054       "when you were using some program which uses libbzip2 as a\n"
00055       "component, you should also report this bug to the author(s)\n"
00056       "of that program.  Please make an effort to report this bug;\n"
00057       "timely and accurate bug reports eventually lead to higher\n"
00058       "quality software.  Thanks.  Julian Seward, 10 December 2007.\n\n",
00059       errcode,
00060       BZ2_bzlibVersion()
00061    );
00062 
00063    if (errcode == 1007) {
00064    fprintf(stderr,
00065       "\n*** A special note about internal error number 1007 ***\n"
00066       "\n"
00067       "Experience suggests that a common cause of i.e. 1007\n"
00068       "is unreliable memory or other hardware.  The 1007 assertion\n"
00069       "just happens to cross-check the results of huge numbers of\n"
00070       "memory reads/writes, and so acts (unintendedly) as a stress\n"
00071       "test of your memory system.\n"
00072       "\n"
00073       "I suggest the following: try compressing the file again,\n"
00074       "possibly monitoring progress in detail with the -vv flag.\n"
00075       "\n"
00076       "* If the error cannot be reproduced, and/or happens at different\n"
00077       "  points in compression, you may have a flaky memory system.\n"
00078       "  Try a memory-test program.  I have used Memtest86\n"
00079       "  (www.memtest86.com).  At the time of writing it is free (GPLd).\n"
00080       "  Memtest86 tests memory much more thorougly than your BIOSs\n"
00081       "  power-on test, and may find failures that the BIOS doesn't.\n"
00082       "\n"
00083       "* If the error can be repeatably reproduced, this is a bug in\n"
00084       "  bzip2, and I would very much like to hear about it.  Please\n"
00085       "  let me know, and, ideally, save a copy of the file causing the\n"
00086       "  problem -- without which I will be unable to investigate it.\n"
00087       "\n"
00088    );
00089    }
00090 
00091    exit(3);
00092 }
00093 #endif
00094 
00095 
00096 /*---------------------------------------------------*/
00097 static
00098 int bz_config_ok ( void )
00099 {
00100    if (sizeof(int)   != 4) return 0;
00101    if (sizeof(short) != 2) return 0;
00102    if (sizeof(char)  != 1) return 0;
00103    return 1;
00104 }
00105 
00106 
00107 /*---------------------------------------------------*/
00108 static
00109 void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
00110 {
00111   return ExAllocatePool( PagedPool, items * size );
00112 }
00113 
00114 static
00115 void default_bzfree ( void* opaque, void* addr )
00116 {
00117   ExFreePool( addr );
00118 }
00119 
00120 #ifndef BZ_DECOMPRESS_ONLY
00121 
00122 /*---------------------------------------------------*/
00123 static
00124 void prepare_new_block ( EState* s )
00125 {
00126    Int32 i;
00127    s->nblock = 0;
00128    s->numZ = 0;
00129    s->state_out_pos = 0;
00130    BZ_INITIALISE_CRC ( s->blockCRC );
00131    for (i = 0; i < 256; i++) s->inUse[i] = False;
00132    s->blockNo++;
00133 }
00134 
00135 
00136 /*---------------------------------------------------*/
00137 static
00138 void init_RL ( EState* s )
00139 {
00140    s->state_in_ch  = 256;
00141    s->state_in_len = 0;
00142 }
00143 
00144 
00145 static
00146 Bool isempty_RL ( EState* s )
00147 {
00148    if (s->state_in_ch < 256 && s->state_in_len > 0)
00149       return False; else
00150       return True;
00151 }
00152 
00153 
00154 /*---------------------------------------------------*/
00155 int BZ_API(BZ2_bzCompressInit) 
00156                     ( bz_stream* strm, 
00157                      int        blockSize100k,
00158                      int        verbosity,
00159                      int        workFactor )
00160 {
00161    Int32   n;
00162    EState* s;
00163 
00164    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
00165 
00166    if (strm == NULL || 
00167        blockSize100k < 1 || blockSize100k > 9 ||
00168        workFactor < 0 || workFactor > 250)
00169      return BZ_PARAM_ERROR;
00170 
00171    if (workFactor == 0) workFactor = 30;
00172    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
00173    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
00174 
00175    s = BZALLOC( sizeof(EState) );
00176    if (s == NULL) return BZ_MEM_ERROR;
00177    s->strm = strm;
00178 
00179    s->arr1 = NULL;
00180    s->arr2 = NULL;
00181    s->ftab = NULL;
00182 
00183    n       = 100000 * blockSize100k;
00184    s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
00185    s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
00186    s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
00187 
00188    if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
00189       if (s->arr1 != NULL) BZFREE(s->arr1);
00190       if (s->arr2 != NULL) BZFREE(s->arr2);
00191       if (s->ftab != NULL) BZFREE(s->ftab);
00192       if (s       != NULL) BZFREE(s);
00193       return BZ_MEM_ERROR;
00194    }
00195 
00196    s->blockNo           = 0;
00197    s->state             = BZ_S_INPUT;
00198    s->mode              = BZ_M_RUNNING;
00199    s->combinedCRC       = 0;
00200    s->blockSize100k     = blockSize100k;
00201    s->nblockMAX         = 100000 * blockSize100k - 19;
00202    s->verbosity         = verbosity;
00203    s->workFactor        = workFactor;
00204 
00205    s->block             = (UChar*)s->arr2;
00206    s->mtfv              = (UInt16*)s->arr1;
00207    s->zbits             = NULL;
00208    s->ptr               = (UInt32*)s->arr1;
00209 
00210    strm->state          = s;
00211    strm->total_in_lo32  = 0;
00212    strm->total_in_hi32  = 0;
00213    strm->total_out_lo32 = 0;
00214    strm->total_out_hi32 = 0;
00215    init_RL ( s );
00216    prepare_new_block ( s );
00217    return BZ_OK;
00218 }
00219 
00220 
00221 /*---------------------------------------------------*/
00222 static
00223 void add_pair_to_block ( EState* s )
00224 {
00225    Int32 i;
00226    UChar ch = (UChar)(s->state_in_ch);
00227    for (i = 0; i < s->state_in_len; i++) {
00228       BZ_UPDATE_CRC( s->blockCRC, ch );
00229    }
00230    s->inUse[s->state_in_ch] = True;
00231    switch (s->state_in_len) {
00232       case 1:
00233          s->block[s->nblock] = (UChar)ch; s->nblock++;
00234          break;
00235       case 2:
00236          s->block[s->nblock] = (UChar)ch; s->nblock++;
00237          s->block[s->nblock] = (UChar)ch; s->nblock++;
00238          break;
00239       case 3:
00240          s->block[s->nblock] = (UChar)ch; s->nblock++;
00241          s->block[s->nblock] = (UChar)ch; s->nblock++;
00242          s->block[s->nblock] = (UChar)ch; s->nblock++;
00243          break;
00244       default:
00245          s->inUse[s->state_in_len-4] = True;
00246          s->block[s->nblock] = (UChar)ch; s->nblock++;
00247          s->block[s->nblock] = (UChar)ch; s->nblock++;
00248          s->block[s->nblock] = (UChar)ch; s->nblock++;
00249          s->block[s->nblock] = (UChar)ch; s->nblock++;
00250          s->block[s->nblock] = ((UChar)(s->state_in_len-4));
00251          s->nblock++;
00252          break;
00253    }
00254 }
00255 
00256 
00257 /*---------------------------------------------------*/
00258 static
00259 void flush_RL ( EState* s )
00260 {
00261    if (s->state_in_ch < 256) add_pair_to_block ( s );
00262    init_RL ( s );
00263 }
00264 
00265 
00266 /*---------------------------------------------------*/
00267 #define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
00268 {                                                 \
00269    UInt32 zchh = (UInt32)(zchh0);                 \
00270    /*-- fast track the common case --*/           \
00271    if (zchh != zs->state_in_ch &&                 \
00272        zs->state_in_len == 1) {                   \
00273       UChar ch = (UChar)(zs->state_in_ch);        \
00274       BZ_UPDATE_CRC( zs->blockCRC, ch );          \
00275       zs->inUse[zs->state_in_ch] = True;          \
00276       zs->block[zs->nblock] = (UChar)ch;          \
00277       zs->nblock++;                               \
00278       zs->state_in_ch = zchh;                     \
00279    }                                              \
00280    else                                           \
00281    /*-- general, uncommon cases --*/              \
00282    if (zchh != zs->state_in_ch ||                 \
00283       zs->state_in_len == 255) {                  \
00284       if (zs->state_in_ch < 256)                  \
00285          add_pair_to_block ( zs );                \
00286       zs->state_in_ch = zchh;                     \
00287       zs->state_in_len = 1;                       \
00288    } else {                                       \
00289       zs->state_in_len++;                         \
00290    }                                              \
00291 }
00292 
00293 
00294 /*---------------------------------------------------*/
00295 static
00296 Bool copy_input_until_stop ( EState* s )
00297 {
00298    Bool progress_in = False;
00299 
00300    if (s->mode == BZ_M_RUNNING) {
00301 
00302       /*-- fast track the common case --*/
00303       while (True) {
00304          /*-- block full? --*/
00305          if (s->nblock >= s->nblockMAX) break;
00306          /*-- no input? --*/
00307          if (s->strm->avail_in == 0) break;
00308          progress_in = True;
00309          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
00310          s->strm->next_in++;
00311          s->strm->avail_in--;
00312          s->strm->total_in_lo32++;
00313          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
00314       }
00315 
00316    } else {
00317 
00318       /*-- general, uncommon case --*/
00319       while (True) {
00320          /*-- block full? --*/
00321          if (s->nblock >= s->nblockMAX) break;
00322          /*-- no input? --*/
00323          if (s->strm->avail_in == 0) break;
00324          /*-- flush/finish end? --*/
00325          if (s->avail_in_expect == 0) break;
00326          progress_in = True;
00327          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); 
00328          s->strm->next_in++;
00329          s->strm->avail_in--;
00330          s->strm->total_in_lo32++;
00331          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
00332          s->avail_in_expect--;
00333       }
00334    }
00335    return progress_in;
00336 }
00337 
00338 
00339 /*---------------------------------------------------*/
00340 static
00341 Bool copy_output_until_stop ( EState* s )
00342 {
00343    Bool progress_out = False;
00344 
00345    while (True) {
00346 
00347       /*-- no output space? --*/
00348       if (s->strm->avail_out == 0) break;
00349 
00350       /*-- block done? --*/
00351       if (s->state_out_pos >= s->numZ) break;
00352 
00353       progress_out = True;
00354       *(s->strm->next_out) = s->zbits[s->state_out_pos];
00355       s->state_out_pos++;
00356       s->strm->avail_out--;
00357       s->strm->next_out++;
00358       s->strm->total_out_lo32++;
00359       if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
00360    }
00361 
00362    return progress_out;
00363 }
00364 
00365 
00366 /*---------------------------------------------------*/
00367 static
00368 Bool handle_compress ( bz_stream* strm )
00369 {
00370    Bool progress_in  = False;
00371    Bool progress_out = False;
00372    EState* s = strm->state;
00373    
00374    while (True) {
00375 
00376       if (s->state == BZ_S_OUTPUT) {
00377          progress_out |= copy_output_until_stop ( s );
00378          if (s->state_out_pos < s->numZ) break;
00379          if (s->mode == BZ_M_FINISHING && 
00380              s->avail_in_expect == 0 &&
00381              isempty_RL(s)) break;
00382          prepare_new_block ( s );
00383          s->state = BZ_S_INPUT;
00384          if (s->mode == BZ_M_FLUSHING && 
00385              s->avail_in_expect == 0 &&
00386              isempty_RL(s)) break;
00387       }
00388 
00389       if (s->state == BZ_S_INPUT) {
00390          progress_in |= copy_input_until_stop ( s );
00391          if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
00392             flush_RL ( s );
00393             BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
00394             s->state = BZ_S_OUTPUT;
00395          }
00396          else
00397          if (s->nblock >= s->nblockMAX) {
00398             BZ2_compressBlock ( s, False );
00399             s->state = BZ_S_OUTPUT;
00400          }
00401          else
00402          if (s->strm->avail_in == 0) {
00403             break;
00404          }
00405       }
00406 
00407    }
00408 
00409    return progress_in || progress_out;
00410 }
00411 
00412 
00413 /*---------------------------------------------------*/
00414 int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
00415 {
00416    Bool progress;
00417    EState* s;
00418    if (strm == NULL) return BZ_PARAM_ERROR;
00419    s = strm->state;
00420    if (s == NULL) return BZ_PARAM_ERROR;
00421    if (s->strm != strm) return BZ_PARAM_ERROR;
00422 
00423    preswitch:
00424    switch (s->mode) {
00425 
00426       case BZ_M_IDLE:
00427          return BZ_SEQUENCE_ERROR;
00428 
00429       case BZ_M_RUNNING:
00430          if (action == BZ_RUN) {
00431             progress = handle_compress ( strm );
00432             return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
00433          } 
00434          else
00435      if (action == BZ_FLUSH) {
00436             s->avail_in_expect = strm->avail_in;
00437             s->mode = BZ_M_FLUSHING;
00438             goto preswitch;
00439          }
00440          else
00441          if (action == BZ_FINISH) {
00442             s->avail_in_expect = strm->avail_in;
00443             s->mode = BZ_M_FINISHING;
00444             goto preswitch;
00445          }
00446          else 
00447             return BZ_PARAM_ERROR;
00448 
00449       case BZ_M_FLUSHING:
00450          if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
00451          if (s->avail_in_expect != s->strm->avail_in) 
00452             return BZ_SEQUENCE_ERROR;
00453          progress = handle_compress ( strm );
00454          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
00455              s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
00456          s->mode = BZ_M_RUNNING;
00457          return BZ_RUN_OK;
00458 
00459       case BZ_M_FINISHING:
00460          if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
00461          if (s->avail_in_expect != s->strm->avail_in) 
00462             return BZ_SEQUENCE_ERROR;
00463          progress = handle_compress ( strm );
00464          if (!progress) return BZ_SEQUENCE_ERROR;
00465          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
00466              s->state_out_pos < s->numZ) return BZ_FINISH_OK;
00467          s->mode = BZ_M_IDLE;
00468          return BZ_STREAM_END;
00469    }
00470    return BZ_OK; /*--not reached--*/
00471 }
00472 
00473 
00474 /*---------------------------------------------------*/
00475 int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
00476 {
00477    EState* s;
00478    if (strm == NULL) return BZ_PARAM_ERROR;
00479    s = strm->state;
00480    if (s == NULL) return BZ_PARAM_ERROR;
00481    if (s->strm != strm) return BZ_PARAM_ERROR;
00482 
00483    if (s->arr1 != NULL) BZFREE(s->arr1);
00484    if (s->arr2 != NULL) BZFREE(s->arr2);
00485    if (s->ftab != NULL) BZFREE(s->ftab);
00486    BZFREE(strm->state);
00487 
00488    strm->state = NULL;   
00489 
00490    return BZ_OK;
00491 }
00492 
00493 #endif // BZ_DECOMPRESS_ONLY
00494 
00495 /*---------------------------------------------------*/
00496 /*--- Decompression stuff                         ---*/
00497 /*---------------------------------------------------*/
00498 
00499 /*---------------------------------------------------*/
00500 int BZ_API(BZ2_bzDecompressInit) 
00501                      ( bz_stream* strm, 
00502                        int        verbosity,
00503                        int        small )
00504 {
00505    DState* s;
00506 
00507    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
00508 
00509    if (strm == NULL) return BZ_PARAM_ERROR;
00510    if (small != 0 && small != 1) return BZ_PARAM_ERROR;
00511    if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
00512 
00513    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
00514    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
00515 
00516    s = BZALLOC( sizeof(DState) );
00517    if (s == NULL) return BZ_MEM_ERROR;
00518    s->strm                  = strm;
00519    strm->state              = s;
00520    s->state                 = BZ_X_MAGIC_1;
00521    s->bsLive                = 0;
00522    s->bsBuff                = 0;
00523    s->calculatedCombinedCRC = 0;
00524    strm->total_in_lo32      = 0;
00525    strm->total_in_hi32      = 0;
00526    strm->total_out_lo32     = 0;
00527    strm->total_out_hi32     = 0;
00528    s->smallDecompress       = (Bool)small;
00529    s->ll4                   = NULL;
00530    s->ll16                  = NULL;
00531    s->tt                    = NULL;
00532    s->currBlockNo           = 0;
00533    s->verbosity             = verbosity;
00534 
00535    return BZ_OK;
00536 }
00537 
00538 #ifndef BZ_DECOMPRESS_ONLY
00539 
00540 /*---------------------------------------------------*/
00541 /* Return  True iff data corruption is discovered.
00542    Returns False if there is no problem.
00543 */
00544 static
00545 Bool unRLE_obuf_to_output_FAST ( DState* s )
00546 {
00547    UChar k1;
00548 
00549    if (s->blockRandomised) {
00550 
00551       while (True) {
00552          /* try to finish existing run */
00553          while (True) {
00554             if (s->strm->avail_out == 0) return False;
00555             if (s->state_out_len == 0) break;
00556             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
00557             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
00558             s->state_out_len--;
00559             s->strm->next_out++;
00560             s->strm->avail_out--;
00561             s->strm->total_out_lo32++;
00562             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
00563          }
00564 
00565          /* can a new run be started? */
00566          if (s->nblock_used == s->save_nblock+1) return False;
00567                
00568          /* Only caused by corrupt data stream? */
00569          if (s->nblock_used > s->save_nblock+1)
00570             return True;
00571    
00572          s->state_out_len = 1;
00573          s->state_out_ch = s->k0;
00574          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
00575          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00576          if (s->nblock_used == s->save_nblock+1) continue;
00577          if (k1 != s->k0) { s->k0 = k1; continue; };
00578    
00579          s->state_out_len = 2;
00580          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
00581          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00582          if (s->nblock_used == s->save_nblock+1) continue;
00583          if (k1 != s->k0) { s->k0 = k1; continue; };
00584    
00585          s->state_out_len = 3;
00586          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
00587          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00588          if (s->nblock_used == s->save_nblock+1) continue;
00589          if (k1 != s->k0) { s->k0 = k1; continue; };
00590    
00591          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; 
00592          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00593          s->state_out_len = ((Int32)k1) + 4;
00594          BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; 
00595          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
00596       }
00597 
00598    } else {
00599 
00600       /* restore */
00601       UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
00602       UChar         c_state_out_ch       = s->state_out_ch;
00603       Int32         c_state_out_len      = s->state_out_len;
00604       Int32         c_nblock_used        = s->nblock_used;
00605       Int32         c_k0                 = s->k0;
00606       UInt32*       c_tt                 = s->tt;
00607       UInt32        c_tPos               = s->tPos;
00608       char*         cs_next_out          = s->strm->next_out;
00609       unsigned int  cs_avail_out         = s->strm->avail_out;
00610       Int32         ro_blockSize100k     = s->blockSize100k;
00611       /* end restore */
00612 
00613       UInt32       avail_out_INIT = cs_avail_out;
00614       Int32        s_save_nblockPP = s->save_nblock+1;
00615       unsigned int total_out_lo32_old;
00616 
00617       while (True) {
00618 
00619          /* try to finish existing run */
00620          if (c_state_out_len > 0) {
00621             while (True) {
00622                if (cs_avail_out == 0) goto return_notr;
00623                if (c_state_out_len == 1) break;
00624                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
00625                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
00626                c_state_out_len--;
00627                cs_next_out++;
00628                cs_avail_out--;
00629             }
00630             s_state_out_len_eq_one:
00631             {
00632                if (cs_avail_out == 0) { 
00633                   c_state_out_len = 1; goto return_notr;
00634                };
00635                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
00636                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
00637                cs_next_out++;
00638                cs_avail_out--;
00639             }
00640          }   
00641          /* Only caused by corrupt data stream? */
00642          if (c_nblock_used > s_save_nblockPP)
00643             return True;
00644 
00645          /* can a new run be started? */
00646          if (c_nblock_used == s_save_nblockPP) {
00647             c_state_out_len = 0; goto return_notr;
00648          };   
00649          c_state_out_ch = c_k0;
00650          BZ_GET_FAST_C(k1); c_nblock_used++;
00651          if (k1 != c_k0) { 
00652             c_k0 = k1; goto s_state_out_len_eq_one; 
00653          };
00654          if (c_nblock_used == s_save_nblockPP) 
00655             goto s_state_out_len_eq_one;
00656    
00657          c_state_out_len = 2;
00658          BZ_GET_FAST_C(k1); c_nblock_used++;
00659          if (c_nblock_used == s_save_nblockPP) continue;
00660          if (k1 != c_k0) { c_k0 = k1; continue; };
00661    
00662          c_state_out_len = 3;
00663          BZ_GET_FAST_C(k1); c_nblock_used++;
00664          if (c_nblock_used == s_save_nblockPP) continue;
00665          if (k1 != c_k0) { c_k0 = k1; continue; };
00666    
00667          BZ_GET_FAST_C(k1); c_nblock_used++;
00668          c_state_out_len = ((Int32)k1) + 4;
00669          BZ_GET_FAST_C(c_k0); c_nblock_used++;
00670       }
00671 
00672       return_notr:
00673       total_out_lo32_old = s->strm->total_out_lo32;
00674       s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
00675       if (s->strm->total_out_lo32 < total_out_lo32_old)
00676          s->strm->total_out_hi32++;
00677 
00678       /* save */
00679       s->calculatedBlockCRC = c_calculatedBlockCRC;
00680       s->state_out_ch       = c_state_out_ch;
00681       s->state_out_len      = c_state_out_len;
00682       s->nblock_used        = c_nblock_used;
00683       s->k0                 = c_k0;
00684       s->tt                 = c_tt;
00685       s->tPos               = c_tPos;
00686       s->strm->next_out     = cs_next_out;
00687       s->strm->avail_out    = cs_avail_out;
00688       /* end save */
00689    }
00690    return False;
00691 }
00692 
00693 #endif // BZ_DECOMPRESS_ONLY
00694 
00695 
00696 /*---------------------------------------------------*/
00697 __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
00698 {
00699    Int32 nb, na, mid;
00700    nb = 0;
00701    na = 256;
00702    do {
00703       mid = (nb + na) >> 1;
00704       if (indx >= cftab[mid]) nb = mid; else na = mid;
00705    }
00706    while (na - nb != 1);
00707    return nb;
00708 }
00709 
00710 
00711 /*---------------------------------------------------*/
00712 /* Return  True iff data corruption is discovered.
00713    Returns False if there is no problem.
00714 */
00715 static
00716 Bool unRLE_obuf_to_output_SMALL ( DState* s )
00717 {
00718    UChar k1;
00719 
00720    if (s->blockRandomised) {
00721 
00722       while (True) {
00723          /* try to finish existing run */
00724          while (True) {
00725             if (s->strm->avail_out == 0) return False;
00726             if (s->state_out_len == 0) break;
00727             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
00728             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
00729             s->state_out_len--;
00730             s->strm->next_out++;
00731             s->strm->avail_out--;
00732             s->strm->total_out_lo32++;
00733             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
00734          }
00735    
00736          /* can a new run be started? */
00737          if (s->nblock_used == s->save_nblock+1) return False;
00738 
00739          /* Only caused by corrupt data stream? */
00740          if (s->nblock_used > s->save_nblock+1)
00741             return True;
00742    
00743          s->state_out_len = 1;
00744          s->state_out_ch = s->k0;
00745          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
00746          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00747          if (s->nblock_used == s->save_nblock+1) continue;
00748          if (k1 != s->k0) { s->k0 = k1; continue; };
00749    
00750          s->state_out_len = 2;
00751          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
00752          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00753          if (s->nblock_used == s->save_nblock+1) continue;
00754          if (k1 != s->k0) { s->k0 = k1; continue; };
00755    
00756          s->state_out_len = 3;
00757          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
00758          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00759          if (s->nblock_used == s->save_nblock+1) continue;
00760          if (k1 != s->k0) { s->k0 = k1; continue; };
00761    
00762          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; 
00763          k1 ^= BZ_RAND_MASK; s->nblock_used++;
00764          s->state_out_len = ((Int32)k1) + 4;
00765          BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; 
00766          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
00767       }
00768 
00769    } else {
00770 
00771       while (True) {
00772          /* try to finish existing run */
00773          while (True) {
00774             if (s->strm->avail_out == 0) return False;
00775             if (s->state_out_len == 0) break;
00776             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
00777             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
00778             s->state_out_len--;
00779             s->strm->next_out++;
00780             s->strm->avail_out--;
00781             s->strm->total_out_lo32++;
00782             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
00783          }
00784    
00785          /* can a new run be started? */
00786          if (s->nblock_used == s->save_nblock+1) return False;
00787 
00788          /* Only caused by corrupt data stream? */
00789          if (s->nblock_used > s->save_nblock+1)
00790             return True;
00791    
00792          s->state_out_len = 1;
00793          s->state_out_ch = s->k0;
00794          BZ_GET_SMALL(k1); s->nblock_used++;
00795          if (s->nblock_used == s->save_nblock+1) continue;
00796          if (k1 != s->k0) { s->k0 = k1; continue; };
00797    
00798          s->state_out_len = 2;
00799          BZ_GET_SMALL(k1); s->nblock_used++;
00800          if (s->nblock_used == s->save_nblock+1) continue;
00801          if (k1 != s->k0) { s->k0 = k1; continue; };
00802    
00803          s->state_out_len = 3;
00804          BZ_GET_SMALL(k1); s->nblock_used++;
00805          if (s->nblock_used == s->save_nblock+1) continue;
00806          if (k1 != s->k0) { s->k0 = k1; continue; };
00807    
00808          BZ_GET_SMALL(k1); s->nblock_used++;
00809          s->state_out_len = ((Int32)k1) + 4;
00810          BZ_GET_SMALL(s->k0); s->nblock_used++;
00811       }
00812 
00813    }
00814 }
00815 
00816 
00817 /*---------------------------------------------------*/
00818 int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
00819 {
00820    Bool    corrupt;
00821    DState* s;
00822    if (strm == NULL) return BZ_PARAM_ERROR;
00823    s = strm->state;
00824    if (s == NULL) return BZ_PARAM_ERROR;
00825    if (s->strm != strm) return BZ_PARAM_ERROR;
00826 
00827    while (True) {
00828       if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
00829       if (s->state == BZ_X_OUTPUT) {
00830 #ifndef BZ_DECOMPRESS_ONLY
00831          if (s->smallDecompress)
00832             corrupt = unRLE_obuf_to_output_SMALL ( s ); else
00833             corrupt = unRLE_obuf_to_output_FAST  ( s );
00834          if (corrupt) return BZ_DATA_ERROR;
00835 #else
00836          corrupt = unRLE_obuf_to_output_SMALL ( s );
00837          if (corrupt) return BZ_DATA_ERROR;
00838 #endif
00839          if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
00840             BZ_FINALISE_CRC ( s->calculatedBlockCRC );
00841             if (s->verbosity >= 3) 
00842                VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, 
00843                           s->calculatedBlockCRC );
00844             if (s->verbosity >= 2) VPrintf0 ( "]" );
00845             if (s->calculatedBlockCRC != s->storedBlockCRC)
00846                return BZ_DATA_ERROR;
00847             s->calculatedCombinedCRC 
00848                = (s->calculatedCombinedCRC << 1) | 
00849                     (s->calculatedCombinedCRC >> 31);
00850             s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
00851             s->state = BZ_X_BLKHDR_1;
00852          } else {
00853             return BZ_OK;
00854          }
00855       }
00856       if (s->state >= BZ_X_MAGIC_1) {
00857          Int32 r = BZ2_decompress ( s );
00858          if (r == BZ_STREAM_END) {
00859             if (s->verbosity >= 3)
00860                VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x", 
00861                           s->storedCombinedCRC, s->calculatedCombinedCRC );
00862             if (s->calculatedCombinedCRC != s->storedCombinedCRC)
00863                return BZ_DATA_ERROR;
00864             return r;
00865          }
00866          if (s->state != BZ_X_OUTPUT) return r;
00867       }
00868    }
00869 
00870    AssertH ( 0, 6001 );
00871 
00872    return 0;  /*NOTREACHED*/
00873 }
00874 
00875 
00876 /*---------------------------------------------------*/
00877 int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
00878 {
00879    DState* s;
00880    if (strm == NULL) return BZ_PARAM_ERROR;
00881    s = strm->state;
00882    if (s == NULL) return BZ_PARAM_ERROR;
00883    if (s->strm != strm) return BZ_PARAM_ERROR;
00884 
00885    if (s->tt   != NULL) BZFREE(s->tt);
00886    if (s->ll16 != NULL) BZFREE(s->ll16);
00887    if (s->ll4  != NULL) BZFREE(s->ll4);
00888 
00889    BZFREE(strm->state);
00890    strm->state = NULL;
00891 
00892    return BZ_OK;
00893 }
00894 
00895 
00896 #ifndef BZ_NO_STDIO
00897 /*---------------------------------------------------*/
00898 /*--- File I/O stuff                              ---*/
00899 /*---------------------------------------------------*/
00900 
00901 #define BZ_SETERR(eee)                    \
00902 {                                         \
00903    if (bzerror != NULL) *bzerror = eee;   \
00904    if (bzf != NULL) bzf->lastErr = eee;   \
00905 }
00906 
00907 typedef 
00908    struct {
00909       FILE*     handle;
00910       Char      buf[BZ_MAX_UNUSED];
00911       Int32     bufN;
00912       Bool      writing;
00913       bz_stream strm;
00914       Int32     lastErr;
00915       Bool      initialisedOk;
00916    }
00917    bzFile;
00918 
00919 
00920 /*---------------------------------------------*/
00921 static Bool myfeof ( FILE* f )
00922 {
00923    Int32 c = fgetc ( f );
00924    if (c == EOF) return True;
00925    ungetc ( c, f );
00926    return False;
00927 }
00928 
00929 
00930 /*---------------------------------------------------*/
00931 BZFILE* BZ_API(BZ2_bzWriteOpen) 
00932                     ( int*  bzerror,      
00933                       FILE* f, 
00934                       int   blockSize100k, 
00935                       int   verbosity,
00936                       int   workFactor )
00937 {
00938    Int32   ret;
00939    bzFile* bzf = NULL;
00940 
00941    BZ_SETERR(BZ_OK);
00942 
00943    if (f == NULL ||
00944        (blockSize100k < 1 || blockSize100k > 9) ||
00945        (workFactor < 0 || workFactor > 250) ||
00946        (verbosity < 0 || verbosity > 4))
00947       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
00948 
00949    if (ferror(f))
00950       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
00951 
00952    bzf = malloc ( sizeof(bzFile) );
00953    if (bzf == NULL)
00954       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
00955 
00956    BZ_SETERR(BZ_OK);
00957    bzf->initialisedOk = False;
00958    bzf->bufN          = 0;
00959    bzf->handle        = f;
00960    bzf->writing       = True;
00961    bzf->strm.bzalloc  = NULL;
00962    bzf->strm.bzfree   = NULL;
00963    bzf->strm.opaque   = NULL;
00964 
00965    if (workFactor == 0) workFactor = 30;
00966    ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, 
00967                               verbosity, workFactor );
00968    if (ret != BZ_OK)
00969       { BZ_SETERR(ret); free(bzf); return NULL; };
00970 
00971    bzf->strm.avail_in = 0;
00972    bzf->initialisedOk = True;
00973    return bzf;   
00974 }
00975 
00976 
00977 
00978 /*---------------------------------------------------*/
00979 void BZ_API(BZ2_bzWrite)
00980              ( int*    bzerror, 
00981                BZFILE* b, 
00982                void*   buf, 
00983                int     len )
00984 {
00985    Int32 n, n2, ret;
00986    bzFile* bzf = (bzFile*)b;
00987 
00988    BZ_SETERR(BZ_OK);
00989    if (bzf == NULL || buf == NULL || len < 0)
00990       { BZ_SETERR(BZ_PARAM_ERROR); return; };
00991    if (!(bzf->writing))
00992       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
00993    if (ferror(bzf->handle))
00994       { BZ_SETERR(BZ_IO_ERROR); return; };
00995 
00996    if (len == 0)
00997       { BZ_SETERR(BZ_OK); return; };
00998 
00999    bzf->strm.avail_in = len;
01000    bzf->strm.next_in  = buf;
01001 
01002    while (True) {
01003       bzf->strm.avail_out = BZ_MAX_UNUSED;
01004       bzf->strm.next_out = bzf->buf;
01005       ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
01006       if (ret != BZ_RUN_OK)
01007          { BZ_SETERR(ret); return; };
01008 
01009       if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
01010          n = BZ_MAX_UNUSED - bzf->strm.avail_out;
01011          n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
01012                        n, bzf->handle );
01013          if (n != n2 || ferror(bzf->handle))
01014             { BZ_SETERR(BZ_IO_ERROR); return; };
01015       }
01016 
01017       if (bzf->strm.avail_in == 0)
01018          { BZ_SETERR(BZ_OK); return; };
01019    }
01020 }
01021 
01022 
01023 /*---------------------------------------------------*/
01024 void BZ_API(BZ2_bzWriteClose)
01025                   ( int*          bzerror, 
01026                     BZFILE*       b, 
01027                     int           abandon,
01028                     unsigned int* nbytes_in,
01029                     unsigned int* nbytes_out )
01030 {
01031    BZ2_bzWriteClose64 ( bzerror, b, abandon, 
01032                         nbytes_in, NULL, nbytes_out, NULL );
01033 }
01034 
01035 
01036 void BZ_API(BZ2_bzWriteClose64)
01037                   ( int*          bzerror, 
01038                     BZFILE*       b, 
01039                     int           abandon,
01040                     unsigned int* nbytes_in_lo32,
01041                     unsigned int* nbytes_in_hi32,
01042                     unsigned int* nbytes_out_lo32,
01043                     unsigned int* nbytes_out_hi32 )
01044 {
01045    Int32   n, n2, ret;
01046    bzFile* bzf = (bzFile*)b;
01047 
01048    if (bzf == NULL)
01049       { BZ_SETERR(BZ_OK); return; };
01050    if (!(bzf->writing))
01051       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
01052    if (ferror(bzf->handle))
01053       { BZ_SETERR(BZ_IO_ERROR); return; };
01054 
01055    if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
01056    if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
01057    if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
01058    if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
01059 
01060    if ((!abandon) && bzf->lastErr == BZ_OK) {
01061       while (True) {
01062          bzf->strm.avail_out = BZ_MAX_UNUSED;
01063          bzf->strm.next_out = bzf->buf;
01064          ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
01065          if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
01066             { BZ_SETERR(ret); return; };
01067 
01068          if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
01069             n = BZ_MAX_UNUSED - bzf->strm.avail_out;
01070             n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), 
01071                           n, bzf->handle );
01072             if (n != n2 || ferror(bzf->handle))
01073                { BZ_SETERR(BZ_IO_ERROR); return; };
01074          }
01075 
01076          if (ret == BZ_STREAM_END) break;
01077       }
01078    }
01079 
01080    if ( !abandon && !ferror ( bzf->handle ) ) {
01081       fflush ( bzf->handle );
01082       if (ferror(bzf->handle))
01083          { BZ_SETERR(BZ_IO_ERROR); return; };
01084    }
01085 
01086    if (nbytes_in_lo32 != NULL)
01087       *nbytes_in_lo32 = bzf->strm.total_in_lo32;
01088    if (nbytes_in_hi32 != NULL)
01089       *nbytes_in_hi32 = bzf->strm.total_in_hi32;
01090    if (nbytes_out_lo32 != NULL)
01091       *nbytes_out_lo32 = bzf->strm.total_out_lo32;
01092    if (nbytes_out_hi32 != NULL)
01093       *nbytes_out_hi32 = bzf->strm.total_out_hi32;
01094 
01095    BZ_SETERR(BZ_OK);
01096    BZ2_bzCompressEnd ( &(bzf->strm) );
01097    free ( bzf );
01098 }
01099 
01100 
01101 /*---------------------------------------------------*/
01102 BZFILE* BZ_API(BZ2_bzReadOpen) 
01103                    ( int*  bzerror, 
01104                      FILE* f, 
01105                      int   verbosity,
01106                      int   small,
01107                      void* unused,
01108                      int   nUnused )
01109 {
01110    bzFile* bzf = NULL;
01111    int     ret;
01112 
01113    BZ_SETERR(BZ_OK);
01114 
01115    if (f == NULL || 
01116        (small != 0 && small != 1) ||
01117        (verbosity < 0 || verbosity > 4) ||
01118        (unused == NULL && nUnused != 0) ||
01119        (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
01120       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
01121 
01122    if (ferror(f))
01123       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
01124 
01125    bzf = malloc ( sizeof(bzFile) );
01126    if (bzf == NULL) 
01127       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
01128 
01129    BZ_SETERR(BZ_OK);
01130 
01131    bzf->initialisedOk = False;
01132    bzf->handle        = f;
01133    bzf->bufN          = 0;
01134    bzf->writing       = False;
01135    bzf->strm.bzalloc  = NULL;
01136    bzf->strm.bzfree   = NULL;
01137    bzf->strm.opaque   = NULL;
01138    
01139    while (nUnused > 0) {
01140       bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
01141       unused = ((void*)( 1 + ((UChar*)(unused))  ));
01142       nUnused--;
01143    }
01144 
01145    ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
01146    if (ret != BZ_OK)
01147       { BZ_SETERR(ret); free(bzf); return NULL; };
01148 
01149    bzf->strm.avail_in = bzf->bufN;
01150    bzf->strm.next_in  = bzf->buf;
01151 
01152    bzf->initialisedOk = True;
01153    return bzf;   
01154 }
01155 
01156 
01157 /*---------------------------------------------------*/
01158 void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
01159 {
01160    bzFile* bzf = (bzFile*)b;
01161 
01162    BZ_SETERR(BZ_OK);
01163    if (bzf == NULL)
01164       { BZ_SETERR(BZ_OK); return; };
01165 
01166    if (bzf->writing)
01167       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
01168 
01169    if (bzf->initialisedOk)
01170       (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
01171    free ( bzf );
01172 }
01173 
01174 
01175 /*---------------------------------------------------*/
01176 int BZ_API(BZ2_bzRead) 
01177            ( int*    bzerror, 
01178              BZFILE* b, 
01179              void*   buf, 
01180              int     len )
01181 {
01182    Int32   n, ret;
01183    bzFile* bzf = (bzFile*)b;
01184 
01185    BZ_SETERR(BZ_OK);
01186 
01187    if (bzf == NULL || buf == NULL || len < 0)
01188       { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
01189 
01190    if (bzf->writing)
01191       { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
01192 
01193    if (len == 0)
01194       { BZ_SETERR(BZ_OK); return 0; };
01195 
01196    bzf->strm.avail_out = len;
01197    bzf->strm.next_out = buf;
01198 
01199    while (True) {
01200 
01201       if (ferror(bzf->handle)) 
01202          { BZ_SETERR(BZ_IO_ERROR); return 0; };
01203 
01204       if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
01205          n = fread ( bzf->buf, sizeof(UChar), 
01206                      BZ_MAX_UNUSED, bzf->handle );
01207          if (ferror(bzf->handle))
01208             { BZ_SETERR(BZ_IO_ERROR); return 0; };
01209          bzf->bufN = n;
01210          bzf->strm.avail_in = bzf->bufN;
01211          bzf->strm.next_in = bzf->buf;
01212       }
01213 
01214       ret = BZ2_bzDecompress ( &(bzf->strm) );
01215 
01216       if (ret != BZ_OK && ret != BZ_STREAM_END)
01217          { BZ_SETERR(ret); return 0; };
01218 
01219       if (ret == BZ_OK && myfeof(bzf->handle) && 
01220           bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
01221          { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
01222 
01223       if (ret == BZ_STREAM_END)
01224          { BZ_SETERR(BZ_STREAM_END);
01225            return len - bzf->strm.avail_out; };
01226       if (bzf->strm.avail_out == 0)
01227          { BZ_SETERR(BZ_OK); return len; };
01228       
01229    }
01230 
01231    return 0; /*not reached*/
01232 }
01233 
01234 
01235 /*---------------------------------------------------*/
01236 void BZ_API(BZ2_bzReadGetUnused) 
01237                      ( int*    bzerror, 
01238                        BZFILE* b, 
01239                        void**  unused, 
01240                        int*    nUnused )
01241 {
01242    bzFile* bzf = (bzFile*)b;
01243    if (bzf == NULL)
01244       { BZ_SETERR(BZ_PARAM_ERROR); return; };
01245    if (bzf->lastErr != BZ_STREAM_END)
01246       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
01247    if (unused == NULL || nUnused == NULL)
01248       { BZ_SETERR(BZ_PARAM_ERROR); return; };
01249 
01250    BZ_SETERR(BZ_OK);
01251    *nUnused = bzf->strm.avail_in;
01252    *unused = bzf->strm.next_in;
01253 }
01254 #endif
01255 
01256 #ifndef BZ_DECOMPRESS_ONLY
01257 
01258 /*---------------------------------------------------*/
01259 /*--- Misc convenience stuff                      ---*/
01260 /*---------------------------------------------------*/
01261 
01262 /*---------------------------------------------------*/
01263 int BZ_API(BZ2_bzBuffToBuffCompress) 
01264                          ( char*         dest, 
01265                            unsigned int* destLen,
01266                            char*         source, 
01267                            unsigned int  sourceLen,
01268                            int           blockSize100k, 
01269                            int           verbosity, 
01270                            int           workFactor )
01271 {
01272    bz_stream strm;
01273    int ret;
01274 
01275    if (dest == NULL || destLen == NULL || 
01276        source == NULL ||
01277        blockSize100k < 1 || blockSize100k > 9 ||
01278        verbosity < 0 || verbosity > 4 ||
01279        workFactor < 0 || workFactor > 250) 
01280       return BZ_PARAM_ERROR;
01281 
01282    if (workFactor == 0) workFactor = 30;
01283    strm.bzalloc = NULL;
01284    strm.bzfree = NULL;
01285    strm.opaque = NULL;
01286    ret = BZ2_bzCompressInit ( &strm, blockSize100k, 
01287                               verbosity, workFactor );
01288    if (ret != BZ_OK) return ret;
01289 
01290    strm.next_in = source;
01291    strm.next_out = dest;
01292    strm.avail_in = sourceLen;
01293    strm.avail_out = *destLen;
01294 
01295    ret = BZ2_bzCompress ( &strm, BZ_FINISH );
01296    if (ret == BZ_FINISH_OK) goto output_overflow;
01297    if (ret != BZ_STREAM_END) goto errhandler;
01298 
01299    /* normal termination */
01300    *destLen -= strm.avail_out;   
01301    BZ2_bzCompressEnd ( &strm );
01302    return BZ_OK;
01303 
01304    output_overflow:
01305    BZ2_bzCompressEnd ( &strm );
01306    return BZ_OUTBUFF_FULL;
01307 
01308    errhandler:
01309    BZ2_bzCompressEnd ( &strm );
01310    return ret;
01311 }
01312 
01313 #endif // BZ_DECOMPRESS_0NLY
01314 
01315 /*---------------------------------------------------*/
01316 int BZ_API(BZ2_bzBuffToBuffDecompress) 
01317                            ( char*         dest, 
01318                              unsigned int* destLen,
01319                              char*         source, 
01320                              unsigned int  sourceLen,
01321                              int           small,
01322                              int           verbosity )
01323 {
01324    bz_stream strm;
01325    int ret;
01326 
01327    if (dest == NULL || destLen == NULL || 
01328        source == NULL ||
01329        (small != 0 && small != 1) ||
01330        verbosity < 0 || verbosity > 4) 
01331           return BZ_PARAM_ERROR;
01332 
01333    strm.bzalloc = NULL;
01334    strm.bzfree = NULL;
01335    strm.opaque = NULL;
01336    ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
01337    if (ret != BZ_OK) return ret;
01338 
01339    strm.next_in = source;
01340    strm.next_out = dest;
01341    strm.avail_in = sourceLen;
01342    strm.avail_out = *destLen;
01343 
01344    ret = BZ2_bzDecompress ( &strm );
01345    if (ret == BZ_OK) goto output_overflow_or_eof;
01346    if (ret != BZ_STREAM_END) goto errhandler;
01347 
01348    /* normal termination */
01349    *destLen -= strm.avail_out;
01350    BZ2_bzDecompressEnd ( &strm );
01351    return BZ_OK;
01352 
01353    output_overflow_or_eof:
01354    if (strm.avail_out > 0) {
01355       BZ2_bzDecompressEnd ( &strm );
01356       return BZ_UNEXPECTED_EOF;
01357    } else {
01358       BZ2_bzDecompressEnd ( &strm );
01359       return BZ_OUTBUFF_FULL;
01360    };      
01361 
01362    errhandler:
01363    BZ2_bzDecompressEnd ( &strm );
01364    return ret; 
01365 }
01366 
01367 
01368 /*---------------------------------------------------*/
01369 /*--
01370    Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
01371    to support better zlib compatibility.
01372    This code is not _officially_ part of libbzip2 (yet);
01373    I haven't tested it, documented it, or considered the
01374    threading-safeness of it.
01375    If this code breaks, please contact both Yoshioka and me.
01376 --*/
01377 /*---------------------------------------------------*/
01378 
01379 /*---------------------------------------------------*/
01380 /*--
01381    return version like "0.9.5d, 4-Sept-1999".
01382 --*/
01383 const char * BZ_API(BZ2_bzlibVersion)(void)
01384 {
01385    return BZ_VERSION;
01386 }
01387 
01388 
01389 #ifndef BZ_NO_STDIO
01390 /*---------------------------------------------------*/
01391 
01392 #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
01393 #   include <fcntl.h>
01394 #   include <io.h>
01395 #   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
01396 #else
01397 #   define SET_BINARY_MODE(file)
01398 #endif
01399 static
01400 BZFILE * bzopen_or_bzdopen
01401                ( const char *path,   /* no use when bzdopen */
01402                  int fd,             /* no use when bzdopen */
01403                  const char *mode,
01404                  int open_mode)      /* bzopen: 0, bzdopen:1 */
01405 {
01406    int    bzerr;
01407    char   unused[BZ_MAX_UNUSED];
01408    int    blockSize100k = 9;
01409    int    writing       = 0;
01410    char   mode2[10]     = "";
01411    FILE   *fp           = NULL;
01412    BZFILE *bzfp         = NULL;
01413    int    verbosity     = 0;
01414    int    workFactor    = 30;
01415    int    smallMode     = 0;
01416    int    nUnused       = 0; 
01417 
01418    if (mode == NULL) return NULL;
01419    while (*mode) {
01420       switch (*mode) {
01421       case 'r':
01422          writing = 0; break;
01423       case 'w':
01424          writing = 1; break;
01425       case 's':
01426          smallMode = 1; break;
01427       default:
01428          if (isdigit((int)(*mode))) {
01429             blockSize100k = *mode-BZ_HDR_0;
01430          }
01431       }
01432       mode++;
01433    }
01434    strcat(mode2, writing ? "w" : "r" );
01435    strcat(mode2,"b");   /* binary mode */
01436 
01437    if (open_mode==0) {
01438       if (path==NULL || strcmp(path,"")==0) {
01439         fp = (writing ? stdout : stdin);
01440         SET_BINARY_MODE(fp);
01441       } else {
01442         fp = fopen(path,mode2);
01443       }
01444    } else {
01445 #ifdef BZ_STRICT_ANSI
01446       fp = NULL;
01447 #else
01448       fp = fdopen(fd,mode2);
01449 #endif
01450    }
01451    if (fp == NULL) return NULL;
01452 
01453    if (writing) {
01454       /* Guard against total chaos and anarchy -- JRS */
01455       if (blockSize100k < 1) blockSize100k = 1;
01456       if (blockSize100k > 9) blockSize100k = 9; 
01457       bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
01458                              verbosity,workFactor);
01459    } else {
01460       bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
01461                             unused,nUnused);
01462    }
01463    if (bzfp == NULL) {
01464       if (fp != stdin && fp != stdout) fclose(fp);
01465       return NULL;
01466    }
01467    return bzfp;
01468 }
01469 
01470 
01471 /*---------------------------------------------------*/
01472 /*--
01473    open file for read or write.
01474       ex) bzopen("file","w9")
01475       case path="" or NULL => use stdin or stdout.
01476 --*/
01477 BZFILE * BZ_API(BZ2_bzopen)
01478                ( const char *path,
01479                  const char *mode )
01480 {
01481    return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
01482 }
01483 
01484 
01485 /*---------------------------------------------------*/
01486 BZFILE * BZ_API(BZ2_bzdopen)
01487                ( int fd,
01488                  const char *mode )
01489 {
01490    return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
01491 }
01492 
01493 
01494 /*---------------------------------------------------*/
01495 int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
01496 {
01497    int bzerr, nread;
01498    if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
01499    nread = BZ2_bzRead(&bzerr,b,buf,len);
01500    if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
01501       return nread;
01502    } else {
01503       return -1;
01504    }
01505 }
01506 
01507 
01508 /*---------------------------------------------------*/
01509 int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
01510 {
01511    int bzerr;
01512 
01513    BZ2_bzWrite(&bzerr,b,buf,len);
01514    if(bzerr == BZ_OK){
01515       return len;
01516    }else{
01517       return -1;
01518    }
01519 }
01520 
01521 
01522 /*---------------------------------------------------*/
01523 int BZ_API(BZ2_bzflush) (BZFILE *b)
01524 {
01525    /* do nothing now... */
01526    return 0;
01527 }
01528 
01529 
01530 /*---------------------------------------------------*/
01531 void BZ_API(BZ2_bzclose) (BZFILE* b)
01532 {
01533    int bzerr;
01534    FILE *fp;
01535    
01536    if (b==NULL) {return;}
01537    fp = ((bzFile *)b)->handle;
01538    if(((bzFile*)b)->writing){
01539       BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
01540       if(bzerr != BZ_OK){
01541          BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
01542       }
01543    }else{
01544       BZ2_bzReadClose(&bzerr,b);
01545    }
01546    if(fp!=stdin && fp!=stdout){
01547       fclose(fp);
01548    }
01549 }
01550 
01551 
01552 /*---------------------------------------------------*/
01553 /*--
01554    return last error code 
01555 --*/
01556 static const char *bzerrorstrings[] = {
01557        "OK"
01558       ,"SEQUENCE_ERROR"
01559       ,"PARAM_ERROR"
01560       ,"MEM_ERROR"
01561       ,"DATA_ERROR"
01562       ,"DATA_ERROR_MAGIC"
01563       ,"IO_ERROR"
01564       ,"UNEXPECTED_EOF"
01565       ,"OUTBUFF_FULL"
01566       ,"CONFIG_ERROR"
01567       ,"???"   /* for future */
01568       ,"???"   /* for future */
01569       ,"???"   /* for future */
01570       ,"???"   /* for future */
01571       ,"???"   /* for future */
01572       ,"???"   /* for future */
01573 };
01574 
01575 
01576 const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
01577 {
01578    int err = ((bzFile *)b)->lastErr;
01579 
01580    if(err>0) err = 0;
01581    *errnum = err;
01582    return bzerrorstrings[err*-1];
01583 }
01584 #endif
01585 
01586 
01587 /*-------------------------------------------------------------*/
01588 /*--- end                                           bzlib.c ---*/
01589 /*-------------------------------------------------------------*/

Generated on Tue May 22 2012 04:37:36 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.