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