xref: /dflybsd-src/contrib/bzip2/compress.c (revision d9ad29c0511b752ac1e5cb3f9d537a66f4bfded4)
171e7ee59SPeter Avalos 
271e7ee59SPeter Avalos /*-------------------------------------------------------------*/
371e7ee59SPeter Avalos /*--- Compression machinery (not incl block sorting)        ---*/
471e7ee59SPeter Avalos /*---                                            compress.c ---*/
571e7ee59SPeter Avalos /*-------------------------------------------------------------*/
671e7ee59SPeter Avalos 
771e7ee59SPeter Avalos /* ------------------------------------------------------------------
871e7ee59SPeter Avalos    This file is part of bzip2/libbzip2, a program and library for
971e7ee59SPeter Avalos    lossless, block-sorting data compression.
1071e7ee59SPeter Avalos 
11*86954436SDaniel Fojt    bzip2/libbzip2 version 1.0.8 of 13 July 2019
12*86954436SDaniel Fojt    Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
1371e7ee59SPeter Avalos 
1471e7ee59SPeter Avalos    Please read the WARNING, DISCLAIMER and PATENTS sections in the
1571e7ee59SPeter Avalos    README file.
1671e7ee59SPeter Avalos 
1771e7ee59SPeter Avalos    This program is released under the terms of the license contained
1871e7ee59SPeter Avalos    in the file LICENSE.
1971e7ee59SPeter Avalos    ------------------------------------------------------------------ */
2071e7ee59SPeter Avalos 
2171e7ee59SPeter Avalos 
2271e7ee59SPeter Avalos /* CHANGES
2371e7ee59SPeter Avalos     0.9.0    -- original version.
2471e7ee59SPeter Avalos     0.9.0a/b -- no changes in this file.
2571e7ee59SPeter Avalos     0.9.0c   -- changed setting of nGroups in sendMTFValues()
2671e7ee59SPeter Avalos                 so as to do a bit better on small files
2771e7ee59SPeter Avalos */
2871e7ee59SPeter Avalos 
2971e7ee59SPeter Avalos #include "bzlib_private.h"
3071e7ee59SPeter Avalos 
3171e7ee59SPeter Avalos 
3271e7ee59SPeter Avalos /*---------------------------------------------------*/
3371e7ee59SPeter Avalos /*--- Bit stream I/O                              ---*/
3471e7ee59SPeter Avalos /*---------------------------------------------------*/
3571e7ee59SPeter Avalos 
3671e7ee59SPeter Avalos /*---------------------------------------------------*/
BZ2_bsInitWrite(EState * s)3771e7ee59SPeter Avalos void BZ2_bsInitWrite ( EState* s )
3871e7ee59SPeter Avalos {
3971e7ee59SPeter Avalos    s->bsLive = 0;
4071e7ee59SPeter Avalos    s->bsBuff = 0;
4171e7ee59SPeter Avalos }
4271e7ee59SPeter Avalos 
4371e7ee59SPeter Avalos 
4471e7ee59SPeter Avalos /*---------------------------------------------------*/
4571e7ee59SPeter Avalos static
bsFinishWrite(EState * s)4671e7ee59SPeter Avalos void bsFinishWrite ( EState* s )
4771e7ee59SPeter Avalos {
4871e7ee59SPeter Avalos    while (s->bsLive > 0) {
4971e7ee59SPeter Avalos       s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
5071e7ee59SPeter Avalos       s->numZ++;
5171e7ee59SPeter Avalos       s->bsBuff <<= 8;
5271e7ee59SPeter Avalos       s->bsLive -= 8;
5371e7ee59SPeter Avalos    }
5471e7ee59SPeter Avalos }
5571e7ee59SPeter Avalos 
5671e7ee59SPeter Avalos 
5771e7ee59SPeter Avalos /*---------------------------------------------------*/
5871e7ee59SPeter Avalos #define bsNEEDW(nz)                           \
5971e7ee59SPeter Avalos {                                             \
6071e7ee59SPeter Avalos    while (s->bsLive >= 8) {                   \
6171e7ee59SPeter Avalos       s->zbits[s->numZ]                       \
6271e7ee59SPeter Avalos          = (UChar)(s->bsBuff >> 24);          \
6371e7ee59SPeter Avalos       s->numZ++;                              \
6471e7ee59SPeter Avalos       s->bsBuff <<= 8;                        \
6571e7ee59SPeter Avalos       s->bsLive -= 8;                         \
6671e7ee59SPeter Avalos    }                                          \
6771e7ee59SPeter Avalos }
6871e7ee59SPeter Avalos 
6971e7ee59SPeter Avalos 
7071e7ee59SPeter Avalos /*---------------------------------------------------*/
7171e7ee59SPeter Avalos static
7271e7ee59SPeter Avalos __inline__
bsW(EState * s,Int32 n,UInt32 v)7371e7ee59SPeter Avalos void bsW ( EState* s, Int32 n, UInt32 v )
7471e7ee59SPeter Avalos {
7571e7ee59SPeter Avalos    bsNEEDW ( n );
7671e7ee59SPeter Avalos    s->bsBuff |= (v << (32 - s->bsLive - n));
7771e7ee59SPeter Avalos    s->bsLive += n;
7871e7ee59SPeter Avalos }
7971e7ee59SPeter Avalos 
8071e7ee59SPeter Avalos 
8171e7ee59SPeter Avalos /*---------------------------------------------------*/
8271e7ee59SPeter Avalos static
bsPutUInt32(EState * s,UInt32 u)8371e7ee59SPeter Avalos void bsPutUInt32 ( EState* s, UInt32 u )
8471e7ee59SPeter Avalos {
8571e7ee59SPeter Avalos    bsW ( s, 8, (u >> 24) & 0xffL );
8671e7ee59SPeter Avalos    bsW ( s, 8, (u >> 16) & 0xffL );
8771e7ee59SPeter Avalos    bsW ( s, 8, (u >>  8) & 0xffL );
8871e7ee59SPeter Avalos    bsW ( s, 8,  u        & 0xffL );
8971e7ee59SPeter Avalos }
9071e7ee59SPeter Avalos 
9171e7ee59SPeter Avalos 
9271e7ee59SPeter Avalos /*---------------------------------------------------*/
9371e7ee59SPeter Avalos static
bsPutUChar(EState * s,UChar c)9471e7ee59SPeter Avalos void bsPutUChar ( EState* s, UChar c )
9571e7ee59SPeter Avalos {
9671e7ee59SPeter Avalos    bsW( s, 8, (UInt32)c );
9771e7ee59SPeter Avalos }
9871e7ee59SPeter Avalos 
9971e7ee59SPeter Avalos 
10071e7ee59SPeter Avalos /*---------------------------------------------------*/
10171e7ee59SPeter Avalos /*--- The back end proper                         ---*/
10271e7ee59SPeter Avalos /*---------------------------------------------------*/
10371e7ee59SPeter Avalos 
10471e7ee59SPeter Avalos /*---------------------------------------------------*/
10571e7ee59SPeter Avalos static
makeMaps_e(EState * s)10671e7ee59SPeter Avalos void makeMaps_e ( EState* s )
10771e7ee59SPeter Avalos {
10871e7ee59SPeter Avalos    Int32 i;
10971e7ee59SPeter Avalos    s->nInUse = 0;
11071e7ee59SPeter Avalos    for (i = 0; i < 256; i++)
11171e7ee59SPeter Avalos       if (s->inUse[i]) {
11271e7ee59SPeter Avalos          s->unseqToSeq[i] = s->nInUse;
11371e7ee59SPeter Avalos          s->nInUse++;
11471e7ee59SPeter Avalos       }
11571e7ee59SPeter Avalos }
11671e7ee59SPeter Avalos 
11771e7ee59SPeter Avalos 
11871e7ee59SPeter Avalos /*---------------------------------------------------*/
11971e7ee59SPeter Avalos static
generateMTFValues(EState * s)12071e7ee59SPeter Avalos void generateMTFValues ( EState* s )
12171e7ee59SPeter Avalos {
12271e7ee59SPeter Avalos    UChar   yy[256];
12371e7ee59SPeter Avalos    Int32   i, j;
12471e7ee59SPeter Avalos    Int32   zPend;
12571e7ee59SPeter Avalos    Int32   wr;
12671e7ee59SPeter Avalos    Int32   EOB;
12771e7ee59SPeter Avalos 
12871e7ee59SPeter Avalos    /*
12971e7ee59SPeter Avalos       After sorting (eg, here),
13071e7ee59SPeter Avalos          s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
13171e7ee59SPeter Avalos          and
13271e7ee59SPeter Avalos          ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
13371e7ee59SPeter Avalos          holds the original block data.
13471e7ee59SPeter Avalos 
13571e7ee59SPeter Avalos       The first thing to do is generate the MTF values,
13671e7ee59SPeter Avalos       and put them in
13771e7ee59SPeter Avalos          ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
13871e7ee59SPeter Avalos       Because there are strictly fewer or equal MTF values
13971e7ee59SPeter Avalos       than block values, ptr values in this area are overwritten
14071e7ee59SPeter Avalos       with MTF values only when they are no longer needed.
14171e7ee59SPeter Avalos 
14271e7ee59SPeter Avalos       The final compressed bitstream is generated into the
14371e7ee59SPeter Avalos       area starting at
14471e7ee59SPeter Avalos          (UChar*) (&((UChar*)s->arr2)[s->nblock])
14571e7ee59SPeter Avalos 
14671e7ee59SPeter Avalos       These storage aliases are set up in bzCompressInit(),
14771e7ee59SPeter Avalos       except for the last one, which is arranged in
14871e7ee59SPeter Avalos       compressBlock().
14971e7ee59SPeter Avalos    */
15071e7ee59SPeter Avalos    UInt32* ptr   = s->ptr;
15171e7ee59SPeter Avalos    UChar* block  = s->block;
15271e7ee59SPeter Avalos    UInt16* mtfv  = s->mtfv;
15371e7ee59SPeter Avalos 
15471e7ee59SPeter Avalos    makeMaps_e ( s );
15571e7ee59SPeter Avalos    EOB = s->nInUse+1;
15671e7ee59SPeter Avalos 
15771e7ee59SPeter Avalos    for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
15871e7ee59SPeter Avalos 
15971e7ee59SPeter Avalos    wr = 0;
16071e7ee59SPeter Avalos    zPend = 0;
16171e7ee59SPeter Avalos    for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
16271e7ee59SPeter Avalos 
16371e7ee59SPeter Avalos    for (i = 0; i < s->nblock; i++) {
16471e7ee59SPeter Avalos       UChar ll_i;
16571e7ee59SPeter Avalos       AssertD ( wr <= i, "generateMTFValues(1)" );
16671e7ee59SPeter Avalos       j = ptr[i]-1; if (j < 0) j += s->nblock;
16771e7ee59SPeter Avalos       ll_i = s->unseqToSeq[block[j]];
16871e7ee59SPeter Avalos       AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
16971e7ee59SPeter Avalos 
17071e7ee59SPeter Avalos       if (yy[0] == ll_i) {
17171e7ee59SPeter Avalos          zPend++;
17271e7ee59SPeter Avalos       } else {
17371e7ee59SPeter Avalos 
17471e7ee59SPeter Avalos          if (zPend > 0) {
17571e7ee59SPeter Avalos             zPend--;
17671e7ee59SPeter Avalos             while (True) {
17771e7ee59SPeter Avalos                if (zPend & 1) {
17871e7ee59SPeter Avalos                   mtfv[wr] = BZ_RUNB; wr++;
17971e7ee59SPeter Avalos                   s->mtfFreq[BZ_RUNB]++;
18071e7ee59SPeter Avalos                } else {
18171e7ee59SPeter Avalos                   mtfv[wr] = BZ_RUNA; wr++;
18271e7ee59SPeter Avalos                   s->mtfFreq[BZ_RUNA]++;
18371e7ee59SPeter Avalos                }
18471e7ee59SPeter Avalos                if (zPend < 2) break;
18571e7ee59SPeter Avalos                zPend = (zPend - 2) / 2;
18671e7ee59SPeter Avalos             };
18771e7ee59SPeter Avalos             zPend = 0;
18871e7ee59SPeter Avalos          }
18971e7ee59SPeter Avalos          {
19071e7ee59SPeter Avalos             register UChar  rtmp;
19171e7ee59SPeter Avalos             register UChar* ryy_j;
19271e7ee59SPeter Avalos             register UChar  rll_i;
19371e7ee59SPeter Avalos             rtmp  = yy[1];
19471e7ee59SPeter Avalos             yy[1] = yy[0];
19571e7ee59SPeter Avalos             ryy_j = &(yy[1]);
19671e7ee59SPeter Avalos             rll_i = ll_i;
19771e7ee59SPeter Avalos             while ( rll_i != rtmp ) {
19871e7ee59SPeter Avalos                register UChar rtmp2;
19971e7ee59SPeter Avalos                ryy_j++;
20071e7ee59SPeter Avalos                rtmp2  = rtmp;
20171e7ee59SPeter Avalos                rtmp   = *ryy_j;
20271e7ee59SPeter Avalos                *ryy_j = rtmp2;
20371e7ee59SPeter Avalos             };
20471e7ee59SPeter Avalos             yy[0] = rtmp;
20571e7ee59SPeter Avalos             j = ryy_j - &(yy[0]);
20671e7ee59SPeter Avalos             mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
20771e7ee59SPeter Avalos          }
20871e7ee59SPeter Avalos 
20971e7ee59SPeter Avalos       }
21071e7ee59SPeter Avalos    }
21171e7ee59SPeter Avalos 
21271e7ee59SPeter Avalos    if (zPend > 0) {
21371e7ee59SPeter Avalos       zPend--;
21471e7ee59SPeter Avalos       while (True) {
21571e7ee59SPeter Avalos          if (zPend & 1) {
21671e7ee59SPeter Avalos             mtfv[wr] = BZ_RUNB; wr++;
21771e7ee59SPeter Avalos             s->mtfFreq[BZ_RUNB]++;
21871e7ee59SPeter Avalos          } else {
21971e7ee59SPeter Avalos             mtfv[wr] = BZ_RUNA; wr++;
22071e7ee59SPeter Avalos             s->mtfFreq[BZ_RUNA]++;
22171e7ee59SPeter Avalos          }
22271e7ee59SPeter Avalos          if (zPend < 2) break;
22371e7ee59SPeter Avalos          zPend = (zPend - 2) / 2;
22471e7ee59SPeter Avalos       };
22571e7ee59SPeter Avalos       zPend = 0;
22671e7ee59SPeter Avalos    }
22771e7ee59SPeter Avalos 
22871e7ee59SPeter Avalos    mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
22971e7ee59SPeter Avalos 
23071e7ee59SPeter Avalos    s->nMTF = wr;
23171e7ee59SPeter Avalos }
23271e7ee59SPeter Avalos 
23371e7ee59SPeter Avalos 
23471e7ee59SPeter Avalos /*---------------------------------------------------*/
23571e7ee59SPeter Avalos #define BZ_LESSER_ICOST  0
23671e7ee59SPeter Avalos #define BZ_GREATER_ICOST 15
23771e7ee59SPeter Avalos 
23871e7ee59SPeter Avalos static
sendMTFValues(EState * s)23971e7ee59SPeter Avalos void sendMTFValues ( EState* s )
24071e7ee59SPeter Avalos {
24171e7ee59SPeter Avalos    Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
24271e7ee59SPeter Avalos    Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
24371e7ee59SPeter Avalos    Int32 nGroups, nBytes;
24471e7ee59SPeter Avalos 
24571e7ee59SPeter Avalos    /*--
24671e7ee59SPeter Avalos    UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
24771e7ee59SPeter Avalos    is a global since the decoder also needs it.
24871e7ee59SPeter Avalos 
24971e7ee59SPeter Avalos    Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
25071e7ee59SPeter Avalos    Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
25171e7ee59SPeter Avalos    are also globals only used in this proc.
25271e7ee59SPeter Avalos    Made global to keep stack frame size small.
25371e7ee59SPeter Avalos    --*/
25471e7ee59SPeter Avalos 
25571e7ee59SPeter Avalos 
25671e7ee59SPeter Avalos    UInt16 cost[BZ_N_GROUPS];
25771e7ee59SPeter Avalos    Int32  fave[BZ_N_GROUPS];
25871e7ee59SPeter Avalos 
25971e7ee59SPeter Avalos    UInt16* mtfv = s->mtfv;
26071e7ee59SPeter Avalos 
26171e7ee59SPeter Avalos    if (s->verbosity >= 3)
26271e7ee59SPeter Avalos       VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
26371e7ee59SPeter Avalos                 "%d+2 syms in use\n",
26471e7ee59SPeter Avalos                 s->nblock, s->nMTF, s->nInUse );
26571e7ee59SPeter Avalos 
26671e7ee59SPeter Avalos    alphaSize = s->nInUse+2;
26771e7ee59SPeter Avalos    for (t = 0; t < BZ_N_GROUPS; t++)
26871e7ee59SPeter Avalos       for (v = 0; v < alphaSize; v++)
26971e7ee59SPeter Avalos          s->len[t][v] = BZ_GREATER_ICOST;
27071e7ee59SPeter Avalos 
27171e7ee59SPeter Avalos    /*--- Decide how many coding tables to use ---*/
27271e7ee59SPeter Avalos    AssertH ( s->nMTF > 0, 3001 );
27371e7ee59SPeter Avalos    if (s->nMTF < 200)  nGroups = 2; else
27471e7ee59SPeter Avalos    if (s->nMTF < 600)  nGroups = 3; else
27571e7ee59SPeter Avalos    if (s->nMTF < 1200) nGroups = 4; else
27671e7ee59SPeter Avalos    if (s->nMTF < 2400) nGroups = 5; else
27771e7ee59SPeter Avalos                        nGroups = 6;
27871e7ee59SPeter Avalos 
27971e7ee59SPeter Avalos    /*--- Generate an initial set of coding tables ---*/
28071e7ee59SPeter Avalos    {
28171e7ee59SPeter Avalos       Int32 nPart, remF, tFreq, aFreq;
28271e7ee59SPeter Avalos 
28371e7ee59SPeter Avalos       nPart = nGroups;
28471e7ee59SPeter Avalos       remF  = s->nMTF;
28571e7ee59SPeter Avalos       gs = 0;
28671e7ee59SPeter Avalos       while (nPart > 0) {
28771e7ee59SPeter Avalos          tFreq = remF / nPart;
28871e7ee59SPeter Avalos          ge = gs-1;
28971e7ee59SPeter Avalos          aFreq = 0;
29071e7ee59SPeter Avalos          while (aFreq < tFreq && ge < alphaSize-1) {
29171e7ee59SPeter Avalos             ge++;
29271e7ee59SPeter Avalos             aFreq += s->mtfFreq[ge];
29371e7ee59SPeter Avalos          }
29471e7ee59SPeter Avalos 
29571e7ee59SPeter Avalos          if (ge > gs
29671e7ee59SPeter Avalos              && nPart != nGroups && nPart != 1
29771e7ee59SPeter Avalos              && ((nGroups-nPart) % 2 == 1)) {
29871e7ee59SPeter Avalos             aFreq -= s->mtfFreq[ge];
29971e7ee59SPeter Avalos             ge--;
30071e7ee59SPeter Avalos          }
30171e7ee59SPeter Avalos 
30271e7ee59SPeter Avalos          if (s->verbosity >= 3)
30371e7ee59SPeter Avalos             VPrintf5( "      initial group %d, [%d .. %d], "
30471e7ee59SPeter Avalos                       "has %d syms (%4.1f%%)\n",
30571e7ee59SPeter Avalos                       nPart, gs, ge, aFreq,
30671e7ee59SPeter Avalos                       (100.0 * (float)aFreq) / (float)(s->nMTF) );
30771e7ee59SPeter Avalos 
30871e7ee59SPeter Avalos          for (v = 0; v < alphaSize; v++)
30971e7ee59SPeter Avalos             if (v >= gs && v <= ge)
31071e7ee59SPeter Avalos                s->len[nPart-1][v] = BZ_LESSER_ICOST; else
31171e7ee59SPeter Avalos                s->len[nPart-1][v] = BZ_GREATER_ICOST;
31271e7ee59SPeter Avalos 
31371e7ee59SPeter Avalos          nPart--;
31471e7ee59SPeter Avalos          gs = ge+1;
31571e7ee59SPeter Avalos          remF -= aFreq;
31671e7ee59SPeter Avalos       }
31771e7ee59SPeter Avalos    }
31871e7ee59SPeter Avalos 
31971e7ee59SPeter Avalos    /*---
32071e7ee59SPeter Avalos       Iterate up to BZ_N_ITERS times to improve the tables.
32171e7ee59SPeter Avalos    ---*/
32271e7ee59SPeter Avalos    for (iter = 0; iter < BZ_N_ITERS; iter++) {
32371e7ee59SPeter Avalos 
32471e7ee59SPeter Avalos       for (t = 0; t < nGroups; t++) fave[t] = 0;
32571e7ee59SPeter Avalos 
32671e7ee59SPeter Avalos       for (t = 0; t < nGroups; t++)
32771e7ee59SPeter Avalos          for (v = 0; v < alphaSize; v++)
32871e7ee59SPeter Avalos             s->rfreq[t][v] = 0;
32971e7ee59SPeter Avalos 
33071e7ee59SPeter Avalos       /*---
33171e7ee59SPeter Avalos         Set up an auxiliary length table which is used to fast-track
33271e7ee59SPeter Avalos 	the common case (nGroups == 6).
33371e7ee59SPeter Avalos       ---*/
33471e7ee59SPeter Avalos       if (nGroups == 6) {
33571e7ee59SPeter Avalos          for (v = 0; v < alphaSize; v++) {
33671e7ee59SPeter Avalos             s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
33771e7ee59SPeter Avalos             s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
33871e7ee59SPeter Avalos             s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
33971e7ee59SPeter Avalos 	 }
34071e7ee59SPeter Avalos       }
34171e7ee59SPeter Avalos 
34271e7ee59SPeter Avalos       nSelectors = 0;
34371e7ee59SPeter Avalos       totc = 0;
34471e7ee59SPeter Avalos       gs = 0;
34571e7ee59SPeter Avalos       while (True) {
34671e7ee59SPeter Avalos 
34771e7ee59SPeter Avalos          /*--- Set group start & end marks. --*/
34871e7ee59SPeter Avalos          if (gs >= s->nMTF) break;
34971e7ee59SPeter Avalos          ge = gs + BZ_G_SIZE - 1;
35071e7ee59SPeter Avalos          if (ge >= s->nMTF) ge = s->nMTF-1;
35171e7ee59SPeter Avalos 
35271e7ee59SPeter Avalos          /*--
35371e7ee59SPeter Avalos             Calculate the cost of this group as coded
35471e7ee59SPeter Avalos             by each of the coding tables.
35571e7ee59SPeter Avalos          --*/
35671e7ee59SPeter Avalos          for (t = 0; t < nGroups; t++) cost[t] = 0;
35771e7ee59SPeter Avalos 
35871e7ee59SPeter Avalos          if (nGroups == 6 && 50 == ge-gs+1) {
35971e7ee59SPeter Avalos             /*--- fast track the common case ---*/
36071e7ee59SPeter Avalos             register UInt32 cost01, cost23, cost45;
36171e7ee59SPeter Avalos             register UInt16 icv;
36271e7ee59SPeter Avalos             cost01 = cost23 = cost45 = 0;
36371e7ee59SPeter Avalos 
36471e7ee59SPeter Avalos #           define BZ_ITER(nn)                \
36571e7ee59SPeter Avalos                icv = mtfv[gs+(nn)];           \
36671e7ee59SPeter Avalos                cost01 += s->len_pack[icv][0]; \
36771e7ee59SPeter Avalos                cost23 += s->len_pack[icv][1]; \
36871e7ee59SPeter Avalos                cost45 += s->len_pack[icv][2]; \
36971e7ee59SPeter Avalos 
37071e7ee59SPeter Avalos             BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
37171e7ee59SPeter Avalos             BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
37271e7ee59SPeter Avalos             BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
37371e7ee59SPeter Avalos             BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
37471e7ee59SPeter Avalos             BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
37571e7ee59SPeter Avalos             BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
37671e7ee59SPeter Avalos             BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
37771e7ee59SPeter Avalos             BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
37871e7ee59SPeter Avalos             BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
37971e7ee59SPeter Avalos             BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
38071e7ee59SPeter Avalos 
38171e7ee59SPeter Avalos #           undef BZ_ITER
38271e7ee59SPeter Avalos 
38371e7ee59SPeter Avalos             cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
38471e7ee59SPeter Avalos             cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
38571e7ee59SPeter Avalos             cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
38671e7ee59SPeter Avalos 
38771e7ee59SPeter Avalos          } else {
38871e7ee59SPeter Avalos 	    /*--- slow version which correctly handles all situations ---*/
38971e7ee59SPeter Avalos             for (i = gs; i <= ge; i++) {
39071e7ee59SPeter Avalos                UInt16 icv = mtfv[i];
39171e7ee59SPeter Avalos                for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
39271e7ee59SPeter Avalos             }
39371e7ee59SPeter Avalos          }
39471e7ee59SPeter Avalos 
39571e7ee59SPeter Avalos          /*--
39671e7ee59SPeter Avalos             Find the coding table which is best for this group,
39771e7ee59SPeter Avalos             and record its identity in the selector table.
39871e7ee59SPeter Avalos          --*/
39971e7ee59SPeter Avalos          bc = 999999999; bt = -1;
40071e7ee59SPeter Avalos          for (t = 0; t < nGroups; t++)
40171e7ee59SPeter Avalos             if (cost[t] < bc) { bc = cost[t]; bt = t; };
40271e7ee59SPeter Avalos          totc += bc;
40371e7ee59SPeter Avalos          fave[bt]++;
40471e7ee59SPeter Avalos          s->selector[nSelectors] = bt;
40571e7ee59SPeter Avalos          nSelectors++;
40671e7ee59SPeter Avalos 
40771e7ee59SPeter Avalos          /*--
40871e7ee59SPeter Avalos             Increment the symbol frequencies for the selected table.
40971e7ee59SPeter Avalos           --*/
41071e7ee59SPeter Avalos          if (nGroups == 6 && 50 == ge-gs+1) {
41171e7ee59SPeter Avalos             /*--- fast track the common case ---*/
41271e7ee59SPeter Avalos 
41371e7ee59SPeter Avalos #           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
41471e7ee59SPeter Avalos 
41571e7ee59SPeter Avalos             BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
41671e7ee59SPeter Avalos             BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
41771e7ee59SPeter Avalos             BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
41871e7ee59SPeter Avalos             BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
41971e7ee59SPeter Avalos             BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
42071e7ee59SPeter Avalos             BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
42171e7ee59SPeter Avalos             BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
42271e7ee59SPeter Avalos             BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
42371e7ee59SPeter Avalos             BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
42471e7ee59SPeter Avalos             BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
42571e7ee59SPeter Avalos 
42671e7ee59SPeter Avalos #           undef BZ_ITUR
42771e7ee59SPeter Avalos 
42871e7ee59SPeter Avalos          } else {
42971e7ee59SPeter Avalos 	    /*--- slow version which correctly handles all situations ---*/
43071e7ee59SPeter Avalos             for (i = gs; i <= ge; i++)
43171e7ee59SPeter Avalos                s->rfreq[bt][ mtfv[i] ]++;
43271e7ee59SPeter Avalos          }
43371e7ee59SPeter Avalos 
43471e7ee59SPeter Avalos          gs = ge+1;
43571e7ee59SPeter Avalos       }
43671e7ee59SPeter Avalos       if (s->verbosity >= 3) {
43771e7ee59SPeter Avalos          VPrintf2 ( "      pass %d: size is %d, grp uses are ",
43871e7ee59SPeter Avalos                    iter+1, totc/8 );
43971e7ee59SPeter Avalos          for (t = 0; t < nGroups; t++)
44071e7ee59SPeter Avalos             VPrintf1 ( "%d ", fave[t] );
44171e7ee59SPeter Avalos          VPrintf0 ( "\n" );
44271e7ee59SPeter Avalos       }
44371e7ee59SPeter Avalos 
44471e7ee59SPeter Avalos       /*--
44571e7ee59SPeter Avalos         Recompute the tables based on the accumulated frequencies.
44671e7ee59SPeter Avalos       --*/
44771e7ee59SPeter Avalos       /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
44871e7ee59SPeter Avalos          comment in huffman.c for details. */
44971e7ee59SPeter Avalos       for (t = 0; t < nGroups; t++)
45071e7ee59SPeter Avalos          BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
45171e7ee59SPeter Avalos                                  alphaSize, 17 /*20*/ );
45271e7ee59SPeter Avalos    }
45371e7ee59SPeter Avalos 
45471e7ee59SPeter Avalos 
45571e7ee59SPeter Avalos    AssertH( nGroups < 8, 3002 );
45671e7ee59SPeter Avalos    AssertH( nSelectors < 32768 &&
457*86954436SDaniel Fojt             nSelectors <= BZ_MAX_SELECTORS,
45871e7ee59SPeter Avalos             3003 );
45971e7ee59SPeter Avalos 
46071e7ee59SPeter Avalos 
46171e7ee59SPeter Avalos    /*--- Compute MTF values for the selectors. ---*/
46271e7ee59SPeter Avalos    {
46371e7ee59SPeter Avalos       UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
46471e7ee59SPeter Avalos       for (i = 0; i < nGroups; i++) pos[i] = i;
46571e7ee59SPeter Avalos       for (i = 0; i < nSelectors; i++) {
46671e7ee59SPeter Avalos          ll_i = s->selector[i];
46771e7ee59SPeter Avalos          j = 0;
46871e7ee59SPeter Avalos          tmp = pos[j];
46971e7ee59SPeter Avalos          while ( ll_i != tmp ) {
47071e7ee59SPeter Avalos             j++;
47171e7ee59SPeter Avalos             tmp2 = tmp;
47271e7ee59SPeter Avalos             tmp = pos[j];
47371e7ee59SPeter Avalos             pos[j] = tmp2;
47471e7ee59SPeter Avalos          };
47571e7ee59SPeter Avalos          pos[0] = tmp;
47671e7ee59SPeter Avalos          s->selectorMtf[i] = j;
47771e7ee59SPeter Avalos       }
47871e7ee59SPeter Avalos    };
47971e7ee59SPeter Avalos 
48071e7ee59SPeter Avalos    /*--- Assign actual codes for the tables. --*/
48171e7ee59SPeter Avalos    for (t = 0; t < nGroups; t++) {
48271e7ee59SPeter Avalos       minLen = 32;
48371e7ee59SPeter Avalos       maxLen = 0;
48471e7ee59SPeter Avalos       for (i = 0; i < alphaSize; i++) {
48571e7ee59SPeter Avalos          if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
48671e7ee59SPeter Avalos          if (s->len[t][i] < minLen) minLen = s->len[t][i];
48771e7ee59SPeter Avalos       }
48871e7ee59SPeter Avalos       AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
48971e7ee59SPeter Avalos       AssertH ( !(minLen < 1),  3005 );
49071e7ee59SPeter Avalos       BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
49171e7ee59SPeter Avalos                           minLen, maxLen, alphaSize );
49271e7ee59SPeter Avalos    }
49371e7ee59SPeter Avalos 
49471e7ee59SPeter Avalos    /*--- Transmit the mapping table. ---*/
49571e7ee59SPeter Avalos    {
49671e7ee59SPeter Avalos       Bool inUse16[16];
49771e7ee59SPeter Avalos       for (i = 0; i < 16; i++) {
49871e7ee59SPeter Avalos           inUse16[i] = False;
49971e7ee59SPeter Avalos           for (j = 0; j < 16; j++)
50071e7ee59SPeter Avalos              if (s->inUse[i * 16 + j]) inUse16[i] = True;
50171e7ee59SPeter Avalos       }
50271e7ee59SPeter Avalos 
50371e7ee59SPeter Avalos       nBytes = s->numZ;
50471e7ee59SPeter Avalos       for (i = 0; i < 16; i++)
50571e7ee59SPeter Avalos          if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
50671e7ee59SPeter Avalos 
50771e7ee59SPeter Avalos       for (i = 0; i < 16; i++)
50871e7ee59SPeter Avalos          if (inUse16[i])
50971e7ee59SPeter Avalos             for (j = 0; j < 16; j++) {
51071e7ee59SPeter Avalos                if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
51171e7ee59SPeter Avalos             }
51271e7ee59SPeter Avalos 
51371e7ee59SPeter Avalos       if (s->verbosity >= 3)
51471e7ee59SPeter Avalos          VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
51571e7ee59SPeter Avalos    }
51671e7ee59SPeter Avalos 
51771e7ee59SPeter Avalos    /*--- Now the selectors. ---*/
51871e7ee59SPeter Avalos    nBytes = s->numZ;
51971e7ee59SPeter Avalos    bsW ( s, 3, nGroups );
52071e7ee59SPeter Avalos    bsW ( s, 15, nSelectors );
52171e7ee59SPeter Avalos    for (i = 0; i < nSelectors; i++) {
52271e7ee59SPeter Avalos       for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
52371e7ee59SPeter Avalos       bsW(s,1,0);
52471e7ee59SPeter Avalos    }
52571e7ee59SPeter Avalos    if (s->verbosity >= 3)
52671e7ee59SPeter Avalos       VPrintf1( "selectors %d, ", s->numZ-nBytes );
52771e7ee59SPeter Avalos 
52871e7ee59SPeter Avalos    /*--- Now the coding tables. ---*/
52971e7ee59SPeter Avalos    nBytes = s->numZ;
53071e7ee59SPeter Avalos 
53171e7ee59SPeter Avalos    for (t = 0; t < nGroups; t++) {
53271e7ee59SPeter Avalos       Int32 curr = s->len[t][0];
53371e7ee59SPeter Avalos       bsW ( s, 5, curr );
53471e7ee59SPeter Avalos       for (i = 0; i < alphaSize; i++) {
53571e7ee59SPeter Avalos          while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
53671e7ee59SPeter Avalos          while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
53771e7ee59SPeter Avalos          bsW ( s, 1, 0 );
53871e7ee59SPeter Avalos       }
53971e7ee59SPeter Avalos    }
54071e7ee59SPeter Avalos 
54171e7ee59SPeter Avalos    if (s->verbosity >= 3)
54271e7ee59SPeter Avalos       VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
54371e7ee59SPeter Avalos 
54471e7ee59SPeter Avalos    /*--- And finally, the block data proper ---*/
54571e7ee59SPeter Avalos    nBytes = s->numZ;
54671e7ee59SPeter Avalos    selCtr = 0;
54771e7ee59SPeter Avalos    gs = 0;
54871e7ee59SPeter Avalos    while (True) {
54971e7ee59SPeter Avalos       if (gs >= s->nMTF) break;
55071e7ee59SPeter Avalos       ge = gs + BZ_G_SIZE - 1;
55171e7ee59SPeter Avalos       if (ge >= s->nMTF) ge = s->nMTF-1;
55271e7ee59SPeter Avalos       AssertH ( s->selector[selCtr] < nGroups, 3006 );
55371e7ee59SPeter Avalos 
55471e7ee59SPeter Avalos       if (nGroups == 6 && 50 == ge-gs+1) {
55571e7ee59SPeter Avalos             /*--- fast track the common case ---*/
55671e7ee59SPeter Avalos             UInt16 mtfv_i;
55771e7ee59SPeter Avalos             UChar* s_len_sel_selCtr
55871e7ee59SPeter Avalos                = &(s->len[s->selector[selCtr]][0]);
55971e7ee59SPeter Avalos             Int32* s_code_sel_selCtr
56071e7ee59SPeter Avalos                = &(s->code[s->selector[selCtr]][0]);
56171e7ee59SPeter Avalos 
56271e7ee59SPeter Avalos #           define BZ_ITAH(nn)                      \
56371e7ee59SPeter Avalos                mtfv_i = mtfv[gs+(nn)];              \
56471e7ee59SPeter Avalos                bsW ( s,                             \
56571e7ee59SPeter Avalos                      s_len_sel_selCtr[mtfv_i],      \
56671e7ee59SPeter Avalos                      s_code_sel_selCtr[mtfv_i] )
56771e7ee59SPeter Avalos 
56871e7ee59SPeter Avalos             BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
56971e7ee59SPeter Avalos             BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
57071e7ee59SPeter Avalos             BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
57171e7ee59SPeter Avalos             BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
57271e7ee59SPeter Avalos             BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
57371e7ee59SPeter Avalos             BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
57471e7ee59SPeter Avalos             BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
57571e7ee59SPeter Avalos             BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
57671e7ee59SPeter Avalos             BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
57771e7ee59SPeter Avalos             BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
57871e7ee59SPeter Avalos 
57971e7ee59SPeter Avalos #           undef BZ_ITAH
58071e7ee59SPeter Avalos 
58171e7ee59SPeter Avalos       } else {
58271e7ee59SPeter Avalos 	 /*--- slow version which correctly handles all situations ---*/
58371e7ee59SPeter Avalos          for (i = gs; i <= ge; i++) {
58471e7ee59SPeter Avalos             bsW ( s,
58571e7ee59SPeter Avalos                   s->len  [s->selector[selCtr]] [mtfv[i]],
58671e7ee59SPeter Avalos                   s->code [s->selector[selCtr]] [mtfv[i]] );
58771e7ee59SPeter Avalos          }
58871e7ee59SPeter Avalos       }
58971e7ee59SPeter Avalos 
59071e7ee59SPeter Avalos 
59171e7ee59SPeter Avalos       gs = ge+1;
59271e7ee59SPeter Avalos       selCtr++;
59371e7ee59SPeter Avalos    }
59471e7ee59SPeter Avalos    AssertH( selCtr == nSelectors, 3007 );
59571e7ee59SPeter Avalos 
59671e7ee59SPeter Avalos    if (s->verbosity >= 3)
59771e7ee59SPeter Avalos       VPrintf1( "codes %d\n", s->numZ-nBytes );
59871e7ee59SPeter Avalos }
59971e7ee59SPeter Avalos 
60071e7ee59SPeter Avalos 
60171e7ee59SPeter Avalos /*---------------------------------------------------*/
BZ2_compressBlock(EState * s,Bool is_last_block)60271e7ee59SPeter Avalos void BZ2_compressBlock ( EState* s, Bool is_last_block )
60371e7ee59SPeter Avalos {
60471e7ee59SPeter Avalos    if (s->nblock > 0) {
60571e7ee59SPeter Avalos 
60671e7ee59SPeter Avalos       BZ_FINALISE_CRC ( s->blockCRC );
60771e7ee59SPeter Avalos       s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
60871e7ee59SPeter Avalos       s->combinedCRC ^= s->blockCRC;
60971e7ee59SPeter Avalos       if (s->blockNo > 1) s->numZ = 0;
61071e7ee59SPeter Avalos 
61171e7ee59SPeter Avalos       if (s->verbosity >= 2)
61271e7ee59SPeter Avalos          VPrintf4( "    block %d: crc = 0x%08x, "
61371e7ee59SPeter Avalos                    "combined CRC = 0x%08x, size = %d\n",
61471e7ee59SPeter Avalos                    s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
61571e7ee59SPeter Avalos 
61671e7ee59SPeter Avalos       BZ2_blockSort ( s );
61771e7ee59SPeter Avalos    }
61871e7ee59SPeter Avalos 
61971e7ee59SPeter Avalos    s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
62071e7ee59SPeter Avalos 
62171e7ee59SPeter Avalos    /*-- If this is the first block, create the stream header. --*/
62271e7ee59SPeter Avalos    if (s->blockNo == 1) {
62371e7ee59SPeter Avalos       BZ2_bsInitWrite ( s );
62471e7ee59SPeter Avalos       bsPutUChar ( s, BZ_HDR_B );
62571e7ee59SPeter Avalos       bsPutUChar ( s, BZ_HDR_Z );
62671e7ee59SPeter Avalos       bsPutUChar ( s, BZ_HDR_h );
62771e7ee59SPeter Avalos       bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
62871e7ee59SPeter Avalos    }
62971e7ee59SPeter Avalos 
63071e7ee59SPeter Avalos    if (s->nblock > 0) {
63171e7ee59SPeter Avalos 
63271e7ee59SPeter Avalos       bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
63371e7ee59SPeter Avalos       bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
63471e7ee59SPeter Avalos       bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
63571e7ee59SPeter Avalos 
63671e7ee59SPeter Avalos       /*-- Now the block's CRC, so it is in a known place. --*/
63771e7ee59SPeter Avalos       bsPutUInt32 ( s, s->blockCRC );
63871e7ee59SPeter Avalos 
63971e7ee59SPeter Avalos       /*--
64071e7ee59SPeter Avalos          Now a single bit indicating (non-)randomisation.
64171e7ee59SPeter Avalos          As of version 0.9.5, we use a better sorting algorithm
64271e7ee59SPeter Avalos          which makes randomisation unnecessary.  So always set
64371e7ee59SPeter Avalos          the randomised bit to 'no'.  Of course, the decoder
64471e7ee59SPeter Avalos          still needs to be able to handle randomised blocks
64571e7ee59SPeter Avalos          so as to maintain backwards compatibility with
64671e7ee59SPeter Avalos          older versions of bzip2.
64771e7ee59SPeter Avalos       --*/
64871e7ee59SPeter Avalos       bsW(s,1,0);
64971e7ee59SPeter Avalos 
65071e7ee59SPeter Avalos       bsW ( s, 24, s->origPtr );
65171e7ee59SPeter Avalos       generateMTFValues ( s );
65271e7ee59SPeter Avalos       sendMTFValues ( s );
65371e7ee59SPeter Avalos    }
65471e7ee59SPeter Avalos 
65571e7ee59SPeter Avalos 
65671e7ee59SPeter Avalos    /*-- If this is the last block, add the stream trailer. --*/
65771e7ee59SPeter Avalos    if (is_last_block) {
65871e7ee59SPeter Avalos 
65971e7ee59SPeter Avalos       bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
66071e7ee59SPeter Avalos       bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
66171e7ee59SPeter Avalos       bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
66271e7ee59SPeter Avalos       bsPutUInt32 ( s, s->combinedCRC );
66371e7ee59SPeter Avalos       if (s->verbosity >= 2)
66471e7ee59SPeter Avalos          VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
66571e7ee59SPeter Avalos       bsFinishWrite ( s );
66671e7ee59SPeter Avalos    }
66771e7ee59SPeter Avalos }
66871e7ee59SPeter Avalos 
66971e7ee59SPeter Avalos 
67071e7ee59SPeter Avalos /*-------------------------------------------------------------*/
67171e7ee59SPeter Avalos /*--- end                                        compress.c ---*/
67271e7ee59SPeter Avalos /*-------------------------------------------------------------*/
673