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