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