[Cmake-commits] [cmake-commits] hoffman committed CHANGES NONE 1.1 CMakeLists.txt NONE 1.1 LICENSE NONE 1.1 Makefile NONE 1.1 Makefile-libbz2_so NONE 1.1 README NONE 1.1 README.COMPILATION.PROBLEMS NONE 1.1 README.XML.STUFF NONE 1.1 blocksort.c NONE 1.1 bz-common.xsl NONE 1.1 bz-fo.xsl NONE 1.1 bz-html.xsl NONE 1.1 bzdiff NONE 1.1 bzdiff.1 NONE 1.1 bzgrep NONE 1.1 bzgrep.1 NONE 1.1 bzip.css NONE 1.1 bzip2.1 NONE 1.1 bzip2.1.preformatted NONE 1.1 bzip2.c NONE 1.1 bzip2.txt NONE 1.1 bzip2recover.c NONE 1.1 bzlib.c NONE 1.1 bzlib.h NONE 1.1 bzlib_private.h NONE 1.1 bzmore NONE 1.1 bzmore.1 NONE 1.1 compress.c NONE 1.1 crctable.c NONE 1.1 decompress.c NONE 1.1 dlltest.c NONE 1.1 dlltest.dsp NONE 1.1 entities.xml NONE 1.1 format.pl NONE 1.1 huffman.c NONE 1.1 libbz2.def NONE 1.1 libbz2.dsp NONE 1.1 libbz2.lib NONE 1.1 makefile.msc NONE 1.1 manual.html NONE 1.1 manual.pdf NONE 1.1 manual.ps NONE 1.1 manual.xml NONE 1.1 mk251.c NONE 1.1 randtable.c NONE 1.1 sample1.bz2 NONE 1.1 sample1.rb2 NONE 1.1 sample1.ref NONE 1.1 sample1.tst NONE 1.1 sample2.bz2 NONE 1.1 sample2.rb2 NONE 1.1 sample2.ref NONE 1.1 sample2.tst NONE 1.1 sample3.bz2 NONE 1.1 sample3.rb2 NONE 1.1 sample3.ref NONE 1.1 sample3.tst NONE 1.1 spewG.c NONE 1.1 unzcrash.c NONE 1.1 words0 NONE 1.1 words1 NONE 1.1 words2 NONE 1.1 words3 NONE 1.1 xmlproc.sh NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Fri Oct 30 13:09:08 EDT 2009


Update of /cvsroot/CMake/CMake/Utilities/cmbzip2
In directory public:/mounts/ram/cvs-serv26614/Utilities/cmbzip2

Added Files:
	CHANGES CMakeLists.txt LICENSE Makefile Makefile-libbz2_so 
	README README.COMPILATION.PROBLEMS README.XML.STUFF 
	blocksort.c bz-common.xsl bz-fo.xsl bz-html.xsl bzdiff 
	bzdiff.1 bzgrep bzgrep.1 bzip.css bzip2.1 bzip2.1.preformatted 
	bzip2.c bzip2.txt bzip2recover.c bzlib.c bzlib.h 
	bzlib_private.h bzmore bzmore.1 compress.c crctable.c 
	decompress.c dlltest.c dlltest.dsp entities.xml format.pl 
	huffman.c libbz2.def libbz2.dsp libbz2.lib makefile.msc 
	manual.html manual.pdf manual.ps manual.xml mk251.c 
	randtable.c sample1.bz2 sample1.rb2 sample1.ref sample1.tst 
	sample2.bz2 sample2.rb2 sample2.ref sample2.tst sample3.bz2 
	sample3.rb2 sample3.ref sample3.tst spewG.c unzcrash.c words0 
	words1 words2 words3 xmlproc.sh 
Log Message:
Switch to using libarchive from libtar for cpack and cmake -E tar

This allows for a built in bzip and zip capability, so external tools 
will not be needed for these packagers.  The cmake -E tar xf should be
able to handle all compression types now as well.



--- NEW FILE: manual.pdf ---
%PDF-1.4
5 0 obj
<< /S /GoTo /D (userman.1) >>
endobj
8 0 obj
(bzip2 and libbzip2, version 1.0.5)
endobj
9 0 obj
<< /S /GoTo /D (intro.2) >>
endobj
12 0 obj
(Introduction)
endobj
13 0 obj
<< /S /GoTo /D (using.2) >>
endobj
16 0 obj
(How to use bzip2)
endobj
[...4924 lines suppressed...]
0000265456 00000 n 
0000266627 00000 n 
0000266745 00000 n 
0000266822 00000 n 
0000266892 00000 n 
0000269341 00000 n 
0000274103 00000 n 
0000274142 00000 n 
0000274180 00000 n 
0000274310 00000 n 
trailer
<<
/Size 671
/Root 669 0 R
/Info 670 0 R
/ID [<3DC7B7C1C1466948A580D8F6BD788550> <3DC7B7C1C1466948A580D8F6BD788550>]
>>
startxref
274555
%%EOF

--- NEW FILE: unzcrash.c ---

/* A test program written to test robustness to decompression of
   corrupted data.  Usage is 
       unzcrash filename
   and the program will read the specified file, compress it (in memory),
   and then repeatedly decompress it, each time with a different bit of
   the compressed data inverted, so as to test all possible one-bit errors.
   This should not cause any invalid memory accesses.  If it does, 
   I want to know about it!

   PS.  As you can see from the above description, the process is
   incredibly slow.  A file of size eg 5KB will cause it to run for
   many hours.
*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#include <stdio.h>
#include <assert.h>
#include "bzlib.h"

#define M_BLOCK 1000000

typedef unsigned char uchar;

#define M_BLOCK_OUT (M_BLOCK + 1000000)
uchar inbuf[M_BLOCK];
uchar outbuf[M_BLOCK_OUT];
uchar zbuf[M_BLOCK + 600 + (M_BLOCK / 100)];

int nIn, nOut, nZ;

static char *bzerrorstrings[] = {
       "OK"
      ,"SEQUENCE_ERROR"
      ,"PARAM_ERROR"
      ,"MEM_ERROR"
      ,"DATA_ERROR"
      ,"DATA_ERROR_MAGIC"
      ,"IO_ERROR"
      ,"UNEXPECTED_EOF"
      ,"OUTBUFF_FULL"
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
};

void flip_bit ( int bit )
{
   int byteno = bit / 8;
   int bitno  = bit % 8;
   uchar mask = 1 << bitno;
   //fprintf ( stderr, "(byte %d  bit %d  mask %d)",
   //          byteno, bitno, (int)mask );
   zbuf[byteno] ^= mask;
}

int main ( int argc, char** argv )
{
   FILE* f;
   int   r;
   int   bit;
   int   i;

   if (argc != 2) {
      fprintf ( stderr, "usage: unzcrash filename\n" );
      return 1;
   }

   f = fopen ( argv[1], "r" );
   if (!f) {
      fprintf ( stderr, "unzcrash: can't open %s\n", argv[1] );
      return 1;
   }

   nIn = fread ( inbuf, 1, M_BLOCK, f );
   fprintf ( stderr, "%d bytes read\n", nIn );

   nZ = M_BLOCK;
   r = BZ2_bzBuffToBuffCompress (
         zbuf, &nZ, inbuf, nIn, 9, 0, 30 );

   assert (r == BZ_OK);
   fprintf ( stderr, "%d after compression\n", nZ );

   for (bit = 0; bit < nZ*8; bit++) {
      fprintf ( stderr, "bit %d  ", bit );
      flip_bit ( bit );
      nOut = M_BLOCK_OUT;
      r = BZ2_bzBuffToBuffDecompress (
            outbuf, &nOut, zbuf, nZ, 0, 0 );
      fprintf ( stderr, " %d  %s ", r, bzerrorstrings[-r] );

      if (r != BZ_OK) {
         fprintf ( stderr, "\n" );
      } else {
         if (nOut != nIn) {
           fprintf(stderr, "nIn/nOut mismatch %d %d\n", nIn, nOut );
           return 1;
         } else {
           for (i = 0; i < nOut; i++)
             if (inbuf[i] != outbuf[i]) { 
                fprintf(stderr, "mismatch at %d\n", i ); 
                return 1; 
           }
           if (i == nOut) fprintf(stderr, "really ok!\n" );
         }
      }

      flip_bit ( bit );
   }

#if 0
   assert (nOut == nIn);
   for (i = 0; i < nOut; i++) {
     if (inbuf[i] != outbuf[i]) {
        fprintf ( stderr, "difference at %d !\n", i );
        return 1;
     }
   }
#endif

   fprintf ( stderr, "all ok\n" );
   return 0;
}

--- NEW FILE: README.COMPILATION.PROBLEMS ---
------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.

bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

Please read the WARNING, DISCLAIMER and PATENTS sections in the 
README file.

This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------

bzip2-1.0.5 should compile without problems on the vast majority of
platforms.  Using the supplied Makefile, I've built and tested it
myself for x86-linux and amd64-linux.  With makefile.msc, Visual C++
6.0 and nmake, you can build a native Win32 version too.  Large file
support seems to work correctly on at least on amd64-linux.

When I say "large file" I mean a file of size 2,147,483,648 (2^31)
bytes or above.  Many older OSs can't handle files above this size,
but many newer ones can.  Large files are pretty huge -- most files
you'll encounter are not Large Files.

Early versions of bzip2 (0.1, 0.9.0, 0.9.5) compiled on a wide variety
of platforms without difficulty, and I hope this version will continue
in that tradition.  However, in order to support large files, I've had
to include the define -D_FILE_OFFSET_BITS=64 in the Makefile.  This
can cause problems.

The technique of adding -D_FILE_OFFSET_BITS=64 to get large file
support is, as far as I know, the Recommended Way to get correct large
file support.  For more details, see the Large File Support
Specification, published by the Large File Summit, at

   http://ftp.sas.com/standards/large.file

As a general comment, if you get compilation errors which you think
are related to large file support, try removing the above define from
the Makefile, ie, delete the line

   BIGFILES=-D_FILE_OFFSET_BITS=64 

from the Makefile, and do 'make clean ; make'.  This will give you a
version of bzip2 without large file support, which, for most
applications, is probably not a problem.  

Alternatively, try some of the platform-specific hints listed below.

You can use the spewG.c program to generate huge files to test bzip2's
large file support, if you are feeling paranoid.  Be aware though that
any compilation problems which affect bzip2 will also affect spewG.c,
alas.

AIX: I have reports that for large file support, you need to specify
-D_LARGE_FILES rather than -D_FILE_OFFSET_BITS=64.  I have not tested
this myself.

--- NEW FILE: bzlib.c ---

/*-------------------------------------------------------------*/
/*--- Library top-level functions.                          ---*/
/*---                                               bzlib.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */
[...1533 lines suppressed...]
      ,"???"   /* for future */
      ,"???"   /* for future */
      ,"???"   /* for future */
};


const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
{
   int err = ((bzFile *)b)->lastErr;

   if(err>0) err = 0;
   *errnum = err;
   return bzerrorstrings[err*-1];
}
#endif


/*-------------------------------------------------------------*/
/*--- end                                           bzlib.c ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: LICENSE ---

--------------------------------------------------------------------------

This program, "bzip2", the associated library "libbzip2", and all
documentation, are copyright (C) 1996-2007 Julian R Seward.  All
rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. The origin of this software must not be misrepresented; you must 
   not claim that you wrote the original software.  If you use this 
   software in a product, an acknowledgment in the product 
   documentation would be appreciated but is not required.

3. Altered source versions must be plainly marked as such, and must
   not be misrepresented as being the original software.

4. The name of the author may not be used to endorse or promote 
   products derived from this software without specific prior written 
   permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Julian Seward, jseward at bzip.org
bzip2/libbzip2 version 1.0.5 of 10 December 2007

--------------------------------------------------------------------------

--- NEW FILE: bzdiff ---
#!/bin/sh
# sh is buggy on RS/6000 AIX 3.2. Replace above line with #!/bin/ksh

# Bzcmp/diff wrapped for bzip2, 
# adapted from zdiff by Philippe Troin <phil at fifi.org> for Debian GNU/Linux.

# Bzcmp and bzdiff are used to invoke the cmp or the  diff  pro-
# gram  on compressed files.  All options specified are passed
# directly to cmp or diff.  If only 1 file is specified,  then
# the  files  compared  are file1 and an uncompressed file1.gz.
# If two files are specified, then they are  uncompressed  (if
# necessary) and fed to cmp or diff.  The exit status from cmp
# or diff is preserved.

PATH="/usr/bin:/bin:$PATH"; export PATH
prog=`echo $0 | sed 's|.*/||'`
case "$prog" in
  *cmp) comp=${CMP-cmp}   ;;
  *)    comp=${DIFF-diff} ;;
esac

OPTIONS=
FILES=
for ARG
do
    case "$ARG" in
    -*) OPTIONS="$OPTIONS $ARG";;
     *) if test -f "$ARG"; then
            FILES="$FILES $ARG"
        else
            echo "${prog}: $ARG not found or not a regular file"
        exit 1
        fi ;;
    esac
done
if test -z "$FILES"; then
    echo "Usage: $prog [${comp}_options] file [file]"
    exit 1
fi
tmp=`mktemp ${TMPDIR:-/tmp}/bzdiff.XXXXXXXXXX` || {
      echo 'cannot create a temporary file' >&2
      exit 1
}
set $FILES
if test $# -eq 1; then
    FILE=`echo "$1" | sed 's/.bz2$//'`
    bzip2 -cd "$FILE.bz2" | $comp $OPTIONS - "$FILE"
    STAT="$?"

elif test $# -eq 2; then
    case "$1" in
        *.bz2)
                case "$2" in
            *.bz2)
            F=`echo "$2" | sed 's|.*/||;s|.bz2$||'`
                        bzip2 -cdfq "$2" > $tmp
                        bzip2 -cdfq "$1" | $comp $OPTIONS - $tmp
                        STAT="$?"
            /bin/rm -f $tmp;;

                *)      bzip2 -cdfq "$1" | $comp $OPTIONS - "$2"
                        STAT="$?";;
                esac;;
        *)      case "$2" in
            *.bz2)
                        bzip2 -cdfq "$2" | $comp $OPTIONS "$1" -
                        STAT="$?";;
                *)      $comp $OPTIONS "$1" "$2"
                        STAT="$?";;
                esac;;
    esac
        exit "$STAT"
else
    echo "Usage: $prog [${comp}_options] file [file]"
    exit 1
fi

--- NEW FILE: bzlib.h ---

/*-------------------------------------------------------------*/
/*--- Public header file for the library.                   ---*/
/*---                                               bzlib.h ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#ifndef _BZLIB_H
#define _BZLIB_H

#ifdef __cplusplus
extern "C" {
#endif

#define BZ_RUN               0
#define BZ_FLUSH             1
#define BZ_FINISH            2

#define BZ_OK                0
#define BZ_RUN_OK            1
#define BZ_FLUSH_OK          2
#define BZ_FINISH_OK         3
#define BZ_STREAM_END        4
#define BZ_SEQUENCE_ERROR    (-1)
#define BZ_PARAM_ERROR       (-2)
#define BZ_MEM_ERROR         (-3)
#define BZ_DATA_ERROR        (-4)
#define BZ_DATA_ERROR_MAGIC  (-5)
#define BZ_IO_ERROR          (-6)
#define BZ_UNEXPECTED_EOF    (-7)
#define BZ_OUTBUFF_FULL      (-8)
#define BZ_CONFIG_ERROR      (-9)

typedef 
   struct {
      char *next_in;
      unsigned int avail_in;
      unsigned int total_in_lo32;
      unsigned int total_in_hi32;

      char *next_out;
      unsigned int avail_out;
      unsigned int total_out_lo32;
      unsigned int total_out_hi32;

      void *state;

      void *(*bzalloc)(void *,int,int);
      void (*bzfree)(void *,void *);
      void *opaque;
   } 
   bz_stream;


#ifndef BZ_IMPORT
#define BZ_EXPORT
#endif

#ifndef BZ_NO_STDIO
/* Need a definitition for FILE */
#include <stdio.h>
#endif

#ifdef _WIN32
#   include <windows.h>
#   ifdef small
      /* windows.h define small to char */
#      undef small
#   endif
#   ifdef BZ_EXPORT
#   define BZ_API(func) WINAPI func
#   define BZ_EXTERN extern
#   else
   /* import windows dll dynamically */
#   define BZ_API(func) (WINAPI * func)
#   define BZ_EXTERN
#   endif
#else
#   define BZ_API(func) func
#   define BZ_EXTERN extern
#endif


/*-- Core (low-level) library functions --*/

BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( 
      bz_stream* strm, 
      int        blockSize100k, 
      int        verbosity, 
      int        workFactor 
   );

BZ_EXTERN int BZ_API(BZ2_bzCompress) ( 
      bz_stream* strm, 
      int action 
   );

BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( 
      bz_stream* strm 
   );

BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( 
      bz_stream *strm, 
      int       verbosity, 
      int       small
   );

BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( 
      bz_stream* strm 
   );

BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( 
      bz_stream *strm 
   );



/*-- High(er) level library functions --*/

#ifndef BZ_NO_STDIO
#define BZ_MAX_UNUSED 5000

typedef void BZFILE;

BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( 
      int*  bzerror,   
      FILE* f, 
      int   verbosity, 
      int   small,
      void* unused,    
      int   nUnused 
   );

BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( 
      int*    bzerror, 
      BZFILE* b 
   );

BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( 
      int*    bzerror, 
      BZFILE* b, 
      void**  unused,  
      int*    nUnused 
   );

BZ_EXTERN int BZ_API(BZ2_bzRead) ( 
      int*    bzerror, 
      BZFILE* b, 
      void*   buf, 
      int     len 
   );

BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( 
      int*  bzerror,      
      FILE* f, 
      int   blockSize100k, 
      int   verbosity, 
      int   workFactor 
   );

BZ_EXTERN void BZ_API(BZ2_bzWrite) ( 
      int*    bzerror, 
      BZFILE* b, 
      void*   buf, 
      int     len 
   );

BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( 
      int*          bzerror, 
      BZFILE*       b, 
      int           abandon, 
      unsigned int* nbytes_in, 
      unsigned int* nbytes_out 
   );

BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( 
      int*          bzerror, 
      BZFILE*       b, 
      int           abandon, 
      unsigned int* nbytes_in_lo32, 
      unsigned int* nbytes_in_hi32, 
      unsigned int* nbytes_out_lo32, 
      unsigned int* nbytes_out_hi32
   );
#endif


/*-- Utility functions --*/

BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( 
      char*         dest, 
      unsigned int* destLen,
      char*         source, 
      unsigned int  sourceLen,
      int           blockSize100k, 
      int           verbosity, 
      int           workFactor 
   );

BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( 
      char*         dest, 
      unsigned int* destLen,
      char*         source, 
      unsigned int  sourceLen,
      int           small, 
      int           verbosity 
   );


/*--
   Code contributed by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
   to support better zlib compatibility.
   This code is not _officially_ part of libbzip2 (yet);
   I haven't tested it, documented it, or considered the
   threading-safeness of it.
   If this code breaks, please contact both Yoshioka and me.
--*/

BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
      void
   );

#ifndef BZ_NO_STDIO
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
      const char *path,
      const char *mode
   );

BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
      int        fd,
      const char *mode
   );
         
BZ_EXTERN int BZ_API(BZ2_bzread) (
      BZFILE* b, 
      void* buf, 
      int len 
   );

BZ_EXTERN int BZ_API(BZ2_bzwrite) (
      BZFILE* b, 
      void*   buf, 
      int     len 
   );

BZ_EXTERN int BZ_API(BZ2_bzflush) (
      BZFILE* b
   );

BZ_EXTERN void BZ_API(BZ2_bzclose) (
      BZFILE* b
   );

BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
      BZFILE *b, 
      int    *errnum
   );
#endif

#ifdef __cplusplus
}
#endif

#endif

/*-------------------------------------------------------------*/
/*--- end                                           bzlib.h ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: manual.html ---
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>bzip2 and libbzip2, version 1.0.5</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.69.1">
<style type="text/css" media="screen">/* Colours:
#74240f  dark brown      h1, h2, h3, h4
#336699  medium blue     links
#339999  turquoise       link hover colour
#202020  almost black    general text
#761596  purple          md5sum text
#626262  dark gray       pre border
#eeeeee  very light gray pre background
#f2f2f9  very light blue nav table background
#3366cc  medium blue     nav table border
*/

