xref: /oneTBB/examples/graph/fgbzip2/compress.cpp (revision b15aabb3)
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