Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbzlib.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
1.7.6.1
|