Blame bzlib-src/compress.c

Packit 989e37
Packit 989e37
/*-------------------------------------------------------------*/
Packit 989e37
/*--- Compression machinery (not incl block sorting)        ---*/
Packit 989e37
/*---                                            compress.c ---*/
Packit 989e37
/*-------------------------------------------------------------*/
Packit 989e37
Packit 989e37
/* ------------------------------------------------------------------
Packit 989e37
   This file is part of bzip2/libbzip2, a program and library for
Packit 989e37
   lossless, block-sorting data compression.
Packit 989e37
Packit 989e37
   bzip2/libbzip2 version 1.0.6 of 6 September 2010
Packit 989e37
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Packit 989e37
Packit 989e37
   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
Packit 989e37
   README file.
Packit 989e37
Packit 989e37
   This program is released under the terms of the license contained
Packit 989e37
   in the file LICENSE.
Packit 989e37
   ------------------------------------------------------------------ */
Packit 989e37
Packit 989e37
Packit 989e37
/* CHANGES
Packit 989e37
    0.9.0    -- original version.
Packit 989e37
    0.9.0a/b -- no changes in this file.
Packit 989e37
    0.9.0c   -- changed setting of nGroups in sendMTFValues() 
Packit 989e37
                so as to do a bit better on small files
Packit 989e37
*/
Packit 989e37
Packit 989e37
#include "bzlib_private.h"
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
/*--- Bit stream I/O                              ---*/
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
void BZ2_bsInitWrite ( EState* s )
Packit 989e37
{
Packit 989e37
   s->bsLive = 0;
Packit 989e37
   s->bsBuff = 0;
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
static
Packit 989e37
void bsFinishWrite ( EState* s )
Packit 989e37
{
Packit 989e37
   while (s->bsLive > 0) {
Packit 989e37
      s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
Packit 989e37
      s->numZ++;
Packit 989e37
      s->bsBuff <<= 8;
Packit 989e37
      s->bsLive -= 8;
Packit 989e37
   }
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
#define bsNEEDW(nz)                           \
Packit 989e37
{                                             \
Packit 989e37
   while (s->bsLive >= 8) {                   \
Packit 989e37
      s->zbits[s->numZ]                       \
Packit 989e37
         = (UChar)(s->bsBuff >> 24);          \
Packit 989e37
      s->numZ++;                              \
Packit 989e37
      s->bsBuff <<= 8;                        \
Packit 989e37
      s->bsLive -= 8;                         \
Packit 989e37
   }                                          \
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
static
Packit 989e37
__inline__
Packit 989e37
void bsW ( EState* s, Int32 n, UInt32 v )
Packit 989e37
{
Packit 989e37
   bsNEEDW ( n );
Packit 989e37
   s->bsBuff |= (v << (32 - s->bsLive - n));
Packit 989e37
   s->bsLive += n;
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
static
Packit 989e37
void bsPutUInt32 ( EState* s, UInt32 u )
Packit 989e37
{
Packit 989e37
   bsW ( s, 8, (u >> 24) & 0xffL );
Packit 989e37
   bsW ( s, 8, (u >> 16) & 0xffL );
Packit 989e37
   bsW ( s, 8, (u >>  8) & 0xffL );
Packit 989e37
   bsW ( s, 8,  u        & 0xffL );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
static
Packit 989e37
void bsPutUChar ( EState* s, UChar c )
Packit 989e37
{
Packit 989e37
   bsW( s, 8, (UInt32)c );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
/*--- The back end proper                         ---*/
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
static
Packit 989e37
void makeMaps_e ( EState* s )
Packit 989e37
{
Packit 989e37
   Int32 i;
Packit 989e37
   s->nInUse = 0;
Packit 989e37
   for (i = 0; i < 256; i++)
Packit 989e37
      if (s->inUse[i]) {
Packit 989e37
         s->unseqToSeq[i] = s->nInUse;
Packit 989e37
         s->nInUse++;
Packit 989e37
      }
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
static
Packit 989e37
void generateMTFValues ( EState* s )
Packit 989e37
{
Packit 989e37
   UChar   yy[256];
Packit 989e37
   Int32   i, j;
Packit 989e37
   Int32   zPend;
Packit 989e37
   Int32   wr;
Packit 989e37
   Int32   EOB;
Packit 989e37
Packit 989e37
   /* 
Packit 989e37
      After sorting (eg, here),
Packit 989e37
         s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
Packit 989e37
         and
Packit 989e37
         ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] 
Packit 989e37
         holds the original block data.
Packit 989e37
Packit 989e37
      The first thing to do is generate the MTF values,
Packit 989e37
      and put them in
Packit 989e37
         ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
Packit 989e37
      Because there are strictly fewer or equal MTF values
Packit 989e37
      than block values, ptr values in this area are overwritten
Packit 989e37
      with MTF values only when they are no longer needed.
Packit 989e37
Packit 989e37
      The final compressed bitstream is generated into the
Packit 989e37
      area starting at
Packit 989e37
         (UChar*) (&((UChar*)s->arr2)[s->nblock])
Packit 989e37
Packit 989e37
      These storage aliases are set up in bzCompressInit(),
Packit 989e37
      except for the last one, which is arranged in 
Packit 989e37
      compressBlock().
Packit 989e37
   */
Packit 989e37
   UInt32* ptr   = s->ptr;
Packit 989e37
   UChar* block  = s->block;
Packit 989e37
   UInt16* mtfv  = s->mtfv;
Packit 989e37
Packit 989e37
   makeMaps_e ( s );
Packit 989e37
   EOB = s->nInUse+1;
Packit 989e37
Packit 989e37
   for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
Packit 989e37
Packit 989e37
   wr = 0;
Packit 989e37
   zPend = 0;
Packit 989e37
   for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
Packit 989e37
Packit 989e37
   for (i = 0; i < s->nblock; i++) {
Packit 989e37
      UChar ll_i;
Packit 989e37
      AssertD ( wr <= i, "generateMTFValues(1)" );
Packit 989e37
      j = ptr[i]-1; if (j < 0) j += s->nblock;
Packit 989e37
      ll_i = s->unseqToSeq[block[j]];
Packit 989e37
      AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
Packit 989e37
Packit 989e37
      if (yy[0] == ll_i) { 
Packit 989e37
         zPend++;
Packit 989e37
      } else {
Packit 989e37
Packit 989e37
         if (zPend > 0) {
Packit 989e37
            zPend--;
Packit 989e37
            while (True) {
Packit 989e37
               if (zPend & 1) {
Packit 989e37
                  mtfv[wr] = BZ_RUNB; wr++; 
Packit 989e37
                  s->mtfFreq[BZ_RUNB]++; 
Packit 989e37
               } else {
Packit 989e37
                  mtfv[wr] = BZ_RUNA; wr++; 
Packit 989e37
                  s->mtfFreq[BZ_RUNA]++; 
Packit 989e37
               }
Packit 989e37
               if (zPend < 2) break;
Packit 989e37
               zPend = (zPend - 2) / 2;
Packit 989e37
            };
Packit 989e37
            zPend = 0;
Packit 989e37
         }
Packit 989e37
         {
Packit 989e37
            register UChar  rtmp;
Packit 989e37
            register UChar* ryy_j;
Packit 989e37
            register UChar  rll_i;
Packit 989e37
            rtmp  = yy[1];
Packit 989e37
            yy[1] = yy[0];
Packit 989e37
            ryy_j = &(yy[1]);
Packit 989e37
            rll_i = ll_i;
Packit 989e37
            while ( rll_i != rtmp ) {
Packit 989e37
               register UChar rtmp2;
Packit 989e37
               ryy_j++;
Packit 989e37
               rtmp2  = rtmp;
Packit 989e37
               rtmp   = *ryy_j;
Packit 989e37
               *ryy_j = rtmp2;
Packit 989e37
            };
Packit 989e37
            yy[0] = rtmp;
Packit 989e37
            j = ryy_j - &(yy[0]);
Packit 989e37
            mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
Packit 989e37
         }
Packit 989e37
Packit 989e37
      }
Packit 989e37
   }
Packit 989e37
Packit 989e37
   if (zPend > 0) {
Packit 989e37
      zPend--;
Packit 989e37
      while (True) {
Packit 989e37
         if (zPend & 1) {
Packit 989e37
            mtfv[wr] = BZ_RUNB; wr++; 
Packit 989e37
            s->mtfFreq[BZ_RUNB]++; 
Packit 989e37
         } else {
Packit 989e37
            mtfv[wr] = BZ_RUNA; wr++; 
Packit 989e37
            s->mtfFreq[BZ_RUNA]++; 
Packit 989e37
         }
Packit 989e37
         if (zPend < 2) break;
Packit 989e37
         zPend = (zPend - 2) / 2;
Packit 989e37
      };
Packit 989e37
      zPend = 0;
Packit 989e37
   }
Packit 989e37
Packit 989e37
   mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
Packit 989e37
Packit 989e37
   s->nMTF = wr;
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
#define BZ_LESSER_ICOST  0
Packit 989e37
#define BZ_GREATER_ICOST 15
Packit 989e37
Packit 989e37
static
Packit 989e37
void sendMTFValues ( EState* s )
Packit 989e37
{
Packit 989e37
   Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
Packit 989e37
   Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
Packit 989e37
   Int32 nGroups, nBytes;
Packit 989e37
Packit 989e37
   /*--
Packit 989e37
   UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Packit 989e37
   is a global since the decoder also needs it.
Packit 989e37
Packit 989e37
   Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Packit 989e37
   Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
Packit 989e37
   are also globals only used in this proc.
Packit 989e37
   Made global to keep stack frame size small.
Packit 989e37
   --*/
Packit 989e37
Packit 989e37
Packit 989e37
   UInt16 cost[BZ_N_GROUPS];
Packit 989e37
   Int32  fave[BZ_N_GROUPS];
Packit 989e37
Packit 989e37
   UInt16* mtfv = s->mtfv;
Packit 989e37
Packit 989e37
   if (s->verbosity >= 3)
Packit 989e37
      VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
Packit 989e37
                "%d+2 syms in use\n", 
Packit 989e37
                s->nblock, s->nMTF, s->nInUse );
Packit 989e37
Packit 989e37
   alphaSize = s->nInUse+2;
Packit 989e37
   for (t = 0; t < BZ_N_GROUPS; t++)
Packit 989e37
      for (v = 0; v < alphaSize; v++)
Packit 989e37
         s->len[t][v] = BZ_GREATER_ICOST;
Packit 989e37
Packit 989e37
   /*--- Decide how many coding tables to use ---*/
Packit 989e37
   AssertH ( s->nMTF > 0, 3001 );
Packit 989e37
   if (s->nMTF < 200)  nGroups = 2; else
Packit 989e37
   if (s->nMTF < 600)  nGroups = 3; else
Packit 989e37
   if (s->nMTF < 1200) nGroups = 4; else
Packit 989e37
   if (s->nMTF < 2400) nGroups = 5; else
Packit 989e37
                       nGroups = 6;
Packit 989e37
Packit 989e37
   /*--- Generate an initial set of coding tables ---*/
Packit 989e37
   { 
Packit 989e37
      Int32 nPart, remF, tFreq, aFreq;
Packit 989e37
Packit 989e37
      nPart = nGroups;
Packit 989e37
      remF  = s->nMTF;
Packit 989e37
      gs = 0;
Packit 989e37
      while (nPart > 0) {
Packit 989e37
         tFreq = remF / nPart;
Packit 989e37
         ge = gs-1;
Packit 989e37
         aFreq = 0;
Packit 989e37
         while (aFreq < tFreq && ge < alphaSize-1) {
Packit 989e37
            ge++;
Packit 989e37
            aFreq += s->mtfFreq[ge];
Packit 989e37
         }
Packit 989e37
Packit 989e37
         if (ge > gs 
Packit 989e37
             && nPart != nGroups && nPart != 1 
Packit 989e37
             && ((nGroups-nPart) % 2 == 1)) {
Packit 989e37
            aFreq -= s->mtfFreq[ge];
Packit 989e37
            ge--;
Packit 989e37
         }
Packit 989e37
Packit 989e37
         if (s->verbosity >= 3)
Packit 989e37
            VPrintf5( "      initial group %d, [%d .. %d], "
Packit 989e37
                      "has %d syms (%4.1f%%)\n",
Packit 989e37
                      nPart, gs, ge, aFreq, 
Packit 989e37
                      (100.0 * (float)aFreq) / (float)(s->nMTF) );
Packit 989e37
 
Packit 989e37
         for (v = 0; v < alphaSize; v++)
Packit 989e37
            if (v >= gs && v <= ge) 
Packit 989e37
               s->len[nPart-1][v] = BZ_LESSER_ICOST; else
Packit 989e37
               s->len[nPart-1][v] = BZ_GREATER_ICOST;
Packit 989e37
 
Packit 989e37
         nPart--;
Packit 989e37
         gs = ge+1;
Packit 989e37
         remF -= aFreq;
Packit 989e37
      }
Packit 989e37
   }
Packit 989e37
Packit 989e37
   /*--- 
Packit 989e37
      Iterate up to BZ_N_ITERS times to improve the tables.
Packit 989e37
   ---*/
Packit 989e37
   for (iter = 0; iter < BZ_N_ITERS; iter++) {
Packit 989e37
Packit 989e37
      for (t = 0; t < nGroups; t++) fave[t] = 0;
Packit 989e37
Packit 989e37
      for (t = 0; t < nGroups; t++)
Packit 989e37
         for (v = 0; v < alphaSize; v++)
Packit 989e37
            s->rfreq[t][v] = 0;
Packit 989e37
Packit 989e37
      /*---
Packit 989e37
        Set up an auxiliary length table which is used to fast-track
Packit 989e37
	the common case (nGroups == 6). 
Packit 989e37
      ---*/
Packit 989e37
      if (nGroups == 6) {
Packit 989e37
         for (v = 0; v < alphaSize; v++) {
Packit 989e37
            s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
Packit 989e37
            s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
Packit 989e37
            s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
Packit 989e37
	 }
Packit 989e37
      }
Packit 989e37
Packit 989e37
      nSelectors = 0;
Packit 989e37
      totc = 0;
Packit 989e37
      gs = 0;
Packit 989e37
      while (True) {
Packit 989e37
Packit 989e37
         /*--- Set group start & end marks. --*/
Packit 989e37
         if (gs >= s->nMTF) break;
Packit 989e37
         ge = gs + BZ_G_SIZE - 1; 
Packit 989e37
         if (ge >= s->nMTF) ge = s->nMTF-1;
Packit 989e37
Packit 989e37
         /*-- 
Packit 989e37
            Calculate the cost of this group as coded
Packit 989e37
            by each of the coding tables.
Packit 989e37
         --*/
Packit 989e37
         for (t = 0; t < BZ_N_GROUPS; t++) cost[t] = 0;
Packit 989e37
Packit 989e37
         if (nGroups == 6 && 50 == ge-gs+1) {
Packit 989e37
            /*--- fast track the common case ---*/
Packit 989e37
            register UInt32 cost01, cost23, cost45;
Packit 989e37
            register UInt16 icv;
Packit 989e37
            cost01 = cost23 = cost45 = 0;
Packit 989e37
Packit 989e37
#           define BZ_ITER(nn)                \
Packit 989e37
               icv = mtfv[gs+(nn)];           \
Packit 989e37
               cost01 += s->len_pack[icv][0]; \
Packit 989e37
               cost23 += s->len_pack[icv][1]; \
Packit 989e37
               cost45 += s->len_pack[icv][2]; \
Packit 989e37
Packit 989e37
            BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
Packit 989e37
            BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
Packit 989e37
            BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
Packit 989e37
            BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
Packit 989e37
            BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
Packit 989e37
            BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
Packit 989e37
            BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
Packit 989e37
            BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
Packit 989e37
            BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
Packit 989e37
            BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
Packit 989e37
Packit 989e37
#           undef BZ_ITER
Packit 989e37
Packit 989e37
            cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
Packit 989e37
            cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
Packit 989e37
            cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
Packit 989e37
Packit 989e37
         } else {
Packit 989e37
	    /*--- slow version which correctly handles all situations ---*/
Packit 989e37
            for (i = gs; i <= ge; i++) { 
Packit 989e37
               UInt16 icv = mtfv[i];
Packit 989e37
               for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
Packit 989e37
            }
Packit 989e37
         }
Packit 989e37
 
Packit 989e37
         /*-- 
Packit 989e37
            Find the coding table which is best for this group,
Packit 989e37
            and record its identity in the selector table.
Packit 989e37
         --*/
Packit 989e37
         bc = 999999999; bt = -1;
Packit 989e37
         for (t = 0; t < nGroups; t++)
Packit 989e37
            if (cost[t] < bc) { bc = cost[t]; bt = t; };
Packit 989e37
         totc += bc;
Packit 989e37
         fave[bt]++;
Packit 989e37
         s->selector[nSelectors] = bt;
Packit 989e37
         nSelectors++;
Packit 989e37
Packit 989e37
         /*-- 
Packit 989e37
            Increment the symbol frequencies for the selected table.
Packit 989e37
          --*/
Packit 989e37
         if (nGroups == 6 && 50 == ge-gs+1) {
Packit 989e37
            /*--- fast track the common case ---*/
Packit 989e37
Packit 989e37
#           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
Packit 989e37
Packit 989e37
            BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
Packit 989e37
            BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
Packit 989e37
            BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
Packit 989e37
            BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
Packit 989e37
            BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
Packit 989e37
            BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
Packit 989e37
            BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
Packit 989e37
            BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
Packit 989e37
            BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
Packit 989e37
            BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
Packit 989e37
Packit 989e37
#           undef BZ_ITUR
Packit 989e37
Packit 989e37
         } else {
Packit 989e37
	    /*--- slow version which correctly handles all situations ---*/
Packit 989e37
            for (i = gs; i <= ge; i++)
Packit 989e37
               s->rfreq[bt][ mtfv[i] ]++;
Packit 989e37
         }
Packit 989e37
Packit 989e37
         gs = ge+1;
Packit 989e37
      }
Packit 989e37
      if (s->verbosity >= 3) {
Packit 989e37
         VPrintf2 ( "      pass %d: size is %d, grp uses are ", 
Packit 989e37
                   iter+1, totc/8 );
Packit 989e37
         for (t = 0; t < nGroups; t++)
Packit 989e37
            VPrintf1 ( "%d ", fave[t] );
Packit 989e37
         VPrintf0 ( "\n" );
Packit 989e37
      }
Packit 989e37
Packit 989e37
      /*--
Packit 989e37
        Recompute the tables based on the accumulated frequencies.
Packit 989e37
      --*/
Packit 989e37
      /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See 
Packit 989e37
         comment in huffman.c for details. */
Packit 989e37
      for (t = 0; t < nGroups; t++)
Packit 989e37
         BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), 
Packit 989e37
                                 alphaSize, 17 /*20*/ );
Packit 989e37
   }
Packit 989e37
Packit 989e37
Packit 989e37
   AssertH( nGroups < 8, 3002 );
Packit 989e37
   AssertH( nSelectors < 32768 &&
Packit 989e37
            nSelectors <= (2 + (900000 / BZ_G_SIZE)),
Packit 989e37
            3003 );
Packit 989e37
Packit 989e37
Packit 989e37
   /*--- Compute MTF values for the selectors. ---*/
Packit 989e37
   {
Packit 989e37
      UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
Packit 989e37
      for (i = 0; i < nGroups; i++) pos[i] = i;
Packit 989e37
      for (i = 0; i < nSelectors; i++) {
Packit 989e37
         ll_i = s->selector[i];
Packit 989e37
         j = 0;
Packit 989e37
         tmp = pos[j];
Packit 989e37
         while ( ll_i != tmp ) {
Packit 989e37
            j++;
Packit 989e37
            tmp2 = tmp;
Packit 989e37
            tmp = pos[j];
Packit 989e37
            pos[j] = tmp2;
Packit 989e37
         };
Packit 989e37
         pos[0] = tmp;
Packit 989e37
         s->selectorMtf[i] = j;
Packit 989e37
      }
Packit 989e37
   };
Packit 989e37
Packit 989e37
   /*--- Assign actual codes for the tables. --*/
Packit 989e37
   for (t = 0; t < nGroups; t++) {
Packit 989e37
      minLen = 32;
Packit 989e37
      maxLen = 0;
Packit 989e37
      for (i = 0; i < alphaSize; i++) {
Packit 989e37
         if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
Packit 989e37
         if (s->len[t][i] < minLen) minLen = s->len[t][i];
Packit 989e37
      }
Packit 989e37
      AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
Packit 989e37
      AssertH ( !(minLen < 1),  3005 );
Packit 989e37
      BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), 
Packit 989e37
                          minLen, maxLen, alphaSize );
Packit 989e37
   }
Packit 989e37
Packit 989e37
   /*--- Transmit the mapping table. ---*/
Packit 989e37
   { 
Packit 989e37
      Bool inUse16[16];
Packit 989e37
      for (i = 0; i < 16; i++) {
Packit 989e37
          inUse16[i] = False;
Packit 989e37
          for (j = 0; j < 16; j++)
Packit 989e37
             if (s->inUse[i * 16 + j]) inUse16[i] = True;
Packit 989e37
      }
Packit 989e37
     
Packit 989e37
      nBytes = s->numZ;
Packit 989e37
      for (i = 0; i < 16; i++)
Packit 989e37
         if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
Packit 989e37
Packit 989e37
      for (i = 0; i < 16; i++)
Packit 989e37
         if (inUse16[i])
Packit 989e37
            for (j = 0; j < 16; j++) {
Packit 989e37
               if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
Packit 989e37
            }
Packit 989e37
Packit 989e37
      if (s->verbosity >= 3) 
Packit 989e37
         VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
Packit 989e37
   }
Packit 989e37
Packit 989e37
   /*--- Now the selectors. ---*/
Packit 989e37
   nBytes = s->numZ;
Packit 989e37
   bsW ( s, 3, nGroups );
Packit 989e37
   bsW ( s, 15, nSelectors );
Packit 989e37
   for (i = 0; i < nSelectors; i++) { 
Packit 989e37
      for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
Packit 989e37
      bsW(s,1,0);
Packit 989e37
   }
Packit 989e37
   if (s->verbosity >= 3)
Packit 989e37
      VPrintf1( "selectors %d, ", s->numZ-nBytes );
Packit 989e37
Packit 989e37
   /*--- Now the coding tables. ---*/
Packit 989e37
   nBytes = s->numZ;
Packit 989e37
Packit 989e37
   for (t = 0; t < nGroups; t++) {
Packit 989e37
      Int32 curr = s->len[t][0];
Packit 989e37
      bsW ( s, 5, curr );
Packit 989e37
      for (i = 0; i < alphaSize; i++) {
Packit 989e37
         while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
Packit 989e37
         while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
Packit 989e37
         bsW ( s, 1, 0 );
Packit 989e37
      }
Packit 989e37
   }
Packit 989e37
Packit 989e37
   if (s->verbosity >= 3)
Packit 989e37
      VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
Packit 989e37
Packit 989e37
   /*--- And finally, the block data proper ---*/
Packit 989e37
   nBytes = s->numZ;
Packit 989e37
   selCtr = 0;
Packit 989e37
   gs = 0;
Packit 989e37
   while (True) {
Packit 989e37
      if (gs >= s->nMTF) break;
Packit 989e37
      ge = gs + BZ_G_SIZE - 1; 
Packit 989e37
      if (ge >= s->nMTF) ge = s->nMTF-1;
Packit 989e37
      AssertH ( s->selector[selCtr] < nGroups, 3006 );
Packit 989e37
Packit 989e37
      if (nGroups == 6 && 50 == ge-gs+1) {
Packit 989e37
            /*--- fast track the common case ---*/
Packit 989e37
            UInt16 mtfv_i;
Packit 989e37
            UChar* s_len_sel_selCtr 
Packit 989e37
               = &(s->len[s->selector[selCtr]][0]);
Packit 989e37
            Int32* s_code_sel_selCtr
Packit 989e37
               = &(s->code[s->selector[selCtr]][0]);
Packit 989e37
Packit 989e37
#           define BZ_ITAH(nn)                      \
Packit 989e37
               mtfv_i = mtfv[gs+(nn)];              \
Packit 989e37
               bsW ( s,                             \
Packit 989e37
                     s_len_sel_selCtr[mtfv_i],      \
Packit 989e37
                     s_code_sel_selCtr[mtfv_i] )
Packit 989e37
Packit 989e37
            BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
Packit 989e37
            BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
Packit 989e37
            BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
Packit 989e37
            BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
Packit 989e37
            BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
Packit 989e37
            BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
Packit 989e37
            BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
Packit 989e37
            BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
Packit 989e37
            BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
Packit 989e37
            BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
Packit 989e37
Packit 989e37
#           undef BZ_ITAH
Packit 989e37
Packit 989e37
      } else {
Packit 989e37
	 /*--- slow version which correctly handles all situations ---*/
Packit 989e37
         for (i = gs; i <= ge; i++) {
Packit 989e37
            bsW ( s, 
Packit 989e37
                  s->len  [s->selector[selCtr]] [mtfv[i]],
Packit 989e37
                  s->code [s->selector[selCtr]] [mtfv[i]] );
Packit 989e37
         }
Packit 989e37
      }
Packit 989e37
Packit 989e37
Packit 989e37
      gs = ge+1;
Packit 989e37
      selCtr++;
Packit 989e37
   }
Packit 989e37
   AssertH( selCtr == nSelectors, 3007 );
Packit 989e37
Packit 989e37
   if (s->verbosity >= 3)
Packit 989e37
      VPrintf1( "codes %d\n", s->numZ-nBytes );
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*---------------------------------------------------*/
Packit 989e37
void BZ2_compressBlock ( EState* s, Bool is_last_block )
Packit 989e37
{
Packit 989e37
   if (s->nblock > 0) {
Packit 989e37
Packit 989e37
      BZ_FINALISE_CRC ( s->blockCRC );
Packit 989e37
      s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
Packit 989e37
      s->combinedCRC ^= s->blockCRC;
Packit 989e37
      if (s->blockNo > 1) s->numZ = 0;
Packit 989e37
Packit 989e37
      if (s->verbosity >= 2)
Packit 989e37
         VPrintf4( "    block %d: crc = 0x%08x, "
Packit 989e37
                   "combined CRC = 0x%08x, size = %d\n",
Packit 989e37
                   s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
Packit 989e37
Packit 989e37
      BZ2_blockSort ( s );
Packit 989e37
   }
Packit 989e37
Packit 989e37
   s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
Packit 989e37
Packit 989e37
   /*-- If this is the first block, create the stream header. --*/
Packit 989e37
   if (s->blockNo == 1) {
Packit 989e37
      BZ2_bsInitWrite ( s );
Packit 989e37
      bsPutUChar ( s, BZ_HDR_B );
Packit 989e37
      bsPutUChar ( s, BZ_HDR_Z );
Packit 989e37
      bsPutUChar ( s, BZ_HDR_h );
Packit 989e37
      bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
Packit 989e37
   }
Packit 989e37
Packit 989e37
   if (s->nblock > 0) {
Packit 989e37
Packit 989e37
      bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
Packit 989e37
      bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
Packit 989e37
      bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
Packit 989e37
Packit 989e37
      /*-- Now the block's CRC, so it is in a known place. --*/
Packit 989e37
      bsPutUInt32 ( s, s->blockCRC );
Packit 989e37
Packit 989e37
      /*-- 
Packit 989e37
         Now a single bit indicating (non-)randomisation. 
Packit 989e37
         As of version 0.9.5, we use a better sorting algorithm
Packit 989e37
         which makes randomisation unnecessary.  So always set
Packit 989e37
         the randomised bit to 'no'.  Of course, the decoder
Packit 989e37
         still needs to be able to handle randomised blocks
Packit 989e37
         so as to maintain backwards compatibility with
Packit 989e37
         older versions of bzip2.
Packit 989e37
      --*/
Packit 989e37
      bsW(s,1,0);
Packit 989e37
Packit 989e37
      bsW ( s, 24, s->origPtr );
Packit 989e37
      generateMTFValues ( s );
Packit 989e37
      sendMTFValues ( s );
Packit 989e37
   }
Packit 989e37
Packit 989e37
Packit 989e37
   /*-- If this is the last block, add the stream trailer. --*/
Packit 989e37
   if (is_last_block) {
Packit 989e37
Packit 989e37
      bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
Packit 989e37
      bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
Packit 989e37
      bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
Packit 989e37
      bsPutUInt32 ( s, s->combinedCRC );
Packit 989e37
      if (s->verbosity >= 2)
Packit 989e37
         VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
Packit 989e37
      bsFinishWrite ( s );
Packit 989e37
   }
Packit 989e37
}
Packit 989e37
Packit 989e37
Packit 989e37
/*-------------------------------------------------------------*/
Packit 989e37
/*--- end                                        compress.c ---*/
Packit 989e37
/*-------------------------------------------------------------*/