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