File Coverage

cpan/Compress-Raw-Bzip2/bzlib.c
Criterion Covered Total %
statement 306 448 68.3
branch n/a
condition n/a
subroutine n/a
total 306 448 68.3


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