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