annotate src/bzip2-1.0.6/bzlib.c @ 23:619f715526df sv_v2.1

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