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