File Coverage

bzlib.c
Criterion Covered Total %
statement 305 508 60.0
branch 148 452 32.7
condition n/a
subroutine n/a
pod n/a
total 453 960 47.1


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