a, a:link, a:visited, a:active { color: #336699; }
a:hover { color: #339999; }
[...2501 lines suppressed...]
described in a paper available from:</p>
<div class="literallayout"><p>http://www.cs.arizona.edu/people/gene/PAPERS/suffix.ps<br>
</p></div>
<p>Finally, the following papers document some
investigations I made into the performance of sorting
and decompression algorithms:</p>
<div class="literallayout"><p>Julian Seward<br>
   On the Performance of BWT Sorting Algorithms<br>
   Proceedings of the IEEE Data Compression Conference 2000<br>
     Snowbird, Utah.  28-30 March 2000.<br>
<br>
Julian Seward<br>
   Space-time Tradeoffs in the Inverse B-W Transform<br>
   Proceedings of the IEEE Data Compression Conference 2001<br>
     Snowbird, Utah.  27-29 March 2001.<br>
</p></div>
</div>
</div>
</div></body>
</html>

--- NEW FILE: bzgrep.1 ---
\"Shamelessly copied from zmore.1 by Philippe Troin <phil at fifi.org>
\"for Debian GNU/Linux
.TH BZGREP 1
.SH NAME
bzgrep, bzfgrep, bzegrep \- search possibly bzip2 compressed files for a regular expression
.SH SYNOPSIS
.B bzgrep
[ grep_options ]
.BI  [\ -e\ ] " pattern"
.IR filename ".\|.\|."
.br
.B bzegrep
[ egrep_options ]
.BI  [\ -e\ ] " pattern"
.IR filename ".\|.\|."
.br
.B bzfgrep
[ fgrep_options ]
.BI  [\ -e\ ] " pattern"
.IR filename ".\|.\|."
.SH DESCRIPTION
.IR  Bzgrep
is used to invoke the
.I grep
on bzip2-compressed files. All options specified are passed directly to
.I grep.
If no file is specified, then the standard input is decompressed
if necessary and fed to grep.
Otherwise the given files are uncompressed if necessary and fed to
.I grep.
.PP
If
.I bzgrep
is invoked as
.I bzegrep
or
.I bzfgrep
then
.I egrep
or
.I fgrep
is used instead of
.I grep.
If the GREP environment variable is set,
.I bzgrep
uses it as the
.I grep
program to be invoked. For example:

    for sh:  GREP=fgrep  bzgrep string files
    for csh: (setenv GREP fgrep; bzgrep string files)
.SH AUTHOR
Charles Levert (charles at comm.polymtl.ca). Adapted to bzip2 by Philippe
Troin <phil at fifi.org> for Debian GNU/Linux.
.SH "SEE ALSO"
grep(1), egrep(1), fgrep(1), bzdiff(1), bzmore(1), bzless(1), bzip2(1)

--- NEW FILE: words3 ---

If you got this far and the 'cmp's didn't complain, it looks
like you're in business.  

To install in /usr/local/bin, /usr/local/lib, /usr/local/man and 
/usr/local/include, type

   make install

To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type 

   make install PREFIX=/xxx/yyy

If you are (justifiably) paranoid and want to see what 'make install'
is going to do, you can first do

   make -n install                      or
   make -n install PREFIX=/xxx/yyy      respectively.

The -n instructs make to show the commands it would execute, but
not actually execute them.

Instructions for use are in the preformatted manual page, in the file
bzip2.txt.  For more detailed documentation, read the full manual.  
It is available in Postscript form (manual.ps), PDF form (manual.pdf),
and HTML form (manual.html).

You can also do "bzip2 --help" to see some helpful information. 
"bzip2 -L" displays the software license.


--- NEW FILE: words2 ---

Checking test results.  If any of the four "cmp"s which follow
report any differences, something is wrong.  If you can't easily
figure out what, please let me know (jseward at bzip.org).


--- NEW FILE: words1 ---

Doing 6 tests (3 compress, 3 uncompress) ...
If there's a problem, things might stop at this point.
 

--- NEW FILE: words0 ---

If compilation produces errors, or a large number of warnings,
please read README.COMPILATION.PROBLEMS -- you might be able to
adjust the flags in this Makefile to improve matters.

Also in README.COMPILATION.PROBLEMS are some hints that may help
if your build produces an executable which is unable to correctly
handle so-called 'large files' -- files of size 2GB or more.


--- NEW FILE: dlltest.c ---
/*
   minibz2
      libbz2.dll test program.
      by Yoshioka Tsuneo (tsuneo at rr.iij4u.or.jp)
      This file is Public Domain.  Welcome any email to me.

   usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]
*/

#define BZ_IMPORT
#include <stdio.h>
#include <stdlib.h>
#include "bzlib.h"
#ifdef _WIN32
#include <io.h>
#endif


#ifdef _WIN32

#define BZ2_LIBNAME "libbz2-1.0.2.DLL" 

#include <windows.h>
static int BZ2DLLLoaded = 0;
static HINSTANCE BZ2DLLhLib;
int BZ2DLLLoadLibrary(void)
{
   HINSTANCE hLib;

   if(BZ2DLLLoaded==1){return 0;}
   hLib=LoadLibrary(BZ2_LIBNAME);
   if(hLib == NULL){
      fprintf(stderr,"Can't load %s\n",BZ2_LIBNAME);
      return -1;
   }
   BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
   BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
   BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
   BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
   BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
   BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
   BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
   BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");

   if (!BZ2_bzlibVersion || !BZ2_bzopen || !BZ2_bzdopen
       || !BZ2_bzread || !BZ2_bzwrite || !BZ2_bzflush
       || !BZ2_bzclose || !BZ2_bzerror) {
      fprintf(stderr,"GetProcAddress failed.\n");
      return -1;
   }
   BZ2DLLLoaded=1;
   BZ2DLLhLib=hLib;
   return 0;

}
int BZ2DLLFreeLibrary(void)
{
   if(BZ2DLLLoaded==0){return 0;}
   FreeLibrary(BZ2DLLhLib);
   BZ2DLLLoaded=0;
}
#endif /* WIN32 */

void usage(void)
{
   puts("usage: minibz2 [-d] [-{1,2,..9}] [[srcfilename] destfilename]");
}

int main(int argc,char *argv[])
{
   int decompress = 0;
   int level = 9;
   char *fn_r = NULL;
   char *fn_w = NULL;

#ifdef _WIN32
   if(BZ2DLLLoadLibrary()<0){
      fprintf(stderr,"Loading of %s failed.  Giving up.\n", BZ2_LIBNAME);
      exit(1);
   }
   printf("Loading of %s succeeded.  Library version is %s.\n",
          BZ2_LIBNAME, BZ2_bzlibVersion() );
#endif
   while(++argv,--argc){
      if(**argv =='-' || **argv=='/'){
         char *p;

         for(p=*argv+1;*p;p++){
            if(*p=='d'){
               decompress = 1;
            }else if('1'<=*p && *p<='9'){
               level = *p - '0';
            }else{
               usage();
               exit(1);
            }
         }
      }else{
         break;
      }
   }
   if(argc>=1){
      fn_r = *argv;
      argc--;argv++;
   }else{
      fn_r = NULL;
   }
   if(argc>=1){
      fn_w = *argv;
      argc--;argv++;
   }else{
      fn_w = NULL;
   }
   {
      int len;
      char buff[0x1000];
      char mode[10];

      if(decompress){
         BZFILE *BZ2fp_r = NULL;
         FILE *fp_w = NULL;

         if(fn_w){
            if((fp_w = fopen(fn_w,"wb"))==NULL){
               printf("can't open [%s]\n",fn_w);
               perror("reason:");
               exit(1);
            }
         }else{
            fp_w = stdout;
         }
         if((fn_r == NULL && (BZ2fp_r = BZ2_bzdopen(fileno(stdin),"rb"))==NULL)
            || (fn_r != NULL && (BZ2fp_r = BZ2_bzopen(fn_r,"rb"))==NULL)){
            printf("can't bz2openstream\n");
            exit(1);
         }
         while((len=BZ2_bzread(BZ2fp_r,buff,0x1000))>0){
            fwrite(buff,1,len,fp_w);
         }
         BZ2_bzclose(BZ2fp_r);
         if(fp_w != stdout) fclose(fp_w);
      }else{
         BZFILE *BZ2fp_w = NULL;
         FILE *fp_r = NULL;

         if(fn_r){
            if((fp_r = fopen(fn_r,"rb"))==NULL){
               printf("can't open [%s]\n",fn_r);
               perror("reason:");
               exit(1);
            }
         }else{
            fp_r = stdin;
         }
         mode[0]='w';
         mode[1] = '0' + level;
         mode[2] = '\0';

         if((fn_w == NULL && (BZ2fp_w = BZ2_bzdopen(fileno(stdout),mode))==NULL)
            || (fn_w !=NULL && (BZ2fp_w = BZ2_bzopen(fn_w,mode))==NULL)){
            printf("can't bz2openstream\n");
            exit(1);
         }
         while((len=fread(buff,1,0x1000,fp_r))>0){
            BZ2_bzwrite(BZ2fp_w,buff,len);
         }
         BZ2_bzclose(BZ2fp_w);
         if(fp_r!=stdin)fclose(fp_r);
      }
   }
#ifdef _WIN32
   BZ2DLLFreeLibrary();
#endif
   return 0;
}

--- NEW FILE: sample3.ref ---
This file is exceedingly boring.  If you find yourself
reading it, please (1) take it from me that you can safely
guess what the rest of the file says, and (2) seek professional
help.

ps.  there are no further sarcastic remarks in this file.

ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
[...29968 lines suppressed...]
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh

--- NEW FILE: README ---

This is the README for bzip2/libzip2.
This version is fully compatible with the previous public releases.

------------------------------------------------------------------
This file is part of bzip2/libbzip2, a program and library for
lossless, block-sorting data compression.

bzip2/libbzip2 version 1.0.5 of 10 December 2007
Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

Please read the WARNING, DISCLAIMER and PATENTS sections in this file.

This program is released under the terms of the license contained
in the file LICENSE.
------------------------------------------------------------------

Complete documentation is available in Postscript form (manual.ps),
PDF (manual.pdf) or html (manual.html).  A plain-text version of the
manual page is available as bzip2.txt.


HOW TO BUILD -- UNIX

Type 'make'.  This builds the library libbz2.a and then the programs
bzip2 and bzip2recover.  Six self-tests are run.  If the self-tests
complete ok, carry on to installation:

To install in /usr/local/bin, /usr/local/lib, /usr/local/man and
/usr/local/include, type

   make install

To install somewhere else, eg, /xxx/yyy/{bin,lib,man,include}, type

   make install PREFIX=/xxx/yyy

If you are (justifiably) paranoid and want to see what 'make install'
is going to do, you can first do

   make -n install                      or
   make -n install PREFIX=/xxx/yyy      respectively.

The -n instructs make to show the commands it would execute, but not
actually execute them.


HOW TO BUILD -- UNIX, shared library libbz2.so.

Do 'make -f Makefile-libbz2_so'.  This Makefile seems to work for
Linux-ELF (RedHat 7.2 on an x86 box), with gcc.  I make no claims
that it works for any other platform, though I suspect it probably
will work for most platforms employing both ELF and gcc.

bzip2-shared, a client of the shared library, is also built, but not
self-tested.  So I suggest you also build using the normal Makefile,
since that conducts a self-test.  A second reason to prefer the
version statically linked to the library is that, on x86 platforms,
building shared objects makes a valuable register (%ebx) unavailable
to gcc, resulting in a slowdown of 10%-20%, at least for bzip2.

Important note for people upgrading .so's from 0.9.0/0.9.5 to version
1.0.X.  All the functions in the library have been renamed, from (eg)
bzCompress to BZ2_bzCompress, to avoid namespace pollution.
Unfortunately this means that the libbz2.so created by
Makefile-libbz2_so will not work with any program which used an older
version of the library.  I do encourage library clients to make the
effort to upgrade to use version 1.0, since it is both faster and more
robust than previous versions.


HOW TO BUILD -- Windows 95, NT, DOS, Mac, etc.

It's difficult for me to support compilation on all these platforms.
My approach is to collect binaries for these platforms, and put them
on the master web site (http://www.bzip.org).  Look there.  However
(FWIW), bzip2-1.0.X is very standard ANSI C and should compile
unmodified with MS Visual C.  If you have difficulties building, you
might want to read README.COMPILATION.PROBLEMS.

At least using MS Visual C++ 6, you can build from the unmodified
sources by issuing, in a command shell: 

   nmake -f makefile.msc

(you may need to first run the MSVC-provided script VCVARS32.BAT
 so as to set up paths to the MSVC tools correctly).


VALIDATION

Correct operation, in the sense that a compressed file can always be
decompressed to reproduce the original, is obviously of paramount
importance.  To validate bzip2, I used a modified version of Mark
Nelson's churn program.  Churn is an automated test driver which
recursively traverses a directory structure, using bzip2 to compress
and then decompress each file it encounters, and checking that the
decompressed data is the same as the original.



Please read and be aware of the following:

WARNING:

   This program and library (attempts to) compress data by 
   performing several non-trivial transformations on it.  
   Unless you are 100% familiar with *all* the algorithms 
   contained herein, and with the consequences of modifying them, 
   you should NOT meddle with the compression or decompression 
   machinery.  Incorrect changes can and very likely *will* 
   lead to disastrous loss of data.


DISCLAIMER:

   I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
   USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.

   Every compression of a file implies an assumption that the
   compressed file can be decompressed to reproduce the original.
   Great efforts in design, coding and testing have been made to
   ensure that this program works correctly.  However, the complexity
   of the algorithms, and, in particular, the presence of various
   special cases in the code which occur with very low but non-zero
   probability make it impossible to rule out the possibility of bugs
   remaining in the program.  DO NOT COMPRESS ANY DATA WITH THIS
   PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
   SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.

   That is not to say this program is inherently unreliable.  
   Indeed, I very much hope the opposite is true.  bzip2/libbzip2 
   has been carefully constructed and extensively tested.


PATENTS:

   To the best of my knowledge, bzip2/libbzip2 does not use any 
   patented algorithms.  However, I do not have the resources 
   to carry out a patent search.  Therefore I cannot give any 
   guarantee of the above statement.



WHAT'S NEW IN 0.9.0 (as compared to 0.1pl2) ?

   * Approx 10% faster compression, 30% faster decompression
   * -t (test mode) is a lot quicker
   * Can decompress concatenated compressed files
   * Programming interface, so programs can directly read/write .bz2 files
   * Less restrictive (BSD-style) licensing
   * Flag handling more compatible with GNU gzip
   * Much more documentation, i.e., a proper user manual
   * Hopefully, improved portability (at least of the library)

WHAT'S NEW IN 0.9.5 ?

   * Compression speed is much less sensitive to the input
     data than in previous versions.  Specifically, the very
     slow performance caused by repetitive data is fixed.
   * Many small improvements in file and flag handling.
   * A Y2K statement.

WHAT'S NEW IN 1.0.0 ?

   See the CHANGES file.

WHAT'S NEW IN 1.0.2 ?

   See the CHANGES file.

WHAT'S NEW IN 1.0.3 ?

   See the CHANGES file.

WHAT'S NEW IN 1.0.4 ?

   See the CHANGES file.

WHAT'S NEW IN 1.0.5 ?

   See the CHANGES file.


I hope you find bzip2 useful.  Feel free to contact me at
   jseward at bzip.org
if you have any suggestions or queries.  Many people mailed me with
comments, suggestions and patches after the releases of bzip-0.15,
bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
feedback.  I thank you for your comments.

bzip2's "home" is http://www.bzip.org/

Julian Seward
jseward at bzip.org
Cambridge, UK.

18     July 1996 (version 0.15)
25   August 1996 (version 0.21)
 7   August 1997 (bzip2, version 0.1)
29   August 1997 (bzip2, version 0.1pl2)
23   August 1998 (bzip2, version 0.9.0)
 8     June 1999 (bzip2, version 0.9.5)
 4     Sept 1999 (bzip2, version 0.9.5d)
 5      May 2000 (bzip2, version 1.0pre8)
30 December 2001 (bzip2, version 1.0.2pre1)
15 February 2005 (bzip2, version 1.0.3)
20 December 2006 (bzip2, version 1.0.4)
10 December 2007 (bzip2, version 1.0.5)

--- NEW FILE: huffman.c ---

/*-------------------------------------------------------------*/
/*--- Huffman coding low-level stuff                        ---*/
/*---                                             huffman.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#include "bzlib_private.h"

/*---------------------------------------------------*/
#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))

#define ADDWEIGHTS(zw1,zw2)                           \
   (WEIGHTOF(zw1)+WEIGHTOF(zw2)) |                    \
   (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))

#define UPHEAP(z)                                     \
{                                                     \
   Int32 zz, tmp;                                     \
   zz = z; tmp = heap[zz];                            \
   while (weight[tmp] < weight[heap[zz >> 1]]) {      \
      heap[zz] = heap[zz >> 1];                       \
      zz >>= 1;                                       \
   }                                                  \
   heap[zz] = tmp;                                    \
}

#define DOWNHEAP(z)                                   \
{                                                     \
   Int32 zz, yy, tmp;                                 \
   zz = z; tmp = heap[zz];                            \
   while (True) {                                     \
      yy = zz << 1;                                   \
      if (yy > nHeap) break;                          \
      if (yy < nHeap &&                               \
          weight[heap[yy+1]] < weight[heap[yy]])      \
         yy++;                                        \
      if (weight[tmp] < weight[heap[yy]]) break;      \
      heap[zz] = heap[yy];                            \
      zz = yy;                                        \
   }                                                  \
   heap[zz] = tmp;                                    \
}


/*---------------------------------------------------*/
void BZ2_hbMakeCodeLengths ( UChar *len, 
                             Int32 *freq,
                             Int32 alphaSize,
                             Int32 maxLen )
{
   /*--
      Nodes and heap entries run from 1.  Entry 0
      for both the heap and nodes is a sentinel.
   --*/
   Int32 nNodes, nHeap, n1, n2, i, j, k;
   Bool  tooLong;

   Int32 heap   [ BZ_MAX_ALPHA_SIZE + 2 ];
   Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
   Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; 

   for (i = 0; i < alphaSize; i++)
      weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;

   while (True) {

      nNodes = alphaSize;
      nHeap = 0;

      heap[0] = 0;
      weight[0] = 0;
      parent[0] = -2;

      for (i = 1; i <= alphaSize; i++) {
         parent[i] = -1;
         nHeap++;
         heap[nHeap] = i;
         UPHEAP(nHeap);
      }

      AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
   
      while (nHeap > 1) {
         n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
         n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
         nNodes++;
         parent[n1] = parent[n2] = nNodes;
         weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
         parent[nNodes] = -1;
         nHeap++;
         heap[nHeap] = nNodes;
         UPHEAP(nHeap);
      }

      AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );

      tooLong = False;
      for (i = 1; i <= alphaSize; i++) {
         j = 0;
         k = i;
         while (parent[k] >= 0) { k = parent[k]; j++; }
         len[i-1] = j;
         if (j > maxLen) tooLong = True;
      }
      
      if (! tooLong) break;

      /* 17 Oct 04: keep-going condition for the following loop used
         to be 'i < alphaSize', which missed the last element,
         theoretically leading to the possibility of the compressor
         looping.  However, this count-scaling step is only needed if
         one of the generated Huffman code words is longer than
         maxLen, which up to and including version 1.0.2 was 20 bits,
         which is extremely unlikely.  In version 1.0.3 maxLen was
         changed to 17 bits, which has minimal effect on compression
         ratio, but does mean this scaling step is used from time to
         time, enough to verify that it works.

         This means that bzip2-1.0.3 and later will only produce
         Huffman codes with a maximum length of 17 bits.  However, in
         order to preserve backwards compatibility with bitstreams
         produced by versions pre-1.0.3, the decompressor must still
         handle lengths of up to 20. */

      for (i = 1; i <= alphaSize; i++) {
         j = weight[i] >> 8;
         j = 1 + (j / 2);
         weight[i] = j << 8;
      }
   }
}


/*---------------------------------------------------*/
void BZ2_hbAssignCodes ( Int32 *code,
                         UChar *length,
                         Int32 minLen,
                         Int32 maxLen,
                         Int32 alphaSize )
{
   Int32 n, vec, i;

   vec = 0;
   for (n = minLen; n <= maxLen; n++) {
      for (i = 0; i < alphaSize; i++)
         if (length[i] == n) { code[i] = vec; vec++; };
      vec <<= 1;
   }
}


/*---------------------------------------------------*/
void BZ2_hbCreateDecodeTables ( Int32 *limit,
                                Int32 *base,
                                Int32 *perm,
                                UChar *length,
                                Int32 minLen,
                                Int32 maxLen,
                                Int32 alphaSize )
{
   Int32 pp, i, j, vec;

   pp = 0;
   for (i = minLen; i <= maxLen; i++)
      for (j = 0; j < alphaSize; j++)
         if (length[j] == i) { perm[pp] = j; pp++; };

   for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
   for (i = 0; i < alphaSize; i++) base[length[i]+1]++;

   for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];

   for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
   vec = 0;

   for (i = minLen; i <= maxLen; i++) {
      vec += (base[i+1] - base[i]);
      limit[i] = vec-1;
      vec <<= 1;
   }
   for (i = minLen + 1; i <= maxLen; i++)
      base[i] = ((limit[i-1] + 1) << 1) - base[i];
}


/*-------------------------------------------------------------*/
/*--- end                                         huffman.c ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: CHANGES ---
 ------------------------------------------------------------------
 This file is part of bzip2/libbzip2, a program and library for
 lossless, block-sorting data compression.

 bzip2/libbzip2 version 1.0.5 of 10 December 2007
 Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

 Please read the WARNING, DISCLAIMER and PATENTS sections in the 
 README file.

 This program is released under the terms of the license contained
 in the file LICENSE.
 ------------------------------------------------------------------


0.9.0
~~~~~
First version.


0.9.0a
~~~~~~
Removed 'ranlib' from Makefile, since most modern Unix-es 
don't need it, or even know about it.


0.9.0b
~~~~~~
Fixed a problem with error reporting in bzip2.c.  This does not effect
the library in any way.  Problem is: versions 0.9.0 and 0.9.0a (of the
program proper) compress and decompress correctly, but give misleading
error messages (internal panics) when an I/O error occurs, instead of
reporting the problem correctly.  This shouldn't give any data loss
(as far as I can see), but is confusing.

Made the inline declarations disappear for non-GCC compilers.


0.9.0c
~~~~~~
Fixed some problems in the library pertaining to some boundary cases.
This makes the library behave more correctly in those situations.  The
fixes apply only to features (calls and parameters) not used by
bzip2.c, so the non-fixedness of them in previous versions has no
effect on reliability of bzip2.c.

In bzlib.c:
   * made zero-length BZ_FLUSH work correctly in bzCompress().
   * fixed bzWrite/bzRead to ignore zero-length requests.
   * fixed bzread to correctly handle read requests after EOF.
   * wrong parameter order in call to bzDecompressInit in
     bzBuffToBuffDecompress.  Fixed.

In compress.c:
   * changed setting of nGroups in sendMTFValues() so as to 
     do a bit better on small files.  This _does_ effect
     bzip2.c.


0.9.5a
~~~~~~
Major change: add a fallback sorting algorithm (blocksort.c)
to give reasonable behaviour even for very repetitive inputs.
Nuked --repetitive-best and --repetitive-fast since they are
no longer useful.

Minor changes: mostly a whole bunch of small changes/
bugfixes in the driver (bzip2.c).  Changes pertaining to the
user interface are:

   allow decompression of symlink'd files to stdout
   decompress/test files even without .bz2 extension
   give more accurate error messages for I/O errors
   when compressing/decompressing to stdout, don't catch control-C
   read flags from BZIP2 and BZIP environment variables
   decline to break hard links to a file unless forced with -f
   allow -c flag even with no filenames
   preserve file ownerships as far as possible
   make -s -1 give the expected block size (100k)
   add a flag -q --quiet to suppress nonessential warnings
   stop decoding flags after --, so files beginning in - can be handled
   resolved inconsistent naming: bzcat or bz2cat ?
   bzip2 --help now returns 0

Programming-level changes are:

   fixed syntax error in GET_LL4 for Borland C++ 5.02
   let bzBuffToBuffDecompress return BZ_DATA_ERROR{_MAGIC}
   fix overshoot of mode-string end in bzopen_or_bzdopen
   wrapped bzlib.h in #ifdef __cplusplus ... extern "C" { ... }
   close file handles under all error conditions
   added minor mods so it compiles with DJGPP out of the box
   fixed Makefile so it doesn't give problems with BSD make
   fix uninitialised memory reads in dlltest.c

0.9.5b
~~~~~~
Open stdin/stdout in binary mode for DJGPP.

0.9.5c
~~~~~~
Changed BZ_N_OVERSHOOT to be ... + 2 instead of ... + 1.  The + 1
version could cause the sorted order to be wrong in some extremely
obscure cases.  Also changed setting of quadrant in blocksort.c.

0.9.5d
~~~~~~
The only functional change is to make bzlibVersion() in the library
return the correct string.  This has no effect whatsoever on the
functioning of the bzip2 program or library.  Added a couple of casts
so the library compiles without warnings at level 3 in MS Visual
Studio 6.0.  Included a Y2K statement in the file Y2K_INFO.  All other
changes are minor documentation changes.

1.0
~~~
Several minor bugfixes and enhancements:

* Large file support.  The library uses 64-bit counters to
  count the volume of data passing through it.  bzip2.c 
  is now compiled with -D_FILE_OFFSET_BITS=64 to get large
  file support from the C library.  -v correctly prints out
  file sizes greater than 4 gigabytes.  All these changes have
  been made without assuming a 64-bit platform or a C compiler
  which supports 64-bit ints, so, except for the C library
  aspect, they are fully portable.

* Decompression robustness.  The library/program should be
  robust to any corruption of compressed data, detecting and
  handling _all_ corruption, instead of merely relying on
  the CRCs.  What this means is that the program should 
  never crash, given corrupted data, and the library should
  always return BZ_DATA_ERROR.

* Fixed an obscure race-condition bug only ever observed on
  Solaris, in which, if you were very unlucky and issued
  control-C at exactly the wrong time, both input and output
  files would be deleted.

* Don't run out of file handles on test/decompression when
  large numbers of files have invalid magic numbers.

* Avoid library namespace pollution.  Prefix all exported 
  symbols with BZ2_.

* Minor sorting enhancements from my DCC2000 paper.

* Advance the version number to 1.0, so as to counteract the
  (false-in-this-case) impression some people have that programs 
  with version numbers less than 1.0 are in some way, experimental,
  pre-release versions.

* Create an initial Makefile-libbz2_so to build a shared library.
  Yes, I know I should really use libtool et al ...

* Make the program exit with 2 instead of 0 when decompression
  fails due to a bad magic number (ie, an invalid bzip2 header).
  Also exit with 1 (as the manual claims :-) whenever a diagnostic
  message would have been printed AND the corresponding operation 
  is aborted, for example
     bzip2: Output file xx already exists.
  When a diagnostic message is printed but the operation is not 
  aborted, for example
     bzip2: Can't guess original name for wurble -- using wurble.out
  then the exit value 0 is returned, unless some other problem is
  also detected.

  I think it corresponds more closely to what the manual claims now.


1.0.1
~~~~~
* Modified dlltest.c so it uses the new BZ2_ naming scheme.
* Modified makefile-msc to fix minor build probs on Win2k.
* Updated README.COMPILATION.PROBLEMS.

There are no functionality changes or bug fixes relative to version
1.0.0.  This is just a documentation update + a fix for minor Win32
build problems.  For almost everyone, upgrading from 1.0.0 to 1.0.1 is
utterly pointless.  Don't bother.


1.0.2
~~~~~
A bug fix release, addressing various minor issues which have appeared
in the 18 or so months since 1.0.1 was released.  Most of the fixes
are to do with file-handling or documentation bugs.  To the best of my
knowledge, there have been no data-loss-causing bugs reported in the
compression/decompression engine of 1.0.0 or 1.0.1.

Note that this release does not improve the rather crude build system
for Unix platforms.  The general plan here is to autoconfiscate/
libtoolise 1.0.2 soon after release, and release the result as 1.1.0
or perhaps 1.2.0.  That, however, is still just a plan at this point.

Here are the changes in 1.0.2.  Bug-reporters and/or patch-senders in
parentheses.

* Fix an infinite segfault loop in 1.0.1 when a directory is
  encountered in -f (force) mode.
     (Trond Eivind Glomsrod, Nicholas Nethercote, Volker Schmidt)

* Avoid double fclose() of output file on certain I/O error paths.
     (Solar Designer)

* Don't fail with internal error 1007 when fed a long stream (> 48MB)
  of byte 251.  Also print useful message suggesting that 1007s may be
  caused by bad memory.
     (noticed by Juan Pedro Vallejo, fixed by me)

* Fix uninitialised variable silly bug in demo prog dlltest.c.
     (Jorj Bauer)

* Remove 512-MB limitation on recovered file size for bzip2recover
  on selected platforms which support 64-bit ints.  At the moment
  all GCC supported platforms, and Win32.
     (me, Alson van der Meulen)

* Hard-code header byte values, to give correct operation on platforms
  using EBCDIC as their native character set (IBM's OS/390).
     (Leland Lucius)

* Copy file access times correctly.
     (Marty Leisner)

* Add distclean and check targets to Makefile.
     (Michael Carmack)

* Parameterise use of ar and ranlib in Makefile.  Also add $(LDFLAGS).
     (Rich Ireland, Bo Thorsen)

* Pass -p (create parent dirs as needed) to mkdir during make install.
     (Jeremy Fusco)

* Dereference symlinks when copying file permissions in -f mode.
     (Volker Schmidt)

* Majorly simplify implementation of uInt64_qrm10.
     (Bo Lindbergh)

* Check the input file still exists before deleting the output one,
  when aborting in cleanUpAndFail().
     (Joerg Prante, Robert Linden, Matthias Krings)

Also a bunch of patches courtesy of Philippe Troin, the Debian maintainer
of bzip2:

* Wrapper scripts (with manpages): bzdiff, bzgrep, bzmore.

* Spelling changes and minor enhancements in bzip2.1.

* Avoid race condition between creating the output file and setting its
  interim permissions safely, by using fopen_output_safely().
  No changes to bzip2recover since there is no issue with file
  permissions there.

* do not print senseless report with -v when compressing an empty
  file.

* bzcat -f works on non-bzip2 files.

* do not try to escape shell meta-characters on unix (the shell takes
  care of these).

* added --fast and --best aliases for -1 -9 for gzip compatibility.


1.0.3 (15 Feb 05)
~~~~~~~~~~~~~~~~~
Fixes some minor bugs since the last version, 1.0.2.

* Further robustification against corrupted compressed data.
  There are currently no known bitstreams which can cause the
  decompressor to crash, loop or access memory which does not
  belong to it.  If you are using bzip2 or the library to 
  decompress bitstreams from untrusted sources, an upgrade
  to 1.0.3 is recommended.  This fixes CAN-2005-1260.

* The documentation has been converted to XML, from which html
  and pdf can be derived.

* Various minor bugs in the documentation have been fixed.

* Fixes for various compilation warnings with newer versions of
  gcc, and on 64-bit platforms.

* The BZ_NO_STDIO cpp symbol was not properly observed in 1.0.2.
  This has been fixed.


1.0.4 (20 Dec 06)
~~~~~~~~~~~~~~~~~
Fixes some minor bugs since the last version, 1.0.3.

* Fix file permissions race problem (CAN-2005-0953).

* Avoid possible segfault in BZ2_bzclose.  From Coverity's NetBSD
  scan.

* 'const'/prototype cleanups in the C code.

* Change default install location to /usr/local, and handle multiple
  'make install's without error.

* Sanitise file names more carefully in bzgrep.  Fixes CAN-2005-0758
  to the extent that applies to bzgrep.

* Use 'mktemp' rather than 'tempfile' in bzdiff.

* Tighten up a couple of assertions in blocksort.c following automated
  analysis.

* Fix minor doc/comment bugs.


1.0.5 (10 Dec 07)
~~~~~~~~~~~~~~~~~
Security fix only.  Fixes CERT-FI 20469 as it applies to bzip2.


--- NEW FILE: bzgrep ---
#!/bin/sh

# Bzgrep wrapped for bzip2, 
# adapted from zgrep by Philippe Troin <phil at fifi.org> for Debian GNU/Linux.
## zgrep notice:
## zgrep -- a wrapper around a grep program that decompresses files as needed
## Adapted from a version sent by Charles Levert <charles at comm.polymtl.ca>

PATH="/usr/bin:$PATH"; export PATH

prog=`echo $0 | sed 's|.*/||'`
case "$prog" in
    *egrep) grep=${EGREP-egrep} ;;
    *fgrep) grep=${FGREP-fgrep} ;;
    *)  grep=${GREP-grep}   ;;
