Blame compress.c

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