xref: /titanic_51/usr/src/common/bzip2/compress.c (revision ca3e8d88e8c867355e441fbc914c52e7416fc537)
1*ca3e8d88SDave Plauger 
2*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/
3*ca3e8d88SDave Plauger /*--- Compression machinery (not incl block sorting)        ---*/
4*ca3e8d88SDave Plauger /*---                                            compress.c ---*/
5*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/
6*ca3e8d88SDave Plauger 
7*ca3e8d88SDave Plauger /* ------------------------------------------------------------------
8*ca3e8d88SDave Plauger    This file is part of bzip2/libbzip2, a program and library for
9*ca3e8d88SDave Plauger    lossless, block-sorting data compression.
10*ca3e8d88SDave Plauger 
11*ca3e8d88SDave Plauger    bzip2/libbzip2 version 1.0.5 of 10 December 2007
12*ca3e8d88SDave Plauger    Copyright (C) 1996-2007 Julian Seward <jseward@bzip.org>
13*ca3e8d88SDave Plauger 
14*ca3e8d88SDave Plauger    Please read the WARNING, DISCLAIMER and PATENTS sections in the
15*ca3e8d88SDave Plauger    README file.
16*ca3e8d88SDave Plauger 
17*ca3e8d88SDave Plauger    This program is released under the terms of the license contained
18*ca3e8d88SDave Plauger    in the file LICENSE.
19*ca3e8d88SDave Plauger    ------------------------------------------------------------------ */
20*ca3e8d88SDave Plauger 
21*ca3e8d88SDave Plauger 
22*ca3e8d88SDave Plauger /* CHANGES
23*ca3e8d88SDave Plauger     0.9.0    -- original version.
24*ca3e8d88SDave Plauger     0.9.0a/b -- no changes in this file.
25*ca3e8d88SDave Plauger     0.9.0c   -- changed setting of nGroups in sendMTFValues()
26*ca3e8d88SDave Plauger                 so as to do a bit better on small files
27*ca3e8d88SDave Plauger */
28*ca3e8d88SDave Plauger 
29*ca3e8d88SDave Plauger #include "bzlib_private.h"
30*ca3e8d88SDave Plauger 
31*ca3e8d88SDave Plauger 
32*ca3e8d88SDave Plauger /*---------------------------------------------------*/
33*ca3e8d88SDave Plauger /*--- Bit stream I/O                              ---*/
34*ca3e8d88SDave Plauger /*---------------------------------------------------*/
35*ca3e8d88SDave Plauger 
36*ca3e8d88SDave Plauger /*---------------------------------------------------*/
37*ca3e8d88SDave Plauger void BZ2_bsInitWrite ( EState* s )
38*ca3e8d88SDave Plauger {
39*ca3e8d88SDave Plauger    s->bsLive = 0;
40*ca3e8d88SDave Plauger    s->bsBuff = 0;
41*ca3e8d88SDave Plauger }
42*ca3e8d88SDave Plauger 
43*ca3e8d88SDave Plauger 
44*ca3e8d88SDave Plauger /*---------------------------------------------------*/
45*ca3e8d88SDave Plauger static
46*ca3e8d88SDave Plauger void bsFinishWrite ( EState* s )
47*ca3e8d88SDave Plauger {
48*ca3e8d88SDave Plauger    while (s->bsLive > 0) {
49*ca3e8d88SDave Plauger       s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
50*ca3e8d88SDave Plauger       s->numZ++;
51*ca3e8d88SDave Plauger       s->bsBuff <<= 8;
52*ca3e8d88SDave Plauger       s->bsLive -= 8;
53*ca3e8d88SDave Plauger    }
54*ca3e8d88SDave Plauger }
55*ca3e8d88SDave Plauger 
56*ca3e8d88SDave Plauger 
57*ca3e8d88SDave Plauger /*---------------------------------------------------*/
58*ca3e8d88SDave Plauger #define bsNEEDW(nz)                           \
59*ca3e8d88SDave Plauger {                                             \
60*ca3e8d88SDave Plauger    while (s->bsLive >= 8) {                   \
61*ca3e8d88SDave Plauger       s->zbits[s->numZ]                       \
62*ca3e8d88SDave Plauger          = (UChar)(s->bsBuff >> 24);          \
63*ca3e8d88SDave Plauger       s->numZ++;                              \
64*ca3e8d88SDave Plauger       s->bsBuff <<= 8;                        \
65*ca3e8d88SDave Plauger       s->bsLive -= 8;                         \
66*ca3e8d88SDave Plauger    }                                          \
67*ca3e8d88SDave Plauger }
68*ca3e8d88SDave Plauger 
69*ca3e8d88SDave Plauger 
70*ca3e8d88SDave Plauger /*---------------------------------------------------*/
71*ca3e8d88SDave Plauger static
72*ca3e8d88SDave Plauger __inline__
73*ca3e8d88SDave Plauger void bsW ( EState* s, Int32 n, UInt32 v )
74*ca3e8d88SDave Plauger {
75*ca3e8d88SDave Plauger    bsNEEDW ( n );
76*ca3e8d88SDave Plauger    s->bsBuff |= (v << (32 - s->bsLive - n));
77*ca3e8d88SDave Plauger    s->bsLive += n;
78*ca3e8d88SDave Plauger }
79*ca3e8d88SDave Plauger 
80*ca3e8d88SDave Plauger 
81*ca3e8d88SDave Plauger /*---------------------------------------------------*/
82*ca3e8d88SDave Plauger static
83*ca3e8d88SDave Plauger void bsPutUInt32 ( EState* s, UInt32 u )
84*ca3e8d88SDave Plauger {
85*ca3e8d88SDave Plauger    bsW ( s, 8, (u >> 24) & 0xffL );
86*ca3e8d88SDave Plauger    bsW ( s, 8, (u >> 16) & 0xffL );
87*ca3e8d88SDave Plauger    bsW ( s, 8, (u >>  8) & 0xffL );
88*ca3e8d88SDave Plauger    bsW ( s, 8,  u        & 0xffL );
89*ca3e8d88SDave Plauger }
90*ca3e8d88SDave Plauger 
91*ca3e8d88SDave Plauger 
92*ca3e8d88SDave Plauger /*---------------------------------------------------*/
93*ca3e8d88SDave Plauger static
94*ca3e8d88SDave Plauger void bsPutUChar ( EState* s, UChar c )
95*ca3e8d88SDave Plauger {
96*ca3e8d88SDave Plauger    bsW( s, 8, (UInt32)c );
97*ca3e8d88SDave Plauger }
98*ca3e8d88SDave Plauger 
99*ca3e8d88SDave Plauger 
100*ca3e8d88SDave Plauger /*---------------------------------------------------*/
101*ca3e8d88SDave Plauger /*--- The back end proper                         ---*/
102*ca3e8d88SDave Plauger /*---------------------------------------------------*/
103*ca3e8d88SDave Plauger 
104*ca3e8d88SDave Plauger /*---------------------------------------------------*/
105*ca3e8d88SDave Plauger static
106*ca3e8d88SDave Plauger void makeMaps_e ( EState* s )
107*ca3e8d88SDave Plauger {
108*ca3e8d88SDave Plauger    Int32 i;
109*ca3e8d88SDave Plauger    s->nInUse = 0;
110*ca3e8d88SDave Plauger    for (i = 0; i < 256; i++)
111*ca3e8d88SDave Plauger       if (s->inUse[i]) {
112*ca3e8d88SDave Plauger          s->unseqToSeq[i] = s->nInUse;
113*ca3e8d88SDave Plauger          s->nInUse++;
114*ca3e8d88SDave Plauger       }
115*ca3e8d88SDave Plauger }
116*ca3e8d88SDave Plauger 
117*ca3e8d88SDave Plauger 
118*ca3e8d88SDave Plauger /*---------------------------------------------------*/
119*ca3e8d88SDave Plauger static
120*ca3e8d88SDave Plauger void generateMTFValues ( EState* s )
121*ca3e8d88SDave Plauger {
122*ca3e8d88SDave Plauger    UChar   yy[256];
123*ca3e8d88SDave Plauger    Int32   i, j;
124*ca3e8d88SDave Plauger    Int32   zPend;
125*ca3e8d88SDave Plauger    Int32   wr;
126*ca3e8d88SDave Plauger    Int32   EOB;
127*ca3e8d88SDave Plauger 
128*ca3e8d88SDave Plauger    /*
129*ca3e8d88SDave Plauger       After sorting (eg, here),
130*ca3e8d88SDave Plauger          s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
131*ca3e8d88SDave Plauger          and
132*ca3e8d88SDave Plauger          ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
133*ca3e8d88SDave Plauger          holds the original block data.
134*ca3e8d88SDave Plauger 
135*ca3e8d88SDave Plauger       The first thing to do is generate the MTF values,
136*ca3e8d88SDave Plauger       and put them in
137*ca3e8d88SDave Plauger          ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
138*ca3e8d88SDave Plauger       Because there are strictly fewer or equal MTF values
139*ca3e8d88SDave Plauger       than block values, ptr values in this area are overwritten
140*ca3e8d88SDave Plauger       with MTF values only when they are no longer needed.
141*ca3e8d88SDave Plauger 
142*ca3e8d88SDave Plauger       The final compressed bitstream is generated into the
143*ca3e8d88SDave Plauger       area starting at
144*ca3e8d88SDave Plauger          (UChar*) (&((UChar*)s->arr2)[s->nblock])
145*ca3e8d88SDave Plauger 
146*ca3e8d88SDave Plauger       These storage aliases are set up in bzCompressInit(),
147*ca3e8d88SDave Plauger       except for the last one, which is arranged in
148*ca3e8d88SDave Plauger       compressBlock().
149*ca3e8d88SDave Plauger    */
150*ca3e8d88SDave Plauger    UInt32* ptr   = s->ptr;
151*ca3e8d88SDave Plauger    UChar* block  = s->block;
152*ca3e8d88SDave Plauger    UInt16* mtfv  = s->mtfv;
153*ca3e8d88SDave Plauger 
154*ca3e8d88SDave Plauger    makeMaps_e ( s );
155*ca3e8d88SDave Plauger    EOB = s->nInUse+1;
156*ca3e8d88SDave Plauger 
157*ca3e8d88SDave Plauger    for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
158*ca3e8d88SDave Plauger 
159*ca3e8d88SDave Plauger    wr = 0;
160*ca3e8d88SDave Plauger    zPend = 0;
161*ca3e8d88SDave Plauger    for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
162*ca3e8d88SDave Plauger 
163*ca3e8d88SDave Plauger    for (i = 0; i < s->nblock; i++) {
164*ca3e8d88SDave Plauger       UChar ll_i;
165*ca3e8d88SDave Plauger       AssertD ( wr <= i, "generateMTFValues(1)" );
166*ca3e8d88SDave Plauger       j = ptr[i]-1; if (j < 0) j += s->nblock;
167*ca3e8d88SDave Plauger       ll_i = s->unseqToSeq[block[j]];
168*ca3e8d88SDave Plauger       AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
169*ca3e8d88SDave Plauger 
170*ca3e8d88SDave Plauger       if (yy[0] == ll_i) {
171*ca3e8d88SDave Plauger          zPend++;
172*ca3e8d88SDave Plauger       } else {
173*ca3e8d88SDave Plauger 
174*ca3e8d88SDave Plauger          if (zPend > 0) {
175*ca3e8d88SDave Plauger             zPend--;
176*ca3e8d88SDave Plauger             while (True) {
177*ca3e8d88SDave Plauger                if (zPend & 1) {
178*ca3e8d88SDave Plauger                   mtfv[wr] = BZ_RUNB; wr++;
179*ca3e8d88SDave Plauger                   s->mtfFreq[BZ_RUNB]++;
180*ca3e8d88SDave Plauger                } else {
181*ca3e8d88SDave Plauger                   mtfv[wr] = BZ_RUNA; wr++;
182*ca3e8d88SDave Plauger                   s->mtfFreq[BZ_RUNA]++;
183*ca3e8d88SDave Plauger                }
184*ca3e8d88SDave Plauger                if (zPend < 2) break;
185*ca3e8d88SDave Plauger                zPend = (zPend - 2) / 2;
186*ca3e8d88SDave Plauger             };
187*ca3e8d88SDave Plauger             zPend = 0;
188*ca3e8d88SDave Plauger          }
189*ca3e8d88SDave Plauger          {
190*ca3e8d88SDave Plauger             register UChar  rtmp;
191*ca3e8d88SDave Plauger             register UChar* ryy_j;
192*ca3e8d88SDave Plauger             register UChar  rll_i;
193*ca3e8d88SDave Plauger             rtmp  = yy[1];
194*ca3e8d88SDave Plauger             yy[1] = yy[0];
195*ca3e8d88SDave Plauger             ryy_j = &(yy[1]);
196*ca3e8d88SDave Plauger             rll_i = ll_i;
197*ca3e8d88SDave Plauger             while ( rll_i != rtmp ) {
198*ca3e8d88SDave Plauger                register UChar rtmp2;
199*ca3e8d88SDave Plauger                ryy_j++;
200*ca3e8d88SDave Plauger                rtmp2  = rtmp;
201*ca3e8d88SDave Plauger                rtmp   = *ryy_j;
202*ca3e8d88SDave Plauger                *ryy_j = rtmp2;
203*ca3e8d88SDave Plauger             };
204*ca3e8d88SDave Plauger             yy[0] = rtmp;
205*ca3e8d88SDave Plauger             j = ryy_j - &(yy[0]);
206*ca3e8d88SDave Plauger             mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
207*ca3e8d88SDave Plauger          }
208*ca3e8d88SDave Plauger 
209*ca3e8d88SDave Plauger       }
210*ca3e8d88SDave Plauger    }
211*ca3e8d88SDave Plauger 
212*ca3e8d88SDave Plauger    if (zPend > 0) {
213*ca3e8d88SDave Plauger       zPend--;
214*ca3e8d88SDave Plauger       while (True) {
215*ca3e8d88SDave Plauger          if (zPend & 1) {
216*ca3e8d88SDave Plauger             mtfv[wr] = BZ_RUNB; wr++;
217*ca3e8d88SDave Plauger             s->mtfFreq[BZ_RUNB]++;
218*ca3e8d88SDave Plauger          } else {
219*ca3e8d88SDave Plauger             mtfv[wr] = BZ_RUNA; wr++;
220*ca3e8d88SDave Plauger             s->mtfFreq[BZ_RUNA]++;
221*ca3e8d88SDave Plauger          }
222*ca3e8d88SDave Plauger          if (zPend < 2) break;
223*ca3e8d88SDave Plauger          zPend = (zPend - 2) / 2;
224*ca3e8d88SDave Plauger       };
225*ca3e8d88SDave Plauger       zPend = 0;
226*ca3e8d88SDave Plauger    }
227*ca3e8d88SDave Plauger 
228*ca3e8d88SDave Plauger    mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
229*ca3e8d88SDave Plauger 
230*ca3e8d88SDave Plauger    s->nMTF = wr;
231*ca3e8d88SDave Plauger }
232*ca3e8d88SDave Plauger 
233*ca3e8d88SDave Plauger 
234*ca3e8d88SDave Plauger /*---------------------------------------------------*/
235*ca3e8d88SDave Plauger #define BZ_LESSER_ICOST  0
236*ca3e8d88SDave Plauger #define BZ_GREATER_ICOST 15
237*ca3e8d88SDave Plauger 
238*ca3e8d88SDave Plauger static
239*ca3e8d88SDave Plauger void sendMTFValues ( EState* s )
240*ca3e8d88SDave Plauger {
241*ca3e8d88SDave Plauger    Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
242*ca3e8d88SDave Plauger    Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
243*ca3e8d88SDave Plauger    Int32 nGroups, nBytes;
244*ca3e8d88SDave Plauger 
245*ca3e8d88SDave Plauger    /*--
246*ca3e8d88SDave Plauger    UChar  len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
247*ca3e8d88SDave Plauger    is a global since the decoder also needs it.
248*ca3e8d88SDave Plauger 
249*ca3e8d88SDave Plauger    Int32  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
250*ca3e8d88SDave Plauger    Int32  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
251*ca3e8d88SDave Plauger    are also globals only used in this proc.
252*ca3e8d88SDave Plauger    Made global to keep stack frame size small.
253*ca3e8d88SDave Plauger    --*/
254*ca3e8d88SDave Plauger 
255*ca3e8d88SDave Plauger 
256*ca3e8d88SDave Plauger    UInt16 cost[BZ_N_GROUPS];
257*ca3e8d88SDave Plauger    Int32  fave[BZ_N_GROUPS];
258*ca3e8d88SDave Plauger 
259*ca3e8d88SDave Plauger    UInt16* mtfv = s->mtfv;
260*ca3e8d88SDave Plauger 
261*ca3e8d88SDave Plauger    if (s->verbosity >= 3)
262*ca3e8d88SDave Plauger       VPrintf3( "      %d in block, %d after MTF & 1-2 coding, "
263*ca3e8d88SDave Plauger                 "%d+2 syms in use\n",
264*ca3e8d88SDave Plauger                 s->nblock, s->nMTF, s->nInUse );
265*ca3e8d88SDave Plauger 
266*ca3e8d88SDave Plauger    alphaSize = s->nInUse+2;
267*ca3e8d88SDave Plauger    for (t = 0; t < BZ_N_GROUPS; t++)
268*ca3e8d88SDave Plauger       for (v = 0; v < alphaSize; v++)
269*ca3e8d88SDave Plauger          s->len[t][v] = BZ_GREATER_ICOST;
270*ca3e8d88SDave Plauger 
271*ca3e8d88SDave Plauger    /*--- Decide how many coding tables to use ---*/
272*ca3e8d88SDave Plauger    AssertH ( s->nMTF > 0, 3001 );
273*ca3e8d88SDave Plauger    if (s->nMTF < 200)  nGroups = 2; else
274*ca3e8d88SDave Plauger    if (s->nMTF < 600)  nGroups = 3; else
275*ca3e8d88SDave Plauger    if (s->nMTF < 1200) nGroups = 4; else
276*ca3e8d88SDave Plauger    if (s->nMTF < 2400) nGroups = 5; else
277*ca3e8d88SDave Plauger                        nGroups = 6;
278*ca3e8d88SDave Plauger 
279*ca3e8d88SDave Plauger    /*--- Generate an initial set of coding tables ---*/
280*ca3e8d88SDave Plauger    {
281*ca3e8d88SDave Plauger       Int32 nPart, remF, tFreq, aFreq;
282*ca3e8d88SDave Plauger 
283*ca3e8d88SDave Plauger       nPart = nGroups;
284*ca3e8d88SDave Plauger       remF  = s->nMTF;
285*ca3e8d88SDave Plauger       gs = 0;
286*ca3e8d88SDave Plauger       while (nPart > 0) {
287*ca3e8d88SDave Plauger          tFreq = remF / nPart;
288*ca3e8d88SDave Plauger          ge = gs-1;
289*ca3e8d88SDave Plauger          aFreq = 0;
290*ca3e8d88SDave Plauger          while (aFreq < tFreq && ge < alphaSize-1) {
291*ca3e8d88SDave Plauger             ge++;
292*ca3e8d88SDave Plauger             aFreq += s->mtfFreq[ge];
293*ca3e8d88SDave Plauger          }
294*ca3e8d88SDave Plauger 
295*ca3e8d88SDave Plauger          if (ge > gs
296*ca3e8d88SDave Plauger              && nPart != nGroups && nPart != 1
297*ca3e8d88SDave Plauger              && ((nGroups-nPart) % 2 == 1)) {
298*ca3e8d88SDave Plauger             aFreq -= s->mtfFreq[ge];
299*ca3e8d88SDave Plauger             ge--;
300*ca3e8d88SDave Plauger          }
301*ca3e8d88SDave Plauger 
302*ca3e8d88SDave Plauger          if (s->verbosity >= 3)
303*ca3e8d88SDave Plauger             VPrintf5( "      initial group %d, [%d .. %d], "
304*ca3e8d88SDave Plauger                       "has %d syms (%4.1f%%)\n",
305*ca3e8d88SDave Plauger                       nPart, gs, ge, aFreq,
306*ca3e8d88SDave Plauger                       (100.0 * (float)aFreq) / (float)(s->nMTF) );
307*ca3e8d88SDave Plauger 
308*ca3e8d88SDave Plauger          for (v = 0; v < alphaSize; v++)
309*ca3e8d88SDave Plauger             if (v >= gs && v <= ge)
310*ca3e8d88SDave Plauger                s->len[nPart-1][v] = BZ_LESSER_ICOST; else
311*ca3e8d88SDave Plauger                s->len[nPart-1][v] = BZ_GREATER_ICOST;
312*ca3e8d88SDave Plauger 
313*ca3e8d88SDave Plauger          nPart--;
314*ca3e8d88SDave Plauger          gs = ge+1;
315*ca3e8d88SDave Plauger          remF -= aFreq;
316*ca3e8d88SDave Plauger       }
317*ca3e8d88SDave Plauger    }
318*ca3e8d88SDave Plauger 
319*ca3e8d88SDave Plauger    /*---
320*ca3e8d88SDave Plauger       Iterate up to BZ_N_ITERS times to improve the tables.
321*ca3e8d88SDave Plauger    ---*/
322*ca3e8d88SDave Plauger    for (iter = 0; iter < BZ_N_ITERS; iter++) {
323*ca3e8d88SDave Plauger 
324*ca3e8d88SDave Plauger       for (t = 0; t < nGroups; t++) fave[t] = 0;
325*ca3e8d88SDave Plauger 
326*ca3e8d88SDave Plauger       for (t = 0; t < nGroups; t++)
327*ca3e8d88SDave Plauger          for (v = 0; v < alphaSize; v++)
328*ca3e8d88SDave Plauger             s->rfreq[t][v] = 0;
329*ca3e8d88SDave Plauger 
330*ca3e8d88SDave Plauger       /*---
331*ca3e8d88SDave Plauger         Set up an auxiliary length table which is used to fast-track
332*ca3e8d88SDave Plauger 	the common case (nGroups == 6).
333*ca3e8d88SDave Plauger       ---*/
334*ca3e8d88SDave Plauger       if (nGroups == 6) {
335*ca3e8d88SDave Plauger          for (v = 0; v < alphaSize; v++) {
336*ca3e8d88SDave Plauger             s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
337*ca3e8d88SDave Plauger             s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
338*ca3e8d88SDave Plauger             s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
339*ca3e8d88SDave Plauger 	 }
340*ca3e8d88SDave Plauger       }
341*ca3e8d88SDave Plauger 
342*ca3e8d88SDave Plauger       nSelectors = 0;
343*ca3e8d88SDave Plauger       totc = 0;
344*ca3e8d88SDave Plauger       gs = 0;
345*ca3e8d88SDave Plauger       while (True) {
346*ca3e8d88SDave Plauger 
347*ca3e8d88SDave Plauger          /*--- Set group start & end marks. --*/
348*ca3e8d88SDave Plauger          if (gs >= s->nMTF) break;
349*ca3e8d88SDave Plauger          ge = gs + BZ_G_SIZE - 1;
350*ca3e8d88SDave Plauger          if (ge >= s->nMTF) ge = s->nMTF-1;
351*ca3e8d88SDave Plauger 
352*ca3e8d88SDave Plauger          /*--
353*ca3e8d88SDave Plauger             Calculate the cost of this group as coded
354*ca3e8d88SDave Plauger             by each of the coding tables.
355*ca3e8d88SDave Plauger          --*/
356*ca3e8d88SDave Plauger          for (t = 0; t < nGroups; t++) cost[t] = 0;
357*ca3e8d88SDave Plauger 
358*ca3e8d88SDave Plauger          if (nGroups == 6 && 50 == ge-gs+1) {
359*ca3e8d88SDave Plauger             /*--- fast track the common case ---*/
360*ca3e8d88SDave Plauger             register UInt32 cost01, cost23, cost45;
361*ca3e8d88SDave Plauger             register UInt16 icv;
362*ca3e8d88SDave Plauger             cost01 = cost23 = cost45 = 0;
363*ca3e8d88SDave Plauger 
364*ca3e8d88SDave Plauger #           define BZ_ITER(nn)                \
365*ca3e8d88SDave Plauger                icv = mtfv[gs+(nn)];           \
366*ca3e8d88SDave Plauger                cost01 += s->len_pack[icv][0]; \
367*ca3e8d88SDave Plauger                cost23 += s->len_pack[icv][1]; \
368*ca3e8d88SDave Plauger                cost45 += s->len_pack[icv][2]; \
369*ca3e8d88SDave Plauger 
370*ca3e8d88SDave Plauger             BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
371*ca3e8d88SDave Plauger             BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
372*ca3e8d88SDave Plauger             BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
373*ca3e8d88SDave Plauger             BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
374*ca3e8d88SDave Plauger             BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
375*ca3e8d88SDave Plauger             BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
376*ca3e8d88SDave Plauger             BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
377*ca3e8d88SDave Plauger             BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
378*ca3e8d88SDave Plauger             BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
379*ca3e8d88SDave Plauger             BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
380*ca3e8d88SDave Plauger 
381*ca3e8d88SDave Plauger #           undef BZ_ITER
382*ca3e8d88SDave Plauger 
383*ca3e8d88SDave Plauger             cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
384*ca3e8d88SDave Plauger             cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
385*ca3e8d88SDave Plauger             cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
386*ca3e8d88SDave Plauger 
387*ca3e8d88SDave Plauger          } else {
388*ca3e8d88SDave Plauger 	    /*--- slow version which correctly handles all situations ---*/
389*ca3e8d88SDave Plauger             for (i = gs; i <= ge; i++) {
390*ca3e8d88SDave Plauger                UInt16 icv = mtfv[i];
391*ca3e8d88SDave Plauger                for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
392*ca3e8d88SDave Plauger             }
393*ca3e8d88SDave Plauger          }
394*ca3e8d88SDave Plauger 
395*ca3e8d88SDave Plauger          /*--
396*ca3e8d88SDave Plauger             Find the coding table which is best for this group,
397*ca3e8d88SDave Plauger             and record its identity in the selector table.
398*ca3e8d88SDave Plauger          --*/
399*ca3e8d88SDave Plauger          bc = 999999999; bt = -1;
400*ca3e8d88SDave Plauger          for (t = 0; t < nGroups; t++)
401*ca3e8d88SDave Plauger             if (cost[t] < bc) { bc = cost[t]; bt = t; };
402*ca3e8d88SDave Plauger          totc += bc;
403*ca3e8d88SDave Plauger          fave[bt]++;
404*ca3e8d88SDave Plauger          s->selector[nSelectors] = bt;
405*ca3e8d88SDave Plauger          nSelectors++;
406*ca3e8d88SDave Plauger 
407*ca3e8d88SDave Plauger          /*--
408*ca3e8d88SDave Plauger             Increment the symbol frequencies for the selected table.
409*ca3e8d88SDave Plauger           --*/
410*ca3e8d88SDave Plauger          if (nGroups == 6 && 50 == ge-gs+1) {
411*ca3e8d88SDave Plauger             /*--- fast track the common case ---*/
412*ca3e8d88SDave Plauger 
413*ca3e8d88SDave Plauger #           define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
414*ca3e8d88SDave Plauger 
415*ca3e8d88SDave Plauger             BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
416*ca3e8d88SDave Plauger             BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
417*ca3e8d88SDave Plauger             BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
418*ca3e8d88SDave Plauger             BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
419*ca3e8d88SDave Plauger             BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
420*ca3e8d88SDave Plauger             BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
421*ca3e8d88SDave Plauger             BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
422*ca3e8d88SDave Plauger             BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
423*ca3e8d88SDave Plauger             BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
424*ca3e8d88SDave Plauger             BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
425*ca3e8d88SDave Plauger 
426*ca3e8d88SDave Plauger #           undef BZ_ITUR
427*ca3e8d88SDave Plauger 
428*ca3e8d88SDave Plauger          } else {
429*ca3e8d88SDave Plauger 	    /*--- slow version which correctly handles all situations ---*/
430*ca3e8d88SDave Plauger             for (i = gs; i <= ge; i++)
431*ca3e8d88SDave Plauger                s->rfreq[bt][ mtfv[i] ]++;
432*ca3e8d88SDave Plauger          }
433*ca3e8d88SDave Plauger 
434*ca3e8d88SDave Plauger          gs = ge+1;
435*ca3e8d88SDave Plauger       }
436*ca3e8d88SDave Plauger       if (s->verbosity >= 3) {
437*ca3e8d88SDave Plauger          VPrintf2 ( "      pass %d: size is %d, grp uses are ",
438*ca3e8d88SDave Plauger                    iter+1, totc/8 );
439*ca3e8d88SDave Plauger          for (t = 0; t < nGroups; t++)
440*ca3e8d88SDave Plauger             VPrintf1 ( "%d ", fave[t] );
441*ca3e8d88SDave Plauger          VPrintf0 ( "\n" );
442*ca3e8d88SDave Plauger       }
443*ca3e8d88SDave Plauger 
444*ca3e8d88SDave Plauger       /*--
445*ca3e8d88SDave Plauger         Recompute the tables based on the accumulated frequencies.
446*ca3e8d88SDave Plauger       --*/
447*ca3e8d88SDave Plauger       /* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
448*ca3e8d88SDave Plauger          comment in huffman.c for details. */
449*ca3e8d88SDave Plauger       for (t = 0; t < nGroups; t++)
450*ca3e8d88SDave Plauger          BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
451*ca3e8d88SDave Plauger                                  alphaSize, 17 /*20*/ );
452*ca3e8d88SDave Plauger    }
453*ca3e8d88SDave Plauger 
454*ca3e8d88SDave Plauger 
455*ca3e8d88SDave Plauger    AssertH( nGroups < 8, 3002 );
456*ca3e8d88SDave Plauger    AssertH( nSelectors < 32768 &&
457*ca3e8d88SDave Plauger             nSelectors <= (2 + (900000 / BZ_G_SIZE)),
458*ca3e8d88SDave Plauger             3003 );
459*ca3e8d88SDave Plauger 
460*ca3e8d88SDave Plauger 
461*ca3e8d88SDave Plauger    /*--- Compute MTF values for the selectors. ---*/
462*ca3e8d88SDave Plauger    {
463*ca3e8d88SDave Plauger       UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
464*ca3e8d88SDave Plauger       for (i = 0; i < nGroups; i++) pos[i] = i;
465*ca3e8d88SDave Plauger       for (i = 0; i < nSelectors; i++) {
466*ca3e8d88SDave Plauger          ll_i = s->selector[i];
467*ca3e8d88SDave Plauger          j = 0;
468*ca3e8d88SDave Plauger          tmp = pos[j];
469*ca3e8d88SDave Plauger          while ( ll_i != tmp ) {
470*ca3e8d88SDave Plauger             j++;
471*ca3e8d88SDave Plauger             tmp2 = tmp;
472*ca3e8d88SDave Plauger             tmp = pos[j];
473*ca3e8d88SDave Plauger             pos[j] = tmp2;
474*ca3e8d88SDave Plauger          };
475*ca3e8d88SDave Plauger          pos[0] = tmp;
476*ca3e8d88SDave Plauger          s->selectorMtf[i] = j;
477*ca3e8d88SDave Plauger       }
478*ca3e8d88SDave Plauger    };
479*ca3e8d88SDave Plauger 
480*ca3e8d88SDave Plauger    /*--- Assign actual codes for the tables. --*/
481*ca3e8d88SDave Plauger    for (t = 0; t < nGroups; t++) {
482*ca3e8d88SDave Plauger       minLen = 32;
483*ca3e8d88SDave Plauger       maxLen = 0;
484*ca3e8d88SDave Plauger       for (i = 0; i < alphaSize; i++) {
485*ca3e8d88SDave Plauger          if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
486*ca3e8d88SDave Plauger          if (s->len[t][i] < minLen) minLen = s->len[t][i];
487*ca3e8d88SDave Plauger       }
488*ca3e8d88SDave Plauger       AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
489*ca3e8d88SDave Plauger       AssertH ( !(minLen < 1),  3005 );
490*ca3e8d88SDave Plauger       BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
491*ca3e8d88SDave Plauger                           minLen, maxLen, alphaSize );
492*ca3e8d88SDave Plauger    }
493*ca3e8d88SDave Plauger 
494*ca3e8d88SDave Plauger    /*--- Transmit the mapping table. ---*/
495*ca3e8d88SDave Plauger    {
496*ca3e8d88SDave Plauger       Bool inUse16[16];
497*ca3e8d88SDave Plauger       for (i = 0; i < 16; i++) {
498*ca3e8d88SDave Plauger           inUse16[i] = False;
499*ca3e8d88SDave Plauger           for (j = 0; j < 16; j++)
500*ca3e8d88SDave Plauger              if (s->inUse[i * 16 + j]) inUse16[i] = True;
501*ca3e8d88SDave Plauger       }
502*ca3e8d88SDave Plauger 
503*ca3e8d88SDave Plauger       nBytes = s->numZ;
504*ca3e8d88SDave Plauger       for (i = 0; i < 16; i++)
505*ca3e8d88SDave Plauger          if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
506*ca3e8d88SDave Plauger 
507*ca3e8d88SDave Plauger       for (i = 0; i < 16; i++)
508*ca3e8d88SDave Plauger          if (inUse16[i])
509*ca3e8d88SDave Plauger             for (j = 0; j < 16; j++) {
510*ca3e8d88SDave Plauger                if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
511*ca3e8d88SDave Plauger             }
512*ca3e8d88SDave Plauger 
513*ca3e8d88SDave Plauger       if (s->verbosity >= 3)
514*ca3e8d88SDave Plauger          VPrintf1( "      bytes: mapping %d, ", s->numZ-nBytes );
515*ca3e8d88SDave Plauger    }
516*ca3e8d88SDave Plauger 
517*ca3e8d88SDave Plauger    /*--- Now the selectors. ---*/
518*ca3e8d88SDave Plauger    nBytes = s->numZ;
519*ca3e8d88SDave Plauger    bsW ( s, 3, nGroups );
520*ca3e8d88SDave Plauger    bsW ( s, 15, nSelectors );
521*ca3e8d88SDave Plauger    for (i = 0; i < nSelectors; i++) {
522*ca3e8d88SDave Plauger       for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
523*ca3e8d88SDave Plauger       bsW(s,1,0);
524*ca3e8d88SDave Plauger    }
525*ca3e8d88SDave Plauger    if (s->verbosity >= 3)
526*ca3e8d88SDave Plauger       VPrintf1( "selectors %d, ", s->numZ-nBytes );
527*ca3e8d88SDave Plauger 
528*ca3e8d88SDave Plauger    /*--- Now the coding tables. ---*/
529*ca3e8d88SDave Plauger    nBytes = s->numZ;
530*ca3e8d88SDave Plauger 
531*ca3e8d88SDave Plauger    for (t = 0; t < nGroups; t++) {
532*ca3e8d88SDave Plauger       Int32 curr = s->len[t][0];
533*ca3e8d88SDave Plauger       bsW ( s, 5, curr );
534*ca3e8d88SDave Plauger       for (i = 0; i < alphaSize; i++) {
535*ca3e8d88SDave Plauger          while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
536*ca3e8d88SDave Plauger          while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
537*ca3e8d88SDave Plauger          bsW ( s, 1, 0 );
538*ca3e8d88SDave Plauger       }
539*ca3e8d88SDave Plauger    }
540*ca3e8d88SDave Plauger 
541*ca3e8d88SDave Plauger    if (s->verbosity >= 3)
542*ca3e8d88SDave Plauger       VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
543*ca3e8d88SDave Plauger 
544*ca3e8d88SDave Plauger    /*--- And finally, the block data proper ---*/
545*ca3e8d88SDave Plauger    nBytes = s->numZ;
546*ca3e8d88SDave Plauger    selCtr = 0;
547*ca3e8d88SDave Plauger    gs = 0;
548*ca3e8d88SDave Plauger    while (True) {
549*ca3e8d88SDave Plauger       if (gs >= s->nMTF) break;
550*ca3e8d88SDave Plauger       ge = gs + BZ_G_SIZE - 1;
551*ca3e8d88SDave Plauger       if (ge >= s->nMTF) ge = s->nMTF-1;
552*ca3e8d88SDave Plauger       AssertH ( s->selector[selCtr] < nGroups, 3006 );
553*ca3e8d88SDave Plauger 
554*ca3e8d88SDave Plauger       if (nGroups == 6 && 50 == ge-gs+1) {
555*ca3e8d88SDave Plauger             /*--- fast track the common case ---*/
556*ca3e8d88SDave Plauger             UInt16 mtfv_i;
557*ca3e8d88SDave Plauger             UChar* s_len_sel_selCtr
558*ca3e8d88SDave Plauger                = &(s->len[s->selector[selCtr]][0]);
559*ca3e8d88SDave Plauger             Int32* s_code_sel_selCtr
560*ca3e8d88SDave Plauger                = &(s->code[s->selector[selCtr]][0]);
561*ca3e8d88SDave Plauger 
562*ca3e8d88SDave Plauger #           define BZ_ITAH(nn)                      \
563*ca3e8d88SDave Plauger                mtfv_i = mtfv[gs+(nn)];              \
564*ca3e8d88SDave Plauger                bsW ( s,                             \
565*ca3e8d88SDave Plauger                      s_len_sel_selCtr[mtfv_i],      \
566*ca3e8d88SDave Plauger                      s_code_sel_selCtr[mtfv_i] )
567*ca3e8d88SDave Plauger 
568*ca3e8d88SDave Plauger             BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
569*ca3e8d88SDave Plauger             BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
570*ca3e8d88SDave Plauger             BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
571*ca3e8d88SDave Plauger             BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
572*ca3e8d88SDave Plauger             BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
573*ca3e8d88SDave Plauger             BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
574*ca3e8d88SDave Plauger             BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
575*ca3e8d88SDave Plauger             BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
576*ca3e8d88SDave Plauger             BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
577*ca3e8d88SDave Plauger             BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
578*ca3e8d88SDave Plauger 
579*ca3e8d88SDave Plauger #           undef BZ_ITAH
580*ca3e8d88SDave Plauger 
581*ca3e8d88SDave Plauger       } else {
582*ca3e8d88SDave Plauger 	 /*--- slow version which correctly handles all situations ---*/
583*ca3e8d88SDave Plauger          for (i = gs; i <= ge; i++) {
584*ca3e8d88SDave Plauger             bsW ( s,
585*ca3e8d88SDave Plauger                   s->len  [s->selector[selCtr]] [mtfv[i]],
586*ca3e8d88SDave Plauger                   s->code [s->selector[selCtr]] [mtfv[i]] );
587*ca3e8d88SDave Plauger          }
588*ca3e8d88SDave Plauger       }
589*ca3e8d88SDave Plauger 
590*ca3e8d88SDave Plauger 
591*ca3e8d88SDave Plauger       gs = ge+1;
592*ca3e8d88SDave Plauger       selCtr++;
593*ca3e8d88SDave Plauger    }
594*ca3e8d88SDave Plauger    AssertH( selCtr == nSelectors, 3007 );
595*ca3e8d88SDave Plauger 
596*ca3e8d88SDave Plauger    if (s->verbosity >= 3)
597*ca3e8d88SDave Plauger       VPrintf1( "codes %d\n", s->numZ-nBytes );
598*ca3e8d88SDave Plauger }
599*ca3e8d88SDave Plauger 
600*ca3e8d88SDave Plauger 
601*ca3e8d88SDave Plauger /*---------------------------------------------------*/
602*ca3e8d88SDave Plauger void BZ2_compressBlock ( EState* s, Bool is_last_block )
603*ca3e8d88SDave Plauger {
604*ca3e8d88SDave Plauger    if (s->nblock > 0) {
605*ca3e8d88SDave Plauger 
606*ca3e8d88SDave Plauger       BZ_FINALISE_CRC ( s->blockCRC );
607*ca3e8d88SDave Plauger       s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
608*ca3e8d88SDave Plauger       s->combinedCRC ^= s->blockCRC;
609*ca3e8d88SDave Plauger       if (s->blockNo > 1) s->numZ = 0;
610*ca3e8d88SDave Plauger 
611*ca3e8d88SDave Plauger       if (s->verbosity >= 2)
612*ca3e8d88SDave Plauger          VPrintf4( "    block %d: crc = 0x%08x, "
613*ca3e8d88SDave Plauger                    "combined CRC = 0x%08x, size = %d\n",
614*ca3e8d88SDave Plauger                    s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
615*ca3e8d88SDave Plauger 
616*ca3e8d88SDave Plauger       BZ2_blockSort ( s );
617*ca3e8d88SDave Plauger    }
618*ca3e8d88SDave Plauger 
619*ca3e8d88SDave Plauger    s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
620*ca3e8d88SDave Plauger 
621*ca3e8d88SDave Plauger    /*-- If this is the first block, create the stream header. --*/
622*ca3e8d88SDave Plauger    if (s->blockNo == 1) {
623*ca3e8d88SDave Plauger       BZ2_bsInitWrite ( s );
624*ca3e8d88SDave Plauger       bsPutUChar ( s, BZ_HDR_B );
625*ca3e8d88SDave Plauger       bsPutUChar ( s, BZ_HDR_Z );
626*ca3e8d88SDave Plauger       bsPutUChar ( s, BZ_HDR_h );
627*ca3e8d88SDave Plauger       bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
628*ca3e8d88SDave Plauger    }
629*ca3e8d88SDave Plauger 
630*ca3e8d88SDave Plauger    if (s->nblock > 0) {
631*ca3e8d88SDave Plauger 
632*ca3e8d88SDave Plauger       bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
633*ca3e8d88SDave Plauger       bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
634*ca3e8d88SDave Plauger       bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
635*ca3e8d88SDave Plauger 
636*ca3e8d88SDave Plauger       /*-- Now the block's CRC, so it is in a known place. --*/
637*ca3e8d88SDave Plauger       bsPutUInt32 ( s, s->blockCRC );
638*ca3e8d88SDave Plauger 
639*ca3e8d88SDave Plauger       /*--
640*ca3e8d88SDave Plauger          Now a single bit indicating (non-)randomisation.
641*ca3e8d88SDave Plauger          As of version 0.9.5, we use a better sorting algorithm
642*ca3e8d88SDave Plauger          which makes randomisation unnecessary.  So always set
643*ca3e8d88SDave Plauger          the randomised bit to 'no'.  Of course, the decoder
644*ca3e8d88SDave Plauger          still needs to be able to handle randomised blocks
645*ca3e8d88SDave Plauger          so as to maintain backwards compatibility with
646*ca3e8d88SDave Plauger          older versions of bzip2.
647*ca3e8d88SDave Plauger       --*/
648*ca3e8d88SDave Plauger       bsW(s,1,0);
649*ca3e8d88SDave Plauger 
650*ca3e8d88SDave Plauger       bsW ( s, 24, s->origPtr );
651*ca3e8d88SDave Plauger       generateMTFValues ( s );
652*ca3e8d88SDave Plauger       sendMTFValues ( s );
653*ca3e8d88SDave Plauger    }
654*ca3e8d88SDave Plauger 
655*ca3e8d88SDave Plauger 
656*ca3e8d88SDave Plauger    /*-- If this is the last block, add the stream trailer. --*/
657*ca3e8d88SDave Plauger    if (is_last_block) {
658*ca3e8d88SDave Plauger 
659*ca3e8d88SDave Plauger       bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
660*ca3e8d88SDave Plauger       bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
661*ca3e8d88SDave Plauger       bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
662*ca3e8d88SDave Plauger       bsPutUInt32 ( s, s->combinedCRC );
663*ca3e8d88SDave Plauger       if (s->verbosity >= 2)
664*ca3e8d88SDave Plauger          VPrintf1( "    final combined CRC = 0x%08x\n   ", s->combinedCRC );
665*ca3e8d88SDave Plauger       bsFinishWrite ( s );
666*ca3e8d88SDave Plauger    }
667*ca3e8d88SDave Plauger }
668*ca3e8d88SDave Plauger 
669*ca3e8d88SDave Plauger 
670*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/
671*ca3e8d88SDave Plauger /*--- end                                        compress.c ---*/
672*ca3e8d88SDave Plauger /*-------------------------------------------------------------*/
673