esac
pat=""
while test $# -ne 0; do
  case "$1" in
  -e | -f) opt="$opt $1"; shift; pat="$1"
           if test "$grep" = grep; then  # grep is buggy with -e on SVR4
             grep=egrep
           fi;;
  -A | -B) opt="$opt $1 $2"; shift;;
  -*)      opt="$opt $1";;
   *)      if test -z "$pat"; then
         pat="$1"
       else
         break;
           fi;;
  esac
  shift
done

if test -z "$pat"; then
  echo "grep through bzip2 files"
  echo "usage: $prog [grep_options] pattern [files]"
  exit 1
fi

list=0
silent=0
op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'`
case "$op" in
  *l*) list=1
esac
case "$op" in
  *h*) silent=1
esac

if test $# -eq 0; then
  bzip2 -cdfq | $grep $opt "$pat"
  exit $?
fi

res=0
for i do
  if test -f "$i"; then :; else if test -f "$i.bz2"; then i="$i.bz2"; fi; fi
  if test $list -eq 1; then
    bzip2 -cdfq "$i" | $grep $opt "$pat" 2>&1 > /dev/null && echo $i
    r=$?
  elif test $# -eq 1 -o $silent -eq 1; then
    bzip2 -cdfq "$i" | $grep $opt "$pat"
    r=$?
  else
    j=${i//\\/\\\\}
    j=${j//|/\\|}
    j=${j//&/\\&}
    j=`printf "%s" "$j" | tr '\n' ' '`
    bzip2 -cdfq "$i" | $grep $opt "$pat" | sed "s|^|${j}:|"
    r=$?
  fi
  test "$r" -ne 0 && res="$r"
done
exit $res

--- NEW FILE: bz-html.xsl ---
<?xml version="1.0"?> <!-- -*- sgml -*- -->
<!DOCTYPE xsl:stylesheet [ <!ENTITY bz-css SYSTEM "./bzip.css"> ]>

<xsl:stylesheet 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
<xsl:import href="bz-common.xsl"/>

<!-- use 8859-1 encoding -->
<xsl:output method="html" encoding="ISO-8859-1" indent="yes"/>

<!-- we include the css directly when generating one large file -->
<xsl:template name="user.head.content">  
  <style type="text/css" media="screen">
    <xsl:text>&bz-css;</xsl:text>
  </style>
</xsl:template>

</xsl:stylesheet>

--- NEW FILE: bzmore.1 ---
.\"Shamelessly copied from zmore.1 by Philippe Troin <phil at fifi.org>
.\"for Debian GNU/Linux
.TH BZMORE 1
.SH NAME
bzmore, bzless \- file perusal filter for crt viewing of bzip2 compressed text
.SH SYNOPSIS
.B bzmore
[ name ...  ]
.br
.B bzless
[ name ...  ]
.SH NOTE
In the following description,
.I bzless
and
.I less
can be used interchangeably with
.I bzmore
and
.I more.
.SH DESCRIPTION
.I  Bzmore
is a filter which allows examination of compressed or plain text files
one screenful at a time on a soft-copy terminal.
.I bzmore
works on files compressed with
.I bzip2
and also on uncompressed files.
If a file does not exist,
.I bzmore
looks for a file of the same name with the addition of a .bz2 suffix.
.PP
.I Bzmore
normally pauses after each screenful, printing --More--
at the bottom of the screen.
If the user then types a carriage return, one more line is displayed.
If the user hits a space,
another screenful is displayed.  Other possibilities are enumerated later.
.PP
.I Bzmore
looks in the file
.I /etc/termcap
to determine terminal characteristics,
and to determine the default window size.
On a terminal capable of displaying 24 lines,
the default window size is 22 lines.
Other sequences which may be typed when
.I bzmore
pauses, and their effects, are as follows (\fIi\fP is an optional integer
argument, defaulting to 1) :
.PP
.IP \fIi\|\fP<space>
display
.I i
more lines, (or another screenful if no argument is given)
.PP
.IP ^D
display 11 more lines (a ``scroll'').
If
.I i
is given, then the scroll size is set to \fIi\|\fP.
.PP
.IP d
same as ^D (control-D)
.PP
.IP \fIi\|\fPz
same as typing a space except that \fIi\|\fP, if present, becomes the new
window size.  Note that the window size reverts back to the default at the
end of the current file.
.PP
.IP \fIi\|\fPs
skip \fIi\|\fP lines and print a screenful of lines
.PP
.IP \fIi\|\fPf
skip \fIi\fP screenfuls and print a screenful of lines
.PP
.IP "q or Q"
quit reading the current file; go on to the next (if any)
.PP
.IP "e or q"
When the prompt --More--(Next file: 
.IR file )
is printed, this command causes bzmore to exit.
.PP
.IP s
When the prompt --More--(Next file: 
.IR file )
is printed, this command causes bzmore to skip the next file and continue.
.PP 
.IP =
Display the current line number.
.PP
.IP \fIi\|\fP/expr
search for the \fIi\|\fP-th occurrence of the regular expression \fIexpr.\fP
If the pattern is not found,
.I bzmore
goes on to the next file (if any).
Otherwise, a screenful is displayed, starting two lines before the place
where the expression was found.
The user's erase and kill characters may be used to edit the regular
expression.
Erasing back past the first column cancels the search command.
.PP
.IP \fIi\|\fPn
search for the \fIi\|\fP-th occurrence of the last regular expression entered.
.PP
.IP !command
invoke a shell with \fIcommand\|\fP. 
The character `!' in "command" are replaced with the
previous shell command.  The sequence "\\!" is replaced by "!".
.PP
.IP ":q or :Q"
quit reading the current file; go on to the next (if any)
(same as q or Q).
.PP
.IP .
(dot) repeat the previous command.
.PP
The commands take effect immediately, i.e., it is not necessary to
type a carriage return.
Up to the time when the command character itself is given,
the user may hit the line kill character to cancel the numerical
argument being formed.
In addition, the user may hit the erase character to redisplay the
--More-- message.
.PP
At any time when output is being sent to the terminal, the user can
hit the quit key (normally control\-\\).
.I Bzmore
will stop sending output, and will display the usual --More--
prompt.
The user may then enter one of the above commands in the normal manner.
Unfortunately, some output is lost when this is done, due to the
fact that any characters waiting in the terminal's output queue
are flushed when the quit signal occurs.
.PP
The terminal is set to
.I noecho
mode by this program so that the output can be continuous.
What you type will thus not show on your terminal, except for the / and !
commands.
.PP
If the standard output is not a teletype, then
.I bzmore
acts just like
.I bzcat,
except that a header is printed before each file.
.SH FILES
.DT
/etc/termcap        Terminal data base
.SH "SEE ALSO"
more(1), less(1), bzip2(1), bzdiff(1), bzgrep(1)

--- NEW FILE: bzip2recover.c ---
/*-----------------------------------------------------------*/
/*--- Block recoverer program for bzip2                   ---*/
/*---                                      bzip2recover.c ---*/
/*-----------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */

/* This program is a complete hack and should be rewritten properly.
     It isn't very complicated. */

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>


/* This program records bit locations in the file to be recovered.
   That means that if 64-bit ints are not supported, we will not
   be able to recover .bz2 files over 512MB (2^32 bits) long.
   On GNU supported platforms, we take advantage of the 64-bit
   int support to circumvent this problem.  Ditto MSVC.

   This change occurred in version 1.0.2; all prior versions have
   the 512MB limitation.
*/
#ifdef __GNUC__
   typedef  unsigned long long int  MaybeUInt64;
#  define MaybeUInt64_FMT "%Lu"
#else
#ifdef _MSC_VER
   typedef  unsigned __int64  MaybeUInt64;
#  define MaybeUInt64_FMT "%I64u"
#else
   typedef  unsigned int   MaybeUInt64;
#  define MaybeUInt64_FMT "%u"
#endif
#endif

typedef  unsigned int   UInt32;
typedef  int            Int32;
typedef  unsigned char  UChar;
typedef  char           Char;
typedef  unsigned char  Bool;
#define True    ((Bool)1)
#define False   ((Bool)0)


#define BZ_MAX_FILENAME 2000

Char inFileName[BZ_MAX_FILENAME];
Char outFileName[BZ_MAX_FILENAME];
Char progName[BZ_MAX_FILENAME];

MaybeUInt64 bytesOut = 0;
MaybeUInt64 bytesIn  = 0;


/*---------------------------------------------------*/
/*--- Header bytes                                ---*/
/*---------------------------------------------------*/

#define BZ_HDR_B 0x42                         /* 'B' */
#define BZ_HDR_Z 0x5a                         /* 'Z' */
#define BZ_HDR_h 0x68                         /* 'h' */
#define BZ_HDR_0 0x30                         /* '0' */
 

/*---------------------------------------------------*/
/*--- I/O errors                                  ---*/
/*---------------------------------------------------*/

/*---------------------------------------------*/
static void readError ( void )
{
   fprintf ( stderr,
             "%s: I/O error reading `%s', possible reason follows.\n",
            progName, inFileName );
   perror ( progName );
   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
             progName );
   exit ( 1 );
}


/*---------------------------------------------*/
static void writeError ( void )
{
   fprintf ( stderr,
             "%s: I/O error reading `%s', possible reason follows.\n",
            progName, inFileName );
   perror ( progName );
   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
             progName );
   exit ( 1 );
}


/*---------------------------------------------*/
static void mallocFail ( Int32 n )
{
   fprintf ( stderr,
             "%s: malloc failed on request for %d bytes.\n",
            progName, n );
   fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
             progName );
   exit ( 1 );
}


/*---------------------------------------------*/
static void tooManyBlocks ( Int32 max_handled_blocks )
{
   fprintf ( stderr,
             "%s: `%s' appears to contain more than %d blocks\n",
            progName, inFileName, max_handled_blocks );
   fprintf ( stderr,
             "%s: and cannot be handled.  To fix, increase\n",
             progName );
   fprintf ( stderr, 
             "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
             progName );
   exit ( 1 );
}



/*---------------------------------------------------*/
/*--- Bit stream I/O                              ---*/
/*---------------------------------------------------*/

typedef
   struct {
      FILE*  handle;
      Int32  buffer;
      Int32  buffLive;
      Char   mode;
   }
   BitStream;


/*---------------------------------------------*/
static BitStream* bsOpenReadStream ( FILE* stream )
{
   BitStream *bs = malloc ( sizeof(BitStream) );
   if (bs == NULL) mallocFail ( sizeof(BitStream) );
   bs->handle = stream;
   bs->buffer = 0;
   bs->buffLive = 0;
   bs->mode = 'r';
   return bs;
}


/*---------------------------------------------*/
static BitStream* bsOpenWriteStream ( FILE* stream )
{
   BitStream *bs = malloc ( sizeof(BitStream) );
   if (bs == NULL) mallocFail ( sizeof(BitStream) );
   bs->handle = stream;
   bs->buffer = 0;
   bs->buffLive = 0;
   bs->mode = 'w';
   return bs;
}


/*---------------------------------------------*/
static void bsPutBit ( BitStream* bs, Int32 bit )
{
   if (bs->buffLive == 8) {
      Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
      if (retVal == EOF) writeError();
      bytesOut++;
      bs->buffLive = 1;
      bs->buffer = bit & 0x1;
   } else {
      bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
      bs->buffLive++;
   };
}


/*---------------------------------------------*/
/*--
   Returns 0 or 1, or 2 to indicate EOF.
--*/
static Int32 bsGetBit ( BitStream* bs )
{
   if (bs->buffLive > 0) {
      bs->buffLive --;
      return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
   } else {
      Int32 retVal = getc ( bs->handle );
      if ( retVal == EOF ) {
         if (errno != 0) readError();
         return 2;
      }
      bs->buffLive = 7;
      bs->buffer = retVal;
      return ( ((bs->buffer) >> 7) & 0x1 );
   }
}


/*---------------------------------------------*/
static void bsClose ( BitStream* bs )
{
   Int32 retVal;

   if ( bs->mode == 'w' ) {
      while ( bs->buffLive < 8 ) {
         bs->buffLive++;
         bs->buffer <<= 1;
      };
      retVal = putc ( (UChar) (bs->buffer), bs->handle );
      if (retVal == EOF) writeError();
      bytesOut++;
      retVal = fflush ( bs->handle );
      if (retVal == EOF) writeError();
   }
   retVal = fclose ( bs->handle );
   if (retVal == EOF) {
      if (bs->mode == 'w') writeError(); else readError();
   }
   free ( bs );
}


/*---------------------------------------------*/
static void bsPutUChar ( BitStream* bs, UChar c )
{
   Int32 i;
   for (i = 7; i >= 0; i--)
      bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
}


/*---------------------------------------------*/
static void bsPutUInt32 ( BitStream* bs, UInt32 c )
{
   Int32 i;

   for (i = 31; i >= 0; i--)
      bsPutBit ( bs, (c >> i) & 0x1 );
}


/*---------------------------------------------*/
static Bool endsInBz2 ( Char* name )
{
   Int32 n = strlen ( name );
   if (n <= 4) return False;
   return
      (name[n-4] == '.' &&
       name[n-3] == 'b' &&
       name[n-2] == 'z' &&
       name[n-1] == '2');
}


/*---------------------------------------------------*/
/*---                                             ---*/
/*---------------------------------------------------*/

/* This logic isn't really right when it comes to Cygwin. */
#ifdef _WIN32
#  define  BZ_SPLIT_SYM  '\\'  /* path splitter on Windows platform */
#else
#  define  BZ_SPLIT_SYM  '/'   /* path splitter on Unix platform */
#endif

#define BLOCK_HEADER_HI  0x00003141UL
#define BLOCK_HEADER_LO  0x59265359UL

#define BLOCK_ENDMARK_HI 0x00001772UL
#define BLOCK_ENDMARK_LO 0x45385090UL

/* Increase if necessary.  However, a .bz2 file with > 50000 blocks
   would have an uncompressed size of at least 40GB, so the chances
   are low you'll need to up this.
*/
#define BZ_MAX_HANDLED_BLOCKS 50000

MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
MaybeUInt64 bEnd   [BZ_MAX_HANDLED_BLOCKS];
MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
MaybeUInt64 rbEnd  [BZ_MAX_HANDLED_BLOCKS];

Int32 main ( Int32 argc, Char** argv )
{
   FILE*       inFile;
   FILE*       outFile;
   BitStream*  bsIn, *bsWr;
   Int32       b, wrBlock, currBlock, rbCtr;
   MaybeUInt64 bitsRead;

   UInt32      buffHi, buffLo, blockCRC;
   Char*       p;

   strcpy ( progName, argv[0] );
   inFileName[0] = outFileName[0] = 0;

   fprintf ( stderr, 
             "bzip2recover 1.0.5: extracts blocks from damaged .bz2 files.\n" );

   if (argc != 2) {
      fprintf ( stderr, "%s: usage is `%s damaged_file_name'.\n",
                        progName, progName );
      switch (sizeof(MaybeUInt64)) {
         case 8:
            fprintf(stderr, 
                    "\trestrictions on size of recovered file: None\n");
            break;
         case 4:
            fprintf(stderr, 
                    "\trestrictions on size of recovered file: 512 MB\n");
            fprintf(stderr, 
                    "\tto circumvent, recompile with MaybeUInt64 as an\n"
                    "\tunsigned 64-bit int.\n");
            break;
         default:
            fprintf(stderr, 
                    "\tsizeof(MaybeUInt64) is not 4 or 8 -- "
                    "configuration error.\n");
            break;
      }
      exit(1);
   }

   if (strlen(argv[1]) >= BZ_MAX_FILENAME-20) {
      fprintf ( stderr, 
                "%s: supplied filename is suspiciously (>= %d chars) long.  Bye!\n",
                progName, (int)strlen(argv[1]) );
      exit(1);
   }

   strcpy ( inFileName, argv[1] );

   inFile = fopen ( inFileName, "rb" );
   if (inFile == NULL) {
      fprintf ( stderr, "%s: can't read `%s'\n", progName, inFileName );
      exit(1);
   }

   bsIn = bsOpenReadStream ( inFile );
   fprintf ( stderr, "%s: searching for block boundaries ...\n", progName );

   bitsRead = 0;
   buffHi = buffLo = 0;
   currBlock = 0;
   bStart[currBlock] = 0;

   rbCtr = 0;

   while (True) {
      b = bsGetBit ( bsIn );
      bitsRead++;
      if (b == 2) {
         if (bitsRead >= bStart[currBlock] &&
            (bitsRead - bStart[currBlock]) >= 40) {
            bEnd[currBlock] = bitsRead-1;
            if (currBlock > 0)
               fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
                                 " to " MaybeUInt64_FMT " (incomplete)\n",
                         currBlock,  bStart[currBlock], bEnd[currBlock] );
         } else
            currBlock--;
         break;
      }
      buffHi = (buffHi << 1) | (buffLo >> 31);
      buffLo = (buffLo << 1) | (b & 1);
      if ( ( (buffHi & 0x0000ffff) == BLOCK_HEADER_HI 
             && buffLo == BLOCK_HEADER_LO)
           || 
           ( (buffHi & 0x0000ffff) == BLOCK_ENDMARK_HI 
             && buffLo == BLOCK_ENDMARK_LO)
         ) {
         if (bitsRead > 49) {
            bEnd[currBlock] = bitsRead-49;
         } else {
            bEnd[currBlock] = 0;
         }
         if (currBlock > 0 &&
         (bEnd[currBlock] - bStart[currBlock]) >= 130) {
            fprintf ( stderr, "   block %d runs from " MaybeUInt64_FMT 
                              " to " MaybeUInt64_FMT "\n",
                      rbCtr+1,  bStart[currBlock], bEnd[currBlock] );
            rbStart[rbCtr] = bStart[currBlock];
            rbEnd[rbCtr] = bEnd[currBlock];
            rbCtr++;
         }
         if (currBlock >= BZ_MAX_HANDLED_BLOCKS)
            tooManyBlocks(BZ_MAX_HANDLED_BLOCKS);
         currBlock++;

         bStart[currBlock] = bitsRead;
      }
   }

   bsClose ( bsIn );

   /*-- identified blocks run from 1 to rbCtr inclusive. --*/

   if (rbCtr < 1) {
      fprintf ( stderr,
                "%s: sorry, I couldn't find any block boundaries.\n",
                progName );
      exit(1);
   };

   fprintf ( stderr, "%s: splitting into blocks\n", progName );

   inFile = fopen ( inFileName, "rb" );
   if (inFile == NULL) {
      fprintf ( stderr, "%s: can't open `%s'\n", progName, inFileName );
      exit(1);
   }
   bsIn = bsOpenReadStream ( inFile );

   /*-- placate gcc's dataflow analyser --*/
   blockCRC = 0; bsWr = 0;

   bitsRead = 0;
   outFile = NULL;
   wrBlock = 0;
   while (True) {
      b = bsGetBit(bsIn);
      if (b == 2) break;
      buffHi = (buffHi << 1) | (buffLo >> 31);
      buffLo = (buffLo << 1) | (b & 1);
      if (bitsRead == 47+rbStart[wrBlock]) 
         blockCRC = (buffHi << 16) | (buffLo >> 16);

      if (outFile != NULL && bitsRead >= rbStart[wrBlock]
                          && bitsRead <= rbEnd[wrBlock]) {
         bsPutBit ( bsWr, b );
      }

      bitsRead++;

      if (bitsRead == rbEnd[wrBlock]+1) {
         if (outFile != NULL) {
            bsPutUChar ( bsWr, 0x17 ); bsPutUChar ( bsWr, 0x72 );
            bsPutUChar ( bsWr, 0x45 ); bsPutUChar ( bsWr, 0x38 );
            bsPutUChar ( bsWr, 0x50 ); bsPutUChar ( bsWr, 0x90 );
            bsPutUInt32 ( bsWr, blockCRC );
            bsClose ( bsWr );
         }
         if (wrBlock >= rbCtr) break;
         wrBlock++;
      } else
      if (bitsRead == rbStart[wrBlock]) {
         /* Create the output file name, correctly handling leading paths. 
            (31.10.2001 by Sergey E. Kusikov) */
         Char* split;
         Int32 ofs, k;
         for (k = 0; k < BZ_MAX_FILENAME; k++) 
            outFileName[k] = 0;
         strcpy (outFileName, inFileName);
         split = strrchr (outFileName, BZ_SPLIT_SYM);
         if (split == NULL) {
            split = outFileName;
         } else {
            ++split;
     }
     /* Now split points to the start of the basename. */
         ofs  = split - outFileName;
         sprintf (split, "rec%5d", wrBlock+1);
         for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
         strcat (outFileName, inFileName + ofs);

         if ( !endsInBz2(outFileName)) strcat ( outFileName, ".bz2" );

         fprintf ( stderr, "   writing block %d to `%s' ...\n",
                           wrBlock+1, outFileName );

         outFile = fopen ( outFileName, "wb" );
         if (outFile == NULL) {
            fprintf ( stderr, "%s: can't write `%s'\n",
                      progName, outFileName );
            exit(1);
         }
         bsWr = bsOpenWriteStream ( outFile );
         bsPutUChar ( bsWr, BZ_HDR_B );    
         bsPutUChar ( bsWr, BZ_HDR_Z );    
         bsPutUChar ( bsWr, BZ_HDR_h );    
         bsPutUChar ( bsWr, BZ_HDR_0 + 9 );
         bsPutUChar ( bsWr, 0x31 ); bsPutUChar ( bsWr, 0x41 );
         bsPutUChar ( bsWr, 0x59 ); bsPutUChar ( bsWr, 0x26 );
         bsPutUChar ( bsWr, 0x53 ); bsPutUChar ( bsWr, 0x59 );
      }
   }

   fprintf ( stderr, "%s: finished\n", progName );
   return 0;
}



