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