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