/*-----------------------------------------------------------*/
/*--- end                                  bzip2recover.c ---*/
/*-----------------------------------------------------------*/

--- NEW FILE: bzip.css ---
/* Colours:
#74240f  dark brown      h1, h2, h3, h4
#336699  medium blue     links
#339999  turquoise       link hover colour
#202020  almost black    general text
#761596  purple          md5sum text
#626262  dark gray       pre border
#eeeeee  very light gray pre background
#f2f2f9  very light blue nav table background
#3366cc  medium blue     nav table border
*/

a, a:link, a:visited, a:active { color: #336699; }
a:hover { color: #339999; }

body { font: 80%/126% sans-serif; }
h1, h2, h3, h4 { color: #74240f; }

dt { color: #336699; font-weight: bold }
dd { 
 margin-left: 1.5em; 
 padding-bottom: 0.8em;
}

/* -- ruler -- */
div.hr_blue { 
  height:  3px; 
  background:#ffffff url("/images/hr_blue.png") repeat-x; }
div.hr_blue hr { display:none; }

/* release styles */
#release p { margin-top: 0.4em; }
#release .md5sum { color: #761596; }


/* ------ styles for docs|manuals|howto ------ */
/* -- lists -- */
ul  { 
 margin:     0px 4px 16px 16px;
 padding:    0px;
 list-style: url("/images/li-blue.png"); 
}
ul li { 
 margin-bottom: 10px;
}
ul ul   { 
 list-style-type:  none; 
 list-style-image: none; 
 margin-left:      0px; 
}

/* header / footer nav tables */
table.nav {
 border:     solid 1px #3366cc;
 background: #f2f2f9;
 background-color: #f2f2f9;
 margin-bottom: 0.5em;
}
/* don't have underlined links in chunked nav menus */
table.nav a { text-decoration: none; }
table.nav a:hover { text-decoration: underline; }
table.nav td { font-size: 85%; }

code, tt, pre { font-size: 120%; }
code, tt { color: #761596; }

div.literallayout, pre.programlisting, pre.screen {
 color:      #000000;
 padding:    0.5em;
 background: #eeeeee;
 border:     1px solid #626262;
 background-color: #eeeeee;
 margin: 4px 0px 4px 0px; 
}

--- NEW FILE: bzip2.1 ---
.PU
.TH bzip2 1
.SH NAME
bzip2, bunzip2 \- a block-sorting file compressor, v1.0.4
.br
bzcat \- decompresses files to stdout
.br
bzip2recover \- recovers data from damaged bzip2 files

.SH SYNOPSIS
.ll +8
.B bzip2
.RB [ " \-cdfkqstvzVL123456789 " ]
[
.I "filenames \&..."
]
.ll -8
.br
.B bunzip2
.RB [ " \-fkvsVL " ]
[ 
.I "filenames \&..."
]
.br
.B bzcat
.RB [ " \-s " ]
[ 
.I "filenames \&..."
]
.br
.B bzip2recover
.I "filename"

.SH DESCRIPTION
.I bzip2
compresses files using the Burrows-Wheeler block sorting
text compression algorithm, and Huffman coding.  Compression is
generally considerably better than that achieved by more conventional
LZ77/LZ78-based compressors, and approaches the performance of the PPM
family of statistical compressors.

The command-line options are deliberately very similar to 
those of 
.I GNU gzip, 
but they are not identical.

.I bzip2
expects a list of file names to accompany the
command-line flags.  Each file is replaced by a compressed version of
itself, with the name "original_name.bz2".  
Each compressed file
has the same modification date, permissions, and, when possible,
ownership as the corresponding original, so that these properties can
be correctly restored at decompression time.  File name handling is
naive in the sense that there is no mechanism for preserving original
file names, permissions, ownerships or dates in filesystems which lack
these concepts, or have serious file name length restrictions, such as
MS-DOS.

.I bzip2
and
.I bunzip2
will by default not overwrite existing
files.  If you want this to happen, specify the \-f flag.

If no file names are specified,
.I bzip2
compresses from standard
input to standard output.  In this case,
.I bzip2
will decline to
write compressed output to a terminal, as this would be entirely
incomprehensible and therefore pointless.

.I bunzip2
(or
.I bzip2 \-d) 
decompresses all
specified files.  Files which were not created by 
.I bzip2
will be detected and ignored, and a warning issued.  
.I bzip2
attempts to guess the filename for the decompressed file 
from that of the compressed file as follows:

       filename.bz2    becomes   filename
       filename.bz     becomes   filename
       filename.tbz2   becomes   filename.tar
       filename.tbz    becomes   filename.tar
       anyothername    becomes   anyothername.out

If the file does not end in one of the recognised endings, 
.I .bz2, 
.I .bz, 
.I .tbz2
or
.I .tbz, 
.I bzip2 
complains that it cannot
guess the name of the original file, and uses the original name
with
.I .out
appended.

As with compression, supplying no
filenames causes decompression from 
standard input to standard output.

.I bunzip2 
will correctly decompress a file which is the
concatenation of two or more compressed files.  The result is the
concatenation of the corresponding uncompressed files.  Integrity
testing (\-t) 
of concatenated 
compressed files is also supported.

You can also compress or decompress files to the standard output by
giving the \-c flag.  Multiple files may be compressed and
decompressed like this.  The resulting outputs are fed sequentially to
stdout.  Compression of multiple files 
in this manner generates a stream
containing multiple compressed file representations.  Such a stream
can be decompressed correctly only by
.I bzip2 
version 0.9.0 or
later.  Earlier versions of
.I bzip2
will stop after decompressing
the first file in the stream.

.I bzcat
(or
.I bzip2 -dc) 
decompresses all specified files to
the standard output.

.I bzip2
will read arguments from the environment variables
.I BZIP2
and
.I BZIP,
in that order, and will process them
before any arguments read from the command line.  This gives a 
convenient way to supply default arguments.

Compression is always performed, even if the compressed 
file is slightly
larger than the original.  Files of less than about one hundred bytes
tend to get larger, since the compression mechanism has a constant
overhead in the region of 50 bytes.  Random data (including the output
of most file compressors) is coded at about 8.05 bits per byte, giving
an expansion of around 0.5%.

As a self-check for your protection, 
.I 
bzip2
uses 32-bit CRCs to
make sure that the decompressed version of a file is identical to the
original.  This guards against corruption of the compressed data, and
against undetected bugs in
.I bzip2
(hopefully very unlikely).  The
chances of data corruption going undetected is microscopic, about one
chance in four billion for each file processed.  Be aware, though, that
the check occurs upon decompression, so it can only tell you that
something is wrong.  It can't help you 
recover the original uncompressed
data.  You can use 
.I bzip2recover
to try to recover data from
damaged files.

Return values: 0 for a normal exit, 1 for environmental problems (file
not found, invalid flags, I/O errors, &c), 2 to indicate a corrupt
compressed file, 3 for an internal consistency error (eg, bug) which
caused
.I bzip2
to panic.

.SH OPTIONS
.TP
.B \-c --stdout
Compress or decompress to standard output.
.TP
.B \-d --decompress
Force decompression.  
.I bzip2, 
.I bunzip2 
and
.I bzcat 
are
really the same program, and the decision about what actions to take is
done on the basis of which name is used.  This flag overrides that
mechanism, and forces 
.I bzip2
to decompress.
.TP
.B \-z --compress
The complement to \-d: forces compression, regardless of the
invocation name.
.TP
.B \-t --test
Check integrity of the specified file(s), but don't decompress them.
This really performs a trial decompression and throws away the result.
.TP
.B \-f --force
Force overwrite of output files.  Normally,
.I bzip2 
will not overwrite
existing output files.  Also forces 
.I bzip2 
to break hard links
to files, which it otherwise wouldn't do.

bzip2 normally declines to decompress files which don't have the
correct magic header bytes.  If forced (-f), however, it will pass
such files through unmodified.  This is how GNU gzip behaves.
.TP
.B \-k --keep
Keep (don't delete) input files during compression
or decompression.
.TP
.B \-s --small
Reduce memory usage, for compression, decompression and testing.  Files
are decompressed and tested using a modified algorithm which only
requires 2.5 bytes per block byte.  This means any file can be
decompressed in 2300k of memory, albeit at about half the normal speed.

During compression, \-s selects a block size of 200k, which limits
memory use to around the same figure, at the expense of your compression
ratio.  In short, if your machine is low on memory (8 megabytes or
less), use \-s for everything.  See MEMORY MANAGEMENT below.
.TP
.B \-q --quiet
Suppress non-essential warning messages.  Messages pertaining to
I/O errors and other critical events will not be suppressed.
.TP
.B \-v --verbose
Verbose mode -- show the compression ratio for each file processed.
Further \-v's increase the verbosity level, spewing out lots of
information which is primarily of interest for diagnostic purposes.
.TP
.B \-L --license -V --version
Display the software version, license terms and conditions.
.TP
.B \-1 (or \-\-fast) to \-9 (or \-\-best)
Set the block size to 100 k, 200 k ..  900 k when compressing.  Has no
effect when decompressing.  See MEMORY MANAGEMENT below.
The \-\-fast and \-\-best aliases are primarily for GNU gzip 
compatibility.  In particular, \-\-fast doesn't make things
significantly faster.  
And \-\-best merely selects the default behaviour.
.TP
.B \--
Treats all subsequent arguments as file names, even if they start
with a dash.  This is so you can handle files with names beginning
with a dash, for example: bzip2 \-- \-myfilename.
.TP
.B \--repetitive-fast --repetitive-best
These flags are redundant in versions 0.9.5 and above.  They provided
some coarse control over the behaviour of the sorting algorithm in
earlier versions, which was sometimes useful.  0.9.5 and above have an
improved algorithm which renders these flags irrelevant.

.SH MEMORY MANAGEMENT
.I bzip2 
compresses large files in blocks.  The block size affects
both the compression ratio achieved, and the amount of memory needed for
compression and decompression.  The flags \-1 through \-9
specify the block size to be 100,000 bytes through 900,000 bytes (the
default) respectively.  At decompression time, the block size used for
compression is read from the header of the compressed file, and
.I bunzip2
then allocates itself just enough memory to decompress
the file.  Since block sizes are stored in compressed files, it follows
that the flags \-1 to \-9 are irrelevant to and so ignored
during decompression.

Compression and decompression requirements, 
in bytes, can be estimated as:

       Compression:   400k + ( 8 x block size )

       Decompression: 100k + ( 4 x block size ), or
                      100k + ( 2.5 x block size )

Larger block sizes give rapidly diminishing marginal returns.  Most of
the compression comes from the first two or three hundred k of block
size, a fact worth bearing in mind when using
.I bzip2
on small machines.
It is also important to appreciate that the decompression memory
requirement is set at compression time by the choice of block size.

For files compressed with the default 900k block size,
.I bunzip2
will require about 3700 kbytes to decompress.  To support decompression
of any file on a 4 megabyte machine, 
.I bunzip2
has an option to
decompress using approximately half this amount of memory, about 2300
kbytes.  Decompression speed is also halved, so you should use this
option only where necessary.  The relevant flag is -s.

In general, try and use the largest block size memory constraints allow,
since that maximises the compression achieved.  Compression and
decompression speed are virtually unaffected by block size.

Another significant point applies to files which fit in a single block
-- that means most files you'd encounter using a large block size.  The
amount of real memory touched is proportional to the size of the file,
since the file is smaller than a block.  For example, compressing a file
20,000 bytes long with the flag -9 will cause the compressor to
allocate around 7600k of memory, but only touch 400k + 20000 * 8 = 560
kbytes of it.  Similarly, the decompressor will allocate 3700k but only
touch 100k + 20000 * 4 = 180 kbytes.

Here is a table which summarises the maximum memory usage for different
block sizes.  Also recorded is the total compressed size for 14 files of
the Calgary Text Compression Corpus totalling 3,141,622 bytes.  This
column gives some feel for how compression varies with block size.
These figures tend to understate the advantage of larger block sizes for
larger files, since the Corpus is dominated by smaller files.

           Compress   Decompress   Decompress   Corpus
    Flag     usage      usage       -s usage     Size

     -1      1200k       500k         350k      914704
     -2      2000k       900k         600k      877703
     -3      2800k      1300k         850k      860338
     -4      3600k      1700k        1100k      846899
     -5      4400k      2100k        1350k      845160
     -6      5200k      2500k        1600k      838626
     -7      6100k      2900k        1850k      834096
     -8      6800k      3300k        2100k      828642
     -9      7600k      3700k        2350k      828642

.SH RECOVERING DATA FROM DAMAGED FILES
.I bzip2
compresses files in blocks, usually 900kbytes long.  Each
block is handled independently.  If a media or transmission error causes
a multi-block .bz2
file to become damaged, it may be possible to
recover data from the undamaged blocks in the file.

The compressed representation of each block is delimited by a 48-bit
pattern, which makes it possible to find the block boundaries with
reasonable certainty.  Each block also carries its own 32-bit CRC, so
damaged blocks can be distinguished from undamaged ones.

.I bzip2recover
is a simple program whose purpose is to search for
blocks in .bz2 files, and write each block out into its own .bz2 
file.  You can then use
.I bzip2 
\-t
to test the
integrity of the resulting files, and decompress those which are
undamaged.

.I bzip2recover
takes a single argument, the name of the damaged file, 
and writes a number of files "rec00001file.bz2",
"rec00002file.bz2", etc, containing the  extracted  blocks.
The  output  filenames  are  designed  so  that the use of
wildcards in subsequent processing -- for example,  
"bzip2 -dc  rec*file.bz2 > recovered_data" -- processes the files in
the correct order.

.I bzip2recover
should be of most use dealing with large .bz2
files,  as  these will contain many blocks.  It is clearly
futile to use it on damaged single-block  files,  since  a
damaged  block  cannot  be recovered.  If you wish to minimise 
any potential data loss through media  or  transmission errors, 
you might consider compressing with a smaller
block size.

.SH PERFORMANCE NOTES
The sorting phase of compression gathers together similar strings in the
file.  Because of this, files containing very long runs of repeated
symbols, like "aabaabaabaab ..."  (repeated several hundred times) may
compress more slowly than normal.  Versions 0.9.5 and above fare much
better than previous versions in this respect.  The ratio between
worst-case and average-case compression time is in the region of 10:1.
For previous versions, this figure was more like 100:1.  You can use the
\-vvvv option to monitor progress in great detail, if you want.

Decompression speed is unaffected by these phenomena.

.I bzip2
usually allocates several megabytes of memory to operate
in, and then charges all over it in a fairly random fashion.  This means
that performance, both for compressing and decompressing, is largely
determined by the speed at which your machine can service cache misses.
Because of this, small changes to the code to reduce the miss rate have
been observed to give disproportionately large performance improvements.
I imagine 
.I bzip2
will perform best on machines with very large caches.

.SH CAVEATS
I/O error messages are not as helpful as they could be.
.I bzip2
tries hard to detect I/O errors and exit cleanly, but the details of
what the problem is sometimes seem rather misleading.

This manual page pertains to version 1.0.4 of
.I bzip2.  
Compressed data created by this version is entirely forwards and
backwards compatible with the previous public releases, versions
0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1, 1.0.2 and 1.0.3, but with the following
exception: 0.9.0 and above can correctly decompress multiple
concatenated compressed files.  0.1pl2 cannot do this; it will stop
after decompressing just the first file in the stream.

.I bzip2recover
versions prior to 1.0.2 used 32-bit integers to represent
bit positions in compressed files, so they could not handle compressed
files more than 512 megabytes long.  Versions 1.0.2 and above use
64-bit ints on some platforms which support them (GNU supported
targets, and Windows).  To establish whether or not bzip2recover was
built with such a limitation, run it without arguments.  In any event
you can build yourself an unlimited version if you can recompile it
with MaybeUInt64 set to be an unsigned 64-bit integer.



.SH AUTHOR
Julian Seward, jsewardbzip.org.

http://www.bzip.org

The ideas embodied in
.I bzip2
are due to (at least) the following
people: Michael Burrows and David Wheeler (for the block sorting
transformation), David Wheeler (again, for the Huffman coder), Peter
Fenwick (for the structured coding model in the original
.I bzip,
and many refinements), and Alistair Moffat, Radford Neal and Ian Witten
(for the arithmetic coder in the original
.I bzip).  
I am much
indebted for their help, support and advice.  See the manual in the
source distribution for pointers to sources of documentation.  Christian
von Roques encouraged me to look for faster sorting algorithms, so as to
speed up compression.  Bela Lubkin encouraged me to improve the
worst-case compression performance.  
Donna Robinson XMLised the documentation.
The bz* scripts are derived from those of GNU gzip.
Many people sent patches, helped
with portability problems, lent machines, gave advice and were generally
helpful.

--- NEW FILE: bz-common.xsl ---
<?xml version="1.0"?> <!-- -*- sgml -*- -->
<xsl:stylesheet 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<!-- we like '1.2 Title' -->
<xsl:param name="section.autolabel" select="'1'"/> 
<xsl:param name="section.label.includes.component.label" select="'1'"/>

<!-- Do not put 'Chapter' at the start of eg 'Chapter 1. Doing This' -->
<xsl:param name="local.l10n.xml" select="document('')"/> 
<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> 
  <l:l10n language="en"> 
    <l:context name="title-numbered">
      <l:template name="chapter" text="%n.&#160;%t"/>
    </l:context> 
  </l:l10n>
</l:i18n>

<!-- don't generate sub-tocs for qanda sets -->
<xsl:param name="generate.toc">
set       toc,title
book      toc,title,figure,table,example,equation
chapter   toc,title
section   toc
sect1     toc
sect2     toc
sect3     toc
sect4     nop
sect5     nop
qandaset  toc
qandadiv  nop
appendix  toc,title
article/appendix  nop
article   toc,title
preface   toc,title
reference toc,title
</xsl:param>

</xsl:stylesheet>

--- NEW FILE: sample2.bz2 ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: mk251.c ---

/* Spew out a long sequence of the byte 251.  When fed to bzip2
   versions 1.0.0 or 1.0.1, causes it to die with internal error
   1007 in blocksort.c.  This assertion misses an extremely rare
   case, which is fixed in this version (1.0.2) and above.
*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#include <stdio.h>

int main ()
{
   int i;
   for (i = 0; i < 48500000 ; i++)
     putchar(251);
   return 0;
}

--- NEW FILE: README.XML.STUFF ---
  ----------------------------------------------------------------
  This file is part of bzip2/libbzip2, a program and library for
  lossless, block-sorting data compression.

  bzip2/libbzip2 version 1.0.5 of 10 December 2007
  Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
  README file.

  This program is released under the terms of the license contained
  in the file LICENSE.
  ----------------------------------------------------------------

The script xmlproc.sh takes an xml file as input,
and processes it to create .pdf, .html or .ps output.
It uses format.pl, a perl script to format <pre> blocks nicely,
 and add CDATA tags so writers do not have to use eg. &lt; 

The file "entities.xml" must be edited to reflect current
version, year, etc.


Usage:

  ./xmlproc.sh -v manual.xml
  Validates an xml file to ensure no dtd-compliance errors

  ./xmlproc.sh -html manual.xml
  Output: manual.html

  ./xmlproc.sh -pdf manual.xml
  Output: manual.pdf

  ./xmlproc.sh -ps manual.xml
  Output: manual.ps


Notum bene: 
- pdfxmltex barfs if given a filename with an underscore in it

- xmltex won't work yet - there's a bug in passivetex
    which we are all waiting for Sebastian to fix.
  So we are going the xml -> pdf -> ps route for the time being,
    using pdfxmltex.

--- NEW FILE: sample2.tst ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: entities.xml ---
<!-- misc. strings -->
<!ENTITY bz-url "http://www.bzip.org">
<!ENTITY bz-email "jseward at bzip.org">
<!ENTITY bz-lifespan "1996-2007">

<!ENTITY bz-version "1.0.5">
<!ENTITY bz-date "10 December 2007">

<!ENTITY manual-title "bzip2 Manual">

--- NEW FILE: manual.xml ---
<?xml version="1.0"?> <!-- -*- sgml -*- -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"[

<!-- various strings, dates etc. common to all docs -->
<!ENTITY % common-ents SYSTEM "entities.xml"> %common-ents;
]>

<book lang="en" id="userman" xreflabel="bzip2 Manual">

 <bookinfo>
  <title>bzip2 and libbzip2, version 1.0.5</title>
  <subtitle>A program and library for data compression</subtitle>
  <copyright>
   <year>&bz-lifespan;</year>
   <holder>Julian Seward</holder>
  </copyright>
  <releaseinfo>Version &bz-version; of &bz-date;</releaseinfo>

[...2925 lines suppressed...]
<para>Finally, the following papers document some
investigations I made into the performance of sorting
and decompression algorithms:</para>

<literallayout>Julian Seward
   On the Performance of BWT Sorting Algorithms
   Proceedings of the IEEE Data Compression Conference 2000
     Snowbird, Utah.  28-30 March 2000.

Julian Seward
   Space-time Tradeoffs in the Inverse B-W Transform
   Proceedings of the IEEE Data Compression Conference 2001
     Snowbird, Utah.  27-29 March 2001.
</literallayout>

</sect1>

</chapter>

</book>

--- NEW FILE: manual.ps ---
%!PS-Adobe-3.0
%%Creator: xpdf/pdftops 3.01
%%LanguageLevel: 2
%%DocumentSuppliedResources: (atend)
%%DocumentMedia: plain 612 792 0 () ()
%%BoundingBox: 0 0 612 792
%%Pages: 38
%%EndComments
%%BeginDefaults
%%PageMedia: plain
%%EndDefaults
%%BeginProlog
%%BeginResource: procset xpdf 3.01 0
/xpdf 75 dict def xpdf begin
% PDF special state
/pdfDictSize 15 def
/pdfSetup {
  3 1 roll 2 array astore
  /setpagedevice where {
[...82861 lines suppressed...]
[1 0 0 1 -13.1436 0] cm
/DeviceGray {} cs
[0] sc
/DeviceGray {} CS
[0] SC
Q
showpage
%%PageTrailer
pdfEndPage
%%Trailer
end
%%DocumentSuppliedResources:
%%+ font DTUUHP+NimbusSanL-Bold
%%+ font VXAMRV+NimbusRomNo9L-Regu
%%+ font MFECUR+NimbusMonL-Regu
%%+ font ZOVMRD+CMMI10
%%+ font ERVBFT+NimbusMonL-Bold
%%+ font BZXIEB+CMSY10
%%+ font WWWUTU+NimbusRomNo9L-ReguItal
%%EOF

--- NEW FILE: bzdiff.1 ---
\"Shamelessly copied from zmore.1 by Philippe Troin <phil at fifi.org>
\"for Debian GNU/Linux
.TH BZDIFF 1
.SH NAME
bzcmp, bzdiff \- compare bzip2 compressed files
.SH SYNOPSIS
.B bzcmp
[ cmp_options ] file1
[ file2 ]
.br
.B bzdiff
[ diff_options ] file1
[ file2 ]
.SH DESCRIPTION
.I  Bzcmp
and 
.I bzdiff
are used to invoke the
.I cmp
or the
.I diff
program on bzip2 compressed files.  All options specified are passed
directly to
.I cmp
or
.IR diff "."
If only 1 file is specified, then the files compared are
.I file1
and an uncompressed
.IR file1 ".bz2."
If two files are specified, then they are uncompressed if necessary and fed to
.I cmp
or
.IR diff "."
The exit status from 
.I cmp
or
.I diff
is preserved.
.SH "SEE ALSO"
cmp(1), diff(1), bzmore(1), bzless(1), bzgrep(1), bzip2(1)
.SH BUGS
Messages from the
.I cmp
or
.I diff
programs refer to temporary filenames instead of those specified.

--- NEW FILE: dlltest.dsp ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: blocksort.c ---

/*-------------------------------------------------------------*/
/*--- Block sorting machinery                               ---*/
/*---                                           blocksort.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */
[...1055 lines suppressed...]
      if (budget < 0) {
         if (verb >= 2) 
            VPrintf0 ( "    too repetitive; using fallback"
                       " sorting algorithm\n" );
         fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb );
      }
   }

   s->origPtr = -1;
   for (i = 0; i < s->nblock; i++)
      if (ptr[i] == 0)
         { s->origPtr = i; break; };

   AssertH( s->origPtr != -1, 1003 );
}


/*-------------------------------------------------------------*/
/*--- end                                       blocksort.c ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: libbz2.lib ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: bzip2.1.preformatted ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: decompress.c ---

/*-------------------------------------------------------------*/
/*--- Decompression machinery                               ---*/
/*---                                          decompress.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#include "bzlib_private.h"


/*---------------------------------------------------*/
static
void makeMaps_d ( DState* s )
{
   Int32 i;
   s->nInUse = 0;
   for (i = 0; i < 256; i++)
      if (s->inUse[i]) {
         s->seqToUnseq[s->nInUse] = i;
         s->nInUse++;
      }
}


/*---------------------------------------------------*/
#define RETURN(rrr)                               \
   { retVal = rrr; goto save_state_and_return; };

#define GET_BITS(lll,vvv,nnn)                     \
   case lll: s->state = lll;                      \
   while (True) {                                 \
      if (s->bsLive >= nnn) {                     \
         UInt32 v;                                \
         v = (s->bsBuff >>                        \
             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
         s->bsLive -= nnn;                        \
         vvv = v;                                 \
         break;                                   \
      }                                           \
      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
      s->bsBuff                                   \
         = (s->bsBuff << 8) |                     \
           ((UInt32)                              \
              (*((UChar*)(s->strm->next_in))));   \
      s->bsLive += 8;                             \
      s->strm->next_in++;                         \
      s->strm->avail_in--;                        \
      s->strm->total_in_lo32++;                   \
      if (s->strm->total_in_lo32 == 0)            \
         s->strm->total_in_hi32++;                \
   }

#define GET_UCHAR(lll,uuu)                        \
   GET_BITS(lll,uuu,8)

#define GET_BIT(lll,uuu)                          \
   GET_BITS(lll,uuu,1)

/*---------------------------------------------------*/
#define GET_MTF_VAL(label1,label2,lval)           \
{                                                 \
   if (groupPos == 0) {                           \
      groupNo++;                                  \
      if (groupNo >= nSelectors)                  \
         RETURN(BZ_DATA_ERROR);                   \
      groupPos = BZ_G_SIZE;                       \
      gSel = s->selector[groupNo];                \
      gMinlen = s->minLens[gSel];                 \
      gLimit = &(s->limit[gSel][0]);              \
      gPerm = &(s->perm[gSel][0]);                \
      gBase = &(s->base[gSel][0]);                \
   }                                              \
   groupPos--;                                    \
   zn = gMinlen;                                  \
   GET_BITS(label1, zvec, zn);                    \
   while (1) {                                    \
      if (zn > 20 /* the longest code */)         \
         RETURN(BZ_DATA_ERROR);                   \
      if (zvec <= gLimit[zn]) break;              \
      zn++;                                       \
      GET_BIT(label2, zj);                        \
      zvec = (zvec << 1) | zj;                    \
   };                                             \
   if (zvec - gBase[zn] < 0                       \
       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
      RETURN(BZ_DATA_ERROR);                      \
   lval = gPerm[zvec - gBase[zn]];                \
}


/*---------------------------------------------------*/
Int32 BZ2_decompress ( DState* s )
{
   UChar      uc;
   Int32      retVal;
   Int32      minLen, maxLen;
   bz_stream* strm = s->strm;

   /* stuff that needs to be saved/restored */
   Int32  i;
   Int32  j;
   Int32  t;
   Int32  alphaSize;
   Int32  nGroups;
   Int32  nSelectors;
   Int32  EOB;
   Int32  groupNo;
   Int32  groupPos;
   Int32  nextSym;
   Int32  nblockMAX;
   Int32  nblock;
   Int32  es;
   Int32  N;
   Int32  curr;
   Int32  zt;
   Int32  zn; 
   Int32  zvec;
   Int32  zj;
   Int32  gSel;
   Int32  gMinlen;
   Int32* gLimit;
   Int32* gBase;
   Int32* gPerm;

   if (s->state == BZ_X_MAGIC_1) {
      /*initialise the save area*/
      s->save_i           = 0;
      s->save_j           = 0;
      s->save_t           = 0;
      s->save_alphaSize   = 0;
      s->save_nGroups     = 0;
      s->save_nSelectors  = 0;
      s->save_EOB         = 0;
      s->save_groupNo     = 0;
      s->save_groupPos    = 0;
      s->save_nextSym     = 0;
      s->save_nblockMAX   = 0;
      s->save_nblock      = 0;
      s->save_es          = 0;
      s->save_N           = 0;
      s->save_curr        = 0;
      s->save_zt          = 0;
      s->save_zn          = 0;
      s->save_zvec        = 0;
      s->save_zj          = 0;
      s->save_gSel        = 0;
      s->save_gMinlen     = 0;
      s->save_gLimit      = NULL;
      s->save_gBase       = NULL;
      s->save_gPerm       = NULL;
   }

   /*restore from the save area*/
   i           = s->save_i;
   j           = s->save_j;
   t           = s->save_t;
   alphaSize   = s->save_alphaSize;
   nGroups     = s->save_nGroups;
   nSelectors  = s->save_nSelectors;
   EOB         = s->save_EOB;
   groupNo     = s->save_groupNo;
   groupPos    = s->save_groupPos;
   nextSym     = s->save_nextSym;
   nblockMAX   = s->save_nblockMAX;
   nblock      = s->save_nblock;
   es          = s->save_es;
   N           = s->save_N;
   curr        = s->save_curr;
   zt          = s->save_zt;
   zn          = s->save_zn; 
   zvec        = s->save_zvec;
   zj          = s->save_zj;
   gSel        = s->save_gSel;
   gMinlen     = s->save_gMinlen;
   gLimit      = s->save_gLimit;
   gBase       = s->save_gBase;
   gPerm       = s->save_gPerm;

   retVal = BZ_OK;

   switch (s->state) {

      GET_UCHAR(BZ_X_MAGIC_1, uc);
      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);

      GET_UCHAR(BZ_X_MAGIC_2, uc);
      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);

      GET_UCHAR(BZ_X_MAGIC_3, uc)
      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);

      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
      if (s->blockSize100k < (BZ_HDR_0 + 1) || 
          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
      s->blockSize100k -= BZ_HDR_0;

      if (s->smallDecompress) {
         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
         s->ll4  = BZALLOC( 
                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
                   );
         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
      } else {
         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
      }

      GET_UCHAR(BZ_X_BLKHDR_1, uc);

      if (uc == 0x17) goto endhdr_2;
      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_BLKHDR_2, uc);
      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_BLKHDR_3, uc);
      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_BLKHDR_4, uc);
      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_BLKHDR_5, uc);
      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_BLKHDR_6, uc);
      if (uc != 0x59) RETURN(BZ_DATA_ERROR);

      s->currBlockNo++;
      if (s->verbosity >= 2)
         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
 
      s->storedBlockCRC = 0;
      GET_UCHAR(BZ_X_BCRC_1, uc);
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
      GET_UCHAR(BZ_X_BCRC_2, uc);
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
      GET_UCHAR(BZ_X_BCRC_3, uc);
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
      GET_UCHAR(BZ_X_BCRC_4, uc);
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);

      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);

      s->origPtr = 0;
      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
      s->origPtr = (s->origPtr << 8) | ((Int32)uc);

      if (s->origPtr < 0)
         RETURN(BZ_DATA_ERROR);
      if (s->origPtr > 10 + 100000*s->blockSize100k) 
         RETURN(BZ_DATA_ERROR);

      /*--- Receive the mapping table ---*/
      for (i = 0; i < 16; i++) {
         GET_BIT(BZ_X_MAPPING_1, uc);
         if (uc == 1) 
            s->inUse16[i] = True; else 
            s->inUse16[i] = False;
      }

      for (i = 0; i < 256; i++) s->inUse[i] = False;

      for (i = 0; i < 16; i++)
         if (s->inUse16[i])
            for (j = 0; j < 16; j++) {
               GET_BIT(BZ_X_MAPPING_2, uc);
               if (uc == 1) s->inUse[i * 16 + j] = True;
            }
      makeMaps_d ( s );
      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
      alphaSize = s->nInUse+2;

      /*--- Now the selectors ---*/
      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
      for (i = 0; i < nSelectors; i++) {
         j = 0;
         while (True) {
            GET_BIT(BZ_X_SELECTOR_3, uc);
            if (uc == 0) break;
            j++;
            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
         }
         s->selectorMtf[i] = j;
      }

      /*--- Undo the MTF values for the selectors. ---*/
      {
         UChar pos[BZ_N_GROUPS], tmp, v;
         for (v = 0; v < nGroups; v++) pos[v] = v;
   
         for (i = 0; i < nSelectors; i++) {
            v = s->selectorMtf[i];
            tmp = pos[v];
            while (v > 0) { pos[v] = pos[v-1]; v--; }
            pos[0] = tmp;
            s->selector[i] = tmp;
         }
      }

      /*--- Now the coding tables ---*/
      for (t = 0; t < nGroups; t++) {
         GET_BITS(BZ_X_CODING_1, curr, 5);
         for (i = 0; i < alphaSize; i++) {
            while (True) {
               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
               GET_BIT(BZ_X_CODING_2, uc);
               if (uc == 0) break;
               GET_BIT(BZ_X_CODING_3, uc);
               if (uc == 0) curr++; else curr--;
            }
            s->len[t][i] = curr;
         }
      }

      /*--- Create the Huffman decoding tables ---*/
      for (t = 0; t < nGroups; t++) {
         minLen = 32;
         maxLen = 0;
         for (i = 0; i < alphaSize; i++) {
            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
            if (s->len[t][i] < minLen) minLen = s->len[t][i];
         }
         BZ2_hbCreateDecodeTables ( 
            &(s->limit[t][0]), 
            &(s->base[t][0]), 
            &(s->perm[t][0]), 
            &(s->len[t][0]),
            minLen, maxLen, alphaSize
         );
         s->minLens[t] = minLen;
      }

      /*--- Now the MTF values ---*/

      EOB      = s->nInUse+1;
      nblockMAX = 100000 * s->blockSize100k;
      groupNo  = -1;
      groupPos = 0;

      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;

      /*-- MTF init --*/
      {
         Int32 ii, jj, kk;
         kk = MTFA_SIZE-1;
         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
               kk--;
            }
            s->mtfbase[ii] = kk + 1;
         }
      }
      /*-- end MTF init --*/

      nblock = 0;
      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);

      while (True) {

         if (nextSym == EOB) break;

         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {

            es = -1;
            N = 1;
            do {
               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
               N = N * 2;
               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
            }
               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);

            es++;
            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
            s->unzftab[uc] += es;

            if (s->smallDecompress)
               while (es > 0) {
                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
                  s->ll16[nblock] = (UInt16)uc;
                  nblock++;
                  es--;
               }
            else
               while (es > 0) {
                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
                  s->tt[nblock] = (UInt32)uc;
                  nblock++;
                  es--;
               };

            continue;

         } else {

            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);

            /*-- uc = MTF ( nextSym-1 ) --*/
            {
               Int32 ii, jj, kk, pp, lno, off;
               UInt32 nn;
               nn = (UInt32)(nextSym - 1);

               if (nn < MTFL_SIZE) {
                  /* avoid general-case expense */
                  pp = s->mtfbase[0];
                  uc = s->mtfa[pp+nn];
                  while (nn > 3) {
                     Int32 z = pp+nn;
                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
                     nn -= 4;
                  }
                  while (nn > 0) { 
                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
                  };
                  s->mtfa[pp] = uc;
               } else { 
                  /* general case */
                  lno = nn / MTFL_SIZE;
                  off = nn % MTFL_SIZE;
                  pp = s->mtfbase[lno] + off;
                  uc = s->mtfa[pp];
                  while (pp > s->mtfbase[lno]) { 
                     s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
                  };
                  s->mtfbase[lno]++;
                  while (lno > 0) {
                     s->mtfbase[lno]--;
                     s->mtfa[s->mtfbase[lno]] 
                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
                     lno--;
                  }
                  s->mtfbase[0]--;
                  s->mtfa[s->mtfbase[0]] = uc;
                  if (s->mtfbase[0] == 0) {
                     kk = MTFA_SIZE-1;
                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
                           kk--;
                        }
                        s->mtfbase[ii] = kk + 1;
                     }
                  }
               }
            }
            /*-- end uc = MTF ( nextSym-1 ) --*/

            s->unzftab[s->seqToUnseq[uc]]++;
            if (s->smallDecompress)
               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
            nblock++;

            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
            continue;
         }
      }

      /* Now we know what nblock is, we can do a better sanity
         check on s->origPtr.
      */
      if (s->origPtr < 0 || s->origPtr >= nblock)
         RETURN(BZ_DATA_ERROR);

      /*-- Set up cftab to facilitate generation of T^(-1) --*/
      s->cftab[0] = 0;
      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
      for (i = 0; i <= 256; i++) {
         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
            /* s->cftab[i] can legitimately be == nblock */
            RETURN(BZ_DATA_ERROR);
         }
      }

      s->state_out_len = 0;
      s->state_out_ch  = 0;
      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
      s->state = BZ_X_OUTPUT;
      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );

      if (s->smallDecompress) {

         /*-- Make a copy of cftab, used in generation of T --*/
         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];

         /*-- compute the T vector --*/
         for (i = 0; i < nblock; i++) {
            uc = (UChar)(s->ll16[i]);
            SET_LL(i, s->cftabCopy[uc]);
            s->cftabCopy[uc]++;
         }

         /*-- Compute T^(-1) by pointer reversal on T --*/
         i = s->origPtr;
         j = GET_LL(i);
         do {
            Int32 tmp = GET_LL(j);
            SET_LL(j, i);
            i = j;
            j = tmp;
         }
            while (i != s->origPtr);

         s->tPos = s->origPtr;
         s->nblock_used = 0;
         if (s->blockRandomised) {
            BZ_RAND_INIT_MASK;
            BZ_GET_SMALL(s->k0); s->nblock_used++;
            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
         } else {
            BZ_GET_SMALL(s->k0); s->nblock_used++;
         }

      } else {

         /*-- compute the T^(-1) vector --*/
         for (i = 0; i < nblock; i++) {
            uc = (UChar)(s->tt[i] & 0xff);
            s->tt[s->cftab[uc]] |= (i << 8);
            s->cftab[uc]++;
         }

         s->tPos = s->tt[s->origPtr] >> 8;
         s->nblock_used = 0;
         if (s->blockRandomised) {
            BZ_RAND_INIT_MASK;
            BZ_GET_FAST(s->k0); s->nblock_used++;
            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
         } else {
            BZ_GET_FAST(s->k0); s->nblock_used++;
         }

      }

      RETURN(BZ_OK);



    endhdr_2:

      GET_UCHAR(BZ_X_ENDHDR_2, uc);
      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_ENDHDR_3, uc);
      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_ENDHDR_4, uc);
      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_ENDHDR_5, uc);
      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
      GET_UCHAR(BZ_X_ENDHDR_6, uc);
      if (uc != 0x90) RETURN(BZ_DATA_ERROR);

      s->storedCombinedCRC = 0;
      GET_UCHAR(BZ_X_CCRC_1, uc);
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
      GET_UCHAR(BZ_X_CCRC_2, uc);
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
      GET_UCHAR(BZ_X_CCRC_3, uc);
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
      GET_UCHAR(BZ_X_CCRC_4, uc);
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);

      s->state = BZ_X_IDLE;
      RETURN(BZ_STREAM_END);

      default: AssertH ( False, 4001 );
   }

   AssertH ( False, 4002 );

   save_state_and_return:

   s->save_i           = i;
   s->save_j           = j;
   s->save_t           = t;
   s->save_alphaSize   = alphaSize;
   s->save_nGroups     = nGroups;
   s->save_nSelectors  = nSelectors;
   s->save_EOB         = EOB;
   s->save_groupNo     = groupNo;
   s->save_groupPos    = groupPos;
   s->save_nextSym     = nextSym;
   s->save_nblockMAX   = nblockMAX;
   s->save_nblock      = nblock;
   s->save_es          = es;
   s->save_N           = N;
   s->save_curr        = curr;
   s->save_zt          = zt;
   s->save_zn          = zn;
   s->save_zvec        = zvec;
   s->save_zj          = zj;
   s->save_gSel        = gSel;
   s->save_gMinlen     = gMinlen;
   s->save_gLimit      = gLimit;
   s->save_gBase       = gBase;
   s->save_gPerm       = gPerm;

   return retVal;   
}


/*-------------------------------------------------------------*/
/*--- end                                      decompress.c ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: CMakeLists.txt ---
project(bzip2)
add_definitions(-D_FILE_OFFSET_BITS=64)
add_library(cmbzip2
  blocksort.c huffman.c crctable.c randtable.c compress.c decompress.c bzlib.c)

--- NEW FILE: sample1.rb2 ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: sample1.ref ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: compress.c ---

/*-------------------------------------------------------------*/
/*--- Compression machinery (not incl block sorting)        ---*/
/*---                                            compress.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


/* CHANGES
    0.9.0    -- original version.
    0.9.0a/b -- no changes in this file.
    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
                so as to do a bit better on small files
*/

#include "bzlib_private.h"


/*---------------------------------------------------*/
/*--- Bit stream I/O                              ---*/
/*---------------------------------------------------*/

/*---------------------------------------------------*/
void BZ2_bsInitWrite ( EState* s )
{
   s->bsLive = 0;
   s->bsBuff = 0;
}


/*---------------------------------------------------*/
static
void bsFinishWrite ( EState* s )
{
   while (s->bsLive > 0) {
      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
      s->numZ++;
      s->bsBuff <<= 8;
      s->bsLive -= 8;
   }
}


/*---------------------------------------------------*/
#define bsNEEDW(nz)                           \
{                                             \
   while (s->bsLive >= 8) {                   \
      s->zbits[s->numZ]                       \
         = (UChar)(s->bsBuff >> 24);          \
      s->numZ++;                              \
      s->bsBuff <<= 8;                        \
      s->bsLive -= 8;                         \
   }                                          \
}


/*---------------------------------------------------*/
static
__inline__
void bsW ( EState* s, Int32 n, UInt32 v )
{
   bsNEEDW ( n );
   s->bsBuff |= (v << (32 - s->bsLive - n));
   s->bsLive += n;
}


/*---------------------------------------------------*/
static
void bsPutUInt32 ( EState* s, UInt32 u )
{
   bsW ( s, 8, (u >> 24) & 0xffL );
   bsW ( s, 8, (u >> 16) & 0xffL );
   bsW ( s, 8, (u >>  8) & 0xffL );
   bsW ( s, 8,  u        & 0xffL );
}


/*---------------------------------------------------*/
static
void bsPutUChar ( EState* s, UChar c )
{
   bsW( s, 8, (UInt32)c );
}


/*---------------------------------------------------*/
/*--- The back end proper                         ---*/
/*---------------------------------------------------*/

/*---------------------------------------------------*/
static
void makeMaps_e ( EState* s )
{
   Int32 i;
   s->nInUse = 0;
   for (i = 0; i < 256; i++)
      if (s->inUse[i]) {
         s->unseqToSeq[i] = s->nInUse;
         s->nInUse++;
      }
}


/*---------------------------------------------------*/
static
void generateMTFValues ( EState* s )
{
   UChar   yy[256];
   Int32   i, j;
   Int32   zPend;
   Int32   wr;
   Int32   EOB;

   /* 
      After sorting (eg, here),
         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
         and
         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
         holds the original block data.

      The first thing to do is generate the MTF values,
      and put them in
         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
      Because there are strictly fewer or equal MTF values
      than block values, ptr values in this area are overwritten
      with MTF values only when they are no longer needed.

      The final compressed bitstream is generated into the
      area starting at
         (UChar*) (&((UChar*)s->arr2)[s->nblock])

      These storage aliases are set up in bzCompressInit(),
      except for the last one, which is arranged in 
      compressBlock().
   */
   UInt32* ptr   = s->ptr;
   UChar* block  = s->block;
   UInt16* mtfv  = s->mtfv;

   makeMaps_e ( s );
   EOB = s->nInUse+1;

   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;

   wr = 0;
   zPend = 0;
   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;

   for (i = 0; i < s->nblock; i++) {
      UChar ll_i;
      AssertD ( wr <= i, "generateMTFValues(1)" );
      j = ptr[i]-1; if (j < 0) j += s->nblock;
      ll_i = s->unseqToSeq[block[j]];
      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );

      if (yy[0] == ll_i) { 
         zPend++;
      } else {

         if (zPend > 0) {
            zPend--;
            while (True) {
               if (zPend & 1) {
                  mtfv[wr] = BZ_RUNB; wr++; 
                  s->mtfFreq[BZ_RUNB]++; 
               } else {
                  mtfv[wr] = BZ_RUNA; wr++; 
                  s->mtfFreq[BZ_RUNA]++; 
               }
               if (zPend < 2) break;
               zPend = (zPend - 2) / 2;
            };
            zPend = 0;
         }
         {
            register UChar  rtmp;
            register UChar* ryy_j;
            register UChar  rll_i;
            rtmp  = yy[1];
            yy[1] = yy[0];
            ryy_j = &(yy[1]);
            rll_i = ll_i;
            while ( rll_i != rtmp ) {
               register UChar rtmp2;
               ryy_j++;
               rtmp2  = rtmp;
               rtmp   = *ryy_j;
               *ryy_j = rtmp2;
            };
            yy[0] = rtmp;
            j = ryy_j - &(yy[0]);
            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
         }

      }
   }

   if (zPend > 0) {
      zPend--;
      while (True) {
         if (zPend & 1) {
            mtfv[wr] = BZ_RUNB; wr++; 
            s->mtfFreq[BZ_RUNB]++; 
         } else {
            mtfv[wr] = BZ_RUNA; wr++; 
            s->mtfFreq[BZ_RUNA]++; 
         }
         if (zPend < 2) break;
         zPend = (zPend - 2) / 2;
      };
      zPend = 0;
   }

   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;

   s->nMTF = wr;
}


/*---------------------------------------------------*/
#define BZ_LESSER_ICOST  0
#define BZ_GREATER_ICOST 15

static
void sendMTFValues ( EState* s )
{
   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
   Int32 nGroups, nBytes;

   /*--
   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
   is a global since the decoder also needs it.

   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
   are also globals only used in this proc.
   Made global to keep stack frame size small.
   --*/


   UInt16 cost[BZ_N_GROUPS];
   Int32  fave[BZ_N_GROUPS];

   UInt16* mtfv = s->mtfv;

   if (s->verbosity >= 3)
      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
                "%d+2 syms in use\n", 
                s->nblock, s->nMTF, s->nInUse );

   alphaSize = s->nInUse+2;
   for (t = 0; t < BZ_N_GROUPS; t++)
      for (v = 0; v < alphaSize; v++)
         s->len[t][v] = BZ_GREATER_ICOST;

   /*--- Decide how many coding tables to use ---*/
   AssertH ( s->nMTF > 0, 3001 );
   if (s->nMTF < 200)  nGroups = 2; else
   if (s->nMTF < 600)  nGroups = 3; else
   if (s->nMTF < 1200) nGroups = 4; else
   if (s->nMTF < 2400) nGroups = 5; else
                       nGroups = 6;

   /*--- Generate an initial set of coding tables ---*/
   { 
      Int32 nPart, remF, tFreq, aFreq;

      nPart = nGroups;
      remF  = s->nMTF;
      gs = 0;
      while (nPart > 0) {
         tFreq = remF / nPart;
         ge = gs-1;
         aFreq = 0;
         while (aFreq < tFreq && ge < alphaSize-1) {
            ge++;
            aFreq += s->mtfFreq[ge];
         }

         if (ge > gs 
             && nPart != nGroups && nPart != 1 
             && ((nGroups-nPart) % 2 == 1)) {
            aFreq -= s->mtfFreq[ge];
            ge--;
         }

         if (s->verbosity >= 3)
            VPrintf5( "      initial group %d, [%d .. %d], "
                      "has %d syms (%4.1f%%)\n",
                      nPart, gs, ge, aFreq, 
                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
 
         for (v = 0; v < alphaSize; v++)
            if (v >= gs && v <= ge) 
               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
               s->len[nPart-1][v] = BZ_GREATER_ICOST;
 
         nPart--;
         gs = ge+1;
         remF -= aFreq;
      }
   }

   /*--- 
      Iterate up to BZ_N_ITERS times to improve the tables.
   ---*/
   for (iter = 0; iter < BZ_N_ITERS; iter++) {

      for (t = 0; t < nGroups; t++) fave[t] = 0;

      for (t = 0; t < nGroups; t++)
         for (v = 0; v < alphaSize; v++)
            s->rfreq[t][v] = 0;

      /*---
        Set up an auxiliary length table which is used to fast-track
    the common case (nGroups == 6). 
      ---*/
      if (nGroups == 6) {
         for (v = 0; v < alphaSize; v++) {
            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
     }
      }

      nSelectors = 0;
      totc = 0;
      gs = 0;
      while (True) {

         /*--- Set group start & end marks. --*/
         if (gs >= s->nMTF) break;
         ge = gs + BZ_G_SIZE - 1; 
         if (ge >= s->nMTF) ge = s->nMTF-1;

         /*-- 
            Calculate the cost of this group as coded
            by each of the coding tables.
         --*/
         for (t = 0; t < nGroups; t++) cost[t] = 0;

         if (nGroups == 6 && 50 == ge-gs+1) {
            /*--- fast track the common case ---*/
            register UInt32 cost01, cost23, cost45;
            register UInt16 icv;
            cost01 = cost23 = cost45 = 0;

#           define BZ_ITER(nn)                \
               icv = mtfv[gs+(nn)];           \
               cost01 += s->len_pack[icv][0]; \
               cost23 += s->len_pack[icv][1]; \
               cost45 += s->len_pack[icv][2]; \

            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);

#           undef BZ_ITER

            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;

         } else {
        /*--- slow version which correctly handles all situations ---*/
            for (i = gs; i <= ge; i++) { 
               UInt16 icv = mtfv[i];
               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
            }
         }
 
         /*-- 
            Find the coding table which is best for this group,
            and record its identity in the selector table.
         --*/
         bc = 999999999; bt = -1;
         for (t = 0; t < nGroups; t++)
            if (cost[t] < bc) { bc = cost[t]; bt = t; };
         totc += bc;
         fave[bt]++;
         s->selector[nSelectors] = bt;
         nSelectors++;

         /*-- 
            Increment the symbol frequencies for the selected table.
          --*/
         if (nGroups == 6 && 50 == ge-gs+1) {
            /*--- fast track the common case ---*/

#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++

            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);

#           undef BZ_ITUR

         } else {
        /*--- slow version which correctly handles all situations ---*/
            for (i = gs; i <= ge; i++)
               s->rfreq[bt][ mtfv[i] ]++;
         }

         gs = ge+1;
      }
      if (s->verbosity >= 3) {
         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
                   iter+1, totc/8 );
         for (t = 0; t < nGroups; t++)
            VPrintf1 ( "%d ", fave[t] );
         VPrintf0 ( "\n" );
      }

      /*--
        Recompute the tables based on the accumulated frequencies.
      --*/
      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
         comment in huffman.c for details. */
      for (t = 0; t < nGroups; t++)
         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
                                 alphaSize, 17 /*20*/ );
   }


   AssertH( nGroups < 8, 3002 );
   AssertH( nSelectors < 32768 &&
            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
            3003 );


   /*--- Compute MTF values for the selectors. ---*/
   {
      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
      for (i = 0; i < nGroups; i++) pos[i] = i;
      for (i = 0; i < nSelectors; i++) {
         ll_i = s->selector[i];
         j = 0;
         tmp = pos[j];
         while ( ll_i != tmp ) {
            j++;
            tmp2 = tmp;
            tmp = pos[j];
            pos[j] = tmp2;
         };
         pos[0] = tmp;
         s->selectorMtf[i] = j;
      }
   };

   /*--- Assign actual codes for the tables. --*/
   for (t = 0; t < nGroups; t++) {
      minLen = 32;
      maxLen = 0;
      for (i = 0; i < alphaSize; i++) {
         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
         if (s->len[t][i] < minLen) minLen = s->len[t][i];
      }
      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
      AssertH ( !(minLen < 1),  3005 );
      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
                          minLen, maxLen, alphaSize );
   }

   /*--- Transmit the mapping table. ---*/
   { 
      Bool inUse16[16];
      for (i = 0; i < 16; i++) {
          inUse16[i] = False;
          for (j = 0; j < 16; j++)
             if (s->inUse[i * 16 + j]) inUse16[i] = True;
      }
     
      nBytes = s->numZ;
      for (i = 0; i < 16; i++)
         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);

      for (i = 0; i < 16; i++)
         if (inUse16[i])
            for (j = 0; j < 16; j++) {
               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
            }

      if (s->verbosity >= 3) 
         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
   }

   /*--- Now the selectors. ---*/
   nBytes = s->numZ;
   bsW ( s, 3, nGroups );
   bsW ( s, 15, nSelectors );
   for (i = 0; i < nSelectors; i++) { 
      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
      bsW(s,1,0);
   }
   if (s->verbosity >= 3)
      VPrintf1( "selectors %d, ", s->numZ-nBytes );

   /*--- Now the coding tables. ---*/
   nBytes = s->numZ;

   for (t = 0; t < nGroups; t++) {
      Int32 curr = s->len[t][0];
      bsW ( s, 5, curr );
      for (i = 0; i < alphaSize; i++) {
         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
         bsW ( s, 1, 0 );
      }
   }

   if (s->verbosity >= 3)
      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );

   /*--- And finally, the block data proper ---*/
   nBytes = s->numZ;
   selCtr = 0;
   gs = 0;
   while (True) {
      if (gs >= s->nMTF) break;
      ge = gs + BZ_G_SIZE - 1; 
      if (ge >= s->nMTF) ge = s->nMTF-1;
      AssertH ( s->selector[selCtr] < nGroups, 3006 );

      if (nGroups == 6 && 50 == ge-gs+1) {
            /*--- fast track the common case ---*/
            UInt16 mtfv_i;
            UChar* s_len_sel_selCtr 
               = &(s->len[s->selector[selCtr]][0]);
            Int32* s_code_sel_selCtr
               = &(s->code[s->selector[selCtr]][0]);

#           define BZ_ITAH(nn)                      \
               mtfv_i = mtfv[gs+(nn)];              \
               bsW ( s,                             \
                     s_len_sel_selCtr[mtfv_i],      \
                     s_code_sel_selCtr[mtfv_i] )

            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);

#           undef BZ_ITAH

      } else {
     /*--- slow version which correctly handles all situations ---*/
         for (i = gs; i <= ge; i++) {
            bsW ( s, 
                  s->len  [s->selector[selCtr]] [mtfv[i]],
                  s->code [s->selector[selCtr]] [mtfv[i]] );
         }
      }


      gs = ge+1;
      selCtr++;
   }
   AssertH( selCtr == nSelectors, 3007 );

   if (s->verbosity >= 3)
      VPrintf1( "codes %d\n", s->numZ-nBytes );
}


/*---------------------------------------------------*/
void BZ2_compressBlock ( EState* s, Bool is_last_block )
{
   if (s->nblock > 0) {

      BZ_FINALISE_CRC ( s->blockCRC );
      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
      s->combinedCRC ^= s->blockCRC;
      if (s->blockNo > 1) s->numZ = 0;

      if (s->verbosity >= 2)
         VPrintf4( "    block %d: crc = 0x%08x, "
                   "combined CRC = 0x%08x, size = %d\n",
                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );

      BZ2_blockSort ( s );
   }

   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);

   /*-- If this is the first block, create the stream header. --*/
   if (s->blockNo == 1) {
      BZ2_bsInitWrite ( s );
      bsPutUChar ( s, BZ_HDR_B );
      bsPutUChar ( s, BZ_HDR_Z );
      bsPutUChar ( s, BZ_HDR_h );
      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
   }

   if (s->nblock > 0) {

      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );

      /*-- Now the block's CRC, so it is in a known place. --*/
      bsPutUInt32 ( s, s->blockCRC );

      /*-- 
         Now a single bit indicating (non-)randomisation. 
         As of version 0.9.5, we use a better sorting algorithm
         which makes randomisation unnecessary.  So always set
         the randomised bit to 'no'.  Of course, the decoder
         still needs to be able to handle randomised blocks
         so as to maintain backwards compatibility with
         older versions of bzip2.
      --*/
      bsW(s,1,0);

      bsW ( s, 24, s->origPtr );
      generateMTFValues ( s );
      sendMTFValues ( s );
   }


   /*-- If this is the last block, add the stream trailer. --*/
   if (is_last_block) {

      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
      bsPutUInt32 ( s, s->combinedCRC );
      if (s->verbosity >= 2)
         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
      bsFinishWrite ( s );
   }
}


/*-------------------------------------------------------------*/
/*--- end                                        compress.c ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: sample3.tst ---
This file is exceedingly boring.  If you find yourself
reading it, please (1) take it from me that you can safely
guess what the rest of the file says, and (2) seek professional
help.

ps.  there are no further sarcastic remarks in this file.

ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
[...29968 lines suppressed...]
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh
ugh

--- NEW FILE: format.pl ---
#!/usr/bin/perl -w
#
# ------------------------------------------------------------------
# This file is part of bzip2/libbzip2, a program and library for
# lossless, block-sorting data compression.
#
# bzip2/libbzip2 version 1.0.5 of 10 December 2007
# Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>
#
# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
# README file.
#
# This program is released under the terms of the license contained
# in the file LICENSE.
# ------------------------------------------------------------------
#
use strict;

# get command line values:
if ( $#ARGV !=1 ) {
    die "Usage:  $0 xml_infile xml_outfile\n";
}

my $infile = shift;
# check infile exists
die "Can't find file \"$infile\""
  unless -f $infile;
# check we can read infile
if (! -r $infile) {
    die "Can't read input $infile\n";
}
# check we can open infile
open( INFILE,"<$infile" ) or 
    die "Can't input $infile $!";

#my $outfile = 'fmt-manual.xml';
my $outfile = shift;
#print "Infile: $infile, Outfile: $outfile\n";
# check we can write to outfile
open( OUTFILE,">$outfile" ) or 
    die "Can't output $outfile $! for writing";

my ($prev, $curr, $str);
$prev = ''; $curr = '';
while ( <INFILE> ) {

        print OUTFILE $prev;
    $prev = $curr;
    $curr = $_;
    $str = '';

    if ( $prev =~ /<programlisting>$|<screen>$/ ) {
        chomp $prev;
        $curr = join( '', $prev, "<![CDATA[", $curr );
                $prev = '';
        next;
    }
    elsif ( $curr =~ /<\/programlisting>|<\/screen>/ ) {
        chomp $prev;
        $curr = join( '', $prev, "]]>", $curr );
                $prev = '';
        next;
    }
}
print OUTFILE $curr;
close INFILE;
close OUTFILE;
exit;

--- NEW FILE: Makefile-libbz2_so ---

# This Makefile builds a shared version of the library, 
# libbz2.so.1.0.4, with soname libbz2.so.1.0,
# at least on x86-Linux (RedHat 7.2), 
# with gcc-2.96 20000731 (Red Hat Linux 7.1 2.96-98).  
# Please see the README file for some important info 
# about building the library like this.

# ------------------------------------------------------------------
# This file is part of bzip2/libbzip2, a program and library for
# lossless, block-sorting data compression.
#
# bzip2/libbzip2 version 1.0.5 of 10 December 2007
# Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>
#
# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
# README file.
#
# This program is released under the terms of the license contained
# in the file LICENSE.
# ------------------------------------------------------------------


SHELL=/bin/sh
CC=gcc
BIGFILES=-D_FILE_OFFSET_BITS=64
CFLAGS=-fpic -fPIC -Wall -Winline -O2 -g $(BIGFILES)

OBJS= blocksort.o  \
      huffman.o    \
      crctable.o   \
      randtable.o  \
      compress.o   \
      decompress.o \
      bzlib.o

all: $(OBJS)
    $(CC) -shared -Wl,-soname -Wl,libbz2.so.1.0 -o libbz2.so.1.0.4 $(OBJS)
    $(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.1.0.4
    rm -f libbz2.so.1.0
    ln -s libbz2.so.1.0.4 libbz2.so.1.0

clean: 
    rm -f $(OBJS) bzip2.o libbz2.so.1.0.4 libbz2.so.1.0 bzip2-shared

blocksort.o: blocksort.c
    $(CC) $(CFLAGS) -c blocksort.c
huffman.o: huffman.c
    $(CC) $(CFLAGS) -c huffman.c
crctable.o: crctable.c
    $(CC) $(CFLAGS) -c crctable.c
randtable.o: randtable.c
    $(CC) $(CFLAGS) -c randtable.c
compress.o: compress.c
    $(CC) $(CFLAGS) -c compress.c
decompress.o: decompress.c
    $(CC) $(CFLAGS) -c decompress.c
bzlib.o: bzlib.c
    $(CC) $(CFLAGS) -c bzlib.c

--- NEW FILE: bzlib_private.h ---

/*-------------------------------------------------------------*/
/*--- Private header file for the library.                  ---*/
/*---                                       bzlib_private.h ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#ifndef _BZLIB_PRIVATE_H
#define _BZLIB_PRIVATE_H

#include <stdlib.h>

#ifndef BZ_NO_STDIO
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#endif

#include "bzlib.h"



/*-- General stuff. --*/

#define BZ_VERSION  "1.0.5, 10-Dec-2007"

typedef char            Char;
typedef unsigned char   Bool;
typedef unsigned char   UChar;
typedef int             Int32;
typedef unsigned int    UInt32;
typedef short           Int16;
typedef unsigned short  UInt16;

#define True  ((Bool)1)
#define False ((Bool)0)

#ifndef __GNUC__
#define __inline__  /* */
#endif 

#ifndef BZ_NO_STDIO

extern void BZ2_bz__AssertH__fail ( int errcode );
#define AssertH(cond,errcode) \
   { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }

#if BZ_DEBUG
#define AssertD(cond,msg) \
   { if (!(cond)) {       \
      fprintf ( stderr,   \
        "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
      exit(1); \
   }}
#else
#define AssertD(cond,msg) /* */
#endif

#define VPrintf0(zf) \
   fprintf(stderr,zf)
#define VPrintf1(zf,za1) \
   fprintf(stderr,zf,za1)
#define VPrintf2(zf,za1,za2) \
   fprintf(stderr,zf,za1,za2)
#define VPrintf3(zf,za1,za2,za3) \
   fprintf(stderr,zf,za1,za2,za3)
#define VPrintf4(zf,za1,za2,za3,za4) \
   fprintf(stderr,zf,za1,za2,za3,za4)
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
   fprintf(stderr,zf,za1,za2,za3,za4,za5)

#else

extern void bz_internal_error ( int errcode );
#define AssertH(cond,errcode) \
   { if (!(cond)) bz_internal_error ( errcode ); }
#define AssertD(cond,msg)                do { } while (0)
#define VPrintf0(zf)                     do { } while (0)
#define VPrintf1(zf,za1)                 do { } while (0)
#define VPrintf2(zf,za1,za2)             do { } while (0)
#define VPrintf3(zf,za1,za2,za3)         do { } while (0)
#define VPrintf4(zf,za1,za2,za3,za4)     do { } while (0)
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)

#endif


#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
#define BZFREE(ppp)  (strm->bzfree)(strm->opaque,(ppp))


/*-- Header bytes. --*/

#define BZ_HDR_B 0x42   /* 'B' */
#define BZ_HDR_Z 0x5a   /* 'Z' */
#define BZ_HDR_h 0x68   /* 'h' */
#define BZ_HDR_0 0x30   /* '0' */
  
/*-- Constants for the back end. --*/

#define BZ_MAX_ALPHA_SIZE 258
#define BZ_MAX_CODE_LEN    23

#define BZ_RUNA 0
#define BZ_RUNB 1

#define BZ_N_GROUPS 6
#define BZ_G_SIZE   50
#define BZ_N_ITERS  4

#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))



/*-- Stuff for randomising repetitive blocks. --*/

extern Int32 BZ2_rNums[512];

#define BZ_RAND_DECLS                          \
   Int32 rNToGo;                               \
   Int32 rTPos                                 \

#define BZ_RAND_INIT_MASK                      \
   s->rNToGo = 0;                              \
   s->rTPos  = 0                               \

#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)

#define BZ_RAND_UPD_MASK                       \
   if (s->rNToGo == 0) {                       \
      s->rNToGo = BZ2_rNums[s->rTPos];         \
      s->rTPos++;                              \
      if (s->rTPos == 512) s->rTPos = 0;       \
   }                                           \
   s->rNToGo--;



/*-- Stuff for doing CRCs. --*/

extern UInt32 BZ2_crc32Table[256];

#define BZ_INITIALISE_CRC(crcVar)              \
{                                              \
   crcVar = 0xffffffffL;                       \
}

#define BZ_FINALISE_CRC(crcVar)                \
{                                              \
   crcVar = ~(crcVar);                         \
}

#define BZ_UPDATE_CRC(crcVar,cha)              \
{                                              \
   crcVar = (crcVar << 8) ^                    \
            BZ2_crc32Table[(crcVar >> 24) ^    \
                           ((UChar)cha)];      \
}



/*-- States and modes for compression. --*/

#define BZ_M_IDLE      1
#define BZ_M_RUNNING   2
#define BZ_M_FLUSHING  3
#define BZ_M_FINISHING 4

#define BZ_S_OUTPUT    1
#define BZ_S_INPUT     2

#define BZ_N_RADIX 2
#define BZ_N_QSORT 12
#define BZ_N_SHELL 18
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)




/*-- Structure holding all the compression-side stuff. --*/

typedef
   struct {
      /* pointer back to the struct bz_stream */
      bz_stream* strm;

      /* mode this stream is in, and whether inputting */
      /* or outputting data */
      Int32    mode;
      Int32    state;

      /* remembers avail_in when flush/finish requested */
      UInt32   avail_in_expect;

      /* for doing the block sorting */
      UInt32*  arr1;
      UInt32*  arr2;
      UInt32*  ftab;
      Int32    origPtr;

      /* aliases for arr1 and arr2 */
      UInt32*  ptr;
      UChar*   block;
      UInt16*  mtfv;
      UChar*   zbits;

      /* for deciding when to use the fallback sorting algorithm */
      Int32    workFactor;

      /* run-length-encoding of the input */
      UInt32   state_in_ch;
      Int32    state_in_len;
      BZ_RAND_DECLS;

      /* input and output limits and current posns */
      Int32    nblock;
      Int32    nblockMAX;
      Int32    numZ;
      Int32    state_out_pos;

      /* map of bytes used in block */
      Int32    nInUse;
      Bool     inUse[256];
      UChar    unseqToSeq[256];

      /* the buffer for bit stream creation */
      UInt32   bsBuff;
      Int32    bsLive;

      /* block and combined CRCs */
      UInt32   blockCRC;
      UInt32   combinedCRC;

      /* misc administratium */
      Int32    verbosity;
      Int32    blockNo;
      Int32    blockSize100k;

      /* stuff for coding the MTF values */
      Int32    nMTF;
      Int32    mtfFreq    [BZ_MAX_ALPHA_SIZE];
      UChar    selector   [BZ_MAX_SELECTORS];
      UChar    selectorMtf[BZ_MAX_SELECTORS];

      UChar    len     [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
      Int32    code    [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
      Int32    rfreq   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
      /* second dimension: only 3 needed; 4 makes index calculations faster */
      UInt32   len_pack[BZ_MAX_ALPHA_SIZE][4];

   }
   EState;



/*-- externs for compression. --*/

extern void 
BZ2_blockSort ( EState* );

extern void 
BZ2_compressBlock ( EState*, Bool );

extern void 
BZ2_bsInitWrite ( EState* );

extern void 
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );

extern void 
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );



/*-- states for decompression. --*/

#define BZ_X_IDLE        1
#define BZ_X_OUTPUT      2

#define BZ_X_MAGIC_1     10
#define BZ_X_MAGIC_2     11
#define BZ_X_MAGIC_3     12
#define BZ_X_MAGIC_4     13
#define BZ_X_BLKHDR_1    14
#define BZ_X_BLKHDR_2    15
#define BZ_X_BLKHDR_3    16
#define BZ_X_BLKHDR_4    17
#define BZ_X_BLKHDR_5    18
#define BZ_X_BLKHDR_6    19
#define BZ_X_BCRC_1      20
#define BZ_X_BCRC_2      21
#define BZ_X_BCRC_3      22
#define BZ_X_BCRC_4      23
#define BZ_X_RANDBIT     24
#define BZ_X_ORIGPTR_1   25
#define BZ_X_ORIGPTR_2   26
#define BZ_X_ORIGPTR_3   27
#define BZ_X_MAPPING_1   28
#define BZ_X_MAPPING_2   29
#define BZ_X_SELECTOR_1  30
#define BZ_X_SELECTOR_2  31
#define BZ_X_SELECTOR_3  32
#define BZ_X_CODING_1    33
#define BZ_X_CODING_2    34
#define BZ_X_CODING_3    35
#define BZ_X_MTF_1       36
#define BZ_X_MTF_2       37
#define BZ_X_MTF_3       38
#define BZ_X_MTF_4       39
#define BZ_X_MTF_5       40
#define BZ_X_MTF_6       41
#define BZ_X_ENDHDR_2    42
#define BZ_X_ENDHDR_3    43
#define BZ_X_ENDHDR_4    44
#define BZ_X_ENDHDR_5    45
#define BZ_X_ENDHDR_6    46
#define BZ_X_CCRC_1      47
#define BZ_X_CCRC_2      48
#define BZ_X_CCRC_3      49
#define BZ_X_CCRC_4      50



/*-- Constants for the fast MTF decoder. --*/

#define MTFA_SIZE 4096
#define MTFL_SIZE 16



/*-- Structure holding all the decompression-side stuff. --*/

typedef
   struct {
      /* pointer back to the struct bz_stream */
      bz_stream* strm;

      /* state indicator for this stream */
      Int32    state;

      /* for doing the final run-length decoding */
      UChar    state_out_ch;
      Int32    state_out_len;
      Bool     blockRandomised;
      BZ_RAND_DECLS;

      /* the buffer for bit stream reading */
      UInt32   bsBuff;
      Int32    bsLive;

      /* misc administratium */
      Int32    blockSize100k;
      Bool     smallDecompress;
      Int32    currBlockNo;
      Int32    verbosity;

      /* for undoing the Burrows-Wheeler transform */
      Int32    origPtr;
      UInt32   tPos;
      Int32    k0;
      Int32    unzftab[256];
      Int32    nblock_used;
      Int32    cftab[257];
      Int32    cftabCopy[257];

      /* for undoing the Burrows-Wheeler transform (FAST) */
      UInt32   *tt;

      /* for undoing the Burrows-Wheeler transform (SMALL) */
      UInt16   *ll16;
      UChar    *ll4;

      /* stored and calculated CRCs */
      UInt32   storedBlockCRC;
      UInt32   storedCombinedCRC;
      UInt32   calculatedBlockCRC;
      UInt32   calculatedCombinedCRC;

      /* map of bytes used in block */
      Int32    nInUse;
      Bool     inUse[256];
      Bool     inUse16[16];
      UChar    seqToUnseq[256];

      /* for decoding the MTF values */
      UChar    mtfa   [MTFA_SIZE];
      Int32    mtfbase[256 / MTFL_SIZE];
      UChar    selector   [BZ_MAX_SELECTORS];
      UChar    selectorMtf[BZ_MAX_SELECTORS];
      UChar    len  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];

      Int32    limit  [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
      Int32    base   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
      Int32    perm   [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
      Int32    minLens[BZ_N_GROUPS];

      /* save area for scalars in the main decompress code */
      Int32    save_i;
      Int32    save_j;
      Int32    save_t;
      Int32    save_alphaSize;
      Int32    save_nGroups;
      Int32    save_nSelectors;
      Int32    save_EOB;
      Int32    save_groupNo;
      Int32    save_groupPos;
      Int32    save_nextSym;
      Int32    save_nblockMAX;
      Int32    save_nblock;
      Int32    save_es;
      Int32    save_N;
      Int32    save_curr;
      Int32    save_zt;
      Int32    save_zn; 
      Int32    save_zvec;
      Int32    save_zj;
      Int32    save_gSel;
      Int32    save_gMinlen;
      Int32*   save_gLimit;
      Int32*   save_gBase;
      Int32*   save_gPerm;

   }
   DState;



/*-- Macros for decompression. --*/

#define BZ_GET_FAST(cccc)                     \
    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
    s->tPos = s->tt[s->tPos];                 \
    cccc = (UChar)(s->tPos & 0xff);           \
    s->tPos >>= 8;

#define BZ_GET_FAST_C(cccc)                   \
    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
    if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
    c_tPos = c_tt[c_tPos];                    \
    cccc = (UChar)(c_tPos & 0xff);            \
    c_tPos >>= 8;

#define SET_LL4(i,n)                                          \
   { if (((i) & 0x1) == 0)                                    \
        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else    \
        s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4);  \
   }

#define GET_LL4(i)                             \
   ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)

#define SET_LL(i,n)                          \
   { s->ll16[i] = (UInt16)(n & 0x0000ffff);  \
     SET_LL4(i, n >> 16);                    \
   }

#define GET_LL(i) \
   (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))

#define BZ_GET_SMALL(cccc)                            \
    /* c_tPos is unsigned, hence test < 0 is pointless. */ \
    if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
    cccc = BZ2_indexIntoF ( s->tPos, s->cftab );    \
    s->tPos = GET_LL(s->tPos);


/*-- externs for decompression. --*/

extern Int32 
BZ2_indexIntoF ( Int32, Int32* );

extern Int32 
BZ2_decompress ( DState* );

extern void 
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
                           Int32,  Int32, Int32 );


#endif


/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/

#ifdef BZ_NO_STDIO
#ifndef NULL
#define NULL 0
#endif
#endif


/*-------------------------------------------------------------*/
/*--- end                                   bzlib_private.h ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: crctable.c ---

/*-------------------------------------------------------------*/
/*--- Table for doing CRCs                                  ---*/
/*---                                            crctable.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#include "bzlib_private.h"

/*--
  I think this is an implementation of the AUTODIN-II,
  Ethernet & FDDI 32-bit CRC standard.  Vaguely derived
  from code by Rob Warnock, in Section 51 of the
  comp.compression FAQ.
--*/

UInt32 BZ2_crc32Table[256] = {

   /*-- Ugly, innit? --*/

   0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
   0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
   0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
   0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
   0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
   0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
   0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
   0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
   0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
   0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
   0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
   0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
   0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
   0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
   0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
   0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
   0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
   0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
   0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
   0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
   0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
   0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
   0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
   0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
   0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
   0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
   0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
   0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
   0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
   0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
   0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
   0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
   0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
   0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
   0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
   0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
   0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
   0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
   0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
   0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
   0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
   0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
   0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
   0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
   0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
   0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
   0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
   0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
   0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
   0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
   0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
   0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
   0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
   0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
   0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
   0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
   0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
   0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
   0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
   0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
   0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
   0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
   0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
   0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
};


/*-------------------------------------------------------------*/
/*--- end                                        crctable.c ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: sample2.rb2 ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: bzmore ---
#!/bin/sh

# Bzmore wrapped for bzip2, 
# adapted from zmore by Philippe Troin <phil at fifi.org> for Debian GNU/Linux.

PATH="/usr/bin:$PATH"; export PATH

prog=`echo $0 | sed 's|.*/||'`
case "$prog" in
    *less)  more=less   ;;
    *)  more=more       ;;
esac

if test "`echo -n a`" = "-n a"; then
  # looks like a SysV system:
  n1=''; n2='\c'
else
  n1='-n'; n2=''
fi
oldtty=`stty -g 2>/dev/null`
if stty -cbreak 2>/dev/null; then
  cb='cbreak'; ncb='-cbreak'
else
  # 'stty min 1' resets eof to ^a on both SunOS and SysV!
  cb='min 1 -icanon'; ncb='icanon eof ^d'
fi
if test $? -eq 0 -a -n "$oldtty"; then
   trap 'stty $oldtty 2>/dev/null; exit' 0 2 3 5 10 13 15
else
   trap 'stty $ncb echo 2>/dev/null; exit' 0 2 3 5 10 13 15
fi

if test $# = 0; then
    if test -t 0; then
    echo usage: $prog files...
    else
    bzip2 -cdfq | eval $more
    fi
else
    FIRST=1
    for FILE
    do
    if test $FIRST -eq 0; then
        echo $n1 "--More--(Next file: $FILE)$n2"
        stty $cb -echo 2>/dev/null
        ANS=`dd bs=1 count=1 2>/dev/null` 
        stty $ncb echo 2>/dev/null
        echo " "
        if test "$ANS" = 'e' -o "$ANS" = 'q'; then
            exit
        fi
    fi
    if test "$ANS" != 's'; then
        echo "------> $FILE <------"
        bzip2 -cdfq "$FILE" | eval $more
    fi
    if test -t; then
        FIRST=0
    fi
    done
fi

--- NEW FILE: sample2.ref ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: libbz2.def ---
LIBRARY         LIBBZ2
DESCRIPTION     "libbzip2: library for data compression"
EXPORTS
    BZ2_bzCompressInit
    BZ2_bzCompress
    BZ2_bzCompressEnd
    BZ2_bzDecompressInit
    BZ2_bzDecompress
    BZ2_bzDecompressEnd
    BZ2_bzReadOpen
    BZ2_bzReadClose
    BZ2_bzReadGetUnused
    BZ2_bzRead
    BZ2_bzWriteOpen
    BZ2_bzWrite
    BZ2_bzWriteClose
    BZ2_bzWriteClose64
    BZ2_bzBuffToBuffCompress
    BZ2_bzBuffToBuffDecompress
    BZ2_bzlibVersion
    BZ2_bzopen
    BZ2_bzdopen
    BZ2_bzread
    BZ2_bzwrite
    BZ2_bzflush
    BZ2_bzclose
    BZ2_bzerror

--- NEW FILE: randtable.c ---

/*-------------------------------------------------------------*/
/*--- Table for randomising repetitive blocks               ---*/
/*---                                           randtable.c ---*/
/*-------------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */


#include "bzlib_private.h"


/*---------------------------------------------*/
Int32 BZ2_rNums[512] = { 
   619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 
   985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 
   733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 
   419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 
   878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 
   862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 
   150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 
   170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 
   73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 
   909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 
   641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 
   161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 
   382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 
   98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 
   227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 
   469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 
   184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 
   715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 
   951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 
   652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 
   645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 
   609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 
   653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 
   411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 
   170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 
   857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 
   669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 
   944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 
   344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 
   897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 
   433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 
   686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 
   946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 
   978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 
   680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 
   707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 
   297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 
   134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 
   343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 
   140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 
   170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 
   369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 
   804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 
   896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 
   661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 
   768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 
   61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 
   372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 
   780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 
   920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 
   645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 
   936, 638
};


/*-------------------------------------------------------------*/
/*--- end                                       randtable.c ---*/
/*-------------------------------------------------------------*/

--- NEW FILE: libbz2.dsp ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: xmlproc.sh ---
#!/bin/bash
# see the README file for usage etc.
#
# ------------------------------------------------------------------
#  This file is part of bzip2/libbzip2, a program and library for
#  lossless, block-sorting data compression.
#
#  bzip2/libbzip2 version 1.0.5 of 10 December 2007
#  Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>
#
#  Please read the WARNING, DISCLAIMER and PATENTS sections in the 
#  README file.
#
#  This program is released under the terms of the license contained
#  in the file LICENSE.
# ----------------------------------------------------------------


usage() {
  echo '';
  echo 'Usage: xmlproc.sh -[option] <filename.xml>';
  echo 'Specify a target from:';
  echo '-v      verify xml file conforms to dtd';
  echo '-html   output in html format (single file)';
  echo '-ps     output in postscript format';
  echo '-pdf    output in pdf format';
  exit;
}

if test $# -ne 2; then
  usage
fi
# assign the variable for the output type
action=$1; shift
# assign the output filename
xmlfile=$1; shift
# and check user input it correct
if !(test -f $xmlfile); then
  echo "No such file: $xmlfile";
  exit;
fi
# some other stuff we will use
OUT=output
xsl_fo=bz-fo.xsl
xsl_html=bz-html.xsl

basename=$xmlfile
basename=${basename//'.xml'/''}

fofile="${basename}.fo"
htmlfile="${basename}.html"
pdffile="${basename}.pdf"
psfile="${basename}.ps"
xmlfmtfile="${basename}.fmt"

# first process the xmlfile with CDATA tags
./format.pl $xmlfile $xmlfmtfile
# so the shell knows where the catalogs live
export XML_CATALOG_FILES=/etc/xml/catalog

# post-processing tidy up
cleanup() {
  echo "Cleaning up: $@" 
  while [ $# != 0 ]
  do
    arg=$1; shift;
    echo "  deleting $arg";
    rm $arg
  done
}

case $action in
  -v)
   flags='--noout --xinclude --noblanks --postvalid'
   dtd='--dtdvalid http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd'
   xmllint $flags $dtd $xmlfmtfile 2> $OUT 
   egrep 'error' $OUT 
   rm $OUT
  ;;

  -html)
   echo "Creating $htmlfile ..."
   xsltproc --nonet --xinclude  -o $htmlfile $xsl_html $xmlfmtfile
   cleanup $xmlfmtfile
  ;;

  -pdf)
   echo "Creating $pdffile ..."
   xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
   pdfxmltex $fofile >$OUT </dev/null
   pdfxmltex $fofile >$OUT </dev/null
   pdfxmltex $fofile >$OUT </dev/null
   cleanup $OUT $xmlfmtfile *.aux *.fo *.log *.out
  ;;

  -ps)
   echo "Creating $psfile ..."
   xsltproc --nonet --xinclude -o $fofile $xsl_fo $xmlfmtfile
   pdfxmltex $fofile >$OUT </dev/null
   pdfxmltex $fofile >$OUT </dev/null
   pdfxmltex $fofile >$OUT </dev/null
   pdftops $pdffile $psfile
   cleanup $OUT $xmlfmtfile $pdffile *.aux *.fo *.log *.out
#  passivetex is broken, so we can't go this route yet.
#   xmltex $fofile >$OUT </dev/null
#   xmltex $fofile >$OUT </dev/null
#   xmltex $fofile >$OUT </dev/null
#   dvips -R -q -o bzip-manual.ps *.dvi
  ;;

  *)
  usage
  ;;
esac

--- NEW FILE: bz-fo.xsl ---
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml -*- -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">

<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
<xsl:import href="bz-common.xsl"/>

<!-- set indent = yes while debugging, then change to NO -->
<xsl:output method="xml" indent="yes"/>

<!-- ensure only passivetex extensions are on -->
<xsl:param name="stylesheet.result.type" select="'fo'"/>
<!-- fo extensions: PDF bookmarks and index terms -->
<xsl:param name="use.extensions" select="'1'"/>
<xsl:param name="xep.extensions" select="0"/>      
<xsl:param name="fop.extensions" select="0"/>     
<xsl:param name="saxon.extensions" select="0"/>   
<xsl:param name="passivetex.extensions" select="1"/>
<xsl:param name="tablecolumns.extension" select="'1'"/>

<!-- ensure we are using single sided -->
<xsl:param name="double.sided" select="'0'"/> 

<!-- insert cross references to page numbers -->
<xsl:param name="insert.xref.page.number" select="1"/>

<!-- <?custom-pagebreak?> inserts a page break at this point -->
<xsl:template match="processing-instruction('custom-pagebreak')">
  <fo:block break-before='page'/>
</xsl:template>

<!-- show links in color -->
<xsl:attribute-set name="xref.properties">
  <xsl:attribute name="color">blue</xsl:attribute>
</xsl:attribute-set>

<!-- make pre listings indented a bit + a bg colour -->
<xsl:template match="programlisting | screen">
  <fo:block start-indent="0.25in" wrap-option="no-wrap" 
            white-space-collapse="false" text-align="start" 
            font-family="monospace" background-color="#f2f2f9"
            linefeed-treatment="preserve" 
            xsl:use-attribute-sets="normal.para.spacing">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>
<!-- make verbatim output prettier -->
<xsl:template match="literallayout">
  <fo:block start-indent="0.25in" wrap-option="no-wrap" 
            white-space-collapse="false" text-align="start" 
            font-family="monospace" background-color="#edf7f4"
            linefeed-treatment="preserve" 
            space-before="0em" space-after="0em">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<!-- workaround bug in passivetex fo output for itemizedlist -->
<xsl:template match="itemizedlist/listitem">
  <xsl:variable name="id">
  <xsl:call-template name="object.id"/></xsl:variable>
  <xsl:variable name="itemsymbol">
    <xsl:call-template name="list.itemsymbol">
      <xsl:with-param name="node" select="parent::itemizedlist"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="item.contents">
    <fo:list-item-label end-indent="label-end()">
      <fo:block>
        <xsl:choose>
          <xsl:when test="$itemsymbol='disc'">&#x2022;</xsl:when>
          <xsl:when test="$itemsymbol='bullet'">&#x2022;</xsl:when>
          <xsl:otherwise>&#x2022;</xsl:otherwise>
        </xsl:choose>
      </fo:block>
    </fo:list-item-label>
    <fo:list-item-body start-indent="body-start()">
      <xsl:apply-templates/>    <!-- removed extra block wrapper -->
    </fo:list-item-body>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="parent::*/@spacing = 'compact'">
      <fo:list-item id="{$id}" 
          xsl:use-attribute-sets="compact.list.item.spacing">
        <xsl:copy-of select="$item.contents"/>
      </fo:list-item>
    </xsl:when>
    <xsl:otherwise>
      <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
        <xsl:copy-of select="$item.contents"/>
      </fo:list-item>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- workaround bug in passivetex fo output for orderedlist -->
<xsl:template match="orderedlist/listitem">
  <xsl:variable name="id">
  <xsl:call-template name="object.id"/></xsl:variable>
  <xsl:variable name="item.contents">
    <fo:list-item-label end-indent="label-end()">
      <fo:block>
        <xsl:apply-templates select="." mode="item-number"/>
      </fo:block>
    </fo:list-item-label>
    <fo:list-item-body start-indent="body-start()">
      <xsl:apply-templates/>    <!-- removed extra block wrapper -->
    </fo:list-item-body>
  </xsl:variable>
  <xsl:choose>
    <xsl:when test="parent::*/@spacing = 'compact'">
      <fo:list-item id="{$id}" 
          xsl:use-attribute-sets="compact.list.item.spacing">
        <xsl:copy-of select="$item.contents"/>
      </fo:list-item>
    </xsl:when>
    <xsl:otherwise>
      <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
        <xsl:copy-of select="$item.contents"/>
      </fo:list-item>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<!-- workaround bug in passivetex fo output for variablelist -->
<xsl:param name="variablelist.as.blocks" select="1"/>
<xsl:template match="varlistentry" mode="vl.as.blocks">
  <xsl:variable name="id">
    <xsl:call-template name="object.id"/></xsl:variable>
  <fo:block id="{$id}" xsl:use-attribute-sets="list.item.spacing"  
      keep-together.within-column="always" 
      keep-with-next.within-column="always">
    <xsl:apply-templates select="term"/>
  </fo:block>
  <fo:block start-indent="0.5in" end-indent="0in" 
            space-after.minimum="0.2em" 
            space-after.optimum="0.4em" 
            space-after.maximum="0.6em">
    <fo:block>
      <xsl:apply-templates select="listitem"/>
    </fo:block>
  </fo:block>
</xsl:template>


<!-- workaround bug in footers: force right-align w/two 80|30 cols -->
<xsl:template name="footer.table">
  <xsl:param name="pageclass" select="''"/>
  <xsl:param name="sequence" select="''"/>
  <xsl:param name="gentext-key" select="''"/>
  <xsl:choose>
    <xsl:when test="$pageclass = 'index'">
      <xsl:attribute name="margin-left">0pt</xsl:attribute>
    </xsl:when>
  </xsl:choose>
  <xsl:variable name="candidate">
    <fo:table table-layout="fixed" width="100%">
      <fo:table-column column-number="1" column-width="80%"/>
      <fo:table-column column-number="2" column-width="20%"/>
      <fo:table-body>
        <fo:table-row height="14pt">
          <fo:table-cell text-align="left" display-align="after">
            <xsl:attribute name="relative-align">baseline</xsl:attribute>
            <fo:block> 
              <fo:block> </fo:block><!-- empty cell -->
            </fo:block>
          </fo:table-cell>
          <fo:table-cell text-align="center" display-align="after">
            <xsl:attribute name="relative-align">baseline</xsl:attribute>
            <fo:block>
              <xsl:call-template name="footer.content">
                <xsl:with-param name="pageclass" select="$pageclass"/>
                <xsl:with-param name="sequence" select="$sequence"/>
                <xsl:with-param name="position" select="'center'"/>
                <xsl:with-param name="gentext-key" select="$gentext-key"/>
              </xsl:call-template>
            </fo:block>
          </fo:table-cell>
        </fo:table-row>
      </fo:table-body>
    </fo:table>
  </xsl:variable>
  <!-- Really output a footer? -->
  <xsl:choose>
    <xsl:when test="$pageclass='titlepage' and $gentext-key='book'
                    and $sequence='first'">
      <!-- no, book titlepages have no footers at all -->
    </xsl:when>
    <xsl:when test="$sequence = 'blank' and $footers.on.blank.pages = 0">
      <!-- no output -->
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="$candidate"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- fix bug in headers: force right-align w/two 40|60 cols -->
<xsl:template name="header.table">
  <xsl:param name="pageclass" select="''"/>
  <xsl:param name="sequence" select="''"/>
  <xsl:param name="gentext-key" select="''"/>
  <xsl:choose>
    <xsl:when test="$pageclass = 'index'">
      <xsl:attribute name="margin-left">0pt</xsl:attribute>
    </xsl:when>
  </xsl:choose>
  <xsl:variable name="candidate">
    <fo:table table-layout="fixed" width="100%">
      <xsl:call-template name="head.sep.rule">
        <xsl:with-param name="pageclass" select="$pageclass"/>
        <xsl:with-param name="sequence" select="$sequence"/>
        <xsl:with-param name="gentext-key" select="$gentext-key"/>
      </xsl:call-template>
      <fo:table-column column-number="1" column-width="40%"/>
      <fo:table-column column-number="2" column-width="60%"/>
      <fo:table-body>
        <fo:table-row height="14pt">
          <fo:table-cell text-align="left" display-align="before">
            <xsl:attribute name="relative-align">baseline</xsl:attribute>
            <fo:block>
              <fo:block> </fo:block><!-- empty cell -->
            </fo:block>
          </fo:table-cell>
          <fo:table-cell text-align="center" display-align="before">
            <xsl:attribute name="relative-align">baseline</xsl:attribute>
            <fo:block>
              <xsl:call-template name="header.content">
                <xsl:with-param name="pageclass" select="$pageclass"/>
                <xsl:with-param name="sequence" select="$sequence"/>
                <xsl:with-param name="position" select="'center'"/>
                <xsl:with-param name="gentext-key" select="$gentext-key"/>
              </xsl:call-template>
            </fo:block>
          </fo:table-cell>
        </fo:table-row>
      </fo:table-body>
    </fo:table>
  </xsl:variable>
  <!-- Really output a header? -->
  <xsl:choose>
    <xsl:when test="$pageclass = 'titlepage' and $gentext-key = 'book'
                    and $sequence='first'">
      <!-- no, book titlepages have no headers at all -->
    </xsl:when>
    <xsl:when test="$sequence = 'blank' and $headers.on.blank.pages = 0">
      <!-- no output -->
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="$candidate"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- Bug-fix for Suse 10 PassiveTex version -->
<!-- Precompute attribute values 'cos PassiveTex is too stupid: -->
<xsl:attribute-set name="component.title.properties">
  <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
  <xsl:attribute name="space-before.optimum">
    <xsl:value-of select="concat($body.font.master, 'pt')"/>
  </xsl:attribute>
  <xsl:attribute name="space-before.minimum">
    <xsl:value-of select="$body.font.master * 0.8"/>
    <xsl:text>pt</xsl:text>
  </xsl:attribute>
  <xsl:attribute name="space-before.maximum">
    <xsl:value-of select="$body.font.master * 1.2"/>
    <xsl:text>pt</xsl:text>
  </xsl:attribute>
  <xsl:attribute name="hyphenate">false</xsl:attribute>
</xsl:attribute-set>


</xsl:stylesheet>

--- NEW FILE: spewG.c ---

/* spew out a thoroughly gigantic file designed so that bzip2
   can compress it reasonably rapidly.  This is to help test
   support for large files (> 2GB) in a reasonable amount of time.
   I suggest you use the undocumented --exponential option to
   bzip2 when compressing the resulting file; this saves a bit of
   time.  Note: *don't* bother with --exponential when compressing 
   Real Files; it'll just waste a lot of CPU time :-)
   (but is otherwise harmless).
*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
     ------------------------------------------------------------------ */


#define _FILE_OFFSET_BITS 64

#include <stdio.h>
#include <stdlib.h>

/* The number of megabytes of junk to spew out (roughly) */
#define MEGABYTES 5000

#define N_BUF 1000000
char buf[N_BUF];

int main ( int argc, char** argv )
{
   int ii, kk, p;
   srandom(1);
   setbuffer ( stdout, buf, N_BUF );
   for (kk = 0; kk < MEGABYTES * 515; kk+=3) {
      p = 25+random()%50;
      for (ii = 0; ii < p; ii++)
         printf ( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" );
      for (ii = 0; ii < p-1; ii++)
         printf ( "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" );
      for (ii = 0; ii < p+1; ii++)
         printf ( "ccccccccccccccccccccccccccccccccccccc" );
   }
   fflush(stdout);
   return 0;
}

--- NEW FILE: Makefile ---
# ------------------------------------------------------------------
# This file is part of bzip2/libbzip2, a program and library for
# lossless, block-sorting data compression.
#
# bzip2/libbzip2 version 1.0.5 of 10 December 2007
# Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>
#
# Please read the WARNING, DISCLAIMER and PATENTS sections in the 
# README file.
#
# This program is released under the terms of the license contained
# in the file LICENSE.
# ------------------------------------------------------------------

SHELL=/bin/sh

# To assist in cross-compiling
CC=gcc
AR=ar
RANLIB=ranlib
LDFLAGS=

BIGFILES=-D_FILE_OFFSET_BITS=64
CFLAGS=-Wall -Winline -O2 -g $(BIGFILES)

# Where you want it installed when you do 'make install'
PREFIX=/usr/local


OBJS= blocksort.o  \
      huffman.o    \
      crctable.o   \
      randtable.o  \
      compress.o   \
      decompress.o \
      bzlib.o

all: libbz2.a bzip2 bzip2recover test

bzip2: libbz2.a bzip2.o
    $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2 bzip2.o -L. -lbz2

bzip2recover: bzip2recover.o
    $(CC) $(CFLAGS) $(LDFLAGS) -o bzip2recover bzip2recover.o

libbz2.a: $(OBJS)
    rm -f libbz2.a
    $(AR) cq libbz2.a $(OBJS)
    @if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \
        -f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \
        echo $(RANLIB) libbz2.a ; \
        $(RANLIB) libbz2.a ; \
    fi

check: test
test: bzip2
    @cat words1
    ./bzip2 -1  < sample1.ref > sample1.rb2
    ./bzip2 -2  < sample2.ref > sample2.rb2
    ./bzip2 -3  < sample3.ref > sample3.rb2
    ./bzip2 -d  < sample1.bz2 > sample1.tst
    ./bzip2 -d  < sample2.bz2 > sample2.tst
    ./bzip2 -ds < sample3.bz2 > sample3.tst
    cmp sample1.bz2 sample1.rb2 
    cmp sample2.bz2 sample2.rb2
    cmp sample3.bz2 sample3.rb2
    cmp sample1.tst sample1.ref
    cmp sample2.tst sample2.ref
    cmp sample3.tst sample3.ref
    @cat words3

install: bzip2 bzip2recover
    if ( test ! -d $(PREFIX)/bin ) ; then mkdir -p $(PREFIX)/bin ; fi
    if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi
    if ( test ! -d $(PREFIX)/man ) ; then mkdir -p $(PREFIX)/man ; fi
    if ( test ! -d $(PREFIX)/man/man1 ) ; then mkdir -p $(PREFIX)/man/man1 ; fi
    if ( test ! -d $(PREFIX)/include ) ; then mkdir -p $(PREFIX)/include ; fi
    cp -f bzip2 $(PREFIX)/bin/bzip2
    cp -f bzip2 $(PREFIX)/bin/bunzip2
    cp -f bzip2 $(PREFIX)/bin/bzcat
    cp -f bzip2recover $(PREFIX)/bin/bzip2recover
    chmod a+x $(PREFIX)/bin/bzip2
    chmod a+x $(PREFIX)/bin/bunzip2
    chmod a+x $(PREFIX)/bin/bzcat
    chmod a+x $(PREFIX)/bin/bzip2recover
    cp -f bzip2.1 $(PREFIX)/man/man1
    chmod a+r $(PREFIX)/man/man1/bzip2.1
    cp -f bzlib.h $(PREFIX)/include
    chmod a+r $(PREFIX)/include/bzlib.h
    cp -f libbz2.a $(PREFIX)/lib
    chmod a+r $(PREFIX)/lib/libbz2.a
    cp -f bzgrep $(PREFIX)/bin/bzgrep
    ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzegrep
    ln -s -f $(PREFIX)/bin/bzgrep $(PREFIX)/bin/bzfgrep
    chmod a+x $(PREFIX)/bin/bzgrep
    cp -f bzmore $(PREFIX)/bin/bzmore
    ln -s -f $(PREFIX)/bin/bzmore $(PREFIX)/bin/bzless
    chmod a+x $(PREFIX)/bin/bzmore
    cp -f bzdiff $(PREFIX)/bin/bzdiff
    ln -s -f $(PREFIX)/bin/bzdiff $(PREFIX)/bin/bzcmp
    chmod a+x $(PREFIX)/bin/bzdiff
    cp -f bzgrep.1 bzmore.1 bzdiff.1 $(PREFIX)/man/man1
    chmod a+r $(PREFIX)/man/man1/bzgrep.1
    chmod a+r $(PREFIX)/man/man1/bzmore.1
    chmod a+r $(PREFIX)/man/man1/bzdiff.1
    echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzegrep.1
    echo ".so man1/bzgrep.1" > $(PREFIX)/man/man1/bzfgrep.1
    echo ".so man1/bzmore.1" > $(PREFIX)/man/man1/bzless.1
    echo ".so man1/bzdiff.1" > $(PREFIX)/man/man1/bzcmp.1

clean: 
    rm -f *.o libbz2.a bzip2 bzip2recover \
    sample1.rb2 sample2.rb2 sample3.rb2 \
    sample1.tst sample2.tst sample3.tst

blocksort.o: blocksort.c
    @cat words0
    $(CC) $(CFLAGS) -c blocksort.c
huffman.o: huffman.c
    $(CC) $(CFLAGS) -c huffman.c
crctable.o: crctable.c
    $(CC) $(CFLAGS) -c crctable.c
randtable.o: randtable.c
    $(CC) $(CFLAGS) -c randtable.c
compress.o: compress.c
    $(CC) $(CFLAGS) -c compress.c
decompress.o: decompress.c
    $(CC) $(CFLAGS) -c decompress.c
bzlib.o: bzlib.c
    $(CC) $(CFLAGS) -c bzlib.c
bzip2.o: bzip2.c
    $(CC) $(CFLAGS) -c bzip2.c
bzip2recover.o: bzip2recover.c
    $(CC) $(CFLAGS) -c bzip2recover.c


distclean: clean
    rm -f manual.ps manual.html manual.pdf

DISTNAME=bzip2-1.0.5
dist: check manual
    rm -f $(DISTNAME)
    ln -s -f . $(DISTNAME)
    tar cvf $(DISTNAME).tar \
       $(DISTNAME)/blocksort.c \
       $(DISTNAME)/huffman.c \
       $(DISTNAME)/crctable.c \
       $(DISTNAME)/randtable.c \
       $(DISTNAME)/compress.c \
       $(DISTNAME)/decompress.c \
       $(DISTNAME)/bzlib.c \
       $(DISTNAME)/bzip2.c \
       $(DISTNAME)/bzip2recover.c \
       $(DISTNAME)/bzlib.h \
       $(DISTNAME)/bzlib_private.h \
       $(DISTNAME)/Makefile \
       $(DISTNAME)/LICENSE \
       $(DISTNAME)/bzip2.1 \
       $(DISTNAME)/bzip2.1.preformatted \
       $(DISTNAME)/bzip2.txt \
       $(DISTNAME)/words0 \
       $(DISTNAME)/words1 \
       $(DISTNAME)/words2 \
       $(DISTNAME)/words3 \
       $(DISTNAME)/sample1.ref \
       $(DISTNAME)/sample2.ref \
       $(DISTNAME)/sample3.ref \
       $(DISTNAME)/sample1.bz2 \
       $(DISTNAME)/sample2.bz2 \
       $(DISTNAME)/sample3.bz2 \
       $(DISTNAME)/dlltest.c \
       $(DISTNAME)/manual.html \
       $(DISTNAME)/manual.pdf \
       $(DISTNAME)/manual.ps \
       $(DISTNAME)/README \
       $(DISTNAME)/README.COMPILATION.PROBLEMS \
       $(DISTNAME)/README.XML.STUFF \
       $(DISTNAME)/CHANGES \
       $(DISTNAME)/libbz2.def \
       $(DISTNAME)/libbz2.dsp \
       $(DISTNAME)/dlltest.dsp \
       $(DISTNAME)/makefile.msc \
       $(DISTNAME)/unzcrash.c \
       $(DISTNAME)/spewG.c \
       $(DISTNAME)/mk251.c \
       $(DISTNAME)/bzdiff \
       $(DISTNAME)/bzdiff.1 \
       $(DISTNAME)/bzmore \
       $(DISTNAME)/bzmore.1 \
       $(DISTNAME)/bzgrep \
       $(DISTNAME)/bzgrep.1 \
       $(DISTNAME)/Makefile-libbz2_so \
       $(DISTNAME)/bz-common.xsl \
       $(DISTNAME)/bz-fo.xsl \
       $(DISTNAME)/bz-html.xsl \
       $(DISTNAME)/bzip.css \
       $(DISTNAME)/entities.xml \
       $(DISTNAME)/manual.xml \
       $(DISTNAME)/format.pl \
       $(DISTNAME)/xmlproc.sh
    gzip -v $(DISTNAME).tar

# For rebuilding the manual from sources on my SuSE 9.1 box

MANUAL_SRCS=    bz-common.xsl bz-fo.xsl bz-html.xsl bzip.css \
        entities.xml manual.xml 

manual: manual.html manual.ps manual.pdf

manual.ps: $(MANUAL_SRCS)
    ./xmlproc.sh -ps manual.xml

manual.pdf: $(MANUAL_SRCS)
    ./xmlproc.sh -pdf manual.xml

manual.html: $(MANUAL_SRCS)
    ./xmlproc.sh -html manual.xml

--- NEW FILE: sample1.bz2 ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: bzip2.c ---

/*-----------------------------------------------------------*/
/*--- A block-sorting, lossless compressor        bzip2.c ---*/
/*-----------------------------------------------------------*/

/* ------------------------------------------------------------------
   This file is part of bzip2/libbzip2, a program and library for
   lossless, block-sorting data compression.

   bzip2/libbzip2 version 1.0.5 of 10 December 2007
   Copyright (C) 1996-2007 Julian Seward <jseward at bzip.org>

   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
   README file.

   This program is released under the terms of the license contained
   in the file LICENSE.
   ------------------------------------------------------------------ */

[...1995 lines suppressed...]
   }

   /* Free the argument list memory to mollify leak detectors 
      (eg) Purify, Checker.  Serves no other useful purpose.
   */
   aa = argList;
   while (aa != NULL) {
      Cell* aa2 = aa->link;
      if (aa->name != NULL) free(aa->name);
      free(aa);
      aa = aa2;
   }

   return exitValue;
}


/*-----------------------------------------------------------*/
/*--- end                                         bzip2.c ---*/
/*-----------------------------------------------------------*/

--- NEW FILE: sample3.bz2 ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: bzip2.txt ---

NAME
       bzip2, bunzip2 - a block-sorting file compressor, v1.0.4
       bzcat - decompresses files to stdout
       bzip2recover - recovers data from damaged bzip2 files


SYNOPSIS
       bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ...  ]
       bunzip2 [ -fkvsVL ] [ filenames ...  ]
       bzcat [ -s ] [ filenames ...  ]
       bzip2recover filename


DESCRIPTION
       bzip2  compresses  files  using  the Burrows-Wheeler block
       sorting text compression algorithm,  and  Huffman  coding.
       Compression  is  generally  considerably  better than that
       achieved by more conventional LZ77/LZ78-based compressors,
       and  approaches  the performance of the PPM family of sta-
       tistical compressors.

       The command-line options are deliberately very similar  to
       those of GNU gzip, but they are not identical.

       bzip2  expects  a list of file names to accompany the com-
       mand-line flags.  Each file is replaced  by  a  compressed
       version  of  itself,  with  the  name "original_name.bz2".
       Each compressed file has the same modification date,  per-
       missions, and, when possible, ownership as the correspond-
       ing original, so that these properties  can  be  correctly
       restored  at  decompression  time.   File name handling is
       naive in the sense that there is no mechanism for preserv-
       ing  original file names, permissions, ownerships or dates
       in filesystems which lack these concepts, or have  serious
       file name length restrictions, such as MS-DOS.

       bzip2  and  bunzip2 will by default not overwrite existing
       files.  If you want this to happen, specify the -f flag.

       If no file names  are  specified,  bzip2  compresses  from
       standard  input  to  standard output.  In this case, bzip2
       will decline to write compressed output to a terminal,  as
       this  would  be  entirely  incomprehensible  and therefore
       pointless.

       bunzip2 (or bzip2 -d) decompresses  all  specified  files.
       Files which were not created by bzip2 will be detected and
       ignored, and a warning issued.  bzip2  attempts  to  guess
       the  filename  for  the decompressed file from that of the
       compressed file as follows:

              filename.bz2    becomes   filename
              filename.bz     becomes   filename
              filename.tbz2   becomes   filename.tar
              filename.tbz    becomes   filename.tar
              anyothername    becomes   anyothername.out

       If the file does not end in one of the recognised endings,
       .bz2,  .bz,  .tbz2 or .tbz, bzip2 complains that it cannot
       guess the name of the original file, and uses the original
       name with .out appended.

       As  with compression, supplying no filenames causes decom-
       pression from standard input to standard output.

       bunzip2 will correctly decompress a file which is the con-
       catenation of two or more compressed files.  The result is
       the concatenation of the corresponding uncompressed files.
       Integrity testing (-t) of concatenated compressed files is
       also supported.

       You can also compress or decompress files to the  standard
       output  by giving the -c flag.  Multiple files may be com-
       pressed and decompressed like this.  The resulting outputs
       are  fed  sequentially to stdout.  Compression of multiple
       files in this manner generates a stream containing  multi-
       ple compressed file representations.  Such a stream can be
       decompressed correctly only  by  bzip2  version  0.9.0  or
       later.   Earlier  versions of bzip2 will stop after decom-
       pressing the first file in the stream.

       bzcat (or bzip2 -dc) decompresses all specified  files  to
       the standard output.

       bzip2  will  read arguments from the environment variables
       BZIP2 and BZIP, in  that  order,  and  will  process  them
       before  any  arguments  read  from the command line.  This
       gives a convenient way to supply default arguments.

       Compression is always performed, even  if  the  compressed
       file  is slightly larger than the original.  Files of less
       than about one hundred bytes tend to get larger, since the
       compression  mechanism  has  a  constant  overhead  in the
       region of 50 bytes.  Random data (including the output  of
       most  file  compressors)  is  coded at about 8.05 bits per
       byte, giving an expansion of around 0.5%.

       As a self-check for your  protection,  bzip2  uses  32-bit
       CRCs  to make sure that the decompressed version of a file
       is identical to the original.  This guards against corrup-
       tion  of  the compressed data, and against undetected bugs
       in bzip2 (hopefully very unlikely).  The chances  of  data
       corruption  going  undetected  is  microscopic,  about one
       chance in four billion for each file processed.  Be aware,
       though,  that  the  check occurs upon decompression, so it
       can only tell you that something is wrong.  It can't  help
       you  recover  the original uncompressed data.  You can use
       bzip2recover to try to recover data from damaged files.

       Return values: 0 for a normal exit,  1  for  environmental
       problems  (file not found, invalid flags, I/O errors, &c),
       2 to indicate a corrupt compressed file, 3 for an internal
       consistency error (eg, bug) which caused bzip2 to panic.


OPTIONS
       -c --stdout
              Compress or decompress to standard output.

       -d --decompress
              Force  decompression.  bzip2, bunzip2 and bzcat are
              really the same program,  and  the  decision  about
              what  actions to take is done on the basis of which
              name is used.  This flag overrides that  mechanism,
              and forces bzip2 to decompress.

       -z --compress
              The   complement   to   -d:   forces   compression,
              regardless of the invocation name.

       -t --test
              Check integrity of the specified file(s), but don't
              decompress  them.   This  really  performs  a trial
              decompression and throws away the result.

       -f --force
              Force overwrite of output files.   Normally,  bzip2
              will  not  overwrite  existing  output files.  Also
              forces bzip2 to break hard links to files, which it
              otherwise wouldn't do.

              bzip2  normally  declines to decompress files which
              don't have the  correct  magic  header  bytes.   If
              forced  (-f),  however,  it  will  pass  such files
              through unmodified.  This is how GNU gzip  behaves.

       -k --keep
              Keep  (don't delete) input files during compression
              or decompression.

       -s --small
              Reduce memory usage, for compression, decompression
              and  testing.   Files  are  decompressed and tested
              using a modified algorithm which only requires  2.5
              bytes  per  block byte.  This means any file can be
              decompressed in 2300k of memory,  albeit  at  about
              half the normal speed.

              During  compression,  -s  selects  a  block size of
              200k, which limits memory use to  around  the  same
              figure,  at  the expense of your compression ratio.
              In short, if your  machine  is  low  on  memory  (8
              megabytes  or  less),  use  -s for everything.  See
              MEMORY MANAGEMENT below.

       -q --quiet
              Suppress non-essential warning messages.   Messages
              pertaining  to I/O errors and other critical events
              will not be suppressed.

       -v --verbose
              Verbose mode -- show the compression ratio for each
              file  processed.   Further  -v's  increase the ver-
              bosity level, spewing out lots of information which
              is primarily of interest for diagnostic purposes.

       -L --license -V --version
              Display  the  software  version,  license terms and
              conditions.

       -1 (or --fast) to -9 (or --best)
              Set the block size to 100 k, 200 k ..  900  k  when
              compressing.   Has  no  effect  when decompressing.
              See MEMORY MANAGEMENT below.  The --fast and --best
              aliases  are  primarily for GNU gzip compatibility.
              In particular, --fast doesn't make things  signifi-
              cantly  faster.   And  --best  merely  selects  the
              default behaviour.

       --     Treats all subsequent arguments as file names, even
              if they start with a dash.  This is so you can han-
              dle files with names beginning  with  a  dash,  for
              example: bzip2 -- -myfilename.

       --repetitive-fast --repetitive-best
              These  flags  are  redundant  in versions 0.9.5 and
              above.  They provided some coarse control over  the
              behaviour  of the sorting algorithm in earlier ver-
              sions, which was sometimes useful.  0.9.5 and above
              have  an  improved  algorithm  which  renders these
              flags irrelevant.


MEMORY MANAGEMENT
       bzip2 compresses large files in blocks.   The  block  size
       affects  both  the  compression  ratio  achieved,  and the
       amount of memory needed for compression and decompression.
       The  flags  -1  through  -9  specify  the block size to be
       100,000 bytes through 900,000 bytes (the default)  respec-
       tively.   At  decompression  time, the block size used for
       compression is read from  the  header  of  the  compressed
       file, and bunzip2 then allocates itself just enough memory
       to decompress the file.  Since block sizes are  stored  in
       compressed  files,  it follows that the flags -1 to -9 are
       irrelevant to and so ignored during decompression.

       Compression and decompression requirements, in bytes,  can
       be estimated as:

              Compression:   400k + ( 8 x block size )

              Decompression: 100k + ( 4 x block size ), or
                             100k + ( 2.5 x block size )

       Larger  block  sizes  give  rapidly  diminishing  marginal
       returns.  Most of the compression comes from the first two
       or  three hundred k of block size, a fact worth bearing in
       mind when using bzip2  on  small  machines.   It  is  also
       important  to  appreciate  that  the  decompression memory
       requirement is set at compression time by  the  choice  of
       block size.

       For  files  compressed  with  the default 900k block size,
       bunzip2 will require about 3700 kbytes to decompress.   To
       support decompression of any file on a 4 megabyte machine,
       bunzip2 has an option to  decompress  using  approximately
       half this amount of memory, about 2300 kbytes.  Decompres-
       sion speed is also halved, so you should use  this  option
       only where necessary.  The relevant flag is -s.

       In general, try and use the largest block size memory con-
       straints  allow,  since  that  maximises  the  compression
       achieved.   Compression and decompression speed are virtu-
       ally unaffected by block size.

       Another significant point applies to files which fit in  a
       single  block  --  that  means  most files you'd encounter
       using a large block  size.   The  amount  of  real  memory
       touched is proportional to the size of the file, since the
       file is smaller than a block.  For example, compressing  a
       file  20,000  bytes  long  with the flag -9 will cause the
       compressor to allocate around 7600k of  memory,  but  only
       touch 400k + 20000 * 8 = 560 kbytes of it.  Similarly, the
       decompressor will allocate 3700k but  only  touch  100k  +
       20000 * 4 = 180 kbytes.

       Here  is a table which summarises the maximum memory usage
       for different block sizes.  Also  recorded  is  the  total
       compressed  size for 14 files of the Calgary Text Compres-
       sion Corpus totalling 3,141,622 bytes.  This column  gives
       some  feel  for  how  compression  varies with block size.
       These figures tend to understate the advantage  of  larger
       block  sizes  for  larger files, since the Corpus is domi-
       nated by smaller files.

                  Compress   Decompress   Decompress   Corpus
           Flag     usage      usage       -s usage     Size

            -1      1200k       500k         350k      914704
            -2      2000k       900k         600k      877703
            -3      2800k      1300k         850k      860338
            -4      3600k      1700k        1100k      846899
            -5      4400k      2100k        1350k      845160
            -6      5200k      2500k        1600k      838626
            -7      6100k      2900k        1850k      834096
            -8      6800k      3300k        2100k      828642
            -9      7600k      3700k        2350k      828642


RECOVERING DATA FROM DAMAGED FILES
       bzip2 compresses files in blocks, usually 900kbytes  long.
       Each block is handled independently.  If a media or trans-
       mission error causes a multi-block  .bz2  file  to  become
       damaged,  it  may  be  possible  to  recover data from the
       undamaged blocks in the file.

       The compressed representation of each block  is  delimited
       by  a  48-bit pattern, which makes it possible to find the
       block boundaries with reasonable  certainty.   Each  block
       also  carries its own 32-bit CRC, so damaged blocks can be
       distinguished from undamaged ones.

       bzip2recover is a  simple  program  whose  purpose  is  to
       search  for blocks in .bz2 files, and write each block out
       into its own .bz2 file.  You can then use bzip2 -t to test
       the integrity of the resulting files, and decompress those
       which are undamaged.

       bzip2recover takes a single argument, the name of the dam-
       aged    file,    and    writes    a    number   of   files
       "rec00001file.bz2",  "rec00002file.bz2",  etc,  containing
       the   extracted   blocks.   The   output   filenames   are
       designed  so  that the use of wildcards in subsequent pro-
       cessing  -- for example, "bzip2 -dc  rec*file.bz2 > recov-
       ered_data" -- processes the files in the correct order.

       bzip2recover should be of most use dealing with large .bz2
       files,  as  these will contain many blocks.  It is clearly
       futile to use it on damaged single-block  files,  since  a
       damaged  block  cannot  be recovered.  If you wish to min-
       imise any potential data loss through media  or  transmis-
       sion errors, you might consider compressing with a smaller
       block size.


PERFORMANCE NOTES
       The sorting phase of compression gathers together  similar
       strings  in  the  file.  Because of this, files containing
       very long runs of  repeated  symbols,  like  "aabaabaabaab
       ..."   (repeated  several hundred times) may compress more
       slowly than normal.  Versions 0.9.5 and  above  fare  much
       better  than previous versions in this respect.  The ratio
       between worst-case and average-case compression time is in
       the  region  of  10:1.  For previous versions, this figure
       was more like 100:1.  You can use the -vvvv option to mon-
       itor progress in great detail, if you want.

       Decompression speed is unaffected by these phenomena.

       bzip2  usually  allocates  several  megabytes of memory to
       operate in, and then charges all over it in a fairly  ran-
       dom  fashion.   This means that performance, both for com-
       pressing and decompressing, is largely determined  by  the
       speed  at  which  your  machine  can service cache misses.
       Because of this, small changes to the code to  reduce  the
       miss  rate  have  been observed to give disproportionately
       large performance improvements.  I imagine bzip2 will per-
       form best on machines with very large caches.


CAVEATS
       I/O  error  messages  are not as helpful as they could be.
       bzip2 tries hard to detect I/O errors  and  exit  cleanly,
       but  the  details  of  what  the problem is sometimes seem
       rather misleading.

       This manual page pertains to version 1.0.4 of bzip2.  Com-
       pressed  data created by this version is entirely forwards
       and  backwards  compatible  with   the   previous   public
       releases,  versions  0.1pl2,  0.9.0,  0.9.5, 1.0.0, 1.0.1,
       1.0.2 and 1.0.3, but with the  following  exception: 0.9.0
       and above can  correctly decompress  multiple concatenated
       compressed files.  0.1pl2  cannot do this;  it  will  stop
       after  decompressing just the first file in the stream.

       bzip2recover  versions prior to 1.0.2 used 32-bit integers
       to represent bit positions in compressed  files,  so  they
       could  not handle compressed files more than 512 megabytes
       long.  Versions 1.0.2 and above use 64-bit  ints  on  some
       platforms  which  support them (GNU supported targets, and
       Windows).  To establish whether or  not  bzip2recover  was
       built  with  such  a limitation, run it without arguments.
       In any event you can build yourself an  unlimited  version
       if  you  can  recompile  it  with MaybeUInt64 set to be an
       unsigned 64-bit integer.


AUTHOR
       Julian Seward, jsewardbzip.org.

       http://www.bzip.org

       The ideas embodied in bzip2 are due to (at least) the fol-
       lowing  people: Michael Burrows and David Wheeler (for the
       block sorting transformation), David Wheeler  (again,  for
       the Huffman coder), Peter Fenwick (for the structured cod-
       ing model in the original bzip, and many refinements), and
       Alistair  Moffat,  Radford  Neal  and  Ian Witten (for the
       arithmetic  coder  in  the  original  bzip).   I  am  much
       indebted for their help, support and advice.  See the man-
       ual in the source distribution for pointers to sources  of
       documentation.  Christian von Roques encouraged me to look
       for faster sorting algorithms, so as to speed up  compres-
       sion.  Bela Lubkin encouraged me to improve the worst-case
       compression performance.  Donna Robinson XMLised the docu-
       mentation.   The bz* scripts are derived from those of GNU
       gzip.  Many people sent patches, helped  with  portability
       problems,  lent  machines,  gave advice and were generally
       helpful.


--- NEW FILE: makefile.msc ---
# Makefile for Microsoft Visual C++ 6.0
# usage: nmake -f makefile.msc
# K.M. Syring (syring at gsf.de)
# Fixed up by JRS for bzip2-0.9.5d release.

CC=cl
CFLAGS= -DWIN32 -MD -Ox -D_FILE_OFFSET_BITS=64 -nologo

OBJS= blocksort.obj  \
      huffman.obj    \
      crctable.obj   \
      randtable.obj  \
      compress.obj   \
      decompress.obj \
      bzlib.obj

all: lib bzip2 test

bzip2: lib
    $(CC) $(CFLAGS) -o bzip2 bzip2.c libbz2.lib setargv.obj
    $(CC) $(CFLAGS) -o bzip2recover bzip2recover.c

lib: $(OBJS)
    lib /out:libbz2.lib $(OBJS)

test: bzip2
    type words1
    .\\bzip2 -1  < sample1.ref > sample1.rb2
    .\\bzip2 -2  < sample2.ref > sample2.rb2
    .\\bzip2 -3  < sample3.ref > sample3.rb2
    .\\bzip2 -d  < sample1.bz2 > sample1.tst
    .\\bzip2 -d  < sample2.bz2 > sample2.tst
    .\\bzip2 -ds < sample3.bz2 > sample3.tst
    @echo All six of the fc's should find no differences.
    @echo If fc finds an error on sample3.bz2, this could be
    @echo because WinZip's 'TAR file smart CR/LF conversion'
    @echo is too clever for its own good.  Disable this option.
    @echo The correct size for sample3.ref is 120,244.  If it
    @echo is 150,251, WinZip has messed it up.
    fc sample1.bz2 sample1.rb2 
    fc sample2.bz2 sample2.rb2
    fc sample3.bz2 sample3.rb2
    fc sample1.tst sample1.ref
    fc sample2.tst sample2.ref
    fc sample3.tst sample3.ref



clean: 
    del *.obj
    del libbz2.lib 
    del bzip2.exe
    del bzip2recover.exe
    del sample1.rb2 
    del sample2.rb2 
    del sample3.rb2
    del sample1.tst 
    del sample2.tst
    del sample3.tst

.c.obj: 
    $(CC) $(CFLAGS) -c $*.c -o $*.obj


--- NEW FILE: sample3.rb2 ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: sample1.tst ---
(This appears to be a binary file; contents omitted.)



More information about the Cmake-commits mailing list