2 /*-------------------------------------------------------------*/
3 /*--- Library top-level functions. ---*/
5 /*-------------------------------------------------------------*/
8 This file is a part of bzip2 and/or libbzip2, a program and
9 library for lossless, block-sorting data compression.
11 Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions
17 1. Redistributions of source code must retain the above copyright
18 notice, this list of conditions and the following disclaimer.
20 2. The origin of this software must not be misrepresented; you must
21 not claim that you wrote the original software. If you use this
22 software in a product, an acknowledgment in the product
23 documentation would be appreciated but is not required.
25 3. Altered source versions must be plainly marked as such, and must
26 not be misrepresented as being the original software.
28 4. The name of the author may not be used to endorse or promote
29 products derived from this software without specific prior written
32 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
33 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 Julian Seward, Cambridge, UK.
46 bzip2/libbzip2 version 1.0 of 21 March 2000
48 This program is based on (at least) the work of:
58 For more information on these sources, see the manual.
64 0.9.0 -- original version.
66 0.9.0a/b -- no changes in this file.
69 * made zero-length BZ_FLUSH work correctly in bzCompress().
70 * fixed bzWrite/bzRead to ignore zero-length requests.
71 * fixed bzread to correctly handle read requests after EOF.
72 * wrong parameter order in call to bzDecompressInit in
73 bzBuffToBuffDecompress. Fixed.
76 #include "bzlib_private.h"
79 /*---------------------------------------------------*/
80 /*--- Compression stuff ---*/
81 /*---------------------------------------------------*/
84 /*---------------------------------------------------*/
86 void BZ2_bz__AssertH__fail ( int errcode
)
89 "\n\nbzip2/libbzip2: internal error number %d.\n"
90 "This is a bug in bzip2/libbzip2, %s.\n"
91 "Please report it to me at: jseward@acm.org. If this happened\n"
92 "when you were using some program which uses libbzip2 as a\n"
93 "component, you should also report this bug to the author(s)\n"
94 "of that program. Please make an effort to report this bug;\n"
95 "timely and accurate bug reports eventually lead to higher\n"
96 "quality software. Thanks. Julian Seward, 30 December 2001.\n\n",
101 if (errcode
== 1007) {
103 "\n*** A special note about internal error number 1007 ***\n"
105 "Experience suggests that a common cause of i.e. 1007\n"
106 "is unreliable memory or other hardware. The 1007 assertion\n"
107 "just happens to cross-check the results of huge numbers of\n"
108 "memory reads/writes, and so acts (unintendedly) as a stress\n"
109 "test of your memory system.\n"
111 "I suggest the following: try compressing the file again,\n"
112 "possibly monitoring progress in detail with the -vv flag.\n"
114 "* If the error cannot be reproduced, and/or happens at different\n"
115 " points in compression, you may have a flaky memory system.\n"
116 " Try a memory-test program. I have used Memtest86\n"
117 " (www.memtest86.com). At the time of writing it is free (GPLd).\n"
118 " Memtest86 tests memory much more thorougly than your BIOSs\n"
119 " power-on test, and may find failures that the BIOS doesn't.\n"
121 "* If the error can be repeatably reproduced, this is a bug in\n"
122 " bzip2, and I would very much like to hear about it. Please\n"
123 " let me know, and, ideally, save a copy of the file causing the\n"
124 " problem -- without which I will be unable to investigate it.\n"
134 /*---------------------------------------------------*/
136 int bz_config_ok ( void )
138 if (sizeof(int) != 4) return 0;
139 if (sizeof(short) != 2) return 0;
140 if (sizeof(char) != 1) return 0;
145 /*---------------------------------------------------*/
147 void* default_bzalloc ( void* opaque
, Int32 items
, Int32 size
)
149 void* v
= malloc ( items
* size
);
154 void default_bzfree ( void* opaque
, void* addr
)
156 if (addr
!= NULL
) free ( addr
);
160 /*---------------------------------------------------*/
162 void prepare_new_block ( EState
* s
)
167 s
->state_out_pos
= 0;
168 BZ_INITIALISE_CRC ( s
->blockCRC
);
169 for (i
= 0; i
< 256; i
++) s
->inUse
[i
] = False
;
174 /*---------------------------------------------------*/
176 void init_RL ( EState
* s
)
178 s
->state_in_ch
= 256;
184 Bool
isempty_RL ( EState
* s
)
186 if (s
->state_in_ch
< 256 && s
->state_in_len
> 0)
192 /*---------------------------------------------------*/
193 int BZ_API(BZ2_bzCompressInit
)
202 if (!bz_config_ok()) return BZ_CONFIG_ERROR
;
205 blockSize100k
< 1 || blockSize100k
> 9 ||
206 workFactor
< 0 || workFactor
> 250)
207 return BZ_PARAM_ERROR
;
209 if (workFactor
== 0) workFactor
= 30;
210 if (strm
->bzalloc
== NULL
) strm
->bzalloc
= default_bzalloc
;
211 if (strm
->bzfree
== NULL
) strm
->bzfree
= default_bzfree
;
213 s
= BZALLOC( sizeof(EState
) );
214 if (s
== NULL
) return BZ_MEM_ERROR
;
221 n
= 100000 * blockSize100k
;
222 s
->arr1
= BZALLOC( n
* sizeof(UInt32
) );
223 s
->arr2
= BZALLOC( (n
+BZ_N_OVERSHOOT
) * sizeof(UInt32
) );
224 s
->ftab
= BZALLOC( 65537 * sizeof(UInt32
) );
226 if (s
->arr1
== NULL
|| s
->arr2
== NULL
|| s
->ftab
== NULL
) {
227 if (s
->arr1
!= NULL
) BZFREE(s
->arr1
);
228 if (s
->arr2
!= NULL
) BZFREE(s
->arr2
);
229 if (s
->ftab
!= NULL
) BZFREE(s
->ftab
);
230 if (s
!= NULL
) BZFREE(s
);
235 s
->state
= BZ_S_INPUT
;
236 s
->mode
= BZ_M_RUNNING
;
238 s
->blockSize100k
= blockSize100k
;
239 s
->nblockMAX
= 100000 * blockSize100k
- 19;
240 s
->verbosity
= verbosity
;
241 s
->workFactor
= workFactor
;
243 s
->block
= (UChar
*)s
->arr2
;
244 s
->mtfv
= (UInt16
*)s
->arr1
;
246 s
->ptr
= (UInt32
*)s
->arr1
;
249 strm
->total_in_lo32
= 0;
250 strm
->total_in_hi32
= 0;
251 strm
->total_out_lo32
= 0;
252 strm
->total_out_hi32
= 0;
254 prepare_new_block ( s
);
259 /*---------------------------------------------------*/
261 void add_pair_to_block ( EState
* s
)
264 UChar ch
= (UChar
)(s
->state_in_ch
);
265 for (i
= 0; i
< s
->state_in_len
; i
++) {
266 BZ_UPDATE_CRC( s
->blockCRC
, ch
);
268 s
->inUse
[s
->state_in_ch
] = True
;
269 switch (s
->state_in_len
) {
271 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
274 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
275 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
278 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
279 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
280 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
283 s
->inUse
[s
->state_in_len
-4] = True
;
284 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
285 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
286 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
287 s
->block
[s
->nblock
] = (UChar
)ch
; s
->nblock
++;
288 s
->block
[s
->nblock
] = ((UChar
)(s
->state_in_len
-4));
295 /*---------------------------------------------------*/
297 void flush_RL ( EState
* s
)
299 if (s
->state_in_ch
< 256) add_pair_to_block ( s
);
304 /*---------------------------------------------------*/
305 #define ADD_CHAR_TO_BLOCK(zs,zchh0) \
307 UInt32 zchh = (UInt32)(zchh0); \
308 /*-- fast track the common case --*/ \
309 if (zchh != zs->state_in_ch && \
310 zs->state_in_len == 1) { \
311 UChar ch = (UChar)(zs->state_in_ch); \
312 BZ_UPDATE_CRC( zs->blockCRC, ch ); \
313 zs->inUse[zs->state_in_ch] = True; \
314 zs->block[zs->nblock] = (UChar)ch; \
316 zs->state_in_ch = zchh; \
319 /*-- general, uncommon cases --*/ \
320 if (zchh != zs->state_in_ch || \
321 zs->state_in_len == 255) { \
322 if (zs->state_in_ch < 256) \
323 add_pair_to_block ( zs ); \
324 zs->state_in_ch = zchh; \
325 zs->state_in_len = 1; \
327 zs->state_in_len++; \
332 /*---------------------------------------------------*/
334 Bool
copy_input_until_stop ( EState
* s
)
336 Bool progress_in
= False
;
338 if (s
->mode
== BZ_M_RUNNING
) {
340 /*-- fast track the common case --*/
342 /*-- block full? --*/
343 if (s
->nblock
>= s
->nblockMAX
) break;
345 if (s
->strm
->avail_in
== 0) break;
347 ADD_CHAR_TO_BLOCK ( s
, (UInt32
)(*((UChar
*)(s
->strm
->next_in
))) );
350 s
->strm
->total_in_lo32
++;
351 if (s
->strm
->total_in_lo32
== 0) s
->strm
->total_in_hi32
++;
356 /*-- general, uncommon case --*/
358 /*-- block full? --*/
359 if (s
->nblock
>= s
->nblockMAX
) break;
361 if (s
->strm
->avail_in
== 0) break;
362 /*-- flush/finish end? --*/
363 if (s
->avail_in_expect
== 0) break;
365 ADD_CHAR_TO_BLOCK ( s
, (UInt32
)(*((UChar
*)(s
->strm
->next_in
))) );
368 s
->strm
->total_in_lo32
++;
369 if (s
->strm
->total_in_lo32
== 0) s
->strm
->total_in_hi32
++;
370 s
->avail_in_expect
--;
377 /*---------------------------------------------------*/
379 Bool
copy_output_until_stop ( EState
* s
)
381 Bool progress_out
= False
;
385 /*-- no output space? --*/
386 if (s
->strm
->avail_out
== 0) break;
388 /*-- block done? --*/
389 if (s
->state_out_pos
>= s
->numZ
) break;
392 *(s
->strm
->next_out
) = s
->zbits
[s
->state_out_pos
];
394 s
->strm
->avail_out
--;
396 s
->strm
->total_out_lo32
++;
397 if (s
->strm
->total_out_lo32
== 0) s
->strm
->total_out_hi32
++;
404 /*---------------------------------------------------*/
406 Bool
handle_compress ( bz_stream
* strm
)
408 Bool progress_in
= False
;
409 Bool progress_out
= False
;
410 EState
* s
= strm
->state
;
414 if (s
->state
== BZ_S_OUTPUT
) {
415 progress_out
|= copy_output_until_stop ( s
);
416 if (s
->state_out_pos
< s
->numZ
) break;
417 if (s
->mode
== BZ_M_FINISHING
&&
418 s
->avail_in_expect
== 0 &&
419 isempty_RL(s
)) break;
420 prepare_new_block ( s
);
421 s
->state
= BZ_S_INPUT
;
422 if (s
->mode
== BZ_M_FLUSHING
&&
423 s
->avail_in_expect
== 0 &&
424 isempty_RL(s
)) break;
427 if (s
->state
== BZ_S_INPUT
) {
428 progress_in
|= copy_input_until_stop ( s
);
429 if (s
->mode
!= BZ_M_RUNNING
&& s
->avail_in_expect
== 0) {
431 BZ2_compressBlock ( s
, (Bool
)(s
->mode
== BZ_M_FINISHING
) );
432 s
->state
= BZ_S_OUTPUT
;
435 if (s
->nblock
>= s
->nblockMAX
) {
436 BZ2_compressBlock ( s
, False
);
437 s
->state
= BZ_S_OUTPUT
;
440 if (s
->strm
->avail_in
== 0) {
447 return progress_in
|| progress_out
;
451 /*---------------------------------------------------*/
452 int BZ_API(BZ2_bzCompress
) ( bz_stream
*strm
, int action
)
456 if (strm
== NULL
) return BZ_PARAM_ERROR
;
458 if (s
== NULL
) return BZ_PARAM_ERROR
;
459 if (s
->strm
!= strm
) return BZ_PARAM_ERROR
;
465 return BZ_SEQUENCE_ERROR
;
468 if (action
== BZ_RUN
) {
469 progress
= handle_compress ( strm
);
470 return progress
? BZ_RUN_OK
: BZ_PARAM_ERROR
;
473 if (action
== BZ_FLUSH
) {
474 s
->avail_in_expect
= strm
->avail_in
;
475 s
->mode
= BZ_M_FLUSHING
;
479 if (action
== BZ_FINISH
) {
480 s
->avail_in_expect
= strm
->avail_in
;
481 s
->mode
= BZ_M_FINISHING
;
485 return BZ_PARAM_ERROR
;
488 if (action
!= BZ_FLUSH
) return BZ_SEQUENCE_ERROR
;
489 if (s
->avail_in_expect
!= s
->strm
->avail_in
)
490 return BZ_SEQUENCE_ERROR
;
491 progress
= handle_compress ( strm
);
492 if (s
->avail_in_expect
> 0 || !isempty_RL(s
) ||
493 s
->state_out_pos
< s
->numZ
) return BZ_FLUSH_OK
;
494 s
->mode
= BZ_M_RUNNING
;
498 if (action
!= BZ_FINISH
) return BZ_SEQUENCE_ERROR
;
499 if (s
->avail_in_expect
!= s
->strm
->avail_in
)
500 return BZ_SEQUENCE_ERROR
;
501 progress
= handle_compress ( strm
);
502 if (!progress
) return BZ_SEQUENCE_ERROR
;
503 if (s
->avail_in_expect
> 0 || !isempty_RL(s
) ||
504 s
->state_out_pos
< s
->numZ
) return BZ_FINISH_OK
;
506 return BZ_STREAM_END
;
508 return BZ_OK
; /*--not reached--*/
512 /*---------------------------------------------------*/
513 int BZ_API(BZ2_bzCompressEnd
) ( bz_stream
*strm
)
516 if (strm
== NULL
) return BZ_PARAM_ERROR
;
518 if (s
== NULL
) return BZ_PARAM_ERROR
;
519 if (s
->strm
!= strm
) return BZ_PARAM_ERROR
;
521 if (s
->arr1
!= NULL
) BZFREE(s
->arr1
);
522 if (s
->arr2
!= NULL
) BZFREE(s
->arr2
);
523 if (s
->ftab
!= NULL
) BZFREE(s
->ftab
);
532 /*---------------------------------------------------*/
533 /*--- Decompression stuff ---*/
534 /*---------------------------------------------------*/
536 /*---------------------------------------------------*/
537 int BZ_API(BZ2_bzDecompressInit
)
544 if (!bz_config_ok()) return BZ_CONFIG_ERROR
;
546 if (strm
== NULL
) return BZ_PARAM_ERROR
;
547 if (small
!= 0 && small
!= 1) return BZ_PARAM_ERROR
;
548 if (verbosity
< 0 || verbosity
> 4) return BZ_PARAM_ERROR
;
550 if (strm
->bzalloc
== NULL
) strm
->bzalloc
= default_bzalloc
;
551 if (strm
->bzfree
== NULL
) strm
->bzfree
= default_bzfree
;
553 s
= BZALLOC( sizeof(DState
) );
554 if (s
== NULL
) return BZ_MEM_ERROR
;
557 s
->state
= BZ_X_MAGIC_1
;
560 s
->calculatedCombinedCRC
= 0;
561 strm
->total_in_lo32
= 0;
562 strm
->total_in_hi32
= 0;
563 strm
->total_out_lo32
= 0;
564 strm
->total_out_hi32
= 0;
565 s
->smallDecompress
= (Bool
)small
;
570 s
->verbosity
= verbosity
;
576 /*---------------------------------------------------*/
578 void unRLE_obuf_to_output_FAST ( DState
* s
)
582 if (s
->blockRandomised
) {
585 /* try to finish existing run */
587 if (s
->strm
->avail_out
== 0) return;
588 if (s
->state_out_len
== 0) break;
589 *( (UChar
*)(s
->strm
->next_out
) ) = s
->state_out_ch
;
590 BZ_UPDATE_CRC ( s
->calculatedBlockCRC
, s
->state_out_ch
);
593 s
->strm
->avail_out
--;
594 s
->strm
->total_out_lo32
++;
595 if (s
->strm
->total_out_lo32
== 0) s
->strm
->total_out_hi32
++;
598 /* can a new run be started? */
599 if (s
->nblock_used
== s
->save_nblock
+1) return;
602 s
->state_out_len
= 1;
603 s
->state_out_ch
= s
->k0
;
604 BZ_GET_FAST(k1
); BZ_RAND_UPD_MASK
;
605 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
606 if (s
->nblock_used
== s
->save_nblock
+1) continue;
607 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
609 s
->state_out_len
= 2;
610 BZ_GET_FAST(k1
); BZ_RAND_UPD_MASK
;
611 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
612 if (s
->nblock_used
== s
->save_nblock
+1) continue;
613 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
615 s
->state_out_len
= 3;
616 BZ_GET_FAST(k1
); BZ_RAND_UPD_MASK
;
617 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
618 if (s
->nblock_used
== s
->save_nblock
+1) continue;
619 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
621 BZ_GET_FAST(k1
); BZ_RAND_UPD_MASK
;
622 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
623 s
->state_out_len
= ((Int32
)k1
) + 4;
624 BZ_GET_FAST(s
->k0
); BZ_RAND_UPD_MASK
;
625 s
->k0
^= BZ_RAND_MASK
; s
->nblock_used
++;
631 UInt32 c_calculatedBlockCRC
= s
->calculatedBlockCRC
;
632 UChar c_state_out_ch
= s
->state_out_ch
;
633 Int32 c_state_out_len
= s
->state_out_len
;
634 Int32 c_nblock_used
= s
->nblock_used
;
636 UInt32
* c_tt
= s
->tt
;
637 UInt32 c_tPos
= s
->tPos
;
638 char* cs_next_out
= s
->strm
->next_out
;
639 unsigned int cs_avail_out
= s
->strm
->avail_out
;
642 UInt32 avail_out_INIT
= cs_avail_out
;
643 Int32 s_save_nblockPP
= s
->save_nblock
+1;
644 unsigned int total_out_lo32_old
;
648 /* try to finish existing run */
649 if (c_state_out_len
> 0) {
651 if (cs_avail_out
== 0) goto return_notr
;
652 if (c_state_out_len
== 1) break;
653 *( (UChar
*)(cs_next_out
) ) = c_state_out_ch
;
654 BZ_UPDATE_CRC ( c_calculatedBlockCRC
, c_state_out_ch
);
659 s_state_out_len_eq_one
:
661 if (cs_avail_out
== 0) {
662 c_state_out_len
= 1; goto return_notr
;
664 *( (UChar
*)(cs_next_out
) ) = c_state_out_ch
;
665 BZ_UPDATE_CRC ( c_calculatedBlockCRC
, c_state_out_ch
);
670 /* can a new run be started? */
671 if (c_nblock_used
== s_save_nblockPP
) {
672 c_state_out_len
= 0; goto return_notr
;
674 c_state_out_ch
= c_k0
;
675 BZ_GET_FAST_C(k1
); c_nblock_used
++;
677 c_k0
= k1
; goto s_state_out_len_eq_one
;
679 if (c_nblock_used
== s_save_nblockPP
)
680 goto s_state_out_len_eq_one
;
683 BZ_GET_FAST_C(k1
); c_nblock_used
++;
684 if (c_nblock_used
== s_save_nblockPP
) continue;
685 if (k1
!= c_k0
) { c_k0
= k1
; continue; };
688 BZ_GET_FAST_C(k1
); c_nblock_used
++;
689 if (c_nblock_used
== s_save_nblockPP
) continue;
690 if (k1
!= c_k0
) { c_k0
= k1
; continue; };
692 BZ_GET_FAST_C(k1
); c_nblock_used
++;
693 c_state_out_len
= ((Int32
)k1
) + 4;
694 BZ_GET_FAST_C(c_k0
); c_nblock_used
++;
698 total_out_lo32_old
= s
->strm
->total_out_lo32
;
699 s
->strm
->total_out_lo32
+= (avail_out_INIT
- cs_avail_out
);
700 if (s
->strm
->total_out_lo32
< total_out_lo32_old
)
701 s
->strm
->total_out_hi32
++;
704 s
->calculatedBlockCRC
= c_calculatedBlockCRC
;
705 s
->state_out_ch
= c_state_out_ch
;
706 s
->state_out_len
= c_state_out_len
;
707 s
->nblock_used
= c_nblock_used
;
711 s
->strm
->next_out
= cs_next_out
;
712 s
->strm
->avail_out
= cs_avail_out
;
719 /*---------------------------------------------------*/
720 __inline__ Int32
BZ2_indexIntoF ( Int32 indx
, Int32
*cftab
)
726 mid
= (nb
+ na
) >> 1;
727 if (indx
>= cftab
[mid
]) nb
= mid
; else na
= mid
;
729 while (na
- nb
!= 1);
734 /*---------------------------------------------------*/
736 void unRLE_obuf_to_output_SMALL ( DState
* s
)
740 if (s
->blockRandomised
) {
743 /* try to finish existing run */
745 if (s
->strm
->avail_out
== 0) return;
746 if (s
->state_out_len
== 0) break;
747 *( (UChar
*)(s
->strm
->next_out
) ) = s
->state_out_ch
;
748 BZ_UPDATE_CRC ( s
->calculatedBlockCRC
, s
->state_out_ch
);
751 s
->strm
->avail_out
--;
752 s
->strm
->total_out_lo32
++;
753 if (s
->strm
->total_out_lo32
== 0) s
->strm
->total_out_hi32
++;
756 /* can a new run be started? */
757 if (s
->nblock_used
== s
->save_nblock
+1) return;
760 s
->state_out_len
= 1;
761 s
->state_out_ch
= s
->k0
;
762 BZ_GET_SMALL(k1
); BZ_RAND_UPD_MASK
;
763 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
764 if (s
->nblock_used
== s
->save_nblock
+1) continue;
765 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
767 s
->state_out_len
= 2;
768 BZ_GET_SMALL(k1
); BZ_RAND_UPD_MASK
;
769 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
770 if (s
->nblock_used
== s
->save_nblock
+1) continue;
771 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
773 s
->state_out_len
= 3;
774 BZ_GET_SMALL(k1
); BZ_RAND_UPD_MASK
;
775 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
776 if (s
->nblock_used
== s
->save_nblock
+1) continue;
777 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
779 BZ_GET_SMALL(k1
); BZ_RAND_UPD_MASK
;
780 k1
^= BZ_RAND_MASK
; s
->nblock_used
++;
781 s
->state_out_len
= ((Int32
)k1
) + 4;
782 BZ_GET_SMALL(s
->k0
); BZ_RAND_UPD_MASK
;
783 s
->k0
^= BZ_RAND_MASK
; s
->nblock_used
++;
789 /* try to finish existing run */
791 if (s
->strm
->avail_out
== 0) return;
792 if (s
->state_out_len
== 0) break;
793 *( (UChar
*)(s
->strm
->next_out
) ) = s
->state_out_ch
;
794 BZ_UPDATE_CRC ( s
->calculatedBlockCRC
, s
->state_out_ch
);
797 s
->strm
->avail_out
--;
798 s
->strm
->total_out_lo32
++;
799 if (s
->strm
->total_out_lo32
== 0) s
->strm
->total_out_hi32
++;
802 /* can a new run be started? */
803 if (s
->nblock_used
== s
->save_nblock
+1) return;
805 s
->state_out_len
= 1;
806 s
->state_out_ch
= s
->k0
;
807 BZ_GET_SMALL(k1
); s
->nblock_used
++;
808 if (s
->nblock_used
== s
->save_nblock
+1) continue;
809 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
811 s
->state_out_len
= 2;
812 BZ_GET_SMALL(k1
); s
->nblock_used
++;
813 if (s
->nblock_used
== s
->save_nblock
+1) continue;
814 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
816 s
->state_out_len
= 3;
817 BZ_GET_SMALL(k1
); s
->nblock_used
++;
818 if (s
->nblock_used
== s
->save_nblock
+1) continue;
819 if (k1
!= s
->k0
) { s
->k0
= k1
; continue; };
821 BZ_GET_SMALL(k1
); s
->nblock_used
++;
822 s
->state_out_len
= ((Int32
)k1
) + 4;
823 BZ_GET_SMALL(s
->k0
); s
->nblock_used
++;
830 /*---------------------------------------------------*/
831 int BZ_API(BZ2_bzDecompress
) ( bz_stream
*strm
)
834 if (strm
== NULL
) return BZ_PARAM_ERROR
;
836 if (s
== NULL
) return BZ_PARAM_ERROR
;
837 if (s
->strm
!= strm
) return BZ_PARAM_ERROR
;
840 if (s
->state
== BZ_X_IDLE
) return BZ_SEQUENCE_ERROR
;
841 if (s
->state
== BZ_X_OUTPUT
) {
842 if (s
->smallDecompress
)
843 unRLE_obuf_to_output_SMALL ( s
); else
844 unRLE_obuf_to_output_FAST ( s
);
845 if (s
->nblock_used
== s
->save_nblock
+1 && s
->state_out_len
== 0) {
846 BZ_FINALISE_CRC ( s
->calculatedBlockCRC
);
847 if (s
->verbosity
>= 3)
848 VPrintf2 ( " {0x%x, 0x%x}", s
->storedBlockCRC
,
849 s
->calculatedBlockCRC
);
850 if (s
->verbosity
>= 2) VPrintf0 ( "]" );
851 if (s
->calculatedBlockCRC
!= s
->storedBlockCRC
)
852 return BZ_DATA_ERROR
;
853 s
->calculatedCombinedCRC
854 = (s
->calculatedCombinedCRC
<< 1) |
855 (s
->calculatedCombinedCRC
>> 31);
856 s
->calculatedCombinedCRC
^= s
->calculatedBlockCRC
;
857 s
->state
= BZ_X_BLKHDR_1
;
862 if (s
->state
>= BZ_X_MAGIC_1
) {
863 Int32 r
= BZ2_decompress ( s
);
864 if (r
== BZ_STREAM_END
) {
865 if (s
->verbosity
>= 3)
866 VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
867 s
->storedCombinedCRC
, s
->calculatedCombinedCRC
);
868 if (s
->calculatedCombinedCRC
!= s
->storedCombinedCRC
)
869 return BZ_DATA_ERROR
;
872 if (s
->state
!= BZ_X_OUTPUT
) return r
;
878 return 0; /*NOTREACHED*/
882 /*---------------------------------------------------*/
883 int BZ_API(BZ2_bzDecompressEnd
) ( bz_stream
*strm
)
886 if (strm
== NULL
) return BZ_PARAM_ERROR
;
888 if (s
== NULL
) return BZ_PARAM_ERROR
;
889 if (s
->strm
!= strm
) return BZ_PARAM_ERROR
;
891 if (s
->tt
!= NULL
) BZFREE(s
->tt
);
892 if (s
->ll16
!= NULL
) BZFREE(s
->ll16
);
893 if (s
->ll4
!= NULL
) BZFREE(s
->ll4
);
903 /*---------------------------------------------------*/
904 /*--- File I/O stuff ---*/
905 /*---------------------------------------------------*/
907 #define BZ_SETERR(eee) \
909 if (bzerror != NULL) *bzerror = eee; \
910 if (bzf != NULL) bzf->lastErr = eee; \
916 Char buf
[BZ_MAX_UNUSED
];
926 /*---------------------------------------------*/
927 static Bool
myfeof ( FILE* f
)
929 Int32 c
= fgetc ( f
);
930 if (c
== EOF
) return True
;
936 /*---------------------------------------------------*/
937 BZFILE
* BZ_API(BZ2_bzWriteOpen
)
950 (blockSize100k
< 1 || blockSize100k
> 9) ||
951 (workFactor
< 0 || workFactor
> 250) ||
952 (verbosity
< 0 || verbosity
> 4))
953 { BZ_SETERR(BZ_PARAM_ERROR
); return NULL
; };
956 { BZ_SETERR(BZ_IO_ERROR
); return NULL
; };
958 bzf
= malloc ( sizeof(bzFile
) );
960 { BZ_SETERR(BZ_MEM_ERROR
); return NULL
; };
963 bzf
->initialisedOk
= False
;
967 bzf
->strm
.bzalloc
= NULL
;
968 bzf
->strm
.bzfree
= NULL
;
969 bzf
->strm
.opaque
= NULL
;
971 if (workFactor
== 0) workFactor
= 30;
972 ret
= BZ2_bzCompressInit ( &(bzf
->strm
), blockSize100k
,
973 verbosity
, workFactor
);
975 { BZ_SETERR(ret
); free(bzf
); return NULL
; };
977 bzf
->strm
.avail_in
= 0;
978 bzf
->initialisedOk
= True
;
984 /*---------------------------------------------------*/
985 void BZ_API(BZ2_bzWrite
)
992 bzFile
* bzf
= (bzFile
*)b
;
995 if (bzf
== NULL
|| buf
== NULL
|| len
< 0)
996 { BZ_SETERR(BZ_PARAM_ERROR
); return; };
998 { BZ_SETERR(BZ_SEQUENCE_ERROR
); return; };
999 if (ferror(bzf
->handle
))
1000 { BZ_SETERR(BZ_IO_ERROR
); return; };
1003 { BZ_SETERR(BZ_OK
); return; };
1005 bzf
->strm
.avail_in
= len
;
1006 bzf
->strm
.next_in
= buf
;
1009 bzf
->strm
.avail_out
= BZ_MAX_UNUSED
;
1010 bzf
->strm
.next_out
= bzf
->buf
;
1011 ret
= BZ2_bzCompress ( &(bzf
->strm
), BZ_RUN
);
1012 if (ret
!= BZ_RUN_OK
)
1013 { BZ_SETERR(ret
); return; };
1015 if (bzf
->strm
.avail_out
< BZ_MAX_UNUSED
) {
1016 n
= BZ_MAX_UNUSED
- bzf
->strm
.avail_out
;
1017 n2
= fwrite ( (void*)(bzf
->buf
), sizeof(UChar
),
1019 if (n
!= n2
|| ferror(bzf
->handle
))
1020 { BZ_SETERR(BZ_IO_ERROR
); return; };
1023 if (bzf
->strm
.avail_in
== 0)
1024 { BZ_SETERR(BZ_OK
); return; };
1029 /*---------------------------------------------------*/
1030 void BZ_API(BZ2_bzWriteClose
)
1034 unsigned int* nbytes_in
,
1035 unsigned int* nbytes_out
)
1037 BZ2_bzWriteClose64 ( bzerror
, b
, abandon
,
1038 nbytes_in
, NULL
, nbytes_out
, NULL
);
1042 void BZ_API(BZ2_bzWriteClose64
)
1046 unsigned int* nbytes_in_lo32
,
1047 unsigned int* nbytes_in_hi32
,
1048 unsigned int* nbytes_out_lo32
,
1049 unsigned int* nbytes_out_hi32
)
1052 bzFile
* bzf
= (bzFile
*)b
;
1055 { BZ_SETERR(BZ_OK
); return; };
1056 if (!(bzf
->writing
))
1057 { BZ_SETERR(BZ_SEQUENCE_ERROR
); return; };
1058 if (ferror(bzf
->handle
))
1059 { BZ_SETERR(BZ_IO_ERROR
); return; };
1061 if (nbytes_in_lo32
!= NULL
) *nbytes_in_lo32
= 0;
1062 if (nbytes_in_hi32
!= NULL
) *nbytes_in_hi32
= 0;
1063 if (nbytes_out_lo32
!= NULL
) *nbytes_out_lo32
= 0;
1064 if (nbytes_out_hi32
!= NULL
) *nbytes_out_hi32
= 0;
1066 if ((!abandon
) && bzf
->lastErr
== BZ_OK
) {
1068 bzf
->strm
.avail_out
= BZ_MAX_UNUSED
;
1069 bzf
->strm
.next_out
= bzf
->buf
;
1070 ret
= BZ2_bzCompress ( &(bzf
->strm
), BZ_FINISH
);
1071 if (ret
!= BZ_FINISH_OK
&& ret
!= BZ_STREAM_END
)
1072 { BZ_SETERR(ret
); return; };
1074 if (bzf
->strm
.avail_out
< BZ_MAX_UNUSED
) {
1075 n
= BZ_MAX_UNUSED
- bzf
->strm
.avail_out
;
1076 n2
= fwrite ( (void*)(bzf
->buf
), sizeof(UChar
),
1078 if (n
!= n2
|| ferror(bzf
->handle
))
1079 { BZ_SETERR(BZ_IO_ERROR
); return; };
1082 if (ret
== BZ_STREAM_END
) break;
1086 if ( !abandon
&& !ferror ( bzf
->handle
) ) {
1087 fflush ( bzf
->handle
);
1088 if (ferror(bzf
->handle
))
1089 { BZ_SETERR(BZ_IO_ERROR
); return; };
1092 if (nbytes_in_lo32
!= NULL
)
1093 *nbytes_in_lo32
= bzf
->strm
.total_in_lo32
;
1094 if (nbytes_in_hi32
!= NULL
)
1095 *nbytes_in_hi32
= bzf
->strm
.total_in_hi32
;
1096 if (nbytes_out_lo32
!= NULL
)
1097 *nbytes_out_lo32
= bzf
->strm
.total_out_lo32
;
1098 if (nbytes_out_hi32
!= NULL
)
1099 *nbytes_out_hi32
= bzf
->strm
.total_out_hi32
;
1102 BZ2_bzCompressEnd ( &(bzf
->strm
) );
1107 /*---------------------------------------------------*/
1108 BZFILE
* BZ_API(BZ2_bzReadOpen
)
1122 (small
!= 0 && small
!= 1) ||
1123 (verbosity
< 0 || verbosity
> 4) ||
1124 (unused
== NULL
&& nUnused
!= 0) ||
1125 (unused
!= NULL
&& (nUnused
< 0 || nUnused
> BZ_MAX_UNUSED
)))
1126 { BZ_SETERR(BZ_PARAM_ERROR
); return NULL
; };
1129 { BZ_SETERR(BZ_IO_ERROR
); return NULL
; };
1131 bzf
= malloc ( sizeof(bzFile
) );
1133 { BZ_SETERR(BZ_MEM_ERROR
); return NULL
; };
1137 bzf
->initialisedOk
= False
;
1140 bzf
->writing
= False
;
1141 bzf
->strm
.bzalloc
= NULL
;
1142 bzf
->strm
.bzfree
= NULL
;
1143 bzf
->strm
.opaque
= NULL
;
1145 while (nUnused
> 0) {
1146 bzf
->buf
[bzf
->bufN
] = *((UChar
*)(unused
)); bzf
->bufN
++;
1147 unused
= ((void*)( 1 + ((UChar
*)(unused
)) ));
1151 ret
= BZ2_bzDecompressInit ( &(bzf
->strm
), verbosity
, small
);
1153 { BZ_SETERR(ret
); free(bzf
); return NULL
; };
1155 bzf
->strm
.avail_in
= bzf
->bufN
;
1156 bzf
->strm
.next_in
= bzf
->buf
;
1158 bzf
->initialisedOk
= True
;
1163 /*---------------------------------------------------*/
1164 void BZ_API(BZ2_bzReadClose
) ( int *bzerror
, BZFILE
*b
)
1166 bzFile
* bzf
= (bzFile
*)b
;
1170 { BZ_SETERR(BZ_OK
); return; };
1173 { BZ_SETERR(BZ_SEQUENCE_ERROR
); return; };
1175 if (bzf
->initialisedOk
)
1176 (void)BZ2_bzDecompressEnd ( &(bzf
->strm
) );
1181 /*---------------------------------------------------*/
1182 int BZ_API(BZ2_bzRead
)
1189 bzFile
* bzf
= (bzFile
*)b
;
1193 if (bzf
== NULL
|| buf
== NULL
|| len
< 0)
1194 { BZ_SETERR(BZ_PARAM_ERROR
); return 0; };
1197 { BZ_SETERR(BZ_SEQUENCE_ERROR
); return 0; };
1200 { BZ_SETERR(BZ_OK
); return 0; };
1202 bzf
->strm
.avail_out
= len
;
1203 bzf
->strm
.next_out
= buf
;
1207 if (ferror(bzf
->handle
))
1208 { BZ_SETERR(BZ_IO_ERROR
); return 0; };
1210 if (bzf
->strm
.avail_in
== 0 && !myfeof(bzf
->handle
)) {
1211 n
= fread ( bzf
->buf
, sizeof(UChar
),
1212 BZ_MAX_UNUSED
, bzf
->handle
);
1213 if (ferror(bzf
->handle
))
1214 { BZ_SETERR(BZ_IO_ERROR
); return 0; };
1216 bzf
->strm
.avail_in
= bzf
->bufN
;
1217 bzf
->strm
.next_in
= bzf
->buf
;
1220 ret
= BZ2_bzDecompress ( &(bzf
->strm
) );
1222 if (ret
!= BZ_OK
&& ret
!= BZ_STREAM_END
)
1223 { BZ_SETERR(ret
); return 0; };
1225 if (ret
== BZ_OK
&& myfeof(bzf
->handle
) &&
1226 bzf
->strm
.avail_in
== 0 && bzf
->strm
.avail_out
> 0)
1227 { BZ_SETERR(BZ_UNEXPECTED_EOF
); return 0; };
1229 if (ret
== BZ_STREAM_END
)
1230 { BZ_SETERR(BZ_STREAM_END
);
1231 return len
- bzf
->strm
.avail_out
; };
1232 if (bzf
->strm
.avail_out
== 0)
1233 { BZ_SETERR(BZ_OK
); return len
; };
1237 return 0; /*not reached*/
1241 /*---------------------------------------------------*/
1242 void BZ_API(BZ2_bzReadGetUnused
)
1248 bzFile
* bzf
= (bzFile
*)b
;
1250 { BZ_SETERR(BZ_PARAM_ERROR
); return; };
1251 if (bzf
->lastErr
!= BZ_STREAM_END
)
1252 { BZ_SETERR(BZ_SEQUENCE_ERROR
); return; };
1253 if (unused
== NULL
|| nUnused
== NULL
)
1254 { BZ_SETERR(BZ_PARAM_ERROR
); return; };
1257 *nUnused
= bzf
->strm
.avail_in
;
1258 *unused
= bzf
->strm
.next_in
;
1263 /*---------------------------------------------------*/
1264 /*--- Misc convenience stuff ---*/
1265 /*---------------------------------------------------*/
1267 /*---------------------------------------------------*/
1268 int BZ_API(BZ2_bzBuffToBuffCompress
)
1270 unsigned int* destLen
,
1272 unsigned int sourceLen
,
1280 if (dest
== NULL
|| destLen
== NULL
||
1282 blockSize100k
< 1 || blockSize100k
> 9 ||
1283 verbosity
< 0 || verbosity
> 4 ||
1284 workFactor
< 0 || workFactor
> 250)
1285 return BZ_PARAM_ERROR
;
1287 if (workFactor
== 0) workFactor
= 30;
1288 strm
.bzalloc
= NULL
;
1291 ret
= BZ2_bzCompressInit ( &strm
, blockSize100k
,
1292 verbosity
, workFactor
);
1293 if (ret
!= BZ_OK
) return ret
;
1295 strm
.next_in
= source
;
1296 strm
.next_out
= dest
;
1297 strm
.avail_in
= sourceLen
;
1298 strm
.avail_out
= *destLen
;
1300 ret
= BZ2_bzCompress ( &strm
, BZ_FINISH
);
1301 if (ret
== BZ_FINISH_OK
) goto output_overflow
;
1302 if (ret
!= BZ_STREAM_END
) goto errhandler
;
1304 /* normal termination */
1305 *destLen
-= strm
.avail_out
;
1306 BZ2_bzCompressEnd ( &strm
);
1310 BZ2_bzCompressEnd ( &strm
);
1311 return BZ_OUTBUFF_FULL
;
1314 BZ2_bzCompressEnd ( &strm
);
1319 /*---------------------------------------------------*/
1320 int BZ_API(BZ2_bzBuffToBuffDecompress
)
1322 unsigned int* destLen
,
1324 unsigned int sourceLen
,
1331 if (dest
== NULL
|| destLen
== NULL
||
1333 (small
!= 0 && small
!= 1) ||
1334 verbosity
< 0 || verbosity
> 4)
1335 return BZ_PARAM_ERROR
;
1337 strm
.bzalloc
= NULL
;
1340 ret
= BZ2_bzDecompressInit ( &strm
, verbosity
, small
);
1341 if (ret
!= BZ_OK
) return ret
;
1343 strm
.next_in
= source
;
1344 strm
.next_out
= dest
;
1345 strm
.avail_in
= sourceLen
;
1346 strm
.avail_out
= *destLen
;
1348 ret
= BZ2_bzDecompress ( &strm
);
1349 if (ret
== BZ_OK
) goto output_overflow_or_eof
;
1350 if (ret
!= BZ_STREAM_END
) goto errhandler
;
1352 /* normal termination */
1353 *destLen
-= strm
.avail_out
;
1354 BZ2_bzDecompressEnd ( &strm
);
1357 output_overflow_or_eof
:
1358 if (strm
.avail_out
> 0) {
1359 BZ2_bzDecompressEnd ( &strm
);
1360 return BZ_UNEXPECTED_EOF
;
1362 BZ2_bzDecompressEnd ( &strm
);
1363 return BZ_OUTBUFF_FULL
;
1367 BZ2_bzDecompressEnd ( &strm
);
1372 /*---------------------------------------------------*/
1374 Code contributed by Yoshioka Tsuneo
1375 (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
1376 to support better zlib compatibility.
1377 This code is not _officially_ part of libbzip2 (yet);
1378 I haven't tested it, documented it, or considered the
1379 threading-safeness of it.
1380 If this code breaks, please contact both Yoshioka and me.
1382 /*---------------------------------------------------*/
1384 /*---------------------------------------------------*/
1386 return version like "0.9.0c".
1388 const char * BZ_API(BZ2_bzlibVersion
)(void)
1395 /*---------------------------------------------------*/
1397 #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
1400 # define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
1402 # define SET_BINARY_MODE(file)
1405 BZFILE
* bzopen_or_bzdopen
1406 ( const char *path
, /* no use when bzdopen */
1407 int fd
, /* no use when bzdopen */
1409 int open_mode
) /* bzopen: 0, bzdopen:1 */
1412 char unused
[BZ_MAX_UNUSED
];
1413 int blockSize100k
= 9;
1415 char mode2
[10] = "";
1417 BZFILE
*bzfp
= NULL
;
1419 int workFactor
= 30;
1423 if (mode
== NULL
) return NULL
;
1431 smallMode
= 1; break;
1433 if (isdigit((int)(*mode
))) {
1434 blockSize100k
= *mode
-BZ_HDR_0
;
1439 strcat(mode2
, writing
? "w" : "r" );
1440 strcat(mode2
,"b"); /* binary mode */
1443 if (path
==NULL
|| strcmp(path
,"")==0) {
1444 fp
= (writing
? stdout
: stdin
);
1445 SET_BINARY_MODE(fp
);
1447 fp
= fopen(path
,mode2
);
1450 #ifdef BZ_STRICT_ANSI
1453 fp
= fdopen(fd
,mode2
);
1456 if (fp
== NULL
) return NULL
;
1459 /* Guard against total chaos and anarchy -- JRS */
1460 if (blockSize100k
< 1) blockSize100k
= 1;
1461 if (blockSize100k
> 9) blockSize100k
= 9;
1462 bzfp
= BZ2_bzWriteOpen(&bzerr
,fp
,blockSize100k
,
1463 verbosity
,workFactor
);
1465 bzfp
= BZ2_bzReadOpen(&bzerr
,fp
,verbosity
,smallMode
,
1469 if (fp
!= stdin
&& fp
!= stdout
) fclose(fp
);
1476 /*---------------------------------------------------*/
1478 open file for read or write.
1479 ex) bzopen("file","w9")
1480 case path="" or NULL => use stdin or stdout.
1482 BZFILE
* BZ_API(BZ2_bzopen
)
1486 return bzopen_or_bzdopen(path
,-1,mode
,/*bzopen*/0);
1490 /*---------------------------------------------------*/
1491 BZFILE
* BZ_API(BZ2_bzdopen
)
1495 return bzopen_or_bzdopen(NULL
,fd
,mode
,/*bzdopen*/1);
1499 /*---------------------------------------------------*/
1500 int BZ_API(BZ2_bzread
) (BZFILE
* b
, void* buf
, int len
)
1503 if (((bzFile
*)b
)->lastErr
== BZ_STREAM_END
) return 0;
1504 nread
= BZ2_bzRead(&bzerr
,b
,buf
,len
);
1505 if (bzerr
== BZ_OK
|| bzerr
== BZ_STREAM_END
) {
1513 /*---------------------------------------------------*/
1514 int BZ_API(BZ2_bzwrite
) (BZFILE
* b
, void* buf
, int len
)
1518 BZ2_bzWrite(&bzerr
,b
,buf
,len
);
1527 /*---------------------------------------------------*/
1528 int BZ_API(BZ2_bzflush
) (BZFILE
*b
)
1530 /* do nothing now... */
1535 /*---------------------------------------------------*/
1536 void BZ_API(BZ2_bzclose
) (BZFILE
* b
)
1539 FILE *fp
= ((bzFile
*)b
)->handle
;
1541 if (b
==NULL
) {return;}
1542 if(((bzFile
*)b
)->writing
){
1543 BZ2_bzWriteClose(&bzerr
,b
,0,NULL
,NULL
);
1545 BZ2_bzWriteClose(NULL
,b
,1,NULL
,NULL
);
1548 BZ2_bzReadClose(&bzerr
,b
);
1550 if(fp
!=stdin
&& fp
!=stdout
){
1556 /*---------------------------------------------------*/
1558 return last error code
1560 static char *bzerrorstrings
[] = {
1571 ,"???" /* for future */
1572 ,"???" /* for future */
1573 ,"???" /* for future */
1574 ,"???" /* for future */
1575 ,"???" /* for future */
1576 ,"???" /* for future */
1580 const char * BZ_API(BZ2_bzerror
) (BZFILE
*b
, int *errnum
)
1582 int err
= ((bzFile
*)b
)->lastErr
;
1586 return bzerrorstrings
[err
*-1];
1591 /*-------------------------------------------------------------*/
1592 /*--- end bzlib.c ---*/
1593 /*-------------------------------------------------------------*/