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