1 
2 #define BZ_NO_STDIO
3 
4 
5 /*-------------------------------------------------------------*/
6 /*--- Private header file for the library.                  ---*/
7 /*---                                       bzlib_private.h ---*/
8 /*-------------------------------------------------------------*/
9 
10 /*--
11   This file is a part of bzip2 and/or libbzip2, a program and
12   library for lossless, block-sorting data compression.
13 
14   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
15 
16   Redistribution and use in source and binary forms, with or without
17   modification, are permitted provided that the following conditions
18   are met:
19 
20   1. Redistributions of source code must retain the above copyright
21      notice, this list of conditions and the following disclaimer.
22 
23   2. The origin of this software must not be misrepresented; you must
24      not claim that you wrote the original software.  If you use this
25      software in a product, an acknowledgment in the product
26      documentation would be appreciated but is not required.
27 
28   3. Altered source versions must be plainly marked as such, and must
29      not be misrepresented as being the original software.
30 
31   4. The name of the author may not be used to endorse or promote
32      products derived from this software without specific prior written
33      permission.
34 
35   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
36   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
39   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
43   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 
47   Julian Seward, Cambridge, UK.
48   jseward@bzip.org
49   bzip2/libbzip2 version 1.0 of 21 March 2000
50 
51   This program is based on (at least) the work of:
52      Mike Burrows
53      David Wheeler
54      Peter Fenwick
55      Alistair Moffat
56      Radford Neal
57      Ian H. Witten
58      Robert Sedgewick
59      Jon L. Bentley
60 
61   For more information on these sources, see the manual.
62 --*/
63 
64 
65 #ifndef _BZLIB_PRIVATE_H
66 #define _BZLIB_PRIVATE_H
67 
68 #include <stdlib.h>
69 
70 #ifndef BZ_NO_STDIO
71 #include <stdio.h>
72 #include <ctype.h>
73 #include <string.h>
74 #endif
75 
76 
77 /*-------------------------------------------------------------*/
78 /*--- Public header file for the library.                   ---*/
79 /*---                                               bzlib.h ---*/
80 /*-------------------------------------------------------------*/
81 
82 /*--
83   This file is a part of bzip2 and/or libbzip2, a program and
84   library for lossless, block-sorting data compression.
85 
86   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
87 
88   Redistribution and use in source and binary forms, with or without
89   modification, are permitted provided that the following conditions
90   are met:
91 
92   1. Redistributions of source code must retain the above copyright
93      notice, this list of conditions and the following disclaimer.
94 
95   2. The origin of this software must not be misrepresented; you must
96      not claim that you wrote the original software.  If you use this
97      software in a product, an acknowledgment in the product
98      documentation would be appreciated but is not required.
99 
100   3. Altered source versions must be plainly marked as such, and must
101      not be misrepresented as being the original software.
102 
103   4. The name of the author may not be used to endorse or promote
104      products derived from this software without specific prior written
105      permission.
106 
107   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
108   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
110   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
111   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
112   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
113   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
114   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
115   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
116   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
117   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118 
119   Julian Seward, Cambridge, UK.
120   jseward@bzip.org
121   bzip2/libbzip2 version 1.0 of 21 March 2000
122 
123   This program is based on (at least) the work of:
124      Mike Burrows
125      David Wheeler
126      Peter Fenwick
127      Alistair Moffat
128      Radford Neal
129      Ian H. Witten
130      Robert Sedgewick
131      Jon L. Bentley
132 
133   For more information on these sources, see the manual.
134 --*/
135 
136 
137 #ifndef _BZLIB_H
138 #define _BZLIB_H
139 
140 #ifdef __cplusplus
141 extern "C" {
142 #endif
143 
144 #define BZ_RUN               0
145 #define BZ_FLUSH             1
146 #define BZ_FINISH            2
147 
148 #define BZ_OK                0
149 #define BZ_RUN_OK            1
150 #define BZ_FLUSH_OK          2
151 #define BZ_FINISH_OK         3
152 #define BZ_STREAM_END        4
153 #define BZ_SEQUENCE_ERROR    (-1)
154 #define BZ_PARAM_ERROR       (-2)
155 #define BZ_MEM_ERROR         (-3)
156 #define BZ_DATA_ERROR        (-4)
157 #define BZ_DATA_ERROR_MAGIC  (-5)
158 #define BZ_IO_ERROR          (-6)
159 #define BZ_UNEXPECTED_EOF    (-7)
160 #define BZ_OUTBUFF_FULL      (-8)
161 #define BZ_CONFIG_ERROR      (-9)
162 
163 typedef
164    struct {
165       char *next_in;
166       unsigned int avail_in;
167       unsigned int total_in_lo32;
168       unsigned int total_in_hi32;
169 
170       char *next_out;
171       unsigned int avail_out;
172       unsigned int total_out_lo32;
173       unsigned int total_out_hi32;
174 
175       void *state;
176 
177       void *(*bzalloc)(void *,int,int);
178       void (*bzfree)(void *,void *);
179       void *opaque;
180    }
181    bz_stream;
182 
183 
184 #ifndef BZ_IMPORT
185 #define BZ_EXPORT
186 #endif
187 
188 #ifndef BZ_NO_STDIO
189 /* Need a definitition for FILE */
190 #include <stdio.h>
191 #endif
192 
193 #ifdef _WIN32
194 #   include <windows.h>
195 #   ifdef small
196       /* windows.h define small to char */
197 #      undef small
198 #   endif
199 #   ifdef BZ_EXPORT
200 #   define BZ_API(func) WINAPI func
201 #   define BZ_EXTERN extern
202 #   else
203    /* import windows dll dynamically */
204 #   define BZ_API(func) (WINAPI * func)
205 #   define BZ_EXTERN
206 #   endif
207 #else
208 #   define BZ_API(func) func
209 #   define BZ_EXTERN extern
210 #endif
211 
212 
213 /*-- Core (low-level) library functions --*/
214 
215 BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
216       bz_stream* strm,
217       int        blockSize100k,
218       int        verbosity,
219       int        workFactor
220    );
221 
222 BZ_EXTERN int BZ_API(BZ2_bzCompress) (
223       bz_stream* strm,
224       int action
225    );
226 
227 BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
228       bz_stream* strm
229    );
230 
231 BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
232       bz_stream *strm,
233       int       verbosity,
234       int       small
235    );
236 
237 BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
238       bz_stream* strm
239    );
240 
241 BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
242       bz_stream *strm
243    );
244 
245 
246 
247 /*-- High(er) level library functions --*/
248 
249 #ifndef BZ_NO_STDIO
250 #define BZ_MAX_UNUSED 5000
251 
252 typedef void BZFILE;
253 
254 BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
255       int*  bzerror,
256       FILE* f,
257       int   verbosity,
258       int   small,
259       void* unused,
260       int   nUnused
261    );
262 
263 BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
264       int*    bzerror,
265       BZFILE* b
266    );
267 
268 BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
269       int*    bzerror,
270       BZFILE* b,
271       void**  unused,
272       int*    nUnused
273    );
274 
275 BZ_EXTERN int BZ_API(BZ2_bzRead) (
276       int*    bzerror,
277       BZFILE* b,
278       void*   buf,
279       int     len
280    );
281 
282 BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
283       int*  bzerror,
284       FILE* f,
285       int   blockSize100k,
286       int   verbosity,
287       int   workFactor
288    );
289 
290 BZ_EXTERN void BZ_API(BZ2_bzWrite) (
291       int*    bzerror,
292       BZFILE* b,
293       void*   buf,
294       int     len
295    );
296 
297 BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
298       int*          bzerror,
299       BZFILE*       b,
300       int           abandon,
301       unsigned int* nbytes_in,
302       unsigned int* nbytes_out
303    );
304 
305 BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
306       int*          bzerror,
307       BZFILE*       b,
308       int           abandon,
309       unsigned int* nbytes_in_lo32,
310       unsigned int* nbytes_in_hi32,
311       unsigned int* nbytes_out_lo32,
312       unsigned int* nbytes_out_hi32
313    );
314 #endif
315 
316 
317 /*-- Utility functions --*/
318 
319 BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
320       char*         dest,
321       unsigned int* destLen,
322       char*         source,
323       unsigned int  sourceLen,
324       int           blockSize100k,
325       int           verbosity,
326       int           workFactor
327    );
328 
329 BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
330       char*         dest,
331       unsigned int* destLen,
332       char*         source,
333       unsigned int  sourceLen,
334       int           small,
335       int           verbosity
336    );
337 
338 
339 /*--
340    Code contributed by Yoshioka Tsuneo
341    (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
342    to support better zlib compatibility.
343    This code is not _officially_ part of libbzip2 (yet);
344    I haven't tested it, documented it, or considered the
345    threading-safeness of it.
346    If this code breaks, please contact both Yoshioka and me.
347 --*/
348 
349 BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
350       void
351    );
352 
353 #ifndef BZ_NO_STDIO
354 BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
355       const char *path,
356       const char *mode
357    );
358 
359 BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
360       int        fd,
361       const char *mode
362    );
363 
364 BZ_EXTERN int BZ_API(BZ2_bzread) (
365       BZFILE* b,
366       void* buf,
367       int len
368    );
369 
370 BZ_EXTERN int BZ_API(BZ2_bzwrite) (
371       BZFILE* b,
372       void*   buf,
373       int     len
374    );
375 
376 BZ_EXTERN int BZ_API(BZ2_bzflush) (
377       BZFILE* b
378    );
379 
380 BZ_EXTERN void BZ_API(BZ2_bzclose) (
381       BZFILE* b
382    );
383 
384 BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
385       BZFILE *b,
386       int    *errnum
387    );
388 #endif
389 
390 #ifdef __cplusplus
391 }
392 #endif
393 
394 #endif
395 
396 /*-------------------------------------------------------------*/
397 /*--- end                                           bzlib.h ---*/
398 /*-------------------------------------------------------------*/
399 
400 
401 
402 
403 /*-- General stuff. --*/
404 
405 #define BZ_VERSION  "1.0.3, 17-Oct-2004"
406 
407 typedef char            Char;
408 typedef unsigned char   Bool;
409 typedef unsigned char   UChar;
410 typedef int             Int32;
411 typedef unsigned int    UInt32;
412 typedef short           Int16;
413 typedef unsigned short  UInt16;
414 
415 #define True  ((Bool)1)
416 #define False ((Bool)0)
417 
418 #ifndef __GNUC__
419 #define __inline__  /* */
420 #endif
421 
422 #ifndef BZ_NO_STDIO
423 extern void BZ2_bz__AssertH__fail ( int errcode );
424 #define AssertH(cond,errcode) \
425    { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
426 #if BZ_DEBUG
427 #define AssertD(cond,msg) \
428    { if (!(cond)) {       \
429       fprintf ( stderr,   \
430         "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
431       exit(1); \
432    }}
433 #else
434 #define AssertD(cond,msg) /* */
435 #endif
436 #define VPrintf0(zf) \
437    fprintf(stderr,zf)
438 #define VPrintf1(zf,za1) \
439    fprintf(stderr,zf,za1)
440 #define VPrintf2(zf,za1,za2) \
441    fprintf(stderr,zf,za1,za2)
442 #define VPrintf3(zf,za1,za2,za3) \
443    fprintf(stderr,zf,za1,za2,za3)
444 #define VPrintf4(zf,za1,za2,za3,za4) \
445    fprintf(stderr,zf,za1,za2,za3,za4)
446 #define VPrintf5(zf,za1,za2,za3,za4,za5) \
447    fprintf(stderr,zf,za1,za2,za3,za4,za5)
448 #else
449 extern void bz_internal_error ( int errcode );
450 #define AssertH(cond,errcode) \
451    { if (!(cond)) bz_internal_error ( errcode ); }
452 #define AssertD(cond,msg) /* */
453 #define VPrintf0(zf) \
454    vexxx_printf(zf)
455 #define VPrintf1(zf,za1) \
456    vexxx_printf(zf,za1)
457 #define VPrintf2(zf,za1,za2) \
458    vexxx_printf(zf,za1,za2)
459 #define VPrintf3(zf,za1,za2,za3) \
460    vexxx_printf(zf,za1,za2,za3)
461 #define VPrintf4(zf,za1,za2,za3,za4) \
462    vexxx_printf(zf,za1,za2,za3,za4)
463 #define VPrintf5(zf,za1,za2,za3,za4,za5) \
464    vexxx_printf(zf,za1,za2,za3,za4,za5)
465 #endif
466 
467 
468 #define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
469 #define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))
470 
471 
472 /*-- Header bytes. --*/
473 
474 #define BZ_HDR_B 0x42   /* 'B' */
475 #define BZ_HDR_Z 0x5a   /* 'Z' */
476 #define BZ_HDR_h 0x68   /* 'h' */
477 #define BZ_HDR_0 0x30   /* '0' */
478 
479 /*-- Constants for the back end. --*/
480 
481 #define BZ_MAX_ALPHA_SIZE 258
482 #define BZ_MAX_CODE_LEN    23
483 
484 #define BZ_RUNA 0
485 #define BZ_RUNB 1
486 
487 #define BZ_N_GROUPS 6
488 #define BZ_G_SIZE   50
489 #define BZ_N_ITERS  4
490 
491 #define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
492 
493 
494 
495 /*-- Stuff for randomising repetitive blocks. --*/
496 
497 extern Int32 BZ2_rNums[512];
498 
499 #define BZ_RAND_DECLS                          \
500    Int32 rNToGo;                               \
501    Int32 rTPos                                 \
502 
503 #define BZ_RAND_INIT_MASK                      \
504    s->rNToGo = 0;                              \
505    s->rTPos  = 0                               \
506 
507 #define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
508 
509 #define BZ_RAND_UPD_MASK                       \
510    if (s->rNToGo == 0) {                       \
511       s->rNToGo = BZ2_rNums[s->rTPos];         \
512       s->rTPos++;                              \
513       if (s->rTPos == 512) s->rTPos = 0;       \
514    }                                           \
515    s->rNToGo--;
516 
517 
518 
519 /*-- Stuff for doing CRCs. --*/
520 
521 extern UInt32 BZ2_crc32Table[256];
522 
523 #define BZ_INITIALISE_CRC(crcVar)              \
524 {                                              \
525    crcVar = 0xffffffffL;                       \
526 }
527 
528 #define BZ_FINALISE_CRC(crcVar)                \
529 {                                              \
530    crcVar = ~(crcVar);                         \
531 }
532 
533 #define BZ_UPDATE_CRC(crcVar,cha)              \
534 {                                              \
535    crcVar = (crcVar << 8) ^                    \
536             BZ2_crc32Table[(crcVar >> 24) ^    \
537                            ((UChar)cha)];      \
538 }
539 
540 
541 
542 /*-- States and modes for compression. --*/
543 
544 #define BZ_M_IDLE      1
545 #define BZ_M_RUNNING   2
546 #define BZ_M_FLUSHING  3
547 #define BZ_M_FINISHING 4
548 
549 #define BZ_S_OUTPUT    1
550 #define BZ_S_INPUT     2
551 
552 #define BZ_N_RADIX 2
553 #define BZ_N_QSORT 12
554 #define BZ_N_SHELL 18
555 #define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
556 
557 
558 
559 
560 /*-- Structure holding all the compression-side stuff. --*/
561 
562 typedef
563    struct {
564       /* pointer back to the struct bz_stream */
565       bz_stream* strm;
566 
567       /* mode this stream is in, and whether inputting */
568       /* or outputting data */
569       Int32    mode;
570       Int32    state;
571 
572       /* remembers avail_in when flush/finish requested */
573       UInt32   avail_in_expect;
574 
575       /* for doing the block sorting */
576       UInt32*  arr1;
577       UInt32*  arr2;
578       UInt32*  ftab;
579       Int32    origPtr;
580 
581       /* aliases for arr1 and arr2 */
582       UInt32*  ptr;
583       UChar*   block;
584       UInt16*  mtfv;
585       UChar*   zbits;
586 
587       /* for deciding when to use the fallback sorting algorithm */
588       Int32    workFactor;
589 
590       /* run-length-encoding of the input */
591       UInt32   state_in_ch;
592       Int32    state_in_len;
593       BZ_RAND_DECLS;
594 
595       /* input and output limits and current posns */
596       Int32    nblock;
597       Int32    nblockMAX;
598       Int32    numZ;
599       Int32    state_out_pos;
600 
601       /* map of bytes used in block */
602       Int32    nInUse;
603       Bool     inUse[256];
604       UChar    unseqToSeq[256];
605 
606       /* the buffer for bit stream creation */
607       UInt32   bsBuff;
608       Int32    bsLive;
609 
610       /* block and combined CRCs */
611       UInt32   blockCRC;
612       UInt32   combinedCRC;
613 
614       /* misc administratium */
615       Int32    verbosity;
616       Int32    blockNo;
617       Int32    blockSize100k;
618 
619       /* stuff for coding the MTF values */
620       Int32    nMTF;
621       Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
622       UChar    selector   [BZ_MAX_SELECTORS];
623       UChar    selectorMtf[BZ_MAX_SELECTORS];
624 
625       UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
626       Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
627       Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
628       /* second dimension: only 3 needed; 4 makes index calculations faster */
629       UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];
630 
631    }
632    EState;
633 
634 
635 
636 /*-- externs for compression. --*/
637 
638 extern void
639 BZ2_blockSort ( EState* );
640 
641 extern void
642 BZ2_compressBlock ( EState*, Bool );
643 
644 extern void
645 BZ2_bsInitWrite ( EState* );
646 
647 extern void
648 BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
649 
650 extern void
651 BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
652 
653 
654 
655 /*-- states for decompression. --*/
656 
657 #define BZ_X_IDLE        1
658 #define BZ_X_OUTPUT      2
659 
660 #define BZ_X_MAGIC_1     10
661 #define BZ_X_MAGIC_2     11
662 #define BZ_X_MAGIC_3     12
663 #define BZ_X_MAGIC_4     13
664 #define BZ_X_BLKHDR_1    14
665 #define BZ_X_BLKHDR_2    15
666 #define BZ_X_BLKHDR_3    16
667 #define BZ_X_BLKHDR_4    17
668 #define BZ_X_BLKHDR_5    18
669 #define BZ_X_BLKHDR_6    19
670 #define BZ_X_BCRC_1      20
671 #define BZ_X_BCRC_2      21
672 #define BZ_X_BCRC_3      22
673 #define BZ_X_BCRC_4      23
674 #define BZ_X_RANDBIT     24
675 #define BZ_X_ORIGPTR_1   25
676 #define BZ_X_ORIGPTR_2   26
677 #define BZ_X_ORIGPTR_3   27
678 #define BZ_X_MAPPING_1   28
679 #define BZ_X_MAPPING_2   29
680 #define BZ_X_SELECTOR_1  30
681 #define BZ_X_SELECTOR_2  31
682 #define BZ_X_SELECTOR_3  32
683 #define BZ_X_CODING_1    33
684 #define BZ_X_CODING_2    34
685 #define BZ_X_CODING_3    35
686 #define BZ_X_MTF_1       36
687 #define BZ_X_MTF_2       37
688 #define BZ_X_MTF_3       38
689 #define BZ_X_MTF_4       39
690 #define BZ_X_MTF_5       40
691 #define BZ_X_MTF_6       41
692 #define BZ_X_ENDHDR_2    42
693 #define BZ_X_ENDHDR_3    43
694 #define BZ_X_ENDHDR_4    44
695 #define BZ_X_ENDHDR_5    45
696 #define BZ_X_ENDHDR_6    46
697 #define BZ_X_CCRC_1      47
698 #define BZ_X_CCRC_2      48
699 #define BZ_X_CCRC_3      49
700 #define BZ_X_CCRC_4      50
701 
702 
703 
704 /*-- Constants for the fast MTF decoder. --*/
705 
706 #define MTFA_SIZE 4096
707 #define MTFL_SIZE 16
708 
709 
710 
711 /*-- Structure holding all the decompression-side stuff. --*/
712 
713 typedef
714    struct {
715       /* pointer back to the struct bz_stream */
716       bz_stream* strm;
717 
718       /* state indicator for this stream */
719       Int32    state;
720 
721       /* for doing the final run-length decoding */
722       UChar    state_out_ch;
723       Int32    state_out_len;
724       Bool     blockRandomised;
725       BZ_RAND_DECLS;
726 
727       /* the buffer for bit stream reading */
728       UInt32   bsBuff;
729       Int32    bsLive;
730 
731       /* misc administratium */
732       Int32    blockSize100k;
733       Bool     smallDecompress;
734       Int32    currBlockNo;
735       Int32    verbosity;
736 
737       /* for undoing the Burrows-Wheeler transform */
738       Int32    origPtr;
739       UInt32   tPos;
740       Int32    k0;
741       Int32    unzftab[256];
742       Int32    nblock_used;
743       Int32    cftab[257];
744       Int32    cftabCopy[257];
745 
746       /* for undoing the Burrows-Wheeler transform (FAST) */
747       UInt32   *tt;
748 
749       /* for undoing the Burrows-Wheeler transform (SMALL) */
750       UInt16   *ll16;
751       UChar    *ll4;
752 
753       /* stored and calculated CRCs */
754       UInt32   storedBlockCRC;
755       UInt32   storedCombinedCRC;
756       UInt32   calculatedBlockCRC;
757       UInt32   calculatedCombinedCRC;
758 
759       /* map of bytes used in block */
760       Int32    nInUse;
761       Bool     inUse[256];
762       Bool     inUse16[16];
763       UChar    seqToUnseq[256];
764 
765       /* for decoding the MTF values */
766       UChar    mtfa   [MTFA_SIZE];
767       Int32    mtfbase[256 / MTFL_SIZE];
768       UChar    selector   [BZ_MAX_SELECTORS];
769       UChar    selectorMtf[BZ_MAX_SELECTORS];
770       UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
771 
772       Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
773       Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
774       Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
775       Int32    minLens[BZ_N_GROUPS];
776 
777       /* save area for scalars in the main decompress code */
778       Int32    save_i;
779       Int32    save_j;
780       Int32    save_t;
781       Int32    save_alphaSize;
782       Int32    save_nGroups;
783       Int32    save_nSelectors;
784       Int32    save_EOB;
785       Int32    save_groupNo;
786       Int32    save_groupPos;
787       Int32    save_nextSym;
788       Int32    save_nblockMAX;
789       Int32    save_nblock;
790       Int32    save_es;
791       Int32    save_N;
792       Int32    save_curr;
793       Int32    save_zt;
794       Int32    save_zn;
795       Int32    save_zvec;
796       Int32    save_zj;
797       Int32    save_gSel;
798       Int32    save_gMinlen;
799       Int32*   save_gLimit;
800       Int32*   save_gBase;
801       Int32*   save_gPerm;
802 
803    }
804    DState;
805 
806 
807 
808 /*-- Macros for decompression. --*/
809 
810 #define BZ_GET_FAST(cccc)                     \
811     s->tPos = s->tt[s->tPos];                 \
812     cccc = (UChar)(s->tPos & 0xff);           \
813     s->tPos >>= 8;
814 
815 #define BZ_GET_FAST_C(cccc)                   \
816     c_tPos = c_tt[c_tPos];                    \
817     cccc = (UChar)(c_tPos & 0xff);            \
818     c_tPos >>= 8;
819 
820 #define SET_LL4(i,n)                                          \
821    { if (((i) & 0x1) == 0)                                    \
822         s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
823         s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
824    }
825 
826 #define GET_LL4(i)                             \
827    ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
828 
829 #define SET_LL(i,n)                          \
830    { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
831      SET_LL4(i, n >> 16);                    \
832    }
833 
834 #define GET_LL(i) \
835    (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
836 
837 #define BZ_GET_SMALL(cccc)                            \
838       cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
839       s->tPos = GET_LL(s->tPos);
840 
841 
842 /*-- externs for decompression. --*/
843 
844 extern Int32
845 BZ2_indexIntoF ( Int32, Int32* );
846 
847 extern Int32
848 BZ2_decompress ( DState* );
849 
850 extern void
851 BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
852                            Int32,  Int32, Int32 );
853 
854 
855 #endif
856 
857 
858 /*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
859 
860 #ifdef BZ_NO_STDIO
861 #ifndef NULL
862 #define NULL 0
863 #endif
864 #endif
865 
866 
867 /*-------------------------------------------------------------*/
868 /*--- end                                   bzlib_private.h ---*/
869 /*-------------------------------------------------------------*/
870 
871 
872 /* Something which has the same size as void* on the host.  That is,
873    it is 32 bits on a 32-bit host and 64 bits on a 64-bit host, and so
874    it can safely be coerced to and from a pointer type on the host
875    machine. */
876 typedef  unsigned long HWord;
877 typedef  char          HChar;
878 typedef  signed int    Int;
879 typedef  unsigned int  UInt;
880 
881 typedef    signed long long int   Long;
882 typedef  unsigned long long int   ULong;
883 
884 
885 /////////////////////////////////////////////////////////////////////
886 /////////////////////////////////////////////////////////////////////
887 
888 //#include "/home/sewardj/VEX/trunk/pub/libvex_basictypes.h"
889 
890 static HWord (*serviceFn)(HWord,HWord) = 0;
891 
892 
my_strcpy(char * dest,const char * src)893 static char* my_strcpy ( char* dest, const char* src )
894 {
895    char* dest_orig = dest;
896    while (*src) *dest++ = *src++;
897    *dest = 0;
898    return dest_orig;
899 }
900 
my_memcpy(void * dest,const void * src,int sz)901 static void* my_memcpy ( void *dest, const void *src, int sz )
902 {
903    const char *s = (const char *)src;
904    char *d = (char *)dest;
905 
906    while (sz--)
907       *d++ = *s++;
908 
909    return dest;
910 }
911 
my_memmove(void * dst,const void * src,unsigned int len)912 static void* my_memmove( void *dst, const void *src, unsigned int len )
913 {
914     register char *d;
915     register char *s;
916     if ( dst > src ) {
917         d = (char *)dst + len - 1;
918         s = (char *)src + len - 1;
919         while ( len >= 4 ) {
920             *d-- = *s--;
921             *d-- = *s--;
922             *d-- = *s--;
923             *d-- = *s--;
924             len -= 4;
925         }
926         while ( len-- ) {
927             *d-- = *s--;
928         }
929     } else if ( dst < src ) {
930         d = (char *)dst;
931         s = (char *)src;
932         while ( len >= 4 ) {
933             *d++ = *s++;
934             *d++ = *s++;
935             *d++ = *s++;
936             *d++ = *s++;
937             len -= 4;
938         }
939         while ( len-- ) {
940             *d++ = *s++;
941         }
942     }
943     return dst;
944 }
945 
my_strcat(char * dest,const char * src)946 char* my_strcat ( char* dest, const char* src )
947 {
948    char* dest_orig = dest;
949    while (*dest) dest++;
950    while (*src) *dest++ = *src++;
951    *dest = 0;
952    return dest_orig;
953 }
954 
955 
956 /////////////////////////////////////////////////////////////////////
957 
vexxx_log_bytes(char * p,int n)958 static void vexxx_log_bytes ( char* p, int n )
959 {
960    int i;
961    for (i = 0; i < n; i++)
962       (*serviceFn)( 1, (int)p[i] );
963 }
964 
965 /*---------------------------------------------------------*/
966 /*--- vexxx_printf                                        ---*/
967 /*---------------------------------------------------------*/
968 
969 /* This should be the only <...> include in the entire VEX library.
970    New code for vexxx_util.c should go above this point. */
971 #include <stdarg.h>
972 
vexxx_toupper(HChar c)973 static HChar vexxx_toupper ( HChar c )
974 {
975    if (c >= 'a' && c <= 'z')
976       return c + ('A' - 'a');
977    else
978       return c;
979 }
980 
vexxx_strlen(const HChar * str)981 static Int vexxx_strlen ( const HChar* str )
982 {
983    Int i = 0;
984    while (str[i] != 0) i++;
985    return i;
986 }
987 
vexxx_streq(const HChar * s1,const HChar * s2)988 Bool vexxx_streq ( const HChar* s1, const HChar* s2 )
989 {
990    while (True) {
991       if (*s1 == 0 && *s2 == 0)
992          return True;
993       if (*s1 != *s2)
994          return False;
995       s1++;
996       s2++;
997    }
998 }
999 
1000 /* Some flags.  */
1001 #define VG_MSG_SIGNED    1 /* The value is signed. */
1002 #define VG_MSG_ZJUSTIFY  2 /* Must justify with '0'. */
1003 #define VG_MSG_LJUSTIFY  4 /* Must justify on the left. */
1004 #define VG_MSG_PAREN     8 /* Parenthesize if present (for %y) */
1005 #define VG_MSG_COMMA    16 /* Add commas to numbers (for %d, %u) */
1006 
1007 /* Copy a string into the buffer. */
1008 static UInt
myvprintf_str(void (* send)(HChar),Int flags,Int width,HChar * str,Bool capitalise)1009 myvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,
1010                 Bool capitalise )
1011 {
1012 #  define MAYBE_TOUPPER(ch) (capitalise ? vexxx_toupper(ch) : (ch))
1013    UInt ret = 0;
1014    Int i, extra;
1015    Int len = vexxx_strlen(str);
1016 
1017    if (width == 0) {
1018       ret += len;
1019       for (i = 0; i < len; i++)
1020          send(MAYBE_TOUPPER(str[i]));
1021       return ret;
1022    }
1023 
1024    if (len > width) {
1025       ret += width;
1026       for (i = 0; i < width; i++)
1027          send(MAYBE_TOUPPER(str[i]));
1028       return ret;
1029    }
1030 
1031    extra = width - len;
1032    if (flags & VG_MSG_LJUSTIFY) {
1033       ret += extra;
1034       for (i = 0; i < extra; i++)
1035          send(' ');
1036    }
1037    ret += len;
1038    for (i = 0; i < len; i++)
1039       send(MAYBE_TOUPPER(str[i]));
1040    if (!(flags & VG_MSG_LJUSTIFY)) {
1041       ret += extra;
1042       for (i = 0; i < extra; i++)
1043          send(' ');
1044    }
1045 
1046 #  undef MAYBE_TOUPPER
1047 
1048    return ret;
1049 }
1050 
1051 /* Write P into the buffer according to these args:
1052  *  If SIGN is true, p is a signed.
1053  *  BASE is the base.
1054  *  If WITH_ZERO is true, '0' must be added.
1055  *  WIDTH is the width of the field.
1056  */
1057 static UInt
myvprintf_int64(void (* send)(HChar),Int flags,Int base,Int width,ULong pL)1058 myvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, ULong pL)
1059 {
1060    HChar buf[40];
1061    Int   ind = 0;
1062    Int   i, nc = 0;
1063    Bool  neg = False;
1064    HChar *digits = "0123456789ABCDEF";
1065    UInt  ret = 0;
1066    UInt  p = (UInt)pL;
1067 
1068    if (base < 2 || base > 16)
1069       return ret;
1070 
1071    if ((flags & VG_MSG_SIGNED) && (Int)p < 0) {
1072       p   = - (Int)p;
1073       neg = True;
1074    }
1075 
1076    if (p == 0)
1077       buf[ind++] = '0';
1078    else {
1079       while (p > 0) {
1080          if ((flags & VG_MSG_COMMA) && 10 == base &&
1081              0 == (ind-nc) % 3 && 0 != ind)
1082          {
1083             buf[ind++] = ',';
1084             nc++;
1085          }
1086          buf[ind++] = digits[p % base];
1087          p /= base;
1088       }
1089    }
1090 
1091    if (neg)
1092       buf[ind++] = '-';
1093 
1094    if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
1095       for(; ind < width; ind++) {
1096 	//vassert(ind < 39);
1097          buf[ind] = ((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
1098       }
1099    }
1100 
1101    /* Reverse copy to buffer.  */
1102    ret += ind;
1103    for (i = ind -1; i >= 0; i--) {
1104       send(buf[i]);
1105    }
1106    if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
1107       for(; ind < width; ind++) {
1108 	 ret++;
1109          send(' ');  // Never pad with zeroes on RHS -- changes the value!
1110       }
1111    }
1112    return ret;
1113 }
1114 
1115 
1116 /* A simple vprintf().  */
1117 static
vprintf_wrk(void (* send)(HChar),const HChar * format,va_list vargs)1118 UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs )
1119 {
1120    UInt ret = 0;
1121    int i;
1122    int flags;
1123    int width;
1124    Bool is_long;
1125 
1126    /* We assume that vargs has already been initialised by the
1127       caller, using va_start, and that the caller will similarly
1128       clean up with va_end.
1129    */
1130 
1131    for (i = 0; format[i] != 0; i++) {
1132       if (format[i] != '%') {
1133          send(format[i]);
1134 	 ret++;
1135          continue;
1136       }
1137       i++;
1138       /* A '%' has been found.  Ignore a trailing %. */
1139       if (format[i] == 0)
1140          break;
1141       if (format[i] == '%') {
1142          /* `%%' is replaced by `%'. */
1143          send('%');
1144 	 ret++;
1145          continue;
1146       }
1147       flags = 0;
1148       is_long = False;
1149       width = 0; /* length of the field. */
1150       if (format[i] == '(') {
1151 	 flags |= VG_MSG_PAREN;
1152 	 i++;
1153       }
1154       /* If ',' follows '%', commas will be inserted. */
1155       if (format[i] == ',') {
1156          flags |= VG_MSG_COMMA;
1157          i++;
1158       }
1159       /* If '-' follows '%', justify on the left. */
1160       if (format[i] == '-') {
1161          flags |= VG_MSG_LJUSTIFY;
1162          i++;
1163       }
1164       /* If '0' follows '%', pads will be inserted. */
1165       if (format[i] == '0') {
1166          flags |= VG_MSG_ZJUSTIFY;
1167          i++;
1168       }
1169       /* Compute the field length. */
1170       while (format[i] >= '0' && format[i] <= '9') {
1171          width *= 10;
1172          width += format[i++] - '0';
1173       }
1174       while (format[i] == 'l') {
1175          i++;
1176          is_long = True;
1177       }
1178 
1179       switch (format[i]) {
1180          case 'd': /* %d */
1181             flags |= VG_MSG_SIGNED;
1182             if (is_long)
1183                ret += myvprintf_int64(send, flags, 10, width,
1184 				      (ULong)(va_arg (vargs, Long)));
1185             else
1186                ret += myvprintf_int64(send, flags, 10, width,
1187 				      (ULong)(va_arg (vargs, Int)));
1188             break;
1189          case 'u': /* %u */
1190             if (is_long)
1191                ret += myvprintf_int64(send, flags, 10, width,
1192 				      (ULong)(va_arg (vargs, ULong)));
1193             else
1194                ret += myvprintf_int64(send, flags, 10, width,
1195 				      (ULong)(va_arg (vargs, UInt)));
1196             break;
1197          case 'p': /* %p */
1198 	    ret += 2;
1199             send('0');
1200             send('x');
1201             ret += myvprintf_int64(send, flags, 16, width,
1202 				   (ULong)((HWord)va_arg (vargs, void *)));
1203             break;
1204          case 'x': /* %x */
1205             if (is_long)
1206                ret += myvprintf_int64(send, flags, 16, width,
1207 				      (ULong)(va_arg (vargs, ULong)));
1208             else
1209                ret += myvprintf_int64(send, flags, 16, width,
1210 				      (ULong)(va_arg (vargs, UInt)));
1211             break;
1212          case 'c': /* %c */
1213 	    ret++;
1214             send((va_arg (vargs, int)));
1215             break;
1216          case 's': case 'S': { /* %s */
1217             char *str = va_arg (vargs, char *);
1218             if (str == (char*) 0) str = "(null)";
1219             ret += myvprintf_str(send, flags, width, str,
1220                                  (format[i]=='S'));
1221             break;
1222 	 }
1223 #        if 0
1224 	 case 'y': { /* %y - print symbol */
1225 	    Addr a = va_arg(vargs, Addr);
1226 
1227             HChar *name;
1228 	    if (VG_(get_fnname_w_offset)(a, &name)) {
1229                HChar buf[1 + VG_strlen(name) + 1 + 1];
1230 	       if (flags & VG_MSG_PAREN) {
1231                   VG_(sprintf)(str, "(%s)", name):
1232 	       } else {
1233                   VG_(sprintf)(str, "%s", name):
1234                }
1235 	       ret += myvprintf_str(send, flags, width, buf, 0);
1236 	    }
1237 	    break;
1238 	 }
1239 #        endif
1240          default:
1241             break;
1242       }
1243    }
1244    return ret;
1245 }
1246 
1247 
1248 /* A general replacement for printf().  Note that only low-level
1249    debugging info should be sent via here.  The official route is to
1250    to use vg_message().  This interface is deprecated.
1251 */
1252 static HChar myprintf_buf[1000];
1253 static Int   n_myprintf_buf;
1254 
add_to_myprintf_buf(HChar c)1255 static void add_to_myprintf_buf ( HChar c )
1256 {
1257    if (c == '\n' || n_myprintf_buf >= 1000-10 /*paranoia*/ ) {
1258       (*vexxx_log_bytes)( myprintf_buf, vexxx_strlen(myprintf_buf) );
1259       n_myprintf_buf = 0;
1260       myprintf_buf[n_myprintf_buf] = 0;
1261    }
1262    myprintf_buf[n_myprintf_buf++] = c;
1263    myprintf_buf[n_myprintf_buf] = 0;
1264 }
1265 
vexxx_printf(const char * format,...)1266 static UInt vexxx_printf ( const char *format, ... )
1267 {
1268    UInt ret;
1269    va_list vargs;
1270    va_start(vargs,format);
1271 
1272    n_myprintf_buf = 0;
1273    myprintf_buf[n_myprintf_buf] = 0;
1274    ret = vprintf_wrk ( add_to_myprintf_buf, format, vargs );
1275 
1276    if (n_myprintf_buf > 0) {
1277       (*vexxx_log_bytes)( myprintf_buf, n_myprintf_buf );
1278    }
1279 
1280    va_end(vargs);
1281 
1282    return ret;
1283 }
1284 
1285 /*---------------------------------------------------------------*/
1286 /*--- end                                          vexxx_util.c ---*/
1287 /*---------------------------------------------------------------*/
1288 
1289 
1290 /////////////////////////////////////////////////////////////////////
1291 /////////////////////////////////////////////////////////////////////
1292 /////////////////////////////////////////////////////////////////////
1293 /////////////////////////////////////////////////////////////////////
1294 
1295 
1296 /*-------------------------------------------------------------*/
1297 /*--- Decompression machinery                               ---*/
1298 /*---                                          decompress.c ---*/
1299 /*-------------------------------------------------------------*/
1300 
1301 /*--
1302   This file is a part of bzip2 and/or libbzip2, a program and
1303   library for lossless, block-sorting data compression.
1304 
1305   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
1306 
1307   Redistribution and use in source and binary forms, with or without
1308   modification, are permitted provided that the following conditions
1309   are met:
1310 
1311   1. Redistributions of source code must retain the above copyright
1312      notice, this list of conditions and the following disclaimer.
1313 
1314   2. The origin of this software must not be misrepresented; you must
1315      not claim that you wrote the original software.  If you use this
1316      software in a product, an acknowledgment in the product
1317      documentation would be appreciated but is not required.
1318 
1319   3. Altered source versions must be plainly marked as such, and must
1320      not be misrepresented as being the original software.
1321 
1322   4. The name of the author may not be used to endorse or promote
1323      products derived from this software without specific prior written
1324      permission.
1325 
1326   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1327   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1328   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1329   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1330   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1331   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1332   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1333   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1334   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1335   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1336   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1337 
1338   Julian Seward, Cambridge, UK.
1339   jseward@bzip.org
1340   bzip2/libbzip2 version 1.0 of 21 March 2000
1341 
1342   This program is based on (at least) the work of:
1343      Mike Burrows
1344      David Wheeler
1345      Peter Fenwick
1346      Alistair Moffat
1347      Radford Neal
1348      Ian H. Witten
1349      Robert Sedgewick
1350      Jon L. Bentley
1351 
1352   For more information on these sources, see the manual.
1353 --*/
1354 
1355 
1356 
1357 
1358 /*---------------------------------------------------*/
1359 static
makeMaps_d(DState * s)1360 void makeMaps_d ( DState* s )
1361 {
1362    Int32 i;
1363    s->nInUse = 0;
1364    for (i = 0; i < 256; i++)
1365       if (s->inUse[i]) {
1366          s->seqToUnseq[s->nInUse] = i;
1367          s->nInUse++;
1368       }
1369 }
1370 
1371 
1372 /*---------------------------------------------------*/
1373 #define RETURN(rrr)                               \
1374    { retVal = rrr; goto save_state_and_return; };
1375 
1376 #define GET_BITS(lll,vvv,nnn)                     \
1377    case lll: s->state = lll;                      \
1378    while (True) {                                 \
1379       if (s->bsLive >= nnn) {                     \
1380          UInt32 v;                                \
1381          v = (s->bsBuff >>                        \
1382              (s->bsLive-nnn)) & ((1 << nnn)-1);   \
1383          s->bsLive -= nnn;                        \
1384          vvv = v;                                 \
1385          break;                                   \
1386       }                                           \
1387       if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
1388       s->bsBuff                                   \
1389          = (s->bsBuff << 8) |                     \
1390            ((UInt32)                              \
1391               (*((UChar*)(s->strm->next_in))));   \
1392       s->bsLive += 8;                             \
1393       s->strm->next_in++;                         \
1394       s->strm->avail_in--;                        \
1395       s->strm->total_in_lo32++;                   \
1396       if (s->strm->total_in_lo32 == 0)            \
1397          s->strm->total_in_hi32++;                \
1398    }
1399 
1400 #define GET_UCHAR(lll,uuu)                        \
1401    GET_BITS(lll,uuu,8)
1402 
1403 #define GET_BIT(lll,uuu)                          \
1404    GET_BITS(lll,uuu,1)
1405 
1406 /*---------------------------------------------------*/
1407 #define GET_MTF_VAL(label1,label2,lval)           \
1408 {                                                 \
1409    if (groupPos == 0) {                           \
1410       groupNo++;                                  \
1411       if (groupNo >= nSelectors)                  \
1412          RETURN(BZ_DATA_ERROR);                   \
1413       groupPos = BZ_G_SIZE;                       \
1414       gSel = s->selector[groupNo];                \
1415       gMinlen = s->minLens[gSel];                 \
1416       gLimit = &(s->limit[gSel][0]);              \
1417       gPerm = &(s->perm[gSel][0]);                \
1418       gBase = &(s->base[gSel][0]);                \
1419    }                                              \
1420    groupPos--;                                    \
1421    zn = gMinlen;                                  \
1422    GET_BITS(label1, zvec, zn);                    \
1423    while (1) {                                    \
1424       if (zn > 20 /* the longest code */)         \
1425          RETURN(BZ_DATA_ERROR);                   \
1426       if (zvec <= gLimit[zn]) break;              \
1427       zn++;                                       \
1428       GET_BIT(label2, zj);                        \
1429       zvec = (zvec << 1) | zj;                    \
1430    };                                             \
1431    if (zvec - gBase[zn] < 0                       \
1432        || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
1433       RETURN(BZ_DATA_ERROR);                      \
1434    lval = gPerm[zvec - gBase[zn]];                \
1435 }
1436 
1437 
1438 
1439 /*---------------------------------------------------*/
BZ2_indexIntoF(Int32 indx,Int32 * cftab)1440 __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
1441 {
1442    Int32 nb, na, mid;
1443    nb = 0;
1444    na = 256;
1445    do {
1446       mid = (nb + na) >> 1;
1447       if (indx >= cftab[mid]) nb = mid; else na = mid;
1448    }
1449    while (na - nb != 1);
1450    return nb;
1451 }
1452 
1453 /*---------------------------------------------------*/
BZ2_decompress(DState * s)1454 Int32 BZ2_decompress ( DState* s )
1455 {
1456    UChar      uc;
1457    Int32      retVal;
1458    Int32      minLen, maxLen;
1459    bz_stream* strm = s->strm;
1460 
1461    /* stuff that needs to be saved/restored */
1462    Int32  i;
1463    Int32  j;
1464    Int32  t;
1465    Int32  alphaSize;
1466    Int32  nGroups;
1467    Int32  nSelectors;
1468    Int32  EOB;
1469    Int32  groupNo;
1470    Int32  groupPos;
1471    Int32  nextSym;
1472    Int32  nblockMAX;
1473    Int32  nblock;
1474    Int32  es;
1475    Int32  N;
1476    Int32  curr;
1477    Int32  zt;
1478    Int32  zn;
1479    Int32  zvec;
1480    Int32  zj;
1481    Int32  gSel;
1482    Int32  gMinlen;
1483    Int32* gLimit;
1484    Int32* gBase;
1485    Int32* gPerm;
1486 
1487    if (s->state == BZ_X_MAGIC_1) {
1488       /*initialise the save area*/
1489       s->save_i           = 0;
1490       s->save_j           = 0;
1491       s->save_t           = 0;
1492       s->save_alphaSize   = 0;
1493       s->save_nGroups     = 0;
1494       s->save_nSelectors  = 0;
1495       s->save_EOB         = 0;
1496       s->save_groupNo     = 0;
1497       s->save_groupPos    = 0;
1498       s->save_nextSym     = 0;
1499       s->save_nblockMAX   = 0;
1500       s->save_nblock      = 0;
1501       s->save_es          = 0;
1502       s->save_N           = 0;
1503       s->save_curr        = 0;
1504       s->save_zt          = 0;
1505       s->save_zn          = 0;
1506       s->save_zvec        = 0;
1507       s->save_zj          = 0;
1508       s->save_gSel        = 0;
1509       s->save_gMinlen     = 0;
1510       s->save_gLimit      = NULL;
1511       s->save_gBase       = NULL;
1512       s->save_gPerm       = NULL;
1513    }
1514 
1515    /*restore from the save area*/
1516    i           = s->save_i;
1517    j           = s->save_j;
1518    t           = s->save_t;
1519    alphaSize   = s->save_alphaSize;
1520    nGroups     = s->save_nGroups;
1521    nSelectors  = s->save_nSelectors;
1522    EOB         = s->save_EOB;
1523    groupNo     = s->save_groupNo;
1524    groupPos    = s->save_groupPos;
1525    nextSym     = s->save_nextSym;
1526    nblockMAX   = s->save_nblockMAX;
1527    nblock      = s->save_nblock;
1528    es          = s->save_es;
1529    N           = s->save_N;
1530    curr        = s->save_curr;
1531    zt          = s->save_zt;
1532    zn          = s->save_zn;
1533    zvec        = s->save_zvec;
1534    zj          = s->save_zj;
1535    gSel        = s->save_gSel;
1536    gMinlen     = s->save_gMinlen;
1537    gLimit      = s->save_gLimit;
1538    gBase       = s->save_gBase;
1539    gPerm       = s->save_gPerm;
1540 
1541    retVal = BZ_OK;
1542 
1543    switch (s->state) {
1544 
1545       GET_UCHAR(BZ_X_MAGIC_1, uc);
1546       if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
1547 
1548       GET_UCHAR(BZ_X_MAGIC_2, uc);
1549       if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
1550 
1551       GET_UCHAR(BZ_X_MAGIC_3, uc)
1552       if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
1553 
1554       GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
1555       if (s->blockSize100k < (BZ_HDR_0 + 1) ||
1556           s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
1557       s->blockSize100k -= BZ_HDR_0;
1558 
1559       if (s->smallDecompress) {
1560          s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
1561          s->ll4  = BZALLOC(
1562                       ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
1563                    );
1564          if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
1565       } else {
1566          s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
1567          if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
1568       }
1569 
1570       GET_UCHAR(BZ_X_BLKHDR_1, uc);
1571 
1572       if (uc == 0x17) goto endhdr_2;
1573       if (uc != 0x31) RETURN(BZ_DATA_ERROR);
1574       GET_UCHAR(BZ_X_BLKHDR_2, uc);
1575       if (uc != 0x41) RETURN(BZ_DATA_ERROR);
1576       GET_UCHAR(BZ_X_BLKHDR_3, uc);
1577       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
1578       GET_UCHAR(BZ_X_BLKHDR_4, uc);
1579       if (uc != 0x26) RETURN(BZ_DATA_ERROR);
1580       GET_UCHAR(BZ_X_BLKHDR_5, uc);
1581       if (uc != 0x53) RETURN(BZ_DATA_ERROR);
1582       GET_UCHAR(BZ_X_BLKHDR_6, uc);
1583       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
1584 
1585       s->currBlockNo++;
1586       if (s->verbosity >= 2)
1587          VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
1588 
1589       s->storedBlockCRC = 0;
1590       GET_UCHAR(BZ_X_BCRC_1, uc);
1591       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1592       GET_UCHAR(BZ_X_BCRC_2, uc);
1593       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1594       GET_UCHAR(BZ_X_BCRC_3, uc);
1595       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1596       GET_UCHAR(BZ_X_BCRC_4, uc);
1597       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
1598 
1599       GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
1600 
1601       s->origPtr = 0;
1602       GET_UCHAR(BZ_X_ORIGPTR_1, uc);
1603       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1604       GET_UCHAR(BZ_X_ORIGPTR_2, uc);
1605       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1606       GET_UCHAR(BZ_X_ORIGPTR_3, uc);
1607       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
1608 
1609       if (s->origPtr < 0)
1610          RETURN(BZ_DATA_ERROR);
1611       if (s->origPtr > 10 + 100000*s->blockSize100k)
1612          RETURN(BZ_DATA_ERROR);
1613 
1614       /*--- Receive the mapping table ---*/
1615       for (i = 0; i < 16; i++) {
1616          GET_BIT(BZ_X_MAPPING_1, uc);
1617          if (uc == 1)
1618             s->inUse16[i] = True; else
1619             s->inUse16[i] = False;
1620       }
1621 
1622       for (i = 0; i < 256; i++) s->inUse[i] = False;
1623 
1624       for (i = 0; i < 16; i++)
1625          if (s->inUse16[i])
1626             for (j = 0; j < 16; j++) {
1627                GET_BIT(BZ_X_MAPPING_2, uc);
1628                if (uc == 1) s->inUse[i * 16 + j] = True;
1629             }
1630       makeMaps_d ( s );
1631       if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
1632       alphaSize = s->nInUse+2;
1633 
1634       /*--- Now the selectors ---*/
1635       GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
1636       if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
1637       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
1638       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
1639       for (i = 0; i < nSelectors; i++) {
1640          j = 0;
1641          while (True) {
1642             GET_BIT(BZ_X_SELECTOR_3, uc);
1643             if (uc == 0) break;
1644             j++;
1645             if (j >= nGroups) RETURN(BZ_DATA_ERROR);
1646          }
1647          s->selectorMtf[i] = j;
1648       }
1649 
1650       /*--- Undo the MTF values for the selectors. ---*/
1651       {
1652          UChar pos[BZ_N_GROUPS], tmp, v;
1653          for (v = 0; v < nGroups; v++) pos[v] = v;
1654 
1655          for (i = 0; i < nSelectors; i++) {
1656             v = s->selectorMtf[i];
1657             tmp = pos[v];
1658             while (v > 0) { pos[v] = pos[v-1]; v--; }
1659             pos[0] = tmp;
1660             s->selector[i] = tmp;
1661          }
1662       }
1663 
1664       /*--- Now the coding tables ---*/
1665       for (t = 0; t < nGroups; t++) {
1666          GET_BITS(BZ_X_CODING_1, curr, 5);
1667          for (i = 0; i < alphaSize; i++) {
1668             while (True) {
1669                if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
1670                GET_BIT(BZ_X_CODING_2, uc);
1671                if (uc == 0) break;
1672                GET_BIT(BZ_X_CODING_3, uc);
1673                if (uc == 0) curr++; else curr--;
1674             }
1675             s->len[t][i] = curr;
1676          }
1677       }
1678 
1679       /*--- Create the Huffman decoding tables ---*/
1680       for (t = 0; t < nGroups; t++) {
1681          minLen = 32;
1682          maxLen = 0;
1683          for (i = 0; i < alphaSize; i++) {
1684             if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
1685             if (s->len[t][i] < minLen) minLen = s->len[t][i];
1686          }
1687          BZ2_hbCreateDecodeTables (
1688             &(s->limit[t][0]),
1689             &(s->base[t][0]),
1690             &(s->perm[t][0]),
1691             &(s->len[t][0]),
1692             minLen, maxLen, alphaSize
1693          );
1694          s->minLens[t] = minLen;
1695       }
1696 
1697       /*--- Now the MTF values ---*/
1698 
1699       EOB      = s->nInUse+1;
1700       nblockMAX = 100000 * s->blockSize100k;
1701       groupNo  = -1;
1702       groupPos = 0;
1703 
1704       for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
1705 
1706       /*-- MTF init --*/
1707       {
1708          Int32 ii, jj, kk;
1709          kk = MTFA_SIZE-1;
1710          for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
1711             for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
1712                s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
1713                kk--;
1714             }
1715             s->mtfbase[ii] = kk + 1;
1716          }
1717       }
1718       /*-- end MTF init --*/
1719 
1720       nblock = 0;
1721       GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
1722 
1723       while (True) {
1724 
1725          if (nextSym == EOB) break;
1726 
1727          if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
1728 
1729             es = -1;
1730             N = 1;
1731             do {
1732                if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
1733                if (nextSym == BZ_RUNB) es = es + (1+1) * N;
1734                N = N * 2;
1735                GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
1736             }
1737                while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
1738 
1739             es++;
1740             uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
1741             s->unzftab[uc] += es;
1742 
1743             if (s->smallDecompress)
1744                while (es > 0) {
1745                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1746                   s->ll16[nblock] = (UInt16)uc;
1747                   nblock++;
1748                   es--;
1749                }
1750             else
1751                while (es > 0) {
1752                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1753                   s->tt[nblock] = (UInt32)uc;
1754                   nblock++;
1755                   es--;
1756                };
1757 
1758             continue;
1759 
1760          } else {
1761 
1762             if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
1763 
1764             /*-- uc = MTF ( nextSym-1 ) --*/
1765             {
1766                Int32 ii, jj, kk, pp, lno, off;
1767                UInt32 nn;
1768                nn = (UInt32)(nextSym - 1);
1769 
1770                if (nn < MTFL_SIZE) {
1771                   /* avoid general-case expense */
1772                   pp = s->mtfbase[0];
1773                   uc = s->mtfa[pp+nn];
1774                   while (nn > 3) {
1775                      Int32 z = pp+nn;
1776                      s->mtfa[(z)  ] = s->mtfa[(z)-1];
1777                      s->mtfa[(z)-1] = s->mtfa[(z)-2];
1778                      s->mtfa[(z)-2] = s->mtfa[(z)-3];
1779                      s->mtfa[(z)-3] = s->mtfa[(z)-4];
1780                      nn -= 4;
1781                   }
1782                   while (nn > 0) {
1783                      s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
1784                   };
1785                   s->mtfa[pp] = uc;
1786                } else {
1787                   /* general case */
1788                   lno = nn / MTFL_SIZE;
1789                   off = nn % MTFL_SIZE;
1790                   pp = s->mtfbase[lno] + off;
1791                   uc = s->mtfa[pp];
1792                   while (pp > s->mtfbase[lno]) {
1793                      s->mtfa[pp] = s->mtfa[pp-1]; pp--;
1794                   };
1795                   s->mtfbase[lno]++;
1796                   while (lno > 0) {
1797                      s->mtfbase[lno]--;
1798                      s->mtfa[s->mtfbase[lno]]
1799                         = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
1800                      lno--;
1801                   }
1802                   s->mtfbase[0]--;
1803                   s->mtfa[s->mtfbase[0]] = uc;
1804                   if (s->mtfbase[0] == 0) {
1805                      kk = MTFA_SIZE-1;
1806                      for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
1807                         for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
1808                            s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
1809                            kk--;
1810                         }
1811                         s->mtfbase[ii] = kk + 1;
1812                      }
1813                   }
1814                }
1815             }
1816             /*-- end uc = MTF ( nextSym-1 ) --*/
1817 
1818             s->unzftab[s->seqToUnseq[uc]]++;
1819             if (s->smallDecompress)
1820                s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
1821                s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
1822             nblock++;
1823 
1824             GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
1825             continue;
1826          }
1827       }
1828 
1829       /* Now we know what nblock is, we can do a better sanity
1830          check on s->origPtr.
1831       */
1832       if (s->origPtr < 0 || s->origPtr >= nblock)
1833          RETURN(BZ_DATA_ERROR);
1834 
1835       /*-- Set up cftab to facilitate generation of T^(-1) --*/
1836       s->cftab[0] = 0;
1837       for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
1838       for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
1839       for (i = 0; i <= 256; i++) {
1840          if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
1841             /* s->cftab[i] can legitimately be == nblock */
1842             RETURN(BZ_DATA_ERROR);
1843          }
1844       }
1845 
1846       s->state_out_len = 0;
1847       s->state_out_ch  = 0;
1848       BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
1849       s->state = BZ_X_OUTPUT;
1850       if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
1851 
1852       if (s->smallDecompress) {
1853 
1854          /*-- Make a copy of cftab, used in generation of T --*/
1855          for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
1856 
1857          /*-- compute the T vector --*/
1858          for (i = 0; i < nblock; i++) {
1859             uc = (UChar)(s->ll16[i]);
1860             SET_LL(i, s->cftabCopy[uc]);
1861             s->cftabCopy[uc]++;
1862          }
1863 
1864          /*-- Compute T^(-1) by pointer reversal on T --*/
1865          i = s->origPtr;
1866          j = GET_LL(i);
1867          do {
1868             Int32 tmp = GET_LL(j);
1869             SET_LL(j, i);
1870             i = j;
1871             j = tmp;
1872          }
1873             while (i != s->origPtr);
1874 
1875          s->tPos = s->origPtr;
1876          s->nblock_used = 0;
1877          if (s->blockRandomised) {
1878             BZ_RAND_INIT_MASK;
1879             BZ_GET_SMALL(s->k0); s->nblock_used++;
1880             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
1881          } else {
1882             BZ_GET_SMALL(s->k0); s->nblock_used++;
1883          }
1884 
1885       } else {
1886 
1887          /*-- compute the T^(-1) vector --*/
1888          for (i = 0; i < nblock; i++) {
1889             uc = (UChar)(s->tt[i] & 0xff);
1890             s->tt[s->cftab[uc]] |= (i << 8);
1891             s->cftab[uc]++;
1892          }
1893 
1894          s->tPos = s->tt[s->origPtr] >> 8;
1895          s->nblock_used = 0;
1896          if (s->blockRandomised) {
1897             BZ_RAND_INIT_MASK;
1898             BZ_GET_FAST(s->k0); s->nblock_used++;
1899             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
1900          } else {
1901             BZ_GET_FAST(s->k0); s->nblock_used++;
1902          }
1903 
1904       }
1905 
1906       RETURN(BZ_OK);
1907 
1908 
1909 
1910     endhdr_2:
1911 
1912       GET_UCHAR(BZ_X_ENDHDR_2, uc);
1913       if (uc != 0x72) RETURN(BZ_DATA_ERROR);
1914       GET_UCHAR(BZ_X_ENDHDR_3, uc);
1915       if (uc != 0x45) RETURN(BZ_DATA_ERROR);
1916       GET_UCHAR(BZ_X_ENDHDR_4, uc);
1917       if (uc != 0x38) RETURN(BZ_DATA_ERROR);
1918       GET_UCHAR(BZ_X_ENDHDR_5, uc);
1919       if (uc != 0x50) RETURN(BZ_DATA_ERROR);
1920       GET_UCHAR(BZ_X_ENDHDR_6, uc);
1921       if (uc != 0x90) RETURN(BZ_DATA_ERROR);
1922 
1923       s->storedCombinedCRC = 0;
1924       GET_UCHAR(BZ_X_CCRC_1, uc);
1925       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1926       GET_UCHAR(BZ_X_CCRC_2, uc);
1927       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1928       GET_UCHAR(BZ_X_CCRC_3, uc);
1929       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1930       GET_UCHAR(BZ_X_CCRC_4, uc);
1931       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
1932 
1933       s->state = BZ_X_IDLE;
1934       RETURN(BZ_STREAM_END);
1935 
1936       default: AssertH ( False, 4001 );
1937    }
1938 
1939    AssertH ( False, 4002 );
1940 
1941    save_state_and_return:
1942 
1943    s->save_i           = i;
1944    s->save_j           = j;
1945    s->save_t           = t;
1946    s->save_alphaSize   = alphaSize;
1947    s->save_nGroups     = nGroups;
1948    s->save_nSelectors  = nSelectors;
1949    s->save_EOB         = EOB;
1950    s->save_groupNo     = groupNo;
1951    s->save_groupPos    = groupPos;
1952    s->save_nextSym     = nextSym;
1953    s->save_nblockMAX   = nblockMAX;
1954    s->save_nblock      = nblock;
1955    s->save_es          = es;
1956    s->save_N           = N;
1957    s->save_curr        = curr;
1958    s->save_zt          = zt;
1959    s->save_zn          = zn;
1960    s->save_zvec        = zvec;
1961    s->save_zj          = zj;
1962    s->save_gSel        = gSel;
1963    s->save_gMinlen     = gMinlen;
1964    s->save_gLimit      = gLimit;
1965    s->save_gBase       = gBase;
1966    s->save_gPerm       = gPerm;
1967 
1968    return retVal;
1969 }
1970 
1971 
1972 /*-------------------------------------------------------------*/
1973 /*--- end                                      decompress.c ---*/
1974 /*-------------------------------------------------------------*/
1975 
1976 /*-------------------------------------------------------------*/
1977 /*--- Block sorting machinery                               ---*/
1978 /*---                                           blocksort.c ---*/
1979 /*-------------------------------------------------------------*/
1980 
1981 /*--
1982   This file is a part of bzip2 and/or libbzip2, a program and
1983   library for lossless, block-sorting data compression.
1984 
1985   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
1986 
1987   Redistribution and use in source and binary forms, with or without
1988   modification, are permitted provided that the following conditions
1989   are met:
1990 
1991   1. Redistributions of source code must retain the above copyright
1992      notice, this list of conditions and the following disclaimer.
1993 
1994   2. The origin of this software must not be misrepresented; you must
1995      not claim that you wrote the original software.  If you use this
1996      software in a product, an acknowledgment in the product
1997      documentation would be appreciated but is not required.
1998 
1999   3. Altered source versions must be plainly marked as such, and must
2000      not be misrepresented as being the original software.
2001 
2002   4. The name of the author may not be used to endorse or promote
2003      products derived from this software without specific prior written
2004      permission.
2005 
2006   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
2007   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2008   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2009   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
2010   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2011   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
2012   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2013   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2014   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2015   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2016   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2017 
2018   Julian Seward, Cambridge, UK.
2019   jseward@bzip.org
2020   bzip2/libbzip2 version 1.0 of 21 March 2000
2021 
2022   This program is based on (at least) the work of:
2023      Mike Burrows
2024      David Wheeler
2025      Peter Fenwick
2026      Alistair Moffat
2027      Radford Neal
2028      Ian H. Witten
2029      Robert Sedgewick
2030      Jon L. Bentley
2031 
2032   For more information on these sources, see the manual.
2033 
2034   To get some idea how the block sorting algorithms in this file
2035   work, read my paper
2036      On the Performance of BWT Sorting Algorithms
2037   in Proceedings of the IEEE Data Compression Conference 2000,
2038   Snowbird, Utah, USA, 27-30 March 2000.  The main sort in this
2039   file implements the algorithm called  cache  in the paper.
2040 --*/
2041 
2042 
2043 
2044 /*---------------------------------------------*/
2045 /*--- Fallback O(N log(N)^2) sorting        ---*/
2046 /*--- algorithm, for repetitive blocks      ---*/
2047 /*---------------------------------------------*/
2048 
2049 /*---------------------------------------------*/
2050 static
2051 __inline__
fallbackSimpleSort(UInt32 * fmap,UInt32 * eclass,Int32 lo,Int32 hi)2052 void fallbackSimpleSort ( UInt32* fmap,
2053                           UInt32* eclass,
2054                           Int32   lo,
2055                           Int32   hi )
2056 {
2057    Int32 i, j, tmp;
2058    UInt32 ec_tmp;
2059 
2060    if (lo == hi) return;
2061 
2062    if (hi - lo > 3) {
2063       for ( i = hi-4; i >= lo; i-- ) {
2064          tmp = fmap[i];
2065          ec_tmp = eclass[tmp];
2066          for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
2067             fmap[j-4] = fmap[j];
2068          fmap[j-4] = tmp;
2069       }
2070    }
2071 
2072    for ( i = hi-1; i >= lo; i-- ) {
2073       tmp = fmap[i];
2074       ec_tmp = eclass[tmp];
2075       for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
2076          fmap[j-1] = fmap[j];
2077       fmap[j-1] = tmp;
2078    }
2079 }
2080 
2081 
2082 /*---------------------------------------------*/
2083 #define fswap(zz1, zz2) \
2084    { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
2085 
2086 #define fvswap(zzp1, zzp2, zzn)       \
2087 {                                     \
2088    Int32 yyp1 = (zzp1);               \
2089    Int32 yyp2 = (zzp2);               \
2090    Int32 yyn  = (zzn);                \
2091    while (yyn > 0) {                  \
2092       fswap(fmap[yyp1], fmap[yyp2]);  \
2093       yyp1++; yyp2++; yyn--;          \
2094    }                                  \
2095 }
2096 
2097 
2098 #define fmin(a,b) ((a) < (b)) ? (a) : (b)
2099 
2100 #define fpush(lz,hz) { stackLo[sp] = lz; \
2101                        stackHi[sp] = hz; \
2102                        sp++; }
2103 
2104 #define fpop(lz,hz) { sp--;              \
2105                       lz = stackLo[sp];  \
2106                       hz = stackHi[sp]; }
2107 
2108 #define FALLBACK_QSORT_SMALL_THRESH 10
2109 #define FALLBACK_QSORT_STACK_SIZE   100
2110 
2111 
2112 static
fallbackQSort3(UInt32 * fmap,UInt32 * eclass,Int32 loSt,Int32 hiSt)2113 void fallbackQSort3 ( UInt32* fmap,
2114                       UInt32* eclass,
2115                       Int32   loSt,
2116                       Int32   hiSt )
2117 {
2118    Int32 unLo, unHi, ltLo, gtHi, n, m;
2119    Int32 sp, lo, hi;
2120    UInt32 med, r, r3;
2121    Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
2122    Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
2123 
2124    r = 0;
2125 
2126    sp = 0;
2127    fpush ( loSt, hiSt );
2128 
2129    while (sp > 0) {
2130 
2131       AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
2132 
2133       fpop ( lo, hi );
2134       if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
2135          fallbackSimpleSort ( fmap, eclass, lo, hi );
2136          continue;
2137       }
2138 
2139       /* Random partitioning.  Median of 3 sometimes fails to
2140          avoid bad cases.  Median of 9 seems to help but
2141          looks rather expensive.  This too seems to work but
2142          is cheaper.  Guidance for the magic constants
2143          7621 and 32768 is taken from Sedgewick's algorithms
2144          book, chapter 35.
2145       */
2146       r = ((r * 7621) + 1) % 32768;
2147       r3 = r % 3;
2148       if (r3 == 0) med = eclass[fmap[lo]]; else
2149       if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
2150                    med = eclass[fmap[hi]];
2151 
2152       unLo = ltLo = lo;
2153       unHi = gtHi = hi;
2154 
2155       while (1) {
2156          while (1) {
2157             if (unLo > unHi) break;
2158             n = (Int32)eclass[fmap[unLo]] - (Int32)med;
2159             if (n == 0) {
2160                fswap(fmap[unLo], fmap[ltLo]);
2161                ltLo++; unLo++;
2162                continue;
2163             };
2164             if (n > 0) break;
2165             unLo++;
2166          }
2167          while (1) {
2168             if (unLo > unHi) break;
2169             n = (Int32)eclass[fmap[unHi]] - (Int32)med;
2170             if (n == 0) {
2171                fswap(fmap[unHi], fmap[gtHi]);
2172                gtHi--; unHi--;
2173                continue;
2174             };
2175             if (n < 0) break;
2176             unHi--;
2177          }
2178          if (unLo > unHi) break;
2179          fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
2180       }
2181 
2182       AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
2183 
2184       if (gtHi < ltLo) continue;
2185 
2186       n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
2187       m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
2188 
2189       n = lo + unLo - ltLo - 1;
2190       m = hi - (gtHi - unHi) + 1;
2191 
2192       if (n - lo > hi - m) {
2193          fpush ( lo, n );
2194          fpush ( m, hi );
2195       } else {
2196          fpush ( m, hi );
2197          fpush ( lo, n );
2198       }
2199    }
2200 }
2201 
2202 #undef fmin
2203 #undef fpush
2204 #undef fpop
2205 #undef fswap
2206 #undef fvswap
2207 #undef FALLBACK_QSORT_SMALL_THRESH
2208 #undef FALLBACK_QSORT_STACK_SIZE
2209 
2210 
2211 /*---------------------------------------------*/
2212 /* Pre:
2213       nblock > 0
2214       eclass exists for [0 .. nblock-1]
2215       ((UChar*)eclass) [0 .. nblock-1] holds block
2216       ptr exists for [0 .. nblock-1]
2217 
2218    Post:
2219       ((UChar*)eclass) [0 .. nblock-1] holds block
2220       All other areas of eclass destroyed
2221       fmap [0 .. nblock-1] holds sorted order
2222       bhtab [ 0 .. 2+(nblock/32) ] destroyed
2223 */
2224 
2225 #define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
2226 #define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
2227 #define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
2228 #define      WORD_BH(zz)  bhtab[(zz) >> 5]
2229 #define UNALIGNED_BH(zz)  ((zz) & 0x01f)
2230 
2231 static
fallbackSort(UInt32 * fmap,UInt32 * eclass,UInt32 * bhtab,Int32 nblock,Int32 verb)2232 void fallbackSort ( UInt32* fmap,
2233                     UInt32* eclass,
2234                     UInt32* bhtab,
2235                     Int32   nblock,
2236                     Int32   verb )
2237 {
2238    Int32 ftab[257];
2239    Int32 ftabCopy[256];
2240    Int32 H, i, j, k, l, r, cc, cc1;
2241    Int32 nNotDone;
2242    Int32 nBhtab;
2243    UChar* eclass8 = (UChar*)eclass;
2244 
2245    /*--
2246       Initial 1-char radix sort to generate
2247       initial fmap and initial BH bits.
2248    --*/
2249    if (verb >= 4)
2250       VPrintf0 ( "        bucket sorting ...\n" );
2251    for (i = 0; i < 257;    i++) ftab[i] = 0;
2252    for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
2253    for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
2254    for (i = 1; i < 257;    i++) ftab[i] += ftab[i-1];
2255 
2256    for (i = 0; i < nblock; i++) {
2257       j = eclass8[i];
2258       k = ftab[j] - 1;
2259       ftab[j] = k;
2260       fmap[k] = i;
2261    }
2262 
2263    nBhtab = 2 + (nblock / 32);
2264    for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
2265    for (i = 0; i < 256; i++) SET_BH(ftab[i]);
2266 
2267    /*--
2268       Inductively refine the buckets.  Kind-of an
2269       "exponential radix sort" (!), inspired by the
2270       Manber-Myers suffix array construction algorithm.
2271    --*/
2272 
2273    /*-- set sentinel bits for block-end detection --*/
2274    for (i = 0; i < 32; i++) {
2275       SET_BH(nblock + 2*i);
2276       CLEAR_BH(nblock + 2*i + 1);
2277    }
2278 
2279    /*-- the log(N) loop --*/
2280    H = 1;
2281    while (1) {
2282 
2283       if (verb >= 4)
2284          VPrintf1 ( "        depth %6d has ", H );
2285 
2286       j = 0;
2287       for (i = 0; i < nblock; i++) {
2288          if (ISSET_BH(i)) j = i;
2289          k = fmap[i] - H; if (k < 0) k += nblock;
2290          eclass[k] = j;
2291       }
2292 
2293       nNotDone = 0;
2294       r = -1;
2295       while (1) {
2296 
2297 	 /*-- find the next non-singleton bucket --*/
2298          k = r + 1;
2299          while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
2300          if (ISSET_BH(k)) {
2301             while (WORD_BH(k) == 0xffffffff) k += 32;
2302             while (ISSET_BH(k)) k++;
2303          }
2304          l = k - 1;
2305          if (l >= nblock) break;
2306          while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
2307          if (!ISSET_BH(k)) {
2308             while (WORD_BH(k) == 0x00000000) k += 32;
2309             while (!ISSET_BH(k)) k++;
2310          }
2311          r = k - 1;
2312          if (r >= nblock) break;
2313 
2314          /*-- now [l, r] bracket current bucket --*/
2315          if (r > l) {
2316             nNotDone += (r - l + 1);
2317             fallbackQSort3 ( fmap, eclass, l, r );
2318 
2319             /*-- scan bucket and generate header bits-- */
2320             cc = -1;
2321             for (i = l; i <= r; i++) {
2322                cc1 = eclass[fmap[i]];
2323                if (cc != cc1) { SET_BH(i); cc = cc1; };
2324             }
2325          }
2326       }
2327 
2328       if (verb >= 4)
2329          VPrintf1 ( "%6d unresolved strings\n", nNotDone );
2330 
2331       H *= 2;
2332       if (H > nblock || nNotDone == 0) break;
2333    }
2334 
2335    /*--
2336       Reconstruct the original block in
2337       eclass8 [0 .. nblock-1], since the
2338       previous phase destroyed it.
2339    --*/
2340    if (verb >= 4)
2341       VPrintf0 ( "        reconstructing block ...\n" );
2342    j = 0;
2343    for (i = 0; i < nblock; i++) {
2344       while (ftabCopy[j] == 0) j++;
2345       ftabCopy[j]--;
2346       eclass8[fmap[i]] = (UChar)j;
2347    }
2348    AssertH ( j < 256, 1005 );
2349 }
2350 
2351 #undef       SET_BH
2352 #undef     CLEAR_BH
2353 #undef     ISSET_BH
2354 #undef      WORD_BH
2355 #undef UNALIGNED_BH
2356 
2357 
2358 /*---------------------------------------------*/
2359 /*--- The main, O(N^2 log(N)) sorting       ---*/
2360 /*--- algorithm.  Faster for "normal"       ---*/
2361 /*--- non-repetitive blocks.                ---*/
2362 /*---------------------------------------------*/
2363 
2364 /*---------------------------------------------*/
2365 static
2366 __inline__
mainGtU(UInt32 i1,UInt32 i2,UChar * block,UInt16 * quadrant,UInt32 nblock,Int32 * budget)2367 Bool mainGtU ( UInt32  i1,
2368                UInt32  i2,
2369                UChar*  block,
2370                UInt16* quadrant,
2371                UInt32  nblock,
2372                Int32*  budget )
2373 {
2374    Int32  k;
2375    UChar  c1, c2;
2376    UInt16 s1, s2;
2377 
2378    AssertD ( i1 != i2, "mainGtU" );
2379    /* 1 */
2380    c1 = block[i1]; c2 = block[i2];
2381    if (c1 != c2) return (c1 > c2);
2382    i1++; i2++;
2383    /* 2 */
2384    c1 = block[i1]; c2 = block[i2];
2385    if (c1 != c2) return (c1 > c2);
2386    i1++; i2++;
2387    /* 3 */
2388    c1 = block[i1]; c2 = block[i2];
2389    if (c1 != c2) return (c1 > c2);
2390    i1++; i2++;
2391    /* 4 */
2392    c1 = block[i1]; c2 = block[i2];
2393    if (c1 != c2) return (c1 > c2);
2394    i1++; i2++;
2395    /* 5 */
2396    c1 = block[i1]; c2 = block[i2];
2397    if (c1 != c2) return (c1 > c2);
2398    i1++; i2++;
2399    /* 6 */
2400    c1 = block[i1]; c2 = block[i2];
2401    if (c1 != c2) return (c1 > c2);
2402    i1++; i2++;
2403    /* 7 */
2404    c1 = block[i1]; c2 = block[i2];
2405    if (c1 != c2) return (c1 > c2);
2406    i1++; i2++;
2407    /* 8 */
2408    c1 = block[i1]; c2 = block[i2];
2409    if (c1 != c2) return (c1 > c2);
2410    i1++; i2++;
2411    /* 9 */
2412    c1 = block[i1]; c2 = block[i2];
2413    if (c1 != c2) return (c1 > c2);
2414    i1++; i2++;
2415    /* 10 */
2416    c1 = block[i1]; c2 = block[i2];
2417    if (c1 != c2) return (c1 > c2);
2418    i1++; i2++;
2419    /* 11 */
2420    c1 = block[i1]; c2 = block[i2];
2421    if (c1 != c2) return (c1 > c2);
2422    i1++; i2++;
2423    /* 12 */
2424    c1 = block[i1]; c2 = block[i2];
2425    if (c1 != c2) return (c1 > c2);
2426    i1++; i2++;
2427 
2428    k = nblock + 8;
2429 
2430    do {
2431       /* 1 */
2432       c1 = block[i1]; c2 = block[i2];
2433       if (c1 != c2) return (c1 > c2);
2434       s1 = quadrant[i1]; s2 = quadrant[i2];
2435       if (s1 != s2) return (s1 > s2);
2436       i1++; i2++;
2437       /* 2 */
2438       c1 = block[i1]; c2 = block[i2];
2439       if (c1 != c2) return (c1 > c2);
2440       s1 = quadrant[i1]; s2 = quadrant[i2];
2441       if (s1 != s2) return (s1 > s2);
2442       i1++; i2++;
2443       /* 3 */
2444       c1 = block[i1]; c2 = block[i2];
2445       if (c1 != c2) return (c1 > c2);
2446       s1 = quadrant[i1]; s2 = quadrant[i2];
2447       if (s1 != s2) return (s1 > s2);
2448       i1++; i2++;
2449       /* 4 */
2450       c1 = block[i1]; c2 = block[i2];
2451       if (c1 != c2) return (c1 > c2);
2452       s1 = quadrant[i1]; s2 = quadrant[i2];
2453       if (s1 != s2) return (s1 > s2);
2454       i1++; i2++;
2455       /* 5 */
2456       c1 = block[i1]; c2 = block[i2];
2457       if (c1 != c2) return (c1 > c2);
2458       s1 = quadrant[i1]; s2 = quadrant[i2];
2459       if (s1 != s2) return (s1 > s2);
2460       i1++; i2++;
2461       /* 6 */
2462       c1 = block[i1]; c2 = block[i2];
2463       if (c1 != c2) return (c1 > c2);
2464       s1 = quadrant[i1]; s2 = quadrant[i2];
2465       if (s1 != s2) return (s1 > s2);
2466       i1++; i2++;
2467       /* 7 */
2468       c1 = block[i1]; c2 = block[i2];
2469       if (c1 != c2) return (c1 > c2);
2470       s1 = quadrant[i1]; s2 = quadrant[i2];
2471       if (s1 != s2) return (s1 > s2);
2472       i1++; i2++;
2473       /* 8 */
2474       c1 = block[i1]; c2 = block[i2];
2475       if (c1 != c2) return (c1 > c2);
2476       s1 = quadrant[i1]; s2 = quadrant[i2];
2477       if (s1 != s2) return (s1 > s2);
2478       i1++; i2++;
2479 
2480       if (i1 >= nblock) i1 -= nblock;
2481       if (i2 >= nblock) i2 -= nblock;
2482 
2483       k -= 8;
2484       (*budget)--;
2485    }
2486       while (k >= 0);
2487 
2488    return False;
2489 }
2490 
2491 
2492 /*---------------------------------------------*/
2493 /*--
2494    Knuth's increments seem to work better
2495    than Incerpi-Sedgewick here.  Possibly
2496    because the number of elems to sort is
2497    usually small, typically <= 20.
2498 --*/
2499 static
2500 Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
2501                    9841, 29524, 88573, 265720,
2502                    797161, 2391484 };
2503 
2504 static
mainSimpleSort(UInt32 * ptr,UChar * block,UInt16 * quadrant,Int32 nblock,Int32 lo,Int32 hi,Int32 d,Int32 * budget)2505 void mainSimpleSort ( UInt32* ptr,
2506                       UChar*  block,
2507                       UInt16* quadrant,
2508                       Int32   nblock,
2509                       Int32   lo,
2510                       Int32   hi,
2511                       Int32   d,
2512                       Int32*  budget )
2513 {
2514    Int32 i, j, h, bigN, hp;
2515    UInt32 v;
2516 
2517    bigN = hi - lo + 1;
2518    if (bigN < 2) return;
2519 
2520    hp = 0;
2521    while (incs[hp] < bigN) hp++;
2522    hp--;
2523 
2524    for (; hp >= 0; hp--) {
2525       h = incs[hp];
2526 
2527       i = lo + h;
2528       while (True) {
2529 
2530          /*-- copy 1 --*/
2531          if (i > hi) break;
2532          v = ptr[i];
2533          j = i;
2534          while ( mainGtU (
2535                     ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2536                  ) ) {
2537             ptr[j] = ptr[j-h];
2538             j = j - h;
2539             if (j <= (lo + h - 1)) break;
2540          }
2541          ptr[j] = v;
2542          i++;
2543 
2544          /*-- copy 2 --*/
2545          if (i > hi) break;
2546          v = ptr[i];
2547          j = i;
2548          while ( mainGtU (
2549                     ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2550                  ) ) {
2551             ptr[j] = ptr[j-h];
2552             j = j - h;
2553             if (j <= (lo + h - 1)) break;
2554          }
2555          ptr[j] = v;
2556          i++;
2557 
2558          /*-- copy 3 --*/
2559          if (i > hi) break;
2560          v = ptr[i];
2561          j = i;
2562          while ( mainGtU (
2563                     ptr[j-h]+d, v+d, block, quadrant, nblock, budget
2564                  ) ) {
2565             ptr[j] = ptr[j-h];
2566             j = j - h;
2567             if (j <= (lo + h - 1)) break;
2568          }
2569          ptr[j] = v;
2570          i++;
2571 
2572          if (*budget < 0) return;
2573       }
2574    }
2575 }
2576 
2577 
2578 /*---------------------------------------------*/
2579 /*--
2580    The following is an implementation of
2581    an elegant 3-way quicksort for strings,
2582    described in a paper "Fast Algorithms for
2583    Sorting and Searching Strings", by Robert
2584    Sedgewick and Jon L. Bentley.
2585 --*/
2586 
2587 #define mswap(zz1, zz2) \
2588    { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
2589 
2590 #define mvswap(zzp1, zzp2, zzn)       \
2591 {                                     \
2592    Int32 yyp1 = (zzp1);               \
2593    Int32 yyp2 = (zzp2);               \
2594    Int32 yyn  = (zzn);                \
2595    while (yyn > 0) {                  \
2596       mswap(ptr[yyp1], ptr[yyp2]);    \
2597       yyp1++; yyp2++; yyn--;          \
2598    }                                  \
2599 }
2600 
2601 static
2602 __inline__
mmed3(UChar a,UChar b,UChar c)2603 UChar mmed3 ( UChar a, UChar b, UChar c )
2604 {
2605    UChar t;
2606    if (a > b) { t = a; a = b; b = t; };
2607    if (b > c) {
2608       b = c;
2609       if (a > b) b = a;
2610    }
2611    return b;
2612 }
2613 
2614 #define mmin(a,b) ((a) < (b)) ? (a) : (b)
2615 
2616 #define mpush(lz,hz,dz) { stackLo[sp] = lz; \
2617                           stackHi[sp] = hz; \
2618                           stackD [sp] = dz; \
2619                           sp++; }
2620 
2621 #define mpop(lz,hz,dz) { sp--;             \
2622                          lz = stackLo[sp]; \
2623                          hz = stackHi[sp]; \
2624                          dz = stackD [sp]; }
2625 
2626 
2627 #define mnextsize(az) (nextHi[az]-nextLo[az])
2628 
2629 #define mnextswap(az,bz)                                        \
2630    { Int32 tz;                                                  \
2631      tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
2632      tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
2633      tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
2634 
2635 
2636 #define MAIN_QSORT_SMALL_THRESH 20
2637 #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
2638 #define MAIN_QSORT_STACK_SIZE 100
2639 
2640 static
mainQSort3(UInt32 * ptr,UChar * block,UInt16 * quadrant,Int32 nblock,Int32 loSt,Int32 hiSt,Int32 dSt,Int32 * budget)2641 void mainQSort3 ( UInt32* ptr,
2642                   UChar*  block,
2643                   UInt16* quadrant,
2644                   Int32   nblock,
2645                   Int32   loSt,
2646                   Int32   hiSt,
2647                   Int32   dSt,
2648                   Int32*  budget )
2649 {
2650    Int32 unLo, unHi, ltLo, gtHi, n, m, med;
2651    Int32 sp, lo, hi, d;
2652 
2653    Int32 stackLo[MAIN_QSORT_STACK_SIZE];
2654    Int32 stackHi[MAIN_QSORT_STACK_SIZE];
2655    Int32 stackD [MAIN_QSORT_STACK_SIZE];
2656 
2657    Int32 nextLo[3];
2658    Int32 nextHi[3];
2659    Int32 nextD [3];
2660 
2661    sp = 0;
2662    mpush ( loSt, hiSt, dSt );
2663 
2664    while (sp > 0) {
2665 
2666       AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
2667 
2668       mpop ( lo, hi, d );
2669       if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
2670           d > MAIN_QSORT_DEPTH_THRESH) {
2671          mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
2672          if (*budget < 0) return;
2673          continue;
2674       }
2675 
2676       med = (Int32)
2677             mmed3 ( block[ptr[ lo         ]+d],
2678                     block[ptr[ hi         ]+d],
2679                     block[ptr[ (lo+hi)>>1 ]+d] );
2680 
2681       unLo = ltLo = lo;
2682       unHi = gtHi = hi;
2683 
2684       while (True) {
2685          while (True) {
2686             if (unLo > unHi) break;
2687             n = ((Int32)block[ptr[unLo]+d]) - med;
2688             if (n == 0) {
2689                mswap(ptr[unLo], ptr[ltLo]);
2690                ltLo++; unLo++; continue;
2691             };
2692             if (n >  0) break;
2693             unLo++;
2694          }
2695          while (True) {
2696             if (unLo > unHi) break;
2697             n = ((Int32)block[ptr[unHi]+d]) - med;
2698             if (n == 0) {
2699                mswap(ptr[unHi], ptr[gtHi]);
2700                gtHi--; unHi--; continue;
2701             };
2702             if (n <  0) break;
2703             unHi--;
2704          }
2705          if (unLo > unHi) break;
2706          mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
2707       }
2708 
2709       AssertD ( unHi == unLo-1, "mainQSort3(2)" );
2710 
2711       if (gtHi < ltLo) {
2712          mpush(lo, hi, d+1 );
2713          continue;
2714       }
2715 
2716       n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
2717       m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
2718 
2719       n = lo + unLo - ltLo - 1;
2720       m = hi - (gtHi - unHi) + 1;
2721 
2722       nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
2723       nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
2724       nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
2725 
2726       if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
2727       if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
2728       if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
2729 
2730       AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
2731       AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
2732 
2733       mpush (nextLo[0], nextHi[0], nextD[0]);
2734       mpush (nextLo[1], nextHi[1], nextD[1]);
2735       mpush (nextLo[2], nextHi[2], nextD[2]);
2736    }
2737 }
2738 
2739 #undef mswap
2740 #undef mvswap
2741 #undef mpush
2742 #undef mpop
2743 #undef mmin
2744 #undef mnextsize
2745 #undef mnextswap
2746 #undef MAIN_QSORT_SMALL_THRESH
2747 #undef MAIN_QSORT_DEPTH_THRESH
2748 #undef MAIN_QSORT_STACK_SIZE
2749 
2750 
2751 /*---------------------------------------------*/
2752 /* Pre:
2753       nblock > N_OVERSHOOT
2754       block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
2755       ((UChar*)block32) [0 .. nblock-1] holds block
2756       ptr exists for [0 .. nblock-1]
2757 
2758    Post:
2759       ((UChar*)block32) [0 .. nblock-1] holds block
2760       All other areas of block32 destroyed
2761       ftab [0 .. 65536 ] destroyed
2762       ptr [0 .. nblock-1] holds sorted order
2763       if (*budget < 0), sorting was abandoned
2764 */
2765 
2766 #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
2767 #define SETMASK (1 << 21)
2768 #define CLEARMASK (~(SETMASK))
2769 
2770 static
mainSort(UInt32 * ptr,UChar * block,UInt16 * quadrant,UInt32 * ftab,Int32 nblock,Int32 verb,Int32 * budget)2771 void mainSort ( UInt32* ptr,
2772                 UChar*  block,
2773                 UInt16* quadrant,
2774                 UInt32* ftab,
2775                 Int32   nblock,
2776                 Int32   verb,
2777                 Int32*  budget )
2778 {
2779    Int32  i, j, k, ss, sb;
2780    Int32  runningOrder[256];
2781    Bool   bigDone[256];
2782    Int32  copyStart[256];
2783    Int32  copyEnd  [256];
2784    UChar  c1;
2785    Int32  numQSorted;
2786    UInt16 s;
2787    if (verb >= 4) VPrintf0 ( "        main sort initialise ...\n" );
2788 
2789    /*-- set up the 2-byte frequency table --*/
2790    for (i = 65536; i >= 0; i--) ftab[i] = 0;
2791 
2792    j = block[0] << 8;
2793    i = nblock-1;
2794    for (; i >= 3; i -= 4) {
2795       quadrant[i] = 0;
2796       j = (j >> 8) | ( ((UInt16)block[i]) << 8);
2797       ftab[j]++;
2798       quadrant[i-1] = 0;
2799       j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
2800       ftab[j]++;
2801       quadrant[i-2] = 0;
2802       j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
2803       ftab[j]++;
2804       quadrant[i-3] = 0;
2805       j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
2806       ftab[j]++;
2807    }
2808    for (; i >= 0; i--) {
2809       quadrant[i] = 0;
2810       j = (j >> 8) | ( ((UInt16)block[i]) << 8);
2811       ftab[j]++;
2812    }
2813 
2814    /*-- (emphasises close relationship of block & quadrant) --*/
2815    for (i = 0; i < BZ_N_OVERSHOOT; i++) {
2816       block   [nblock+i] = block[i];
2817       quadrant[nblock+i] = 0;
2818    }
2819 
2820    if (verb >= 4) VPrintf0 ( "        bucket sorting ...\n" );
2821 
2822    /*-- Complete the initial radix sort --*/
2823    for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
2824 
2825    s = block[0] << 8;
2826    i = nblock-1;
2827    for (; i >= 3; i -= 4) {
2828       s = (s >> 8) | (block[i] << 8);
2829       j = ftab[s] -1;
2830       ftab[s] = j;
2831       ptr[j] = i;
2832       s = (s >> 8) | (block[i-1] << 8);
2833       j = ftab[s] -1;
2834       ftab[s] = j;
2835       ptr[j] = i-1;
2836       s = (s >> 8) | (block[i-2] << 8);
2837       j = ftab[s] -1;
2838       ftab[s] = j;
2839       ptr[j] = i-2;
2840       s = (s >> 8) | (block[i-3] << 8);
2841       j = ftab[s] -1;
2842       ftab[s] = j;
2843       ptr[j] = i-3;
2844    }
2845    for (; i >= 0; i--) {
2846       s = (s >> 8) | (block[i] << 8);
2847       j = ftab[s] -1;
2848       ftab[s] = j;
2849       ptr[j] = i;
2850    }
2851 
2852    /*--
2853       Now ftab contains the first loc of every small bucket.
2854       Calculate the running order, from smallest to largest
2855       big bucket.
2856    --*/
2857    for (i = 0; i <= 255; i++) {
2858       bigDone     [i] = False;
2859       runningOrder[i] = i;
2860    }
2861 
2862    {
2863       Int32 vv;
2864       Int32 h = 1;
2865       do h = 3 * h + 1; while (h <= 256);
2866       do {
2867          h = h / 3;
2868          for (i = h; i <= 255; i++) {
2869             vv = runningOrder[i];
2870             j = i;
2871             while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
2872                runningOrder[j] = runningOrder[j-h];
2873                j = j - h;
2874                if (j <= (h - 1)) goto zero;
2875             }
2876             zero:
2877             runningOrder[j] = vv;
2878          }
2879       } while (h != 1);
2880    }
2881 
2882    /*--
2883       The main sorting loop.
2884    --*/
2885 
2886    numQSorted = 0;
2887 
2888    for (i = 0; i <= 255; i++) {
2889 
2890       /*--
2891          Process big buckets, starting with the least full.
2892          Basically this is a 3-step process in which we call
2893          mainQSort3 to sort the small buckets [ss, j], but
2894          also make a big effort to avoid the calls if we can.
2895       --*/
2896       ss = runningOrder[i];
2897 
2898       /*--
2899          Step 1:
2900          Complete the big bucket [ss] by quicksorting
2901          any unsorted small buckets [ss, j], for j != ss.
2902          Hopefully previous pointer-scanning phases have already
2903          completed many of the small buckets [ss, j], so
2904          we don't have to sort them at all.
2905       --*/
2906       for (j = 0; j <= 255; j++) {
2907          if (j != ss) {
2908             sb = (ss << 8) + j;
2909             if ( ! (ftab[sb] & SETMASK) ) {
2910                Int32 lo = ftab[sb]   & CLEARMASK;
2911                Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
2912                if (hi > lo) {
2913                   if (verb >= 4)
2914                      VPrintf4 ( "        qsort [0x%x, 0x%x]   "
2915                                 "done %d   this %d\n",
2916                                 ss, j, numQSorted, hi - lo + 1 );
2917                   mainQSort3 (
2918                      ptr, block, quadrant, nblock,
2919                      lo, hi, BZ_N_RADIX, budget
2920                   );
2921                   numQSorted += (hi - lo + 1);
2922                   if (*budget < 0) return;
2923                }
2924             }
2925             ftab[sb] |= SETMASK;
2926          }
2927       }
2928 
2929       AssertH ( !bigDone[ss], 1006 );
2930 
2931       /*--
2932          Step 2:
2933          Now scan this big bucket [ss] so as to synthesise the
2934          sorted order for small buckets [t, ss] for all t,
2935          including, magically, the bucket [ss,ss] too.
2936          This will avoid doing Real Work in subsequent Step 1's.
2937       --*/
2938       {
2939          for (j = 0; j <= 255; j++) {
2940             copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
2941             copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
2942          }
2943          for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
2944             k = ptr[j]-1; if (k < 0) k += nblock;
2945             c1 = block[k];
2946             if (!bigDone[c1])
2947                ptr[ copyStart[c1]++ ] = k;
2948          }
2949          for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
2950             k = ptr[j]-1; if (k < 0) k += nblock;
2951             c1 = block[k];
2952             if (!bigDone[c1])
2953                ptr[ copyEnd[c1]-- ] = k;
2954          }
2955       }
2956 
2957       AssertH ( (copyStart[ss]-1 == copyEnd[ss])
2958                 ||
2959                 /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
2960                    Necessity for this case is demonstrated by compressing
2961                    a sequence of approximately 48.5 million of character
2962                    251; 1.0.0/1.0.1 will then die here. */
2963                 (copyStart[ss] == 0 && copyEnd[ss] == nblock-1),
2964                 1007 )
2965 
2966       for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
2967 
2968       /*--
2969          Step 3:
2970          The [ss] big bucket is now done.  Record this fact,
2971          and update the quadrant descriptors.  Remember to
2972          update quadrants in the overshoot area too, if
2973          necessary.  The "if (i < 255)" test merely skips
2974          this updating for the last bucket processed, since
2975          updating for the last bucket is pointless.
2976 
2977          The quadrant array provides a way to incrementally
2978          cache sort orderings, as they appear, so as to
2979          make subsequent comparisons in fullGtU() complete
2980          faster.  For repetitive blocks this makes a big
2981          difference (but not big enough to be able to avoid
2982          the fallback sorting mechanism, exponential radix sort).
2983 
2984          The precise meaning is: at all times:
2985 
2986             for 0 <= i < nblock and 0 <= j <= nblock
2987 
2988             if block[i] != block[j],
2989 
2990                then the relative values of quadrant[i] and
2991                     quadrant[j] are meaningless.
2992 
2993                else {
2994                   if quadrant[i] < quadrant[j]
2995                      then the string starting at i lexicographically
2996                      precedes the string starting at j
2997 
2998                   else if quadrant[i] > quadrant[j]
2999                      then the string starting at j lexicographically
3000                      precedes the string starting at i
3001 
3002                   else
3003                      the relative ordering of the strings starting
3004                      at i and j has not yet been determined.
3005                }
3006       --*/
3007       bigDone[ss] = True;
3008 
3009       if (i < 255) {
3010          Int32 bbStart  = ftab[ss << 8] & CLEARMASK;
3011          Int32 bbSize   = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
3012          Int32 shifts   = 0;
3013 
3014          while ((bbSize >> shifts) > 65534) shifts++;
3015 
3016          for (j = bbSize-1; j >= 0; j--) {
3017             Int32 a2update     = ptr[bbStart + j];
3018             UInt16 qVal        = (UInt16)(j >> shifts);
3019             quadrant[a2update] = qVal;
3020             if (a2update < BZ_N_OVERSHOOT)
3021                quadrant[a2update + nblock] = qVal;
3022          }
3023          AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
3024       }
3025 
3026    }
3027 
3028    if (verb >= 4)
3029       VPrintf3 ( "        %d pointers, %d sorted, %d scanned\n",
3030                  nblock, numQSorted, nblock - numQSorted );
3031 }
3032 
3033 #undef BIGFREQ
3034 #undef SETMASK
3035 #undef CLEARMASK
3036 
3037 
3038 /*---------------------------------------------*/
3039 /* Pre:
3040       nblock > 0
3041       arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
3042       ((UChar*)arr2)  [0 .. nblock-1] holds block
3043       arr1 exists for [0 .. nblock-1]
3044 
3045    Post:
3046       ((UChar*)arr2) [0 .. nblock-1] holds block
3047       All other areas of block destroyed
3048       ftab [ 0 .. 65536 ] destroyed
3049       arr1 [0 .. nblock-1] holds sorted order
3050 */
BZ2_blockSort(EState * s)3051 void BZ2_blockSort ( EState* s )
3052 {
3053    UInt32* ptr    = s->ptr;
3054    UChar*  block  = s->block;
3055    UInt32* ftab   = s->ftab;
3056    Int32   nblock = s->nblock;
3057    Int32   verb   = s->verbosity;
3058    Int32   wfact  = s->workFactor;
3059    UInt16* quadrant;
3060    Int32   budget;
3061    Int32   budgetInit;
3062    Int32   i;
3063 
3064    if (nblock < /* 10000 */1000 ) {
3065       fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
3066    } else {
3067       /* Calculate the location for quadrant, remembering to get
3068          the alignment right.  Assumes that &(block[0]) is at least
3069          2-byte aligned -- this should be ok since block is really
3070          the first section of arr2.
3071       */
3072       i = nblock+BZ_N_OVERSHOOT;
3073       if (i & 1) i++;
3074       quadrant = (UInt16*)(&(block[i]));
3075 
3076       /* (wfact-1) / 3 puts the default-factor-30
3077          transition point at very roughly the same place as
3078          with v0.1 and v0.9.0.
3079          Not that it particularly matters any more, since the
3080          resulting compressed stream is now the same regardless
3081          of whether or not we use the main sort or fallback sort.
3082       */
3083       if (wfact < 1  ) wfact = 1;
3084       if (wfact > 100) wfact = 100;
3085       budgetInit = nblock * ((wfact-1) / 3);
3086       budget = budgetInit;
3087 
3088       mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget );
3089       if (0 && verb >= 3)
3090          VPrintf3 ( "      %d work, %d block, ratio %5.2f\n",
3091                     budgetInit - budget,
3092                     nblock,
3093                     (float)(budgetInit - budget) /
3094                     (float)(nblock==0 ? 1 : nblock) );
3095       if (budget < 0) {
3096          if (verb >= 2)
3097             VPrintf0 ( "    too repetitive; using fallback"
3098                        " sorting algorithm\n" );
3099          fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
3100       }
3101    }
3102 
3103    s->origPtr = -1;
3104    for (i = 0; i < s->nblock; i++)
3105       if (ptr[i] == 0)
3106          { s->origPtr = i; break; };
3107 
3108    AssertH( s->origPtr != -1, 1003 );
3109 }
3110 
3111 
3112 /*-------------------------------------------------------------*/
3113 /*--- end                                       blocksort.c ---*/
3114 /*-------------------------------------------------------------*/
3115 
3116 /*-------------------------------------------------------------*/
3117 /*--- Huffman coding low-level stuff                        ---*/
3118 /*---                                             huffman.c ---*/
3119 /*-------------------------------------------------------------*/
3120 
3121 /*--
3122   This file is a part of bzip2 and/or libbzip2, a program and
3123   library for lossless, block-sorting data compression.
3124 
3125   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
3126 
3127   Redistribution and use in source and binary forms, with or without
3128   modification, are permitted provided that the following conditions
3129   are met:
3130 
3131   1. Redistributions of source code must retain the above copyright
3132      notice, this list of conditions and the following disclaimer.
3133 
3134   2. The origin of this software must not be misrepresented; you must
3135      not claim that you wrote the original software.  If you use this
3136      software in a product, an acknowledgment in the product
3137      documentation would be appreciated but is not required.
3138 
3139   3. Altered source versions must be plainly marked as such, and must
3140      not be misrepresented as being the original software.
3141 
3142   4. The name of the author may not be used to endorse or promote
3143      products derived from this software without specific prior written
3144      permission.
3145 
3146   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
3147   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3148   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3149   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3150   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3151   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
3152   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3153   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3154   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3155   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3156   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3157 
3158   Julian Seward, Cambridge, UK.
3159   jseward@bzip.org
3160   bzip2/libbzip2 version 1.0 of 21 March 2000
3161 
3162   This program is based on (at least) the work of:
3163      Mike Burrows
3164      David Wheeler
3165      Peter Fenwick
3166      Alistair Moffat
3167      Radford Neal
3168      Ian H. Witten
3169      Robert Sedgewick
3170      Jon L. Bentley
3171 
3172   For more information on these sources, see the manual.
3173 --*/
3174 
3175 
3176 
3177 /*---------------------------------------------------*/
3178 #define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
3179 #define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
3180 #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
3181 
3182 #define ADDWEIGHTS(zw1,zw2)                           \
3183    (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
3184    (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
3185 
3186 #define UPHEAP(z)                                     \
3187 {                                                     \
3188    Int32 zz, tmp;                                     \
3189    zz = z; tmp = heap[zz];                            \
3190    while (weight[tmp] < weight[heap[zz >> 1]]) {      \
3191       heap[zz] = heap[zz >> 1];                       \
3192       zz >>= 1;                                       \
3193    }                                                  \
3194    heap[zz] = tmp;                                    \
3195 }
3196 
3197 #define DOWNHEAP(z)                                   \
3198 {                                                     \
3199    Int32 zz, yy, tmp;                                 \
3200    zz = z; tmp = heap[zz];                            \
3201    while (True) {                                     \
3202       yy = zz << 1;                                   \
3203       if (yy > nHeap) break;                          \
3204       if (yy < nHeap &&                               \
3205           weight[heap[yy+1]] < weight[heap[yy]])      \
3206          yy++;                                        \
3207       if (weight[tmp] < weight[heap[yy]]) break;      \
3208       heap[zz] = heap[yy];                            \
3209       zz = yy;                                        \
3210    }                                                  \
3211    heap[zz] = tmp;                                    \
3212 }
3213 
3214 
3215 /*---------------------------------------------------*/
BZ2_hbMakeCodeLengths(UChar * len,Int32 * freq,Int32 alphaSize,Int32 maxLen)3216 void BZ2_hbMakeCodeLengths ( UChar *len,
3217                              Int32 *freq,
3218                              Int32 alphaSize,
3219                              Int32 maxLen )
3220 {
3221    /*--
3222       Nodes and heap entries run from 1.  Entry 0
3223       for both the heap and nodes is a sentinel.
3224    --*/
3225    Int32 nNodes, nHeap, n1, n2, i, j, k;
3226    Bool  tooLong;
3227 
3228    Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
3229    Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
3230    Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
3231 
3232    for (i = 0; i < alphaSize; i++)
3233       weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
3234 
3235    while (True) {
3236 
3237       nNodes = alphaSize;
3238       nHeap = 0;
3239 
3240       heap[0] = 0;
3241       weight[0] = 0;
3242       parent[0] = -2;
3243 
3244       for (i = 1; i <= alphaSize; i++) {
3245          parent[i] = -1;
3246          nHeap++;
3247          heap[nHeap] = i;
3248          UPHEAP(nHeap);
3249       }
3250 
3251       AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
3252 
3253       while (nHeap > 1) {
3254          n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
3255          n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
3256          nNodes++;
3257          parent[n1] = parent[n2] = nNodes;
3258          weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
3259          parent[nNodes] = -1;
3260          nHeap++;
3261          heap[nHeap] = nNodes;
3262          UPHEAP(nHeap);
3263       }
3264 
3265       AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
3266 
3267       tooLong = False;
3268       for (i = 1; i <= alphaSize; i++) {
3269          j = 0;
3270          k = i;
3271          while (parent[k] >= 0) { k = parent[k]; j++; }
3272          len[i-1] = j;
3273          if (j > maxLen) tooLong = True;
3274       }
3275 
3276       if (! tooLong) break;
3277 
3278       /* 17 Oct 04: keep-going condition for the following loop used
3279          to be 'i < alphaSize', which missed the last element,
3280          theoretically leading to the possibility of the compressor
3281          looping.  However, this count-scaling step is only needed if
3282          one of the generated Huffman code words is longer than
3283          maxLen, which up to and including version 1.0.2 was 20 bits,
3284          which is extremely unlikely.  In version 1.0.3 maxLen was
3285          changed to 17 bits, which has minimal effect on compression
3286          ratio, but does mean this scaling step is used from time to
3287          time, enough to verify that it works.
3288 
3289          This means that bzip2-1.0.3 and later will only produce
3290          Huffman codes with a maximum length of 17 bits.  However, in
3291          order to preserve backwards compatibility with bitstreams
3292          produced by versions pre-1.0.3, the decompressor must still
3293          handle lengths of up to 20. */
3294 
3295       for (i = 1; i <= alphaSize; i++) {
3296          j = weight[i] >> 8;
3297          j = 1 + (j / 2);
3298          weight[i] = j << 8;
3299       }
3300    }
3301 }
3302 
3303 
3304 /*---------------------------------------------------*/
BZ2_hbAssignCodes(Int32 * code,UChar * length,Int32 minLen,Int32 maxLen,Int32 alphaSize)3305 void BZ2_hbAssignCodes ( Int32 *code,
3306                          UChar *length,
3307                          Int32 minLen,
3308                          Int32 maxLen,
3309                          Int32 alphaSize )
3310 {
3311    Int32 n, vec, i;
3312 
3313    vec = 0;
3314    for (n = minLen; n <= maxLen; n++) {
3315       for (i = 0; i < alphaSize; i++)
3316          if (length[i] == n) { code[i] = vec; vec++; };
3317       vec <<= 1;
3318    }
3319 }
3320 
3321 
3322 /*---------------------------------------------------*/
BZ2_hbCreateDecodeTables(Int32 * limit,Int32 * base,Int32 * perm,UChar * length,Int32 minLen,Int32 maxLen,Int32 alphaSize)3323 void BZ2_hbCreateDecodeTables ( Int32 *limit,
3324                                 Int32 *base,
3325                                 Int32 *perm,
3326                                 UChar *length,
3327                                 Int32 minLen,
3328                                 Int32 maxLen,
3329                                 Int32 alphaSize )
3330 {
3331    Int32 pp, i, j, vec;
3332 
3333    pp = 0;
3334    for (i = minLen; i <= maxLen; i++)
3335       for (j = 0; j < alphaSize; j++)
3336          if (length[j] == i) { perm[pp] = j; pp++; };
3337 
3338    for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
3339    for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
3340 
3341    for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
3342 
3343    for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
3344    vec = 0;
3345 
3346    for (i = minLen; i <= maxLen; i++) {
3347       vec += (base[i+1] - base[i]);
3348       limit[i] = vec-1;
3349       vec <<= 1;
3350    }
3351    for (i = minLen + 1; i <= maxLen; i++)
3352       base[i] = ((limit[i-1] + 1) << 1) - base[i];
3353 }
3354 
3355 
3356 /*-------------------------------------------------------------*/
3357 /*--- end                                         huffman.c ---*/
3358 /*-------------------------------------------------------------*/
3359 
3360 /*-------------------------------------------------------------*/
3361 /*--- Compression machinery (not incl block sorting)        ---*/
3362 /*---                                            compress.c ---*/
3363 /*-------------------------------------------------------------*/
3364 
3365 /*--
3366   This file is a part of bzip2 and/or libbzip2, a program and
3367   library for lossless, block-sorting data compression.
3368 
3369   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
3370 
3371   Redistribution and use in source and binary forms, with or without
3372   modification, are permitted provided that the following conditions
3373   are met:
3374 
3375   1. Redistributions of source code must retain the above copyright
3376      notice, this list of conditions and the following disclaimer.
3377 
3378   2. The origin of this software must not be misrepresented; you must
3379      not claim that you wrote the original software.  If you use this
3380      software in a product, an acknowledgment in the product
3381      documentation would be appreciated but is not required.
3382 
3383   3. Altered source versions must be plainly marked as such, and must
3384      not be misrepresented as being the original software.
3385 
3386   4. The name of the author may not be used to endorse or promote
3387      products derived from this software without specific prior written
3388      permission.
3389 
3390   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
3391   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3392   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3393   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
3394   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3395   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
3396   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3397   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3398   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3399   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3400   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3401 
3402   Julian Seward, Cambridge, UK.
3403   jseward@bzip.org
3404   bzip2/libbzip2 version 1.0 of 21 March 2000
3405 
3406   This program is based on (at least) the work of:
3407      Mike Burrows
3408      David Wheeler
3409      Peter Fenwick
3410      Alistair Moffat
3411      Radford Neal
3412      Ian H. Witten
3413      Robert Sedgewick
3414      Jon L. Bentley
3415 
3416   For more information on these sources, see the manual.
3417 --*/
3418 
3419 /*--
3420    CHANGES
3421    ~~~~~~~
3422    0.9.0 -- original version.
3423 
3424    0.9.0a/b -- no changes in this file.
3425 
3426    0.9.0c
3427       * changed setting of nGroups in sendMTFValues() so as to
3428         do a bit better on small files
3429 --*/
3430 
3431 
3432 
3433 /*---------------------------------------------------*/
3434 /*--- Bit stream I/O                              ---*/
3435 /*---------------------------------------------------*/
3436 
3437 /*---------------------------------------------------*/
BZ2_bsInitWrite(EState * s)3438 void BZ2_bsInitWrite ( EState* s )
3439 {
3440    s->bsLive = 0;
3441    s->bsBuff = 0;
3442 }
3443 
3444 
3445 /*---------------------------------------------------*/
3446 static
bsFinishWrite(EState * s)3447 void bsFinishWrite ( EState* s )
3448 {
3449    while (s->bsLive > 0) {
3450       s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
3451       s->numZ++;
3452       s->bsBuff <<= 8;
3453       s->bsLive -= 8;
3454    }
3455 }
3456 
3457 
3458 /*---------------------------------------------------*/
3459 #define bsNEEDW(nz)                           \
3460 {                                             \
3461    while (s->bsLive >= 8) {                   \
3462       s->zbits[s->numZ]                       \
3463          = (UChar)(s->bsBuff >> 24);          \
3464       s->numZ++;                              \
3465       s->bsBuff <<= 8;                        \
3466       s->bsLive -= 8;                         \
3467    }                                          \
3468 }
3469 
3470 
3471 /*---------------------------------------------------*/
3472 static
3473 __inline__
bsW(EState * s,Int32 n,UInt32 v)3474 void bsW ( EState* s, Int32 n, UInt32 v )
3475 {
3476    bsNEEDW ( n );
3477    s->bsBuff |= (v << (32 - s->bsLive - n));
3478    s->bsLive += n;
3479 }
3480 
3481 
3482 /*---------------------------------------------------*/
3483 static
bsPutUInt32(EState * s,UInt32 u)3484 void bsPutUInt32 ( EState* s, UInt32 u )
3485 {
3486    bsW ( s, 8, (u >> 24) & 0xffL );
3487    bsW ( s, 8, (u >> 16) & 0xffL );
3488    bsW ( s, 8, (u >>  8) & 0xffL );
3489    bsW ( s, 8,  u        & 0xffL );
3490 }
3491 
3492 
3493 /*---------------------------------------------------*/
3494 static
bsPutUChar(EState * s,UChar c)3495 void bsPutUChar ( EState* s, UChar c )
3496 {
3497    bsW( s, 8, (UInt32)c );
3498 }
3499 
3500 
3501 /*---------------------------------------------------*/
3502 /*--- The back end proper                         ---*/
3503 /*---------------------------------------------------*/
3504 
3505 /*---------------------------------------------------*/
3506 static
makeMaps_e(EState * s)3507 void makeMaps_e ( EState* s )
3508 {
3509    Int32 i;
3510    s->nInUse = 0;
3511    for (i = 0; i < 256; i++)
3512       if (s->inUse[i]) {
3513          s->unseqToSeq[i] = s->nInUse;
3514          s->nInUse++;
3515       }
3516 }
3517 
3518 
3519 /*---------------------------------------------------*/
3520 static
generateMTFValues(EState * s)3521 void generateMTFValues ( EState* s )
3522 {
3523    UChar   yy[256];
3524    Int32   i, j;
3525    Int32   zPend;
3526    Int32   wr;
3527    Int32   EOB;
3528 
3529    /*
3530       After sorting (eg, here),
3531          s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
3532          and
3533          ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
3534          holds the original block data.
3535 
3536       The first thing to do is generate the MTF values,
3537       and put them in
3538          ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
3539       Because there are strictly fewer or equal MTF values
3540       than block values, ptr values in this area are overwritten
3541       with MTF values only when they are no longer needed.
3542 
3543       The final compressed bitstream is generated into the
3544       area starting at
3545          (UChar*) (&((UChar*)s->arr2)[s->nblock])
3546 
3547       These storage aliases are set up in bzCompressInit(),
3548       except for the last one, which is arranged in
3549       compressBlock().
3550    */
3551    UInt32* ptr   = s->ptr;
3552    UChar* block  = s->block;
3553    UInt16* mtfv  = s->mtfv;
3554 
3555    makeMaps_e ( s );
3556    EOB = s->nInUse+1;
3557 
3558    for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
3559 
3560    wr = 0;
3561    zPend = 0;
3562    for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
3563 
3564    for (i = 0; i < s->nblock; i++) {
3565       UChar ll_i;
3566       AssertD ( wr <= i, "generateMTFValues(1)" );
3567       j = ptr[i]-1; if (j < 0) j += s->nblock;
3568       ll_i = s->unseqToSeq[block[j]];
3569       AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
3570 
3571       if (yy[0] == ll_i) {
3572          zPend++;
3573       } else {
3574 
3575          if (zPend > 0) {
3576             zPend--;
3577             while (True) {
3578                if (zPend & 1) {
3579                   mtfv[wr] = BZ_RUNB; wr++;
3580                   s->mtfFreq[BZ_RUNB]++;
3581                } else {
3582                   mtfv[wr] = BZ_RUNA; wr++;
3583                   s->mtfFreq[BZ_RUNA]++;
3584                }
3585                if (zPend < 2) break;
3586                zPend = (zPend - 2) / 2;
3587             };
3588             zPend = 0;
3589          }
3590          {
3591             register UChar  rtmp;
3592             register UChar* ryy_j;
3593             register UChar  rll_i;
3594             rtmp  = yy[1];
3595             yy[1] = yy[0];
3596             ryy_j = &(yy[1]);
3597             rll_i = ll_i;
3598             while ( rll_i != rtmp ) {
3599                register UChar rtmp2;
3600                ryy_j++;
3601                rtmp2  = rtmp;
3602                rtmp   = *ryy_j;
3603                *ryy_j = rtmp2;
3604             };
3605             yy[0] = rtmp;
3606             j = ryy_j - &(yy[0]);
3607             mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
3608          }
3609 
3610       }
3611    }
3612 
3613    if (zPend > 0) {
3614       zPend--;
3615       while (True) {
3616          if (zPend & 1) {
3617             mtfv[wr] = BZ_RUNB; wr++;
3618             s->mtfFreq[BZ_RUNB]++;
3619          } else {
3620             mtfv[wr] = BZ_RUNA; wr++;
3621             s->mtfFreq[BZ_RUNA]++;
3622          }
3623          if (zPend < 2) break;
3624          zPend = (zPend - 2) / 2;
3625       };
3626       zPend = 0;
3627    }
3628 
3629    mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
3630 
3631    s->nMTF = wr;
3632 }
3633 
3634 
3635 /*---------------------------------------------------*/
3636 #define BZ_LESSER_ICOST  0
3637 #define BZ_GREATER_ICOST 15
3638 
3639 static
sendMTFValues(EState * s)3640 void sendMTFValues ( EState* s )
3641 {
3642    Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
3643    Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
3644    Int32 nGroups, nBytes;
3645 
3646    /*--
3647    UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3648    is a global since the decoder also needs it.
3649 
3650    Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3651    Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
3652    are also globals only used in this proc.
3653    Made global to keep stack frame size small.
3654    --*/
3655 
3656 
3657    UInt16 cost[BZ_N_GROUPS];
3658    Int32  fave[BZ_N_GROUPS];
3659 
3660    UInt16* mtfv = s->mtfv;
3661 
3662    if (s->verbosity >= 3)
3663       VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
3664                 "%d+2 syms in use\n",
3665                 s->nblock, s->nMTF, s->nInUse );
3666 
3667    alphaSize = s->nInUse+2;
3668    for (t = 0; t < BZ_N_GROUPS; t++)
3669       for (v = 0; v < alphaSize; v++)
3670          s->len[t][v] = BZ_GREATER_ICOST;
3671 
3672    /*--- Decide how many coding tables to use ---*/
3673    AssertH ( s->nMTF > 0, 3001 );
3674    if (s->nMTF < 200)  nGroups = 2; else
3675    if (s->nMTF < 600)  nGroups = 3; else
3676    if (s->nMTF < 1200) nGroups = 4; else
3677    if (s->nMTF < 2400) nGroups = 5; else
3678                        nGroups = 6;
3679 
3680    /*--- Generate an initial set of coding tables ---*/
3681    {
3682       Int32 nPart, remF, tFreq, aFreq;
3683 
3684       nPart = nGroups;
3685       remF  = s->nMTF;
3686       gs = 0;
3687       while (nPart > 0) {
3688          tFreq = remF / nPart;
3689          ge = gs-1;
3690          aFreq = 0;
3691          while (aFreq < tFreq && ge < alphaSize-1) {
3692             ge++;
3693             aFreq += s->mtfFreq[ge];
3694          }
3695 
3696          if (ge > gs
3697              && nPart != nGroups && nPart != 1
3698              && ((nGroups-nPart) % 2 == 1)) {
3699             aFreq -= s->mtfFreq[ge];
3700             ge--;
3701          }
3702 
3703          if (0 && s->verbosity >= 3)
3704             VPrintf5( "      initial group %d, [%d .. %d], "
3705                       "has %d syms (%4.1f%%)\n",
3706                       nPart, gs, ge, aFreq,
3707                       (100.0 * (float)aFreq) / (float)(s->nMTF) );
3708 
3709          for (v = 0; v < alphaSize; v++)
3710             if (v >= gs && v <= ge)
3711                s->len[nPart-1][v] = BZ_LESSER_ICOST; else
3712                s->len[nPart-1][v] = BZ_GREATER_ICOST;
3713 
3714          nPart--;
3715          gs = ge+1;
3716          remF -= aFreq;
3717       }
3718    }
3719 
3720    /*---
3721       Iterate up to BZ_N_ITERS times to improve the tables.
3722    ---*/
3723    for (iter = 0; iter < BZ_N_ITERS; iter++) {
3724 
3725       for (t = 0; t < nGroups; t++) fave[t] = 0;
3726 
3727       for (t = 0; t < nGroups; t++)
3728          for (v = 0; v < alphaSize; v++)
3729             s->rfreq[t][v] = 0;
3730 
3731       /*---
3732         Set up an auxiliary length table which is used to fast-track
3733 	the common case (nGroups == 6).
3734       ---*/
3735       if (nGroups == 6) {
3736          for (v = 0; v < alphaSize; v++) {
3737             s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
3738             s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
3739             s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
3740 	 }
3741       }
3742 
3743       nSelectors = 0;
3744       totc = 0;
3745       gs = 0;
3746       while (True) {
3747 
3748          /*--- Set group start & end marks. --*/
3749          if (gs >= s->nMTF) break;
3750          ge = gs + BZ_G_SIZE - 1;
3751          if (ge >= s->nMTF) ge = s->nMTF-1;
3752 
3753          /*--
3754             Calculate the cost of this group as coded
3755             by each of the coding tables.
3756          --*/
3757          for (t = 0; t < nGroups; t++) cost[t] = 0;
3758 
3759          if (nGroups == 6 && 50 == ge-gs+1) {
3760             /*--- fast track the common case ---*/
3761             register UInt32 cost01, cost23, cost45;
3762             register UInt16 icv;
3763             cost01 = cost23 = cost45 = 0;
3764 
3765 #           define BZ_ITER(nn)                \
3766                icv = mtfv[gs+(nn)];           \
3767                cost01 += s->len_pack[icv][0]; \
3768                cost23 += s->len_pack[icv][1]; \
3769                cost45 += s->len_pack[icv][2]; \
3770 
3771             BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
3772             BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
3773             BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
3774             BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
3775             BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
3776             BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
3777             BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
3778             BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
3779             BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
3780             BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
3781 
3782 #           undef BZ_ITER
3783 
3784             cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
3785             cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
3786             cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
3787 
3788          } else {
3789 	    /*--- slow version which correctly handles all situations ---*/
3790             for (i = gs; i <= ge; i++) {
3791                UInt16 icv = mtfv[i];
3792                for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
3793             }
3794          }
3795 
3796          /*--
3797             Find the coding table which is best for this group,
3798             and record its identity in the selector table.
3799          --*/
3800          bc = 999999999; bt = -1;
3801          for (t = 0; t < nGroups; t++)
3802             if (cost[t] < bc) { bc = cost[t]; bt = t; };
3803          totc += bc;
3804          fave[bt]++;
3805          s->selector[nSelectors] = bt;
3806          nSelectors++;
3807 
3808          /*--
3809             Increment the symbol frequencies for the selected table.
3810           --*/
3811          if (nGroups == 6 && 50 == ge-gs+1) {
3812             /*--- fast track the common case ---*/
3813 
3814 #           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
3815 
3816             BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
3817             BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
3818             BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
3819             BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
3820             BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
3821             BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
3822             BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
3823             BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
3824             BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
3825             BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
3826 
3827 #           undef BZ_ITUR
3828 
3829          } else {
3830 	    /*--- slow version which correctly handles all situations ---*/
3831             for (i = gs; i <= ge; i++)
3832                s->rfreq[bt][ mtfv[i] ]++;
3833          }
3834 
3835          gs = ge+1;
3836       }
3837       if (s->verbosity >= 3) {
3838          VPrintf2 ( "      pass %d: size is %d, grp uses are ",
3839                    iter+1, totc/8 );
3840          for (t = 0; t < nGroups; t++)
3841             VPrintf1 ( "%d ", fave[t] );
3842          VPrintf0 ( "\n" );
3843       }
3844 
3845       /*--
3846         Recompute the tables based on the accumulated frequencies.
3847       --*/
3848       /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
3849          comment in huffman.c for details. */
3850       for (t = 0; t < nGroups; t++)
3851          BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
3852                                  alphaSize, 17 /*20*/ );
3853    }
3854 
3855 
3856    AssertH( nGroups < 8, 3002 );
3857    AssertH( nSelectors < 32768 &&
3858             nSelectors <= (2 + (900000 / BZ_G_SIZE)),
3859             3003 );
3860 
3861 
3862    /*--- Compute MTF values for the selectors. ---*/
3863    {
3864       UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
3865       for (i = 0; i < nGroups; i++) pos[i] = i;
3866       for (i = 0; i < nSelectors; i++) {
3867          ll_i = s->selector[i];
3868          j = 0;
3869          tmp = pos[j];
3870          while ( ll_i != tmp ) {
3871             j++;
3872             tmp2 = tmp;
3873             tmp = pos[j];
3874             pos[j] = tmp2;
3875          };
3876          pos[0] = tmp;
3877          s->selectorMtf[i] = j;
3878       }
3879    };
3880 
3881    /*--- Assign actual codes for the tables. --*/
3882    for (t = 0; t < nGroups; t++) {
3883       minLen = 32;
3884       maxLen = 0;
3885       for (i = 0; i < alphaSize; i++) {
3886          if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
3887          if (s->len[t][i] < minLen) minLen = s->len[t][i];
3888       }
3889       AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
3890       AssertH ( !(minLen < 1),  3005 );
3891       BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
3892                           minLen, maxLen, alphaSize );
3893    }
3894 
3895    /*--- Transmit the mapping table. ---*/
3896    {
3897       Bool inUse16[16];
3898       for (i = 0; i < 16; i++) {
3899           inUse16[i] = False;
3900           for (j = 0; j < 16; j++)
3901              if (s->inUse[i * 16 + j]) inUse16[i] = True;
3902       }
3903 
3904       nBytes = s->numZ;
3905       for (i = 0; i < 16; i++)
3906          if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
3907 
3908       for (i = 0; i < 16; i++)
3909          if (inUse16[i])
3910             for (j = 0; j < 16; j++) {
3911                if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
3912             }
3913 
3914       if (s->verbosity >= 3)
3915          VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
3916    }
3917 
3918    /*--- Now the selectors. ---*/
3919    nBytes = s->numZ;
3920    bsW ( s, 3, nGroups );
3921    bsW ( s, 15, nSelectors );
3922    for (i = 0; i < nSelectors; i++) {
3923       for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
3924       bsW(s,1,0);
3925    }
3926    if (s->verbosity >= 3)
3927       VPrintf1( "selectors %d, ", s->numZ-nBytes );
3928 
3929    /*--- Now the coding tables. ---*/
3930    nBytes = s->numZ;
3931 
3932    for (t = 0; t < nGroups; t++) {
3933       Int32 curr = s->len[t][0];
3934       bsW ( s, 5, curr );
3935       for (i = 0; i < alphaSize; i++) {
3936          while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
3937          while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
3938          bsW ( s, 1, 0 );
3939       }
3940    }
3941 
3942    if (s->verbosity >= 3)
3943       VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
3944 
3945    /*--- And finally, the block data proper ---*/
3946    nBytes = s->numZ;
3947    selCtr = 0;
3948    gs = 0;
3949    while (True) {
3950       if (gs >= s->nMTF) break;
3951       ge = gs + BZ_G_SIZE - 1;
3952       if (ge >= s->nMTF) ge = s->nMTF-1;
3953       AssertH ( s->selector[selCtr] < nGroups, 3006 );
3954 
3955       if (nGroups == 6 && 50 == ge-gs+1) {
3956             /*--- fast track the common case ---*/
3957             UInt16 mtfv_i;
3958             UChar* s_len_sel_selCtr
3959                = &(s->len[s->selector[selCtr]][0]);
3960             Int32* s_code_sel_selCtr
3961                = &(s->code[s->selector[selCtr]][0]);
3962 
3963 #           define BZ_ITAH(nn)                      \
3964                mtfv_i = mtfv[gs+(nn)];              \
3965                bsW ( s,                             \
3966                      s_len_sel_selCtr[mtfv_i],      \
3967                      s_code_sel_selCtr[mtfv_i] )
3968 
3969             BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
3970             BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
3971             BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
3972             BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
3973             BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
3974             BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
3975             BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
3976             BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
3977             BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
3978             BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
3979 
3980 #           undef BZ_ITAH
3981 
3982       } else {
3983 	 /*--- slow version which correctly handles all situations ---*/
3984          for (i = gs; i <= ge; i++) {
3985             bsW ( s,
3986                   s->len  [s->selector[selCtr]] [mtfv[i]],
3987                   s->code [s->selector[selCtr]] [mtfv[i]] );
3988          }
3989       }
3990 
3991 
3992       gs = ge+1;
3993       selCtr++;
3994    }
3995    AssertH( selCtr == nSelectors, 3007 );
3996 
3997    if (s->verbosity >= 3)
3998       VPrintf1( "codes %d\n", s->numZ-nBytes );
3999 }
4000 
4001 
4002 /*---------------------------------------------------*/
BZ2_compressBlock(EState * s,Bool is_last_block)4003 void BZ2_compressBlock ( EState* s, Bool is_last_block )
4004 {
4005    if (s->nblock > 0) {
4006 
4007       BZ_FINALISE_CRC ( s->blockCRC );
4008       s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
4009       s->combinedCRC ^= s->blockCRC;
4010       if (s->blockNo > 1) s->numZ = 0;
4011 
4012       if (s->verbosity >= 2)
4013          VPrintf4( "    block %d: crc = 0x%08x, "
4014                    "combined CRC = 0x%08x, size = %d\n",
4015                    s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
4016 
4017       BZ2_blockSort ( s );
4018    }
4019 
4020    s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
4021 
4022    /*-- If this is the first block, create the stream header. --*/
4023    if (s->blockNo == 1) {
4024       BZ2_bsInitWrite ( s );
4025       bsPutUChar ( s, BZ_HDR_B );
4026       bsPutUChar ( s, BZ_HDR_Z );
4027       bsPutUChar ( s, BZ_HDR_h );
4028       bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
4029    }
4030 
4031    if (s->nblock > 0) {
4032 
4033       bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
4034       bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
4035       bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
4036 
4037       /*-- Now the block's CRC, so it is in a known place. --*/
4038       bsPutUInt32 ( s, s->blockCRC );
4039 
4040       /*--
4041          Now a single bit indicating (non-)randomisation.
4042          As of version 0.9.5, we use a better sorting algorithm
4043          which makes randomisation unnecessary.  So always set
4044          the randomised bit to 'no'.  Of course, the decoder
4045          still needs to be able to handle randomised blocks
4046          so as to maintain backwards compatibility with
4047          older versions of bzip2.
4048       --*/
4049       bsW(s,1,0);
4050 
4051       bsW ( s, 24, s->origPtr );
4052       generateMTFValues ( s );
4053       sendMTFValues ( s );
4054    }
4055 
4056 
4057    /*-- If this is the last block, add the stream trailer. --*/
4058    if (is_last_block) {
4059 
4060       bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
4061       bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
4062       bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
4063       bsPutUInt32 ( s, s->combinedCRC );
4064       if (s->verbosity >= 2)
4065          VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
4066       bsFinishWrite ( s );
4067    }
4068 }
4069 
4070 
4071 /*-------------------------------------------------------------*/
4072 /*--- end                                        compress.c ---*/
4073 /*-------------------------------------------------------------*/
4074 
4075 
4076 /*-------------------------------------------------------------*/
4077 /*--- Table for randomising repetitive blocks               ---*/
4078 /*---                                           randtable.c ---*/
4079 /*-------------------------------------------------------------*/
4080 
4081 /*--
4082   This file is a part of bzip2 and/or libbzip2, a program and
4083   library for lossless, block-sorting data compression.
4084 
4085   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4086 
4087   Redistribution and use in source and binary forms, with or without
4088   modification, are permitted provided that the following conditions
4089   are met:
4090 
4091   1. Redistributions of source code must retain the above copyright
4092      notice, this list of conditions and the following disclaimer.
4093 
4094   2. The origin of this software must not be misrepresented; you must
4095      not claim that you wrote the original software.  If you use this
4096      software in a product, an acknowledgment in the product
4097      documentation would be appreciated but is not required.
4098 
4099   3. Altered source versions must be plainly marked as such, and must
4100      not be misrepresented as being the original software.
4101 
4102   4. The name of the author may not be used to endorse or promote
4103      products derived from this software without specific prior written
4104      permission.
4105 
4106   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4107   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4108   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4109   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4110   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4111   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4112   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4113   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4114   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4115   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4116   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4117 
4118   Julian Seward, Cambridge, UK.
4119   jseward@bzip.org
4120   bzip2/libbzip2 version 1.0 of 21 March 2000
4121 
4122   This program is based on (at least) the work of:
4123      Mike Burrows
4124      David Wheeler
4125      Peter Fenwick
4126      Alistair Moffat
4127      Radford Neal
4128      Ian H. Witten
4129      Robert Sedgewick
4130      Jon L. Bentley
4131 
4132   For more information on these sources, see the manual.
4133 --*/
4134 
4135 
4136 
4137 
4138 /*---------------------------------------------*/
4139 Int32 BZ2_rNums[512] = {
4140    619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
4141    985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
4142    733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
4143    419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
4144    878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
4145    862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
4146    150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
4147    170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
4148    73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
4149    909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
4150    641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
4151    161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
4152    382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
4153    98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
4154    227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
4155    469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
4156    184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
4157    715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
4158    951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
4159    652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
4160    645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
4161    609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
4162    653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
4163    411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
4164    170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
4165    857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
4166    669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
4167    944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
4168    344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
4169    897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
4170    433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
4171    686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
4172    946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
4173    978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
4174    680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
4175    707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
4176    297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
4177    134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
4178    343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
4179    140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
4180    170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
4181    369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
4182    804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
4183    896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
4184    661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
4185    768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
4186    61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
4187    372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
4188    780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
4189    920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
4190    645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
4191    936, 638
4192 };
4193 
4194 
4195 /*-------------------------------------------------------------*/
4196 /*--- end                                       randtable.c ---*/
4197 /*-------------------------------------------------------------*/
4198 
4199 /*-------------------------------------------------------------*/
4200 /*--- Table for doing CRCs                                  ---*/
4201 /*---                                            crctable.c ---*/
4202 /*-------------------------------------------------------------*/
4203 
4204 /*--
4205   This file is a part of bzip2 and/or libbzip2, a program and
4206   library for lossless, block-sorting data compression.
4207 
4208   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4209 
4210   Redistribution and use in source and binary forms, with or without
4211   modification, are permitted provided that the following conditions
4212   are met:
4213 
4214   1. Redistributions of source code must retain the above copyright
4215      notice, this list of conditions and the following disclaimer.
4216 
4217   2. The origin of this software must not be misrepresented; you must
4218      not claim that you wrote the original software.  If you use this
4219      software in a product, an acknowledgment in the product
4220      documentation would be appreciated but is not required.
4221 
4222   3. Altered source versions must be plainly marked as such, and must
4223      not be misrepresented as being the original software.
4224 
4225   4. The name of the author may not be used to endorse or promote
4226      products derived from this software without specific prior written
4227      permission.
4228 
4229   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4230   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4231   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4232   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4233   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4234   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4235   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4236   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4237   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4238   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4239   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4240 
4241   Julian Seward, Cambridge, UK.
4242   jseward@bzip.org
4243   bzip2/libbzip2 version 1.0 of 21 March 2000
4244 
4245   This program is based on (at least) the work of:
4246      Mike Burrows
4247      David Wheeler
4248      Peter Fenwick
4249      Alistair Moffat
4250      Radford Neal
4251      Ian H. Witten
4252      Robert Sedgewick
4253      Jon L. Bentley
4254 
4255   For more information on these sources, see the manual.
4256 --*/
4257 
4258 
4259 
4260 
4261 
4262 /*--
4263   I think this is an implementation of the AUTODIN-II,
4264   Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
4265   from code by Rob Warnock, in Section 51 of the
4266   comp.compression FAQ.
4267 --*/
4268 
4269 UInt32 BZ2_crc32Table[256] = {
4270 
4271    /*-- Ugly, innit? --*/
4272 
4273    0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
4274    0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
4275    0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
4276    0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
4277    0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
4278    0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
4279    0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
4280    0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
4281    0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
4282    0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
4283    0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
4284    0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
4285    0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
4286    0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
4287    0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
4288    0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
4289    0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
4290    0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
4291    0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
4292    0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
4293    0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
4294    0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
4295    0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
4296    0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
4297    0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
4298    0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
4299    0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
4300    0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
4301    0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
4302    0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
4303    0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
4304    0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
4305    0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
4306    0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
4307    0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
4308    0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
4309    0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
4310    0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
4311    0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
4312    0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
4313    0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
4314    0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
4315    0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
4316    0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
4317    0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
4318    0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
4319    0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
4320    0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
4321    0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
4322    0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
4323    0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
4324    0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
4325    0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
4326    0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
4327    0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
4328    0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
4329    0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
4330    0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
4331    0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
4332    0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
4333    0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
4334    0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
4335    0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
4336    0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
4337 };
4338 
4339 
4340 /*-------------------------------------------------------------*/
4341 /*--- end                                        crctable.c ---*/
4342 /*-------------------------------------------------------------*/
4343 
4344 /*-------------------------------------------------------------*/
4345 /*--- Library top-level functions.                          ---*/
4346 /*---                                               bzlib.c ---*/
4347 /*-------------------------------------------------------------*/
4348 
4349 /*--
4350   This file is a part of bzip2 and/or libbzip2, a program and
4351   library for lossless, block-sorting data compression.
4352 
4353   Copyright (C) 1996-2004 Julian R Seward.  All rights reserved.
4354 
4355   Redistribution and use in source and binary forms, with or without
4356   modification, are permitted provided that the following conditions
4357   are met:
4358 
4359   1. Redistributions of source code must retain the above copyright
4360      notice, this list of conditions and the following disclaimer.
4361 
4362   2. The origin of this software must not be misrepresented; you must
4363      not claim that you wrote the original software.  If you use this
4364      software in a product, an acknowledgment in the product
4365      documentation would be appreciated but is not required.
4366 
4367   3. Altered source versions must be plainly marked as such, and must
4368      not be misrepresented as being the original software.
4369 
4370   4. The name of the author may not be used to endorse or promote
4371      products derived from this software without specific prior written
4372      permission.
4373 
4374   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
4375   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4376   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4377   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
4378   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4379   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4380   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
4381   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
4382   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4383   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4384   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4385 
4386   Julian Seward, Cambridge, UK.
4387   jseward@bzip.org
4388   bzip2/libbzip2 version 1.0 of 21 March 2000
4389 
4390   This program is based on (at least) the work of:
4391      Mike Burrows
4392      David Wheeler
4393      Peter Fenwick
4394      Alistair Moffat
4395      Radford Neal
4396      Ian H. Witten
4397      Robert Sedgewick
4398      Jon L. Bentley
4399 
4400   For more information on these sources, see the manual.
4401 --*/
4402 
4403 /*--
4404    CHANGES
4405    ~~~~~~~
4406    0.9.0 -- original version.
4407 
4408    0.9.0a/b -- no changes in this file.
4409 
4410    0.9.0c
4411       * made zero-length BZ_FLUSH work correctly in bzCompress().
4412       * fixed bzWrite/bzRead to ignore zero-length requests.
4413       * fixed bzread to correctly handle read requests after EOF.
4414       * wrong parameter order in call to bzDecompressInit in
4415         bzBuffToBuffDecompress.  Fixed.
4416 --*/
4417 
4418 
4419 
4420 /*---------------------------------------------------*/
4421 /*--- Compression stuff                           ---*/
4422 /*---------------------------------------------------*/
4423 
4424 
4425 /*---------------------------------------------------*/
BZ2_bz__AssertH__fail(int errcode)4426 void BZ2_bz__AssertH__fail ( int errcode )
4427 {
4428    vexxx_printf("BZ2_bz__AssertH__fail(%d) called, exiting\n", errcode);
4429    (*serviceFn)(0,0);
4430 }
4431 
bz_internal_error(int errcode)4432 void bz_internal_error ( int errcode )
4433 {
4434    vexxx_printf("bz_internal_error called, exiting\n", errcode);
4435    (*serviceFn)(0,0);
4436 }
4437 
4438 /*---------------------------------------------------*/
4439 static
bz_config_ok(void)4440 int bz_config_ok ( void )
4441 {
4442    if (sizeof(int)   != 4) return 0;
4443    if (sizeof(short) != 2) return 0;
4444    if (sizeof(char)  != 1) return 0;
4445    return 1;
4446 }
4447 
4448 
4449 /*---------------------------------------------------*/
4450 static
default_bzalloc(void * opaque,Int32 items,Int32 size)4451 void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
4452 {
4453    void* v = (void*) (*serviceFn)(2, items * size );
4454    return v;
4455 }
4456 
4457 static
default_bzfree(void * opaque,void * addr)4458 void default_bzfree ( void* opaque, void* addr )
4459 {
4460    if (addr != NULL) (*serviceFn)( 3, (HWord)addr );
4461 }
4462 
4463 
4464 /*---------------------------------------------------*/
4465 static
prepare_new_block(EState * s)4466 void prepare_new_block ( EState* s )
4467 {
4468    Int32 i;
4469    s->nblock = 0;
4470    s->numZ = 0;
4471    s->state_out_pos = 0;
4472    BZ_INITIALISE_CRC ( s->blockCRC );
4473    for (i = 0; i < 256; i++) s->inUse[i] = False;
4474    s->blockNo++;
4475 }
4476 
4477 
4478 /*---------------------------------------------------*/
4479 static
init_RL(EState * s)4480 void init_RL ( EState* s )
4481 {
4482    s->state_in_ch  = 256;
4483    s->state_in_len = 0;
4484 }
4485 
4486 
4487 static
isempty_RL(EState * s)4488 Bool isempty_RL ( EState* s )
4489 {
4490    if (s->state_in_ch < 256 && s->state_in_len > 0)
4491       return False; else
4492       return True;
4493 }
4494 
4495 
4496 /*---------------------------------------------------*/
BZ_API(BZ2_bzCompressInit)4497 int BZ_API(BZ2_bzCompressInit)
4498                     ( bz_stream* strm,
4499                      int        blockSize100k,
4500                      int        verbosity,
4501                      int        workFactor )
4502 {
4503    Int32   n;
4504    EState* s;
4505 
4506    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
4507 
4508    if (strm == NULL ||
4509        blockSize100k < 1 || blockSize100k > 9 ||
4510        workFactor < 0 || workFactor > 250)
4511      return BZ_PARAM_ERROR;
4512 
4513    if (workFactor == 0) workFactor = 30;
4514    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
4515    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
4516 
4517    s = BZALLOC( sizeof(EState) );
4518    if (s == NULL) return BZ_MEM_ERROR;
4519    s->strm = strm;
4520 
4521    s->arr1 = NULL;
4522    s->arr2 = NULL;
4523    s->ftab = NULL;
4524 
4525    n       = 100000 * blockSize100k;
4526    s->arr1 = BZALLOC( n                  * sizeof(UInt32) );
4527    s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
4528    s->ftab = BZALLOC( 65537              * sizeof(UInt32) );
4529 
4530    if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
4531       if (s->arr1 != NULL) BZFREE(s->arr1);
4532       if (s->arr2 != NULL) BZFREE(s->arr2);
4533       if (s->ftab != NULL) BZFREE(s->ftab);
4534       if (s       != NULL) BZFREE(s);
4535       return BZ_MEM_ERROR;
4536    }
4537 
4538    s->blockNo           = 0;
4539    s->state             = BZ_S_INPUT;
4540    s->mode              = BZ_M_RUNNING;
4541    s->combinedCRC       = 0;
4542    s->blockSize100k     = blockSize100k;
4543    s->nblockMAX         = 100000 * blockSize100k - 19;
4544    s->verbosity         = verbosity;
4545    s->workFactor        = workFactor;
4546 
4547    s->block             = (UChar*)s->arr2;
4548    s->mtfv              = (UInt16*)s->arr1;
4549    s->zbits             = NULL;
4550    s->ptr               = (UInt32*)s->arr1;
4551 
4552    strm->state          = s;
4553    strm->total_in_lo32  = 0;
4554    strm->total_in_hi32  = 0;
4555    strm->total_out_lo32 = 0;
4556    strm->total_out_hi32 = 0;
4557    init_RL ( s );
4558    prepare_new_block ( s );
4559    return BZ_OK;
4560 }
4561 
4562 
4563 /*---------------------------------------------------*/
4564 static
add_pair_to_block(EState * s)4565 void add_pair_to_block ( EState* s )
4566 {
4567    Int32 i;
4568    UChar ch = (UChar)(s->state_in_ch);
4569    for (i = 0; i < s->state_in_len; i++) {
4570       BZ_UPDATE_CRC( s->blockCRC, ch );
4571    }
4572    s->inUse[s->state_in_ch] = True;
4573    switch (s->state_in_len) {
4574       case 1:
4575          s->block[s->nblock] = (UChar)ch; s->nblock++;
4576          break;
4577       case 2:
4578          s->block[s->nblock] = (UChar)ch; s->nblock++;
4579          s->block[s->nblock] = (UChar)ch; s->nblock++;
4580          break;
4581       case 3:
4582          s->block[s->nblock] = (UChar)ch; s->nblock++;
4583          s->block[s->nblock] = (UChar)ch; s->nblock++;
4584          s->block[s->nblock] = (UChar)ch; s->nblock++;
4585          break;
4586       default:
4587          s->inUse[s->state_in_len-4] = True;
4588          s->block[s->nblock] = (UChar)ch; s->nblock++;
4589          s->block[s->nblock] = (UChar)ch; s->nblock++;
4590          s->block[s->nblock] = (UChar)ch; s->nblock++;
4591          s->block[s->nblock] = (UChar)ch; s->nblock++;
4592          s->block[s->nblock] = ((UChar)(s->state_in_len-4));
4593          s->nblock++;
4594          break;
4595    }
4596 }
4597 
4598 
4599 /*---------------------------------------------------*/
4600 static
flush_RL(EState * s)4601 void flush_RL ( EState* s )
4602 {
4603    if (s->state_in_ch < 256) add_pair_to_block ( s );
4604    init_RL ( s );
4605 }
4606 
4607 
4608 /*---------------------------------------------------*/
4609 #define ADD_CHAR_TO_BLOCK(zs,zchh0)               \
4610 {                                                 \
4611    UInt32 zchh = (UInt32)(zchh0);                 \
4612    /*-- fast track the common case --*/           \
4613    if (zchh != zs->state_in_ch &&                 \
4614        zs->state_in_len == 1) {                   \
4615       UChar ch = (UChar)(zs->state_in_ch);        \
4616       BZ_UPDATE_CRC( zs->blockCRC, ch );          \
4617       zs->inUse[zs->state_in_ch] = True;          \
4618       zs->block[zs->nblock] = (UChar)ch;          \
4619       zs->nblock++;                               \
4620       zs->state_in_ch = zchh;                     \
4621    }                                              \
4622    else                                           \
4623    /*-- general, uncommon cases --*/              \
4624    if (zchh != zs->state_in_ch ||                 \
4625       zs->state_in_len == 255) {                  \
4626       if (zs->state_in_ch < 256)                  \
4627          add_pair_to_block ( zs );                \
4628       zs->state_in_ch = zchh;                     \
4629       zs->state_in_len = 1;                       \
4630    } else {                                       \
4631       zs->state_in_len++;                         \
4632    }                                              \
4633 }
4634 
4635 
4636 /*---------------------------------------------------*/
4637 static
copy_input_until_stop(EState * s)4638 Bool copy_input_until_stop ( EState* s )
4639 {
4640    Bool progress_in = False;
4641 
4642    if (s->mode == BZ_M_RUNNING) {
4643 
4644       /*-- fast track the common case --*/
4645       while (True) {
4646          /*-- block full? --*/
4647          if (s->nblock >= s->nblockMAX) break;
4648          /*-- no input? --*/
4649          if (s->strm->avail_in == 0) break;
4650          progress_in = True;
4651          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
4652          s->strm->next_in++;
4653          s->strm->avail_in--;
4654          s->strm->total_in_lo32++;
4655          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
4656       }
4657 
4658    } else {
4659 
4660       /*-- general, uncommon case --*/
4661       while (True) {
4662          /*-- block full? --*/
4663          if (s->nblock >= s->nblockMAX) break;
4664          /*-- no input? --*/
4665          if (s->strm->avail_in == 0) break;
4666          /*-- flush/finish end? --*/
4667          if (s->avail_in_expect == 0) break;
4668          progress_in = True;
4669          ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
4670          s->strm->next_in++;
4671          s->strm->avail_in--;
4672          s->strm->total_in_lo32++;
4673          if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
4674          s->avail_in_expect--;
4675       }
4676    }
4677    return progress_in;
4678 }
4679 
4680 
4681 /*---------------------------------------------------*/
4682 static
copy_output_until_stop(EState * s)4683 Bool copy_output_until_stop ( EState* s )
4684 {
4685    Bool progress_out = False;
4686 
4687    while (True) {
4688 
4689       /*-- no output space? --*/
4690       if (s->strm->avail_out == 0) break;
4691 
4692       /*-- block done? --*/
4693       if (s->state_out_pos >= s->numZ) break;
4694 
4695       progress_out = True;
4696       *(s->strm->next_out) = s->zbits[s->state_out_pos];
4697       s->state_out_pos++;
4698       s->strm->avail_out--;
4699       s->strm->next_out++;
4700       s->strm->total_out_lo32++;
4701       if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
4702    }
4703 
4704    return progress_out;
4705 }
4706 
4707 
4708 /*---------------------------------------------------*/
4709 static
handle_compress(bz_stream * strm)4710 Bool handle_compress ( bz_stream* strm )
4711 {
4712    Bool progress_in  = False;
4713    Bool progress_out = False;
4714    EState* s = strm->state;
4715 
4716    while (True) {
4717 
4718       if (s->state == BZ_S_OUTPUT) {
4719          progress_out |= copy_output_until_stop ( s );
4720          if (s->state_out_pos < s->numZ) break;
4721          if (s->mode == BZ_M_FINISHING &&
4722              s->avail_in_expect == 0 &&
4723              isempty_RL(s)) break;
4724          prepare_new_block ( s );
4725          s->state = BZ_S_INPUT;
4726          if (s->mode == BZ_M_FLUSHING &&
4727              s->avail_in_expect == 0 &&
4728              isempty_RL(s)) break;
4729       }
4730 
4731       if (s->state == BZ_S_INPUT) {
4732          progress_in |= copy_input_until_stop ( s );
4733          if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
4734             flush_RL ( s );
4735             BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
4736             s->state = BZ_S_OUTPUT;
4737          }
4738          else
4739          if (s->nblock >= s->nblockMAX) {
4740             BZ2_compressBlock ( s, False );
4741             s->state = BZ_S_OUTPUT;
4742          }
4743          else
4744          if (s->strm->avail_in == 0) {
4745             break;
4746          }
4747       }
4748 
4749    }
4750 
4751    return progress_in || progress_out;
4752 }
4753 
4754 
4755 /*---------------------------------------------------*/
BZ_API(BZ2_bzCompress)4756 int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
4757 {
4758    Bool progress;
4759    EState* s;
4760    if (strm == NULL) return BZ_PARAM_ERROR;
4761    s = strm->state;
4762    if (s == NULL) return BZ_PARAM_ERROR;
4763    if (s->strm != strm) return BZ_PARAM_ERROR;
4764 
4765    preswitch:
4766    switch (s->mode) {
4767 
4768       case BZ_M_IDLE:
4769          return BZ_SEQUENCE_ERROR;
4770 
4771       case BZ_M_RUNNING:
4772          if (action == BZ_RUN) {
4773             progress = handle_compress ( strm );
4774             return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
4775          }
4776          else
4777 	 if (action == BZ_FLUSH) {
4778             s->avail_in_expect = strm->avail_in;
4779             s->mode = BZ_M_FLUSHING;
4780             goto preswitch;
4781          }
4782          else
4783          if (action == BZ_FINISH) {
4784             s->avail_in_expect = strm->avail_in;
4785             s->mode = BZ_M_FINISHING;
4786             goto preswitch;
4787          }
4788          else
4789             return BZ_PARAM_ERROR;
4790 
4791       case BZ_M_FLUSHING:
4792          if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
4793          if (s->avail_in_expect != s->strm->avail_in)
4794             return BZ_SEQUENCE_ERROR;
4795          progress = handle_compress ( strm );
4796          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
4797              s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
4798          s->mode = BZ_M_RUNNING;
4799          return BZ_RUN_OK;
4800 
4801       case BZ_M_FINISHING:
4802          if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
4803          if (s->avail_in_expect != s->strm->avail_in)
4804             return BZ_SEQUENCE_ERROR;
4805          progress = handle_compress ( strm );
4806          if (!progress) return BZ_SEQUENCE_ERROR;
4807          if (s->avail_in_expect > 0 || !isempty_RL(s) ||
4808              s->state_out_pos < s->numZ) return BZ_FINISH_OK;
4809          s->mode = BZ_M_IDLE;
4810          return BZ_STREAM_END;
4811    }
4812    return BZ_OK; /*--not reached--*/
4813 }
4814 
4815 
4816 /*---------------------------------------------------*/
BZ_API(BZ2_bzCompressEnd)4817 int BZ_API(BZ2_bzCompressEnd)  ( bz_stream *strm )
4818 {
4819    EState* s;
4820    if (strm == NULL) return BZ_PARAM_ERROR;
4821    s = strm->state;
4822    if (s == NULL) return BZ_PARAM_ERROR;
4823    if (s->strm != strm) return BZ_PARAM_ERROR;
4824 
4825    if (s->arr1 != NULL) BZFREE(s->arr1);
4826    if (s->arr2 != NULL) BZFREE(s->arr2);
4827    if (s->ftab != NULL) BZFREE(s->ftab);
4828    BZFREE(strm->state);
4829 
4830    strm->state = NULL;
4831 
4832    return BZ_OK;
4833 }
4834 
4835 
4836 /*---------------------------------------------------*/
4837 /*--- Decompression stuff                         ---*/
4838 /*---------------------------------------------------*/
4839 
4840 /*---------------------------------------------------*/
BZ_API(BZ2_bzDecompressInit)4841 int BZ_API(BZ2_bzDecompressInit)
4842                      ( bz_stream* strm,
4843                        int        verbosity,
4844                        int        small )
4845 {
4846    DState* s;
4847 
4848    if (!bz_config_ok()) return BZ_CONFIG_ERROR;
4849 
4850    if (strm == NULL) return BZ_PARAM_ERROR;
4851    if (small != 0 && small != 1) return BZ_PARAM_ERROR;
4852    if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
4853 
4854    if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
4855    if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
4856 
4857    s = BZALLOC( sizeof(DState) );
4858    if (s == NULL) return BZ_MEM_ERROR;
4859    s->strm                  = strm;
4860    strm->state              = s;
4861    s->state                 = BZ_X_MAGIC_1;
4862    s->bsLive                = 0;
4863    s->bsBuff                = 0;
4864    s->calculatedCombinedCRC = 0;
4865    strm->total_in_lo32      = 0;
4866    strm->total_in_hi32      = 0;
4867    strm->total_out_lo32     = 0;
4868    strm->total_out_hi32     = 0;
4869    s->smallDecompress       = (Bool)small;
4870    s->ll4                   = NULL;
4871    s->ll16                  = NULL;
4872    s->tt                    = NULL;
4873    s->currBlockNo           = 0;
4874    s->verbosity             = verbosity;
4875 
4876    return BZ_OK;
4877 }
4878 
4879 
4880 /*---------------------------------------------------*/
4881 /* Return  True iff data corruption is discovered.
4882    Returns False if there is no problem.
4883 */
4884 static
unRLE_obuf_to_output_FAST(DState * s)4885 Bool unRLE_obuf_to_output_FAST ( DState* s )
4886 {
4887    UChar k1;
4888 
4889    if (s->blockRandomised) {
4890 
4891       while (True) {
4892          /* try to finish existing run */
4893          while (True) {
4894             if (s->strm->avail_out == 0) return False;
4895             if (s->state_out_len == 0) break;
4896             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
4897             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
4898             s->state_out_len--;
4899             s->strm->next_out++;
4900             s->strm->avail_out--;
4901             s->strm->total_out_lo32++;
4902             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
4903          }
4904 
4905          /* can a new run be started? */
4906          if (s->nblock_used == s->save_nblock+1) return False;
4907 
4908          /* Only caused by corrupt data stream? */
4909          if (s->nblock_used > s->save_nblock+1)
4910             return True;
4911 
4912          s->state_out_len = 1;
4913          s->state_out_ch = s->k0;
4914          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4915          k1 ^= BZ_RAND_MASK; s->nblock_used++;
4916          if (s->nblock_used == s->save_nblock+1) continue;
4917          if (k1 != s->k0) { s->k0 = k1; continue; };
4918 
4919          s->state_out_len = 2;
4920          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4921          k1 ^= BZ_RAND_MASK; s->nblock_used++;
4922          if (s->nblock_used == s->save_nblock+1) continue;
4923          if (k1 != s->k0) { s->k0 = k1; continue; };
4924 
4925          s->state_out_len = 3;
4926          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4927          k1 ^= BZ_RAND_MASK; s->nblock_used++;
4928          if (s->nblock_used == s->save_nblock+1) continue;
4929          if (k1 != s->k0) { s->k0 = k1; continue; };
4930 
4931          BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
4932          k1 ^= BZ_RAND_MASK; s->nblock_used++;
4933          s->state_out_len = ((Int32)k1) + 4;
4934          BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
4935          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
4936       }
4937 
4938    } else {
4939 
4940       /* restore */
4941       UInt32        c_calculatedBlockCRC = s->calculatedBlockCRC;
4942       UChar         c_state_out_ch       = s->state_out_ch;
4943       Int32         c_state_out_len      = s->state_out_len;
4944       Int32         c_nblock_used        = s->nblock_used;
4945       Int32         c_k0                 = s->k0;
4946       UInt32*       c_tt                 = s->tt;
4947       UInt32        c_tPos               = s->tPos;
4948       char*         cs_next_out          = s->strm->next_out;
4949       unsigned int  cs_avail_out         = s->strm->avail_out;
4950       /* end restore */
4951 
4952       UInt32       avail_out_INIT = cs_avail_out;
4953       Int32        s_save_nblockPP = s->save_nblock+1;
4954       unsigned int total_out_lo32_old;
4955 
4956       while (True) {
4957 
4958          /* try to finish existing run */
4959          if (c_state_out_len > 0) {
4960             while (True) {
4961                if (cs_avail_out == 0) goto return_notr;
4962                if (c_state_out_len == 1) break;
4963                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
4964                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
4965                c_state_out_len--;
4966                cs_next_out++;
4967                cs_avail_out--;
4968             }
4969             s_state_out_len_eq_one:
4970             {
4971                if (cs_avail_out == 0) {
4972                   c_state_out_len = 1; goto return_notr;
4973                };
4974                *( (UChar*)(cs_next_out) ) = c_state_out_ch;
4975                BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
4976                cs_next_out++;
4977                cs_avail_out--;
4978             }
4979          }
4980          /* Only caused by corrupt data stream? */
4981          if (c_nblock_used > s_save_nblockPP)
4982             return True;
4983 
4984          /* can a new run be started? */
4985          if (c_nblock_used == s_save_nblockPP) {
4986             c_state_out_len = 0; goto return_notr;
4987          };
4988          c_state_out_ch = c_k0;
4989          BZ_GET_FAST_C(k1); c_nblock_used++;
4990          if (k1 != c_k0) {
4991             c_k0 = k1; goto s_state_out_len_eq_one;
4992          };
4993          if (c_nblock_used == s_save_nblockPP)
4994             goto s_state_out_len_eq_one;
4995 
4996          c_state_out_len = 2;
4997          BZ_GET_FAST_C(k1); c_nblock_used++;
4998          if (c_nblock_used == s_save_nblockPP) continue;
4999          if (k1 != c_k0) { c_k0 = k1; continue; };
5000 
5001          c_state_out_len = 3;
5002          BZ_GET_FAST_C(k1); c_nblock_used++;
5003          if (c_nblock_used == s_save_nblockPP) continue;
5004          if (k1 != c_k0) { c_k0 = k1; continue; };
5005 
5006          BZ_GET_FAST_C(k1); c_nblock_used++;
5007          c_state_out_len = ((Int32)k1) + 4;
5008          BZ_GET_FAST_C(c_k0); c_nblock_used++;
5009       }
5010 
5011       return_notr:
5012       total_out_lo32_old = s->strm->total_out_lo32;
5013       s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
5014       if (s->strm->total_out_lo32 < total_out_lo32_old)
5015          s->strm->total_out_hi32++;
5016 
5017       /* save */
5018       s->calculatedBlockCRC = c_calculatedBlockCRC;
5019       s->state_out_ch       = c_state_out_ch;
5020       s->state_out_len      = c_state_out_len;
5021       s->nblock_used        = c_nblock_used;
5022       s->k0                 = c_k0;
5023       s->tt                 = c_tt;
5024       s->tPos               = c_tPos;
5025       s->strm->next_out     = cs_next_out;
5026       s->strm->avail_out    = cs_avail_out;
5027       /* end save */
5028    }
5029    return False;
5030 }
5031 
5032 
5033 
5034 /*---------------------------------------------------*/
5035 /* Return  True iff data corruption is discovered.
5036    Returns False if there is no problem.
5037 */
5038 static
unRLE_obuf_to_output_SMALL(DState * s)5039 Bool unRLE_obuf_to_output_SMALL ( DState* s )
5040 {
5041    UChar k1;
5042 
5043    if (s->blockRandomised) {
5044 
5045       while (True) {
5046          /* try to finish existing run */
5047          while (True) {
5048             if (s->strm->avail_out == 0) return False;
5049             if (s->state_out_len == 0) break;
5050             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
5051             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
5052             s->state_out_len--;
5053             s->strm->next_out++;
5054             s->strm->avail_out--;
5055             s->strm->total_out_lo32++;
5056             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
5057          }
5058 
5059          /* can a new run be started? */
5060          if (s->nblock_used == s->save_nblock+1) return False;
5061 
5062          /* Only caused by corrupt data stream? */
5063          if (s->nblock_used > s->save_nblock+1)
5064             return True;
5065 
5066          s->state_out_len = 1;
5067          s->state_out_ch = s->k0;
5068          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5069          k1 ^= BZ_RAND_MASK; s->nblock_used++;
5070          if (s->nblock_used == s->save_nblock+1) continue;
5071          if (k1 != s->k0) { s->k0 = k1; continue; };
5072 
5073          s->state_out_len = 2;
5074          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5075          k1 ^= BZ_RAND_MASK; s->nblock_used++;
5076          if (s->nblock_used == s->save_nblock+1) continue;
5077          if (k1 != s->k0) { s->k0 = k1; continue; };
5078 
5079          s->state_out_len = 3;
5080          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5081          k1 ^= BZ_RAND_MASK; s->nblock_used++;
5082          if (s->nblock_used == s->save_nblock+1) continue;
5083          if (k1 != s->k0) { s->k0 = k1; continue; };
5084 
5085          BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
5086          k1 ^= BZ_RAND_MASK; s->nblock_used++;
5087          s->state_out_len = ((Int32)k1) + 4;
5088          BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
5089          s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
5090       }
5091 
5092    } else {
5093 
5094       while (True) {
5095          /* try to finish existing run */
5096          while (True) {
5097             if (s->strm->avail_out == 0) return False;
5098             if (s->state_out_len == 0) break;
5099             *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
5100             BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
5101             s->state_out_len--;
5102             s->strm->next_out++;
5103             s->strm->avail_out--;
5104             s->strm->total_out_lo32++;
5105             if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
5106          }
5107 
5108          /* can a new run be started? */
5109          if (s->nblock_used == s->save_nblock+1) return False;
5110 
5111          /* Only caused by corrupt data stream? */
5112          if (s->nblock_used > s->save_nblock+1)
5113             return True;
5114 
5115          s->state_out_len = 1;
5116          s->state_out_ch = s->k0;
5117          BZ_GET_SMALL(k1); s->nblock_used++;
5118          if (s->nblock_used == s->save_nblock+1) continue;
5119          if (k1 != s->k0) { s->k0 = k1; continue; };
5120 
5121          s->state_out_len = 2;
5122          BZ_GET_SMALL(k1); s->nblock_used++;
5123          if (s->nblock_used == s->save_nblock+1) continue;
5124          if (k1 != s->k0) { s->k0 = k1; continue; };
5125 
5126          s->state_out_len = 3;
5127          BZ_GET_SMALL(k1); s->nblock_used++;
5128          if (s->nblock_used == s->save_nblock+1) continue;
5129          if (k1 != s->k0) { s->k0 = k1; continue; };
5130 
5131          BZ_GET_SMALL(k1); s->nblock_used++;
5132          s->state_out_len = ((Int32)k1) + 4;
5133          BZ_GET_SMALL(s->k0); s->nblock_used++;
5134       }
5135 
5136    }
5137 }
5138 
5139 
5140 /*---------------------------------------------------*/
BZ_API(BZ2_bzDecompress)5141 int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
5142 {
5143    Bool    corrupt;
5144    DState* s;
5145    if (strm == NULL) return BZ_PARAM_ERROR;
5146    s = strm->state;
5147    if (s == NULL) return BZ_PARAM_ERROR;
5148    if (s->strm != strm) return BZ_PARAM_ERROR;
5149 
5150    while (True) {
5151       if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
5152       if (s->state == BZ_X_OUTPUT) {
5153          if (s->smallDecompress)
5154             corrupt = unRLE_obuf_to_output_SMALL ( s ); else
5155             corrupt = unRLE_obuf_to_output_FAST  ( s );
5156          if (corrupt) return BZ_DATA_ERROR;
5157          if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
5158             BZ_FINALISE_CRC ( s->calculatedBlockCRC );
5159             if (s->verbosity >= 3)
5160                VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC,
5161                           s->calculatedBlockCRC );
5162             if (s->verbosity >= 2) VPrintf0 ( "]" );
5163             if (s->calculatedBlockCRC != s->storedBlockCRC)
5164                return BZ_DATA_ERROR;
5165             s->calculatedCombinedCRC
5166                = (s->calculatedCombinedCRC << 1) |
5167                     (s->calculatedCombinedCRC >> 31);
5168             s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
5169             s->state = BZ_X_BLKHDR_1;
5170          } else {
5171             return BZ_OK;
5172          }
5173       }
5174       if (s->state >= BZ_X_MAGIC_1) {
5175          Int32 r = BZ2_decompress ( s );
5176          if (r == BZ_STREAM_END) {
5177             if (s->verbosity >= 3)
5178                VPrintf2 ( "\n    combined CRCs: stored = 0x%08x, computed = 0x%08x",
5179                           s->storedCombinedCRC, s->calculatedCombinedCRC );
5180             if (s->calculatedCombinedCRC != s->storedCombinedCRC)
5181                return BZ_DATA_ERROR;
5182             return r;
5183          }
5184          if (s->state != BZ_X_OUTPUT) return r;
5185       }
5186    }
5187 
5188    AssertH ( 0, 6001 );
5189 
5190    return 0;  /*NOTREACHED*/
5191 }
5192 
5193 
5194 /*---------------------------------------------------*/
BZ_API(BZ2_bzDecompressEnd)5195 int BZ_API(BZ2_bzDecompressEnd)  ( bz_stream *strm )
5196 {
5197    DState* s;
5198    if (strm == NULL) return BZ_PARAM_ERROR;
5199    s = strm->state;
5200    if (s == NULL) return BZ_PARAM_ERROR;
5201    if (s->strm != strm) return BZ_PARAM_ERROR;
5202 
5203    if (s->tt   != NULL) BZFREE(s->tt);
5204    if (s->ll16 != NULL) BZFREE(s->ll16);
5205    if (s->ll4  != NULL) BZFREE(s->ll4);
5206 
5207    BZFREE(strm->state);
5208    strm->state = NULL;
5209 
5210    return BZ_OK;
5211 }
5212 
5213 
5214 #ifndef BZ_NO_STDIO
5215 /*---------------------------------------------------*/
5216 /*--- File I/O stuff                              ---*/
5217 /*---------------------------------------------------*/
5218 
5219 #define BZ_SETERR(eee)                    \
5220 {                                         \
5221    if (bzerror != NULL) *bzerror = eee;   \
5222    if (bzf != NULL) bzf->lastErr = eee;   \
5223 }
5224 
5225 typedef
5226    struct {
5227       FILE*     handle;
5228       Char      buf[BZ_MAX_UNUSED];
5229       Int32     bufN;
5230       Bool      writing;
5231       bz_stream strm;
5232       Int32     lastErr;
5233       Bool      initialisedOk;
5234    }
5235    bzFile;
5236 
5237 
5238 /*---------------------------------------------*/
myfeof(FILE * f)5239 static Bool myfeof ( FILE* f )
5240 {
5241    Int32 c = fgetc ( f );
5242    if (c == EOF) return True;
5243    ungetc ( c, f );
5244    return False;
5245 }
5246 
5247 
5248 /*---------------------------------------------------*/
BZ_API(BZ2_bzWriteOpen)5249 BZFILE* BZ_API(BZ2_bzWriteOpen)
5250                     ( int*  bzerror,
5251                       FILE* f,
5252                       int   blockSize100k,
5253                       int   verbosity,
5254                       int   workFactor )
5255 {
5256    Int32   ret;
5257    bzFile* bzf = NULL;
5258 
5259    BZ_SETERR(BZ_OK);
5260 
5261    if (f == NULL ||
5262        (blockSize100k < 1 || blockSize100k > 9) ||
5263        (workFactor < 0 || workFactor > 250) ||
5264        (verbosity < 0 || verbosity > 4))
5265       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
5266 
5267    if (ferror(f))
5268       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
5269 
5270    bzf = malloc ( sizeof(bzFile) );
5271    if (bzf == NULL)
5272       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
5273 
5274    BZ_SETERR(BZ_OK);
5275    bzf->initialisedOk = False;
5276    bzf->bufN          = 0;
5277    bzf->handle        = f;
5278    bzf->writing       = True;
5279    bzf->strm.bzalloc  = NULL;
5280    bzf->strm.bzfree   = NULL;
5281    bzf->strm.opaque   = NULL;
5282 
5283    if (workFactor == 0) workFactor = 30;
5284    ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
5285                               verbosity, workFactor );
5286    if (ret != BZ_OK)
5287       { BZ_SETERR(ret); free(bzf); return NULL; };
5288 
5289    bzf->strm.avail_in = 0;
5290    bzf->initialisedOk = True;
5291    return bzf;
5292 }
5293 
5294 
5295 
5296 /*---------------------------------------------------*/
BZ_API(BZ2_bzWrite)5297 void BZ_API(BZ2_bzWrite)
5298              ( int*    bzerror,
5299                BZFILE* b,
5300                void*   buf,
5301                int     len )
5302 {
5303    Int32 n, n2, ret;
5304    bzFile* bzf = (bzFile*)b;
5305 
5306    BZ_SETERR(BZ_OK);
5307    if (bzf == NULL || buf == NULL || len < 0)
5308       { BZ_SETERR(BZ_PARAM_ERROR); return; };
5309    if (!(bzf->writing))
5310       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5311    if (ferror(bzf->handle))
5312       { BZ_SETERR(BZ_IO_ERROR); return; };
5313 
5314    if (len == 0)
5315       { BZ_SETERR(BZ_OK); return; };
5316 
5317    bzf->strm.avail_in = len;
5318    bzf->strm.next_in  = buf;
5319 
5320    while (True) {
5321       bzf->strm.avail_out = BZ_MAX_UNUSED;
5322       bzf->strm.next_out = bzf->buf;
5323       ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
5324       if (ret != BZ_RUN_OK)
5325          { BZ_SETERR(ret); return; };
5326 
5327       if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
5328          n = BZ_MAX_UNUSED - bzf->strm.avail_out;
5329          n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
5330                        n, bzf->handle );
5331          if (n != n2 || ferror(bzf->handle))
5332             { BZ_SETERR(BZ_IO_ERROR); return; };
5333       }
5334 
5335       if (bzf->strm.avail_in == 0)
5336          { BZ_SETERR(BZ_OK); return; };
5337    }
5338 }
5339 
5340 
5341 /*---------------------------------------------------*/
BZ_API(BZ2_bzWriteClose)5342 void BZ_API(BZ2_bzWriteClose)
5343                   ( int*          bzerror,
5344                     BZFILE*       b,
5345                     int           abandon,
5346                     unsigned int* nbytes_in,
5347                     unsigned int* nbytes_out )
5348 {
5349    BZ2_bzWriteClose64 ( bzerror, b, abandon,
5350                         nbytes_in, NULL, nbytes_out, NULL );
5351 }
5352 
5353 
BZ_API(BZ2_bzWriteClose64)5354 void BZ_API(BZ2_bzWriteClose64)
5355                   ( int*          bzerror,
5356                     BZFILE*       b,
5357                     int           abandon,
5358                     unsigned int* nbytes_in_lo32,
5359                     unsigned int* nbytes_in_hi32,
5360                     unsigned int* nbytes_out_lo32,
5361                     unsigned int* nbytes_out_hi32 )
5362 {
5363    Int32   n, n2, ret;
5364    bzFile* bzf = (bzFile*)b;
5365 
5366    if (bzf == NULL)
5367       { BZ_SETERR(BZ_OK); return; };
5368    if (!(bzf->writing))
5369       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5370    if (ferror(bzf->handle))
5371       { BZ_SETERR(BZ_IO_ERROR); return; };
5372 
5373    if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
5374    if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
5375    if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
5376    if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
5377 
5378    if ((!abandon) && bzf->lastErr == BZ_OK) {
5379       while (True) {
5380          bzf->strm.avail_out = BZ_MAX_UNUSED;
5381          bzf->strm.next_out = bzf->buf;
5382          ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
5383          if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
5384             { BZ_SETERR(ret); return; };
5385 
5386          if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
5387             n = BZ_MAX_UNUSED - bzf->strm.avail_out;
5388             n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
5389                           n, bzf->handle );
5390             if (n != n2 || ferror(bzf->handle))
5391                { BZ_SETERR(BZ_IO_ERROR); return; };
5392          }
5393 
5394          if (ret == BZ_STREAM_END) break;
5395       }
5396    }
5397 
5398    if ( !abandon && !ferror ( bzf->handle ) ) {
5399       fflush ( bzf->handle );
5400       if (ferror(bzf->handle))
5401          { BZ_SETERR(BZ_IO_ERROR); return; };
5402    }
5403 
5404    if (nbytes_in_lo32 != NULL)
5405       *nbytes_in_lo32 = bzf->strm.total_in_lo32;
5406    if (nbytes_in_hi32 != NULL)
5407       *nbytes_in_hi32 = bzf->strm.total_in_hi32;
5408    if (nbytes_out_lo32 != NULL)
5409       *nbytes_out_lo32 = bzf->strm.total_out_lo32;
5410    if (nbytes_out_hi32 != NULL)
5411       *nbytes_out_hi32 = bzf->strm.total_out_hi32;
5412 
5413    BZ_SETERR(BZ_OK);
5414    BZ2_bzCompressEnd ( &(bzf->strm) );
5415    free ( bzf );
5416 }
5417 
5418 
5419 /*---------------------------------------------------*/
BZ_API(BZ2_bzReadOpen)5420 BZFILE* BZ_API(BZ2_bzReadOpen)
5421                    ( int*  bzerror,
5422                      FILE* f,
5423                      int   verbosity,
5424                      int   small,
5425                      void* unused,
5426                      int   nUnused )
5427 {
5428    bzFile* bzf = NULL;
5429    int     ret;
5430 
5431    BZ_SETERR(BZ_OK);
5432 
5433    if (f == NULL ||
5434        (small != 0 && small != 1) ||
5435        (verbosity < 0 || verbosity > 4) ||
5436        (unused == NULL && nUnused != 0) ||
5437        (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
5438       { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
5439 
5440    if (ferror(f))
5441       { BZ_SETERR(BZ_IO_ERROR); return NULL; };
5442 
5443    bzf = malloc ( sizeof(bzFile) );
5444    if (bzf == NULL)
5445       { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
5446 
5447    BZ_SETERR(BZ_OK);
5448 
5449    bzf->initialisedOk = False;
5450    bzf->handle        = f;
5451    bzf->bufN          = 0;
5452    bzf->writing       = False;
5453    bzf->strm.bzalloc  = NULL;
5454    bzf->strm.bzfree   = NULL;
5455    bzf->strm.opaque   = NULL;
5456 
5457    while (nUnused > 0) {
5458       bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
5459       unused = ((void*)( 1 + ((UChar*)(unused))  ));
5460       nUnused--;
5461    }
5462 
5463    ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
5464    if (ret != BZ_OK)
5465       { BZ_SETERR(ret); free(bzf); return NULL; };
5466 
5467    bzf->strm.avail_in = bzf->bufN;
5468    bzf->strm.next_in  = bzf->buf;
5469 
5470    bzf->initialisedOk = True;
5471    return bzf;
5472 }
5473 
5474 
5475 /*---------------------------------------------------*/
BZ_API(BZ2_bzReadClose)5476 void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
5477 {
5478    bzFile* bzf = (bzFile*)b;
5479 
5480    BZ_SETERR(BZ_OK);
5481    if (bzf == NULL)
5482       { BZ_SETERR(BZ_OK); return; };
5483 
5484    if (bzf->writing)
5485       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5486 
5487    if (bzf->initialisedOk)
5488       (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
5489    free ( bzf );
5490 }
5491 
5492 
5493 /*---------------------------------------------------*/
BZ_API(BZ2_bzRead)5494 int BZ_API(BZ2_bzRead)
5495            ( int*    bzerror,
5496              BZFILE* b,
5497              void*   buf,
5498              int     len )
5499 {
5500    Int32   n, ret;
5501    bzFile* bzf = (bzFile*)b;
5502 
5503    BZ_SETERR(BZ_OK);
5504 
5505    if (bzf == NULL || buf == NULL || len < 0)
5506       { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
5507 
5508    if (bzf->writing)
5509       { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
5510 
5511    if (len == 0)
5512       { BZ_SETERR(BZ_OK); return 0; };
5513 
5514    bzf->strm.avail_out = len;
5515    bzf->strm.next_out = buf;
5516 
5517    while (True) {
5518 
5519       if (ferror(bzf->handle))
5520          { BZ_SETERR(BZ_IO_ERROR); return 0; };
5521 
5522       if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
5523          n = fread ( bzf->buf, sizeof(UChar),
5524                      BZ_MAX_UNUSED, bzf->handle );
5525          if (ferror(bzf->handle))
5526             { BZ_SETERR(BZ_IO_ERROR); return 0; };
5527          bzf->bufN = n;
5528          bzf->strm.avail_in = bzf->bufN;
5529          bzf->strm.next_in = bzf->buf;
5530       }
5531 
5532       ret = BZ2_bzDecompress ( &(bzf->strm) );
5533 
5534       if (ret != BZ_OK && ret != BZ_STREAM_END)
5535          { BZ_SETERR(ret); return 0; };
5536 
5537       if (ret == BZ_OK && myfeof(bzf->handle) &&
5538           bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
5539          { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
5540 
5541       if (ret == BZ_STREAM_END)
5542          { BZ_SETERR(BZ_STREAM_END);
5543            return len - bzf->strm.avail_out; };
5544       if (bzf->strm.avail_out == 0)
5545          { BZ_SETERR(BZ_OK); return len; };
5546 
5547    }
5548 
5549    return 0; /*not reached*/
5550 }
5551 
5552 
5553 /*---------------------------------------------------*/
BZ_API(BZ2_bzReadGetUnused)5554 void BZ_API(BZ2_bzReadGetUnused)
5555                      ( int*    bzerror,
5556                        BZFILE* b,
5557                        void**  unused,
5558                        int*    nUnused )
5559 {
5560    bzFile* bzf = (bzFile*)b;
5561    if (bzf == NULL)
5562       { BZ_SETERR(BZ_PARAM_ERROR); return; };
5563    if (bzf->lastErr != BZ_STREAM_END)
5564       { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
5565    if (unused == NULL || nUnused == NULL)
5566       { BZ_SETERR(BZ_PARAM_ERROR); return; };
5567 
5568    BZ_SETERR(BZ_OK);
5569    *nUnused = bzf->strm.avail_in;
5570    *unused = bzf->strm.next_in;
5571 }
5572 #endif
5573 
5574 
5575 /*---------------------------------------------------*/
5576 /*--- Misc convenience stuff                      ---*/
5577 /*---------------------------------------------------*/
5578 
5579 /*---------------------------------------------------*/
BZ_API(BZ2_bzBuffToBuffCompress)5580 int BZ_API(BZ2_bzBuffToBuffCompress)
5581                          ( char*         dest,
5582                            unsigned int* destLen,
5583                            char*         source,
5584                            unsigned int  sourceLen,
5585                            int           blockSize100k,
5586                            int           verbosity,
5587                            int           workFactor )
5588 {
5589    bz_stream strm;
5590    int ret;
5591 
5592    if (dest == NULL || destLen == NULL ||
5593        source == NULL ||
5594        blockSize100k < 1 || blockSize100k > 9 ||
5595        verbosity < 0 || verbosity > 4 ||
5596        workFactor < 0 || workFactor > 250)
5597       return BZ_PARAM_ERROR;
5598 
5599    if (workFactor == 0) workFactor = 30;
5600    strm.bzalloc = NULL;
5601    strm.bzfree = NULL;
5602    strm.opaque = NULL;
5603    ret = BZ2_bzCompressInit ( &strm, blockSize100k,
5604                               verbosity, workFactor );
5605    if (ret != BZ_OK) return ret;
5606 
5607    strm.next_in = source;
5608    strm.next_out = dest;
5609    strm.avail_in = sourceLen;
5610    strm.avail_out = *destLen;
5611 
5612    ret = BZ2_bzCompress ( &strm, BZ_FINISH );
5613    if (ret == BZ_FINISH_OK) goto output_overflow;
5614    if (ret != BZ_STREAM_END) goto errhandler;
5615 
5616    /* normal termination */
5617    *destLen -= strm.avail_out;
5618    BZ2_bzCompressEnd ( &strm );
5619    return BZ_OK;
5620 
5621    output_overflow:
5622    BZ2_bzCompressEnd ( &strm );
5623    return BZ_OUTBUFF_FULL;
5624 
5625    errhandler:
5626    BZ2_bzCompressEnd ( &strm );
5627    return ret;
5628 }
5629 
5630 
5631 /*---------------------------------------------------*/
BZ_API(BZ2_bzBuffToBuffDecompress)5632 int BZ_API(BZ2_bzBuffToBuffDecompress)
5633                            ( char*         dest,
5634                              unsigned int* destLen,
5635                              char*         source,
5636                              unsigned int  sourceLen,
5637                              int           small,
5638                              int           verbosity )
5639 {
5640    bz_stream strm;
5641    int ret;
5642 
5643    if (dest == NULL || destLen == NULL ||
5644        source == NULL ||
5645        (small != 0 && small != 1) ||
5646        verbosity < 0 || verbosity > 4)
5647           return BZ_PARAM_ERROR;
5648 
5649    strm.bzalloc = NULL;
5650    strm.bzfree = NULL;
5651    strm.opaque = NULL;
5652    ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
5653    if (ret != BZ_OK) return ret;
5654 
5655    strm.next_in = source;
5656    strm.next_out = dest;
5657    strm.avail_in = sourceLen;
5658    strm.avail_out = *destLen;
5659 
5660    ret = BZ2_bzDecompress ( &strm );
5661    if (ret == BZ_OK) goto output_overflow_or_eof;
5662    if (ret != BZ_STREAM_END) goto errhandler;
5663 
5664    /* normal termination */
5665    *destLen -= strm.avail_out;
5666    BZ2_bzDecompressEnd ( &strm );
5667    return BZ_OK;
5668 
5669    output_overflow_or_eof:
5670    if (strm.avail_out > 0) {
5671       BZ2_bzDecompressEnd ( &strm );
5672       return BZ_UNEXPECTED_EOF;
5673    } else {
5674       BZ2_bzDecompressEnd ( &strm );
5675       return BZ_OUTBUFF_FULL;
5676    };
5677 
5678    errhandler:
5679    BZ2_bzDecompressEnd ( &strm );
5680    return ret;
5681 }
5682 
5683 
5684 /*---------------------------------------------------*/
5685 /*--
5686    Code contributed by Yoshioka Tsuneo
5687    (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
5688    to support better zlib compatibility.
5689    This code is not _officially_ part of libbzip2 (yet);
5690    I haven't tested it, documented it, or considered the
5691    threading-safeness of it.
5692    If this code breaks, please contact both Yoshioka and me.
5693 --*/
5694 /*---------------------------------------------------*/
5695 
5696 /*---------------------------------------------------*/
5697 /*--
5698    return version like "0.9.0c".
5699 --*/
BZ_API(BZ2_bzlibVersion)5700 const char * BZ_API(BZ2_bzlibVersion)(void)
5701 {
5702    return BZ_VERSION;
5703 }
5704 
5705 
5706 #ifndef BZ_NO_STDIO
5707 /*---------------------------------------------------*/
5708 
5709 #if defined(_WIN32) || defined(OS2) || defined(MSDOS)
5710 #   include <fcntl.h>
5711 #   include <io.h>
5712 #   define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
5713 #else
5714 #   define SET_BINARY_MODE(file)
5715 #endif
5716 static
bzopen_or_bzdopen(const char * path,int fd,const char * mode,int open_mode)5717 BZFILE * bzopen_or_bzdopen
5718                ( const char *path,   /* no use when bzdopen */
5719                  int fd,             /* no use when bzdopen */
5720                  const char *mode,
5721                  int open_mode)      /* bzopen: 0, bzdopen:1 */
5722 {
5723    int    bzerr;
5724    char   unused[BZ_MAX_UNUSED];
5725    int    blockSize100k = 9;
5726    int    writing       = 0;
5727    char   mode2[10]     = "";
5728    FILE   *fp           = NULL;
5729    BZFILE *bzfp         = NULL;
5730    int    verbosity     = 0;
5731    int    workFactor    = 30;
5732    int    smallMode     = 0;
5733    int    nUnused       = 0;
5734 
5735    if (mode == NULL) return NULL;
5736    while (*mode) {
5737       switch (*mode) {
5738       case 'r':
5739          writing = 0; break;
5740       case 'w':
5741          writing = 1; break;
5742       case 's':
5743          smallMode = 1; break;
5744       default:
5745          if (isdigit((int)(*mode))) {
5746             blockSize100k = *mode-BZ_HDR_0;
5747          }
5748       }
5749       mode++;
5750    }
5751    strcat(mode2, writing ? "w" : "r" );
5752    strcat(mode2,"b");   /* binary mode */
5753 
5754    if (open_mode==0) {
5755       if (path==NULL || strcmp(path,"")==0) {
5756         fp = (writing ? stdout : stdin);
5757         SET_BINARY_MODE(fp);
5758       } else {
5759         fp = fopen(path,mode2);
5760       }
5761    } else {
5762 #ifdef BZ_STRICT_ANSI
5763       fp = NULL;
5764 #else
5765       fp = fdopen(fd,mode2);
5766 #endif
5767    }
5768    if (fp == NULL) return NULL;
5769 
5770    if (writing) {
5771       /* Guard against total chaos and anarchy -- JRS */
5772       if (blockSize100k < 1) blockSize100k = 1;
5773       if (blockSize100k > 9) blockSize100k = 9;
5774       bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
5775                              verbosity,workFactor);
5776    } else {
5777       bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
5778                             unused,nUnused);
5779    }
5780    if (bzfp == NULL) {
5781       if (fp != stdin && fp != stdout) fclose(fp);
5782       return NULL;
5783    }
5784    return bzfp;
5785 }
5786 
5787 
5788 /*---------------------------------------------------*/
5789 /*--
5790    open file for read or write.
5791       ex) bzopen("file","w9")
5792       case path="" or NULL => use stdin or stdout.
5793 --*/
BZ_API(BZ2_bzopen)5794 BZFILE * BZ_API(BZ2_bzopen)
5795                ( const char *path,
5796                  const char *mode )
5797 {
5798    return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
5799 }
5800 
5801 
5802 /*---------------------------------------------------*/
BZ_API(BZ2_bzdopen)5803 BZFILE * BZ_API(BZ2_bzdopen)
5804                ( int fd,
5805                  const char *mode )
5806 {
5807    return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
5808 }
5809 
5810 
5811 /*---------------------------------------------------*/
BZ_API(BZ2_bzread)5812 int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
5813 {
5814    int bzerr, nread;
5815    if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
5816    nread = BZ2_bzRead(&bzerr,b,buf,len);
5817    if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
5818       return nread;
5819    } else {
5820       return -1;
5821    }
5822 }
5823 
5824 
5825 /*---------------------------------------------------*/
BZ_API(BZ2_bzwrite)5826 int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
5827 {
5828    int bzerr;
5829 
5830    BZ2_bzWrite(&bzerr,b,buf,len);
5831    if(bzerr == BZ_OK){
5832       return len;
5833    }else{
5834       return -1;
5835    }
5836 }
5837 
5838 
5839 /*---------------------------------------------------*/
BZ_API(BZ2_bzflush)5840 int BZ_API(BZ2_bzflush) (BZFILE *b)
5841 {
5842    /* do nothing now... */
5843    return 0;
5844 }
5845 
5846 
5847 /*---------------------------------------------------*/
BZ_API(BZ2_bzclose)5848 void BZ_API(BZ2_bzclose) (BZFILE* b)
5849 {
5850    int bzerr;
5851    FILE *fp = ((bzFile *)b)->handle;
5852 
5853    if (b==NULL) {return;}
5854    if(((bzFile*)b)->writing){
5855       BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
5856       if(bzerr != BZ_OK){
5857          BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
5858       }
5859    }else{
5860       BZ2_bzReadClose(&bzerr,b);
5861    }
5862    if(fp!=stdin && fp!=stdout){
5863       fclose(fp);
5864    }
5865 }
5866 
5867 
5868 /*---------------------------------------------------*/
5869 /*--
5870    return last error code
5871 --*/
5872 static char *bzerrorstrings[] = {
5873        "OK"
5874       ,"SEQUENCE_ERROR"
5875       ,"PARAM_ERROR"
5876       ,"MEM_ERROR"
5877       ,"DATA_ERROR"
5878       ,"DATA_ERROR_MAGIC"
5879       ,"IO_ERROR"
5880       ,"UNEXPECTED_EOF"
5881       ,"OUTBUFF_FULL"
5882       ,"CONFIG_ERROR"
5883       ,"???"   /* for future */
5884       ,"???"   /* for future */
5885       ,"???"   /* for future */
5886       ,"???"   /* for future */
5887       ,"???"   /* for future */
5888       ,"???"   /* for future */
5889 };
5890 
5891 
BZ_API(BZ2_bzerror)5892 const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
5893 {
5894    int err = ((bzFile *)b)->lastErr;
5895 
5896    if(err>0) err = 0;
5897    *errnum = err;
5898    return bzerrorstrings[err*-1];
5899 }
5900 #endif
5901 
5902 
5903 /*-------------------------------------------------------------*/
5904 /*--- end                                           bzlib.c ---*/
5905 /*-------------------------------------------------------------*/
5906 
5907 
5908 /////////////////////////////////////////////////////////////////////
5909 /////////////////////////////////////////////////////////////////////
5910 
5911 
5912 /* A test program written to test robustness to decompression of
5913    corrupted data.  Usage is
5914        unzcrash filename
5915    and the program will read the specified file, compress it (in memory),
5916    and then repeatedly decompress it, each time with a different bit of
5917    the compressed data inverted, so as to test all possible one-bit errors.
5918    This should not cause any invalid memory accesses.  If it does,
5919    I want to know about it!
5920 
5921    p.s.  As you can see from the above description, the process is
5922    incredibly slow.  A file of size eg 5KB will cause it to run for
5923    many hours.
5924 */
5925 
5926 //#include <stdio.h>
5927 //#include <assert.h>
5928 //#include "bzlib.h"
5929 
5930 #define M_BLOCK 1000000
5931 
5932 typedef unsigned char uchar;
5933 
5934 #define M_BLOCK_OUT (M_BLOCK + 1000000)
5935 uchar inbuf[M_BLOCK];
5936 uchar outbuf[M_BLOCK_OUT];
5937 uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];
5938 
5939 int nIn, nOut, nZ;
5940 
5941 static char *bzerrorstrings[] = {
5942        "OK"
5943       ,"SEQUENCE_ERROR"
5944       ,"PARAM_ERROR"
5945       ,"MEM_ERROR"
5946       ,"DATA_ERROR"
5947       ,"DATA_ERROR_MAGIC"
5948       ,"IO_ERROR"
5949       ,"UNEXPECTED_EOF"
5950       ,"OUTBUFF_FULL"
5951       ,"???"   /* for future */
5952       ,"???"   /* for future */
5953       ,"???"   /* for future */
5954       ,"???"   /* for future */
5955       ,"???"   /* for future */
5956       ,"???"   /* for future */
5957 };
5958 
flip_bit(int bit)5959 void flip_bit ( int bit )
5960 {
5961    int byteno = bit / 8;
5962    int bitno  = bit % 8;
5963    uchar mask = 1 << bitno;
5964    //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
5965    //          byteno, bitno, (int)mask );
5966    zbuf[byteno] ^= mask;
5967 }
5968 
set_inbuf(void)5969 void set_inbuf ( void )
5970 {
5971   inbuf[0] = 0;
5972   my_strcat(inbuf, "At her sixtieth birthday party, Margaret Thatcher ");
5973   my_strcat(inbuf, "blew on the cake to light the candles.\n");
5974   my_strcat(inbuf, "This program, bzip2, the associated library libbzip2, and all\n");
5975   my_strcat(inbuf, "documentation, are copyright (C) 1996-2004 Julian R Seward.  All\n");
5976   my_strcat(inbuf, "rights reserved.\n");
5977   my_strcat(inbuf, "\n");
5978   my_strcat(inbuf, "Redistribution and use in source and binary forms, with or without\n");
5979   my_strcat(inbuf, "modification, are permitted provided that the following conditions\n");
5980   my_strcat(inbuf, "are met:\n");
5981   my_strcat(inbuf, "\n");
5982   my_strcat(inbuf, "1. Redistributions of source code must retain the above copyright\n");
5983   my_strcat(inbuf, "   notice, this list of conditions and the following disclaimer.\n");
5984   my_strcat(inbuf, "\n");
5985   my_strcat(inbuf, "2. The origin of this software must not be misrepresented; you must\n");
5986   my_strcat(inbuf, "   not claim that you wrote the original software.  If you use this\n");
5987   my_strcat(inbuf, "   software in a product, an acknowledgment in the product\n");
5988   my_strcat(inbuf, "   documentation would be appreciated but is not required.\n");
5989   my_strcat(inbuf, "\n");
5990   my_strcat(inbuf, "3. Altered source versions must be plainly marked as such, and must\n");
5991   my_strcat(inbuf, "   not be misrepresented as being the original software.\n");
5992   my_strcat(inbuf, "\n");
5993   my_strcat(inbuf, "4. The name of the author may not be used to endorse or promote\n");
5994   my_strcat(inbuf, "   products derived from this software without specific prior written\n");
5995   my_strcat(inbuf, "   permission.\n");
5996   my_strcat(inbuf, "\n");
5997   my_strcat(inbuf, "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n");
5998   my_strcat(inbuf, "OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n");
5999   my_strcat(inbuf, "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n");
6000   my_strcat(inbuf, "ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n");
6001   my_strcat(inbuf, "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n");
6002   my_strcat(inbuf, "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n");
6003   my_strcat(inbuf, "GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n");
6004   my_strcat(inbuf, "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n");
6005   my_strcat(inbuf, "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n");
6006   my_strcat(inbuf, "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n");
6007   my_strcat(inbuf, "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n");
6008   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6009   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6010   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6011   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6012   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6013   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6014   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6015   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6016   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6017   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6018   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6019   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6020   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6021   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6022   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6023   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6024   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6025   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6026   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6027   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6028   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6029   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6030   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6031   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6032   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6033   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6034   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6035   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6036   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6037   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6038   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6039   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6040   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6041   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6042   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6043   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6044   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6045   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6046   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6047   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6048   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6049   my_strcat(inbuf, "ababababababababababababababababababababababababababababababab");
6050   my_strcat(inbuf, "\n");
6051 }
6052 
6053 
entry(HWord (* service)(HWord,HWord))6054 void entry ( HWord(*service)(HWord,HWord) )
6055 {
6056    int   r;
6057    int   bit;
6058    int   i;
6059 
6060    serviceFn = service;
6061 
6062    set_inbuf();
6063    nIn = vexxx_strlen(inbuf)+1;
6064    vexxx_printf( "%d bytes read\n", nIn );
6065 
6066    nZ = M_BLOCK;
6067    r = BZ2_bzBuffToBuffCompress (
6068           zbuf, &nZ, inbuf, nIn, 9, 4/*verb*/, 30 );
6069 
6070    if (r != BZ_OK) {
6071      vexxx_printf("initial compress failed!\n");
6072      (*serviceFn)(0,0);
6073    }
6074    vexxx_printf( "%d after compression\n", nZ );
6075 
6076    for (bit = 0; bit < nZ*8; bit += (bit < 35 ? 1 : 377)) {
6077       vexxx_printf( "bit %d  ", bit );
6078       flip_bit ( bit );
6079       nOut = M_BLOCK_OUT;
6080       r = BZ2_bzBuffToBuffDecompress (
6081              outbuf, &nOut, zbuf, nZ, 1/*small*/, 0 );
6082       vexxx_printf( " %d  %s ", r, bzerrorstrings[-r] );
6083 
6084       if (r != BZ_OK) {
6085          vexxx_printf( "\n" );
6086       } else {
6087          if (nOut != nIn) {
6088            vexxx_printf(  "nIn/nOut mismatch %d %d\n", nIn, nOut );
6089            (*serviceFn)(0,0);
6090          } else {
6091            for (i = 0; i < nOut; i++)
6092              if (inbuf[i] != outbuf[i]) {
6093                 vexxx_printf(  "mismatch at %d\n", i );
6094                 (*serviceFn)(0,0);
6095            }
6096            if (i == nOut) vexxx_printf( "really ok!\n" );
6097          }
6098       }
6099 
6100       flip_bit ( bit );
6101    }
6102 
6103 #if 0
6104    assert (nOut == nIn);
6105    for (i = 0; i < nOut; i++) {
6106      if (inbuf[i] != outbuf[i]) {
6107         vexxx_printf( "difference at %d !\n", i );
6108         return 1;
6109      }
6110    }
6111 #endif
6112 
6113    vexxx_printf( "all ok\n" );
6114    (*serviceFn)(0,0);
6115 }
6116