1*0ac9a9daSXin Li
2*0ac9a9daSXin Li /*-------------------------------------------------------------*/
3*0ac9a9daSXin Li /*--- Decompression machinery ---*/
4*0ac9a9daSXin Li /*--- decompress.c ---*/
5*0ac9a9daSXin Li /*-------------------------------------------------------------*/
6*0ac9a9daSXin Li
7*0ac9a9daSXin Li /* ------------------------------------------------------------------
8*0ac9a9daSXin Li This file is part of bzip2/libbzip2, a program and library for
9*0ac9a9daSXin Li lossless, block-sorting data compression.
10*0ac9a9daSXin Li
11*0ac9a9daSXin Li bzip2/libbzip2 version 1.0.8 of 13 July 2019
12*0ac9a9daSXin Li Copyright (C) 1996-2019 Julian Seward <[email protected]>
13*0ac9a9daSXin Li
14*0ac9a9daSXin Li Please read the WARNING, DISCLAIMER and PATENTS sections in the
15*0ac9a9daSXin Li README file.
16*0ac9a9daSXin Li
17*0ac9a9daSXin Li This program is released under the terms of the license contained
18*0ac9a9daSXin Li in the file LICENSE.
19*0ac9a9daSXin Li ------------------------------------------------------------------ */
20*0ac9a9daSXin Li
21*0ac9a9daSXin Li
22*0ac9a9daSXin Li #include "bzlib_private.h"
23*0ac9a9daSXin Li
24*0ac9a9daSXin Li
25*0ac9a9daSXin Li /*---------------------------------------------------*/
26*0ac9a9daSXin Li static
makeMaps_d(DState * s)27*0ac9a9daSXin Li void makeMaps_d ( DState* s )
28*0ac9a9daSXin Li {
29*0ac9a9daSXin Li Int32 i;
30*0ac9a9daSXin Li s->nInUse = 0;
31*0ac9a9daSXin Li for (i = 0; i < 256; i++)
32*0ac9a9daSXin Li if (s->inUse[i]) {
33*0ac9a9daSXin Li s->seqToUnseq[s->nInUse] = i;
34*0ac9a9daSXin Li s->nInUse++;
35*0ac9a9daSXin Li }
36*0ac9a9daSXin Li }
37*0ac9a9daSXin Li
38*0ac9a9daSXin Li
39*0ac9a9daSXin Li /*---------------------------------------------------*/
40*0ac9a9daSXin Li #define RETURN(rrr) \
41*0ac9a9daSXin Li { retVal = rrr; goto save_state_and_return; };
42*0ac9a9daSXin Li
43*0ac9a9daSXin Li #define GET_BITS(lll,vvv,nnn) \
44*0ac9a9daSXin Li case lll: s->state = lll; \
45*0ac9a9daSXin Li while (True) { \
46*0ac9a9daSXin Li if (s->bsLive >= nnn) { \
47*0ac9a9daSXin Li UInt32 v; \
48*0ac9a9daSXin Li v = (s->bsBuff >> \
49*0ac9a9daSXin Li (s->bsLive-nnn)) & ((1 << nnn)-1); \
50*0ac9a9daSXin Li s->bsLive -= nnn; \
51*0ac9a9daSXin Li vvv = v; \
52*0ac9a9daSXin Li break; \
53*0ac9a9daSXin Li } \
54*0ac9a9daSXin Li if (s->strm->avail_in == 0) RETURN(BZ_OK); \
55*0ac9a9daSXin Li s->bsBuff \
56*0ac9a9daSXin Li = (s->bsBuff << 8) | \
57*0ac9a9daSXin Li ((UInt32) \
58*0ac9a9daSXin Li (*((UChar*)(s->strm->next_in)))); \
59*0ac9a9daSXin Li s->bsLive += 8; \
60*0ac9a9daSXin Li s->strm->next_in++; \
61*0ac9a9daSXin Li s->strm->avail_in--; \
62*0ac9a9daSXin Li s->strm->total_in_lo32++; \
63*0ac9a9daSXin Li if (s->strm->total_in_lo32 == 0) \
64*0ac9a9daSXin Li s->strm->total_in_hi32++; \
65*0ac9a9daSXin Li }
66*0ac9a9daSXin Li
67*0ac9a9daSXin Li #define GET_UCHAR(lll,uuu) \
68*0ac9a9daSXin Li GET_BITS(lll,uuu,8)
69*0ac9a9daSXin Li
70*0ac9a9daSXin Li #define GET_BIT(lll,uuu) \
71*0ac9a9daSXin Li GET_BITS(lll,uuu,1)
72*0ac9a9daSXin Li
73*0ac9a9daSXin Li /*---------------------------------------------------*/
74*0ac9a9daSXin Li #define GET_MTF_VAL(label1,label2,lval) \
75*0ac9a9daSXin Li { \
76*0ac9a9daSXin Li if (groupPos == 0) { \
77*0ac9a9daSXin Li groupNo++; \
78*0ac9a9daSXin Li if (groupNo >= nSelectors) \
79*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR); \
80*0ac9a9daSXin Li groupPos = BZ_G_SIZE; \
81*0ac9a9daSXin Li gSel = s->selector[groupNo]; \
82*0ac9a9daSXin Li gMinlen = s->minLens[gSel]; \
83*0ac9a9daSXin Li gLimit = &(s->limit[gSel][0]); \
84*0ac9a9daSXin Li gPerm = &(s->perm[gSel][0]); \
85*0ac9a9daSXin Li gBase = &(s->base[gSel][0]); \
86*0ac9a9daSXin Li } \
87*0ac9a9daSXin Li groupPos--; \
88*0ac9a9daSXin Li zn = gMinlen; \
89*0ac9a9daSXin Li GET_BITS(label1, zvec, zn); \
90*0ac9a9daSXin Li while (1) { \
91*0ac9a9daSXin Li if (zn > 20 /* the longest code */) \
92*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR); \
93*0ac9a9daSXin Li if (zvec <= gLimit[zn]) break; \
94*0ac9a9daSXin Li zn++; \
95*0ac9a9daSXin Li GET_BIT(label2, zj); \
96*0ac9a9daSXin Li zvec = (zvec << 1) | zj; \
97*0ac9a9daSXin Li }; \
98*0ac9a9daSXin Li if (zvec - gBase[zn] < 0 \
99*0ac9a9daSXin Li || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
100*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR); \
101*0ac9a9daSXin Li lval = gPerm[zvec - gBase[zn]]; \
102*0ac9a9daSXin Li }
103*0ac9a9daSXin Li
104*0ac9a9daSXin Li
105*0ac9a9daSXin Li /*---------------------------------------------------*/
BZ2_decompress(DState * s)106*0ac9a9daSXin Li Int32 BZ2_decompress ( DState* s )
107*0ac9a9daSXin Li {
108*0ac9a9daSXin Li UChar uc;
109*0ac9a9daSXin Li Int32 retVal;
110*0ac9a9daSXin Li Int32 minLen, maxLen;
111*0ac9a9daSXin Li bz_stream* strm = s->strm;
112*0ac9a9daSXin Li
113*0ac9a9daSXin Li /* stuff that needs to be saved/restored */
114*0ac9a9daSXin Li Int32 i;
115*0ac9a9daSXin Li Int32 j;
116*0ac9a9daSXin Li Int32 t;
117*0ac9a9daSXin Li Int32 alphaSize;
118*0ac9a9daSXin Li Int32 nGroups;
119*0ac9a9daSXin Li Int32 nSelectors;
120*0ac9a9daSXin Li Int32 EOB;
121*0ac9a9daSXin Li Int32 groupNo;
122*0ac9a9daSXin Li Int32 groupPos;
123*0ac9a9daSXin Li Int32 nextSym;
124*0ac9a9daSXin Li Int32 nblockMAX;
125*0ac9a9daSXin Li Int32 nblock;
126*0ac9a9daSXin Li Int32 es;
127*0ac9a9daSXin Li Int32 N;
128*0ac9a9daSXin Li Int32 curr;
129*0ac9a9daSXin Li Int32 zt;
130*0ac9a9daSXin Li Int32 zn;
131*0ac9a9daSXin Li Int32 zvec;
132*0ac9a9daSXin Li Int32 zj;
133*0ac9a9daSXin Li Int32 gSel;
134*0ac9a9daSXin Li Int32 gMinlen;
135*0ac9a9daSXin Li Int32* gLimit;
136*0ac9a9daSXin Li Int32* gBase;
137*0ac9a9daSXin Li Int32* gPerm;
138*0ac9a9daSXin Li
139*0ac9a9daSXin Li if (s->state == BZ_X_MAGIC_1) {
140*0ac9a9daSXin Li /*initialise the save area*/
141*0ac9a9daSXin Li s->save_i = 0;
142*0ac9a9daSXin Li s->save_j = 0;
143*0ac9a9daSXin Li s->save_t = 0;
144*0ac9a9daSXin Li s->save_alphaSize = 0;
145*0ac9a9daSXin Li s->save_nGroups = 0;
146*0ac9a9daSXin Li s->save_nSelectors = 0;
147*0ac9a9daSXin Li s->save_EOB = 0;
148*0ac9a9daSXin Li s->save_groupNo = 0;
149*0ac9a9daSXin Li s->save_groupPos = 0;
150*0ac9a9daSXin Li s->save_nextSym = 0;
151*0ac9a9daSXin Li s->save_nblockMAX = 0;
152*0ac9a9daSXin Li s->save_nblock = 0;
153*0ac9a9daSXin Li s->save_es = 0;
154*0ac9a9daSXin Li s->save_N = 0;
155*0ac9a9daSXin Li s->save_curr = 0;
156*0ac9a9daSXin Li s->save_zt = 0;
157*0ac9a9daSXin Li s->save_zn = 0;
158*0ac9a9daSXin Li s->save_zvec = 0;
159*0ac9a9daSXin Li s->save_zj = 0;
160*0ac9a9daSXin Li s->save_gSel = 0;
161*0ac9a9daSXin Li s->save_gMinlen = 0;
162*0ac9a9daSXin Li s->save_gLimit = NULL;
163*0ac9a9daSXin Li s->save_gBase = NULL;
164*0ac9a9daSXin Li s->save_gPerm = NULL;
165*0ac9a9daSXin Li }
166*0ac9a9daSXin Li
167*0ac9a9daSXin Li /*restore from the save area*/
168*0ac9a9daSXin Li i = s->save_i;
169*0ac9a9daSXin Li j = s->save_j;
170*0ac9a9daSXin Li t = s->save_t;
171*0ac9a9daSXin Li alphaSize = s->save_alphaSize;
172*0ac9a9daSXin Li nGroups = s->save_nGroups;
173*0ac9a9daSXin Li nSelectors = s->save_nSelectors;
174*0ac9a9daSXin Li EOB = s->save_EOB;
175*0ac9a9daSXin Li groupNo = s->save_groupNo;
176*0ac9a9daSXin Li groupPos = s->save_groupPos;
177*0ac9a9daSXin Li nextSym = s->save_nextSym;
178*0ac9a9daSXin Li nblockMAX = s->save_nblockMAX;
179*0ac9a9daSXin Li nblock = s->save_nblock;
180*0ac9a9daSXin Li es = s->save_es;
181*0ac9a9daSXin Li N = s->save_N;
182*0ac9a9daSXin Li curr = s->save_curr;
183*0ac9a9daSXin Li zt = s->save_zt;
184*0ac9a9daSXin Li zn = s->save_zn;
185*0ac9a9daSXin Li zvec = s->save_zvec;
186*0ac9a9daSXin Li zj = s->save_zj;
187*0ac9a9daSXin Li gSel = s->save_gSel;
188*0ac9a9daSXin Li gMinlen = s->save_gMinlen;
189*0ac9a9daSXin Li gLimit = s->save_gLimit;
190*0ac9a9daSXin Li gBase = s->save_gBase;
191*0ac9a9daSXin Li gPerm = s->save_gPerm;
192*0ac9a9daSXin Li
193*0ac9a9daSXin Li retVal = BZ_OK;
194*0ac9a9daSXin Li
195*0ac9a9daSXin Li switch (s->state) {
196*0ac9a9daSXin Li
197*0ac9a9daSXin Li GET_UCHAR(BZ_X_MAGIC_1, uc);
198*0ac9a9daSXin Li if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
199*0ac9a9daSXin Li
200*0ac9a9daSXin Li GET_UCHAR(BZ_X_MAGIC_2, uc);
201*0ac9a9daSXin Li if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
202*0ac9a9daSXin Li
203*0ac9a9daSXin Li GET_UCHAR(BZ_X_MAGIC_3, uc)
204*0ac9a9daSXin Li if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
205*0ac9a9daSXin Li
206*0ac9a9daSXin Li GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
207*0ac9a9daSXin Li if (s->blockSize100k < (BZ_HDR_0 + 1) ||
208*0ac9a9daSXin Li s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
209*0ac9a9daSXin Li s->blockSize100k -= BZ_HDR_0;
210*0ac9a9daSXin Li
211*0ac9a9daSXin Li if (s->smallDecompress) {
212*0ac9a9daSXin Li s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
213*0ac9a9daSXin Li s->ll4 = BZALLOC(
214*0ac9a9daSXin Li ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
215*0ac9a9daSXin Li );
216*0ac9a9daSXin Li if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
217*0ac9a9daSXin Li } else {
218*0ac9a9daSXin Li s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
219*0ac9a9daSXin Li if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
220*0ac9a9daSXin Li }
221*0ac9a9daSXin Li
222*0ac9a9daSXin Li GET_UCHAR(BZ_X_BLKHDR_1, uc);
223*0ac9a9daSXin Li
224*0ac9a9daSXin Li if (uc == 0x17) goto endhdr_2;
225*0ac9a9daSXin Li if (uc != 0x31) RETURN(BZ_DATA_ERROR);
226*0ac9a9daSXin Li GET_UCHAR(BZ_X_BLKHDR_2, uc);
227*0ac9a9daSXin Li if (uc != 0x41) RETURN(BZ_DATA_ERROR);
228*0ac9a9daSXin Li GET_UCHAR(BZ_X_BLKHDR_3, uc);
229*0ac9a9daSXin Li if (uc != 0x59) RETURN(BZ_DATA_ERROR);
230*0ac9a9daSXin Li GET_UCHAR(BZ_X_BLKHDR_4, uc);
231*0ac9a9daSXin Li if (uc != 0x26) RETURN(BZ_DATA_ERROR);
232*0ac9a9daSXin Li GET_UCHAR(BZ_X_BLKHDR_5, uc);
233*0ac9a9daSXin Li if (uc != 0x53) RETURN(BZ_DATA_ERROR);
234*0ac9a9daSXin Li GET_UCHAR(BZ_X_BLKHDR_6, uc);
235*0ac9a9daSXin Li if (uc != 0x59) RETURN(BZ_DATA_ERROR);
236*0ac9a9daSXin Li
237*0ac9a9daSXin Li s->currBlockNo++;
238*0ac9a9daSXin Li if (s->verbosity >= 2)
239*0ac9a9daSXin Li VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
240*0ac9a9daSXin Li
241*0ac9a9daSXin Li s->storedBlockCRC = 0;
242*0ac9a9daSXin Li GET_UCHAR(BZ_X_BCRC_1, uc);
243*0ac9a9daSXin Li s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
244*0ac9a9daSXin Li GET_UCHAR(BZ_X_BCRC_2, uc);
245*0ac9a9daSXin Li s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
246*0ac9a9daSXin Li GET_UCHAR(BZ_X_BCRC_3, uc);
247*0ac9a9daSXin Li s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
248*0ac9a9daSXin Li GET_UCHAR(BZ_X_BCRC_4, uc);
249*0ac9a9daSXin Li s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
250*0ac9a9daSXin Li
251*0ac9a9daSXin Li GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
252*0ac9a9daSXin Li
253*0ac9a9daSXin Li s->origPtr = 0;
254*0ac9a9daSXin Li GET_UCHAR(BZ_X_ORIGPTR_1, uc);
255*0ac9a9daSXin Li s->origPtr = (s->origPtr << 8) | ((Int32)uc);
256*0ac9a9daSXin Li GET_UCHAR(BZ_X_ORIGPTR_2, uc);
257*0ac9a9daSXin Li s->origPtr = (s->origPtr << 8) | ((Int32)uc);
258*0ac9a9daSXin Li GET_UCHAR(BZ_X_ORIGPTR_3, uc);
259*0ac9a9daSXin Li s->origPtr = (s->origPtr << 8) | ((Int32)uc);
260*0ac9a9daSXin Li
261*0ac9a9daSXin Li if (s->origPtr < 0)
262*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR);
263*0ac9a9daSXin Li if (s->origPtr > 10 + 100000*s->blockSize100k)
264*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR);
265*0ac9a9daSXin Li
266*0ac9a9daSXin Li /*--- Receive the mapping table ---*/
267*0ac9a9daSXin Li for (i = 0; i < 16; i++) {
268*0ac9a9daSXin Li GET_BIT(BZ_X_MAPPING_1, uc);
269*0ac9a9daSXin Li if (uc == 1)
270*0ac9a9daSXin Li s->inUse16[i] = True; else
271*0ac9a9daSXin Li s->inUse16[i] = False;
272*0ac9a9daSXin Li }
273*0ac9a9daSXin Li
274*0ac9a9daSXin Li for (i = 0; i < 256; i++) s->inUse[i] = False;
275*0ac9a9daSXin Li
276*0ac9a9daSXin Li for (i = 0; i < 16; i++)
277*0ac9a9daSXin Li if (s->inUse16[i])
278*0ac9a9daSXin Li for (j = 0; j < 16; j++) {
279*0ac9a9daSXin Li GET_BIT(BZ_X_MAPPING_2, uc);
280*0ac9a9daSXin Li if (uc == 1) s->inUse[i * 16 + j] = True;
281*0ac9a9daSXin Li }
282*0ac9a9daSXin Li makeMaps_d ( s );
283*0ac9a9daSXin Li if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
284*0ac9a9daSXin Li alphaSize = s->nInUse+2;
285*0ac9a9daSXin Li
286*0ac9a9daSXin Li /*--- Now the selectors ---*/
287*0ac9a9daSXin Li GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
288*0ac9a9daSXin Li if (nGroups < 2 || nGroups > BZ_N_GROUPS) RETURN(BZ_DATA_ERROR);
289*0ac9a9daSXin Li GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
290*0ac9a9daSXin Li if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
291*0ac9a9daSXin Li for (i = 0; i < nSelectors; i++) {
292*0ac9a9daSXin Li j = 0;
293*0ac9a9daSXin Li while (True) {
294*0ac9a9daSXin Li GET_BIT(BZ_X_SELECTOR_3, uc);
295*0ac9a9daSXin Li if (uc == 0) break;
296*0ac9a9daSXin Li j++;
297*0ac9a9daSXin Li if (j >= nGroups) RETURN(BZ_DATA_ERROR);
298*0ac9a9daSXin Li }
299*0ac9a9daSXin Li /* Having more than BZ_MAX_SELECTORS doesn't make much sense
300*0ac9a9daSXin Li since they will never be used, but some implementations might
301*0ac9a9daSXin Li "round up" the number of selectors, so just ignore those. */
302*0ac9a9daSXin Li if (i < BZ_MAX_SELECTORS)
303*0ac9a9daSXin Li s->selectorMtf[i] = j;
304*0ac9a9daSXin Li }
305*0ac9a9daSXin Li if (nSelectors > BZ_MAX_SELECTORS)
306*0ac9a9daSXin Li nSelectors = BZ_MAX_SELECTORS;
307*0ac9a9daSXin Li
308*0ac9a9daSXin Li /*--- Undo the MTF values for the selectors. ---*/
309*0ac9a9daSXin Li {
310*0ac9a9daSXin Li UChar pos[BZ_N_GROUPS], tmp, v;
311*0ac9a9daSXin Li for (v = 0; v < nGroups; v++) pos[v] = v;
312*0ac9a9daSXin Li
313*0ac9a9daSXin Li for (i = 0; i < nSelectors; i++) {
314*0ac9a9daSXin Li v = s->selectorMtf[i];
315*0ac9a9daSXin Li tmp = pos[v];
316*0ac9a9daSXin Li while (v > 0) { pos[v] = pos[v-1]; v--; }
317*0ac9a9daSXin Li pos[0] = tmp;
318*0ac9a9daSXin Li s->selector[i] = tmp;
319*0ac9a9daSXin Li }
320*0ac9a9daSXin Li }
321*0ac9a9daSXin Li
322*0ac9a9daSXin Li /*--- Now the coding tables ---*/
323*0ac9a9daSXin Li for (t = 0; t < nGroups; t++) {
324*0ac9a9daSXin Li GET_BITS(BZ_X_CODING_1, curr, 5);
325*0ac9a9daSXin Li for (i = 0; i < alphaSize; i++) {
326*0ac9a9daSXin Li while (True) {
327*0ac9a9daSXin Li if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
328*0ac9a9daSXin Li GET_BIT(BZ_X_CODING_2, uc);
329*0ac9a9daSXin Li if (uc == 0) break;
330*0ac9a9daSXin Li GET_BIT(BZ_X_CODING_3, uc);
331*0ac9a9daSXin Li if (uc == 0) curr++; else curr--;
332*0ac9a9daSXin Li }
333*0ac9a9daSXin Li s->len[t][i] = curr;
334*0ac9a9daSXin Li }
335*0ac9a9daSXin Li }
336*0ac9a9daSXin Li
337*0ac9a9daSXin Li /*--- Create the Huffman decoding tables ---*/
338*0ac9a9daSXin Li for (t = 0; t < nGroups; t++) {
339*0ac9a9daSXin Li minLen = 32;
340*0ac9a9daSXin Li maxLen = 0;
341*0ac9a9daSXin Li for (i = 0; i < alphaSize; i++) {
342*0ac9a9daSXin Li if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
343*0ac9a9daSXin Li if (s->len[t][i] < minLen) minLen = s->len[t][i];
344*0ac9a9daSXin Li }
345*0ac9a9daSXin Li BZ2_hbCreateDecodeTables (
346*0ac9a9daSXin Li &(s->limit[t][0]),
347*0ac9a9daSXin Li &(s->base[t][0]),
348*0ac9a9daSXin Li &(s->perm[t][0]),
349*0ac9a9daSXin Li &(s->len[t][0]),
350*0ac9a9daSXin Li minLen, maxLen, alphaSize
351*0ac9a9daSXin Li );
352*0ac9a9daSXin Li s->minLens[t] = minLen;
353*0ac9a9daSXin Li }
354*0ac9a9daSXin Li
355*0ac9a9daSXin Li /*--- Now the MTF values ---*/
356*0ac9a9daSXin Li
357*0ac9a9daSXin Li EOB = s->nInUse+1;
358*0ac9a9daSXin Li nblockMAX = 100000 * s->blockSize100k;
359*0ac9a9daSXin Li groupNo = -1;
360*0ac9a9daSXin Li groupPos = 0;
361*0ac9a9daSXin Li
362*0ac9a9daSXin Li for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
363*0ac9a9daSXin Li
364*0ac9a9daSXin Li /*-- MTF init --*/
365*0ac9a9daSXin Li {
366*0ac9a9daSXin Li Int32 ii, jj, kk;
367*0ac9a9daSXin Li kk = MTFA_SIZE-1;
368*0ac9a9daSXin Li for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
369*0ac9a9daSXin Li for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
370*0ac9a9daSXin Li s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
371*0ac9a9daSXin Li kk--;
372*0ac9a9daSXin Li }
373*0ac9a9daSXin Li s->mtfbase[ii] = kk + 1;
374*0ac9a9daSXin Li }
375*0ac9a9daSXin Li }
376*0ac9a9daSXin Li /*-- end MTF init --*/
377*0ac9a9daSXin Li
378*0ac9a9daSXin Li nblock = 0;
379*0ac9a9daSXin Li GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
380*0ac9a9daSXin Li
381*0ac9a9daSXin Li while (True) {
382*0ac9a9daSXin Li
383*0ac9a9daSXin Li if (nextSym == EOB) break;
384*0ac9a9daSXin Li
385*0ac9a9daSXin Li if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
386*0ac9a9daSXin Li
387*0ac9a9daSXin Li es = -1;
388*0ac9a9daSXin Li N = 1;
389*0ac9a9daSXin Li do {
390*0ac9a9daSXin Li /* Check that N doesn't get too big, so that es doesn't
391*0ac9a9daSXin Li go negative. The maximum value that can be
392*0ac9a9daSXin Li RUNA/RUNB encoded is equal to the block size (post
393*0ac9a9daSXin Li the initial RLE), viz, 900k, so bounding N at 2
394*0ac9a9daSXin Li million should guard against overflow without
395*0ac9a9daSXin Li rejecting any legitimate inputs. */
396*0ac9a9daSXin Li if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
397*0ac9a9daSXin Li if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
398*0ac9a9daSXin Li if (nextSym == BZ_RUNB) es = es + (1+1) * N;
399*0ac9a9daSXin Li N = N * 2;
400*0ac9a9daSXin Li GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
401*0ac9a9daSXin Li }
402*0ac9a9daSXin Li while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
403*0ac9a9daSXin Li
404*0ac9a9daSXin Li es++;
405*0ac9a9daSXin Li uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
406*0ac9a9daSXin Li s->unzftab[uc] += es;
407*0ac9a9daSXin Li
408*0ac9a9daSXin Li if (s->smallDecompress)
409*0ac9a9daSXin Li while (es > 0) {
410*0ac9a9daSXin Li if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
411*0ac9a9daSXin Li s->ll16[nblock] = (UInt16)uc;
412*0ac9a9daSXin Li nblock++;
413*0ac9a9daSXin Li es--;
414*0ac9a9daSXin Li }
415*0ac9a9daSXin Li else
416*0ac9a9daSXin Li while (es > 0) {
417*0ac9a9daSXin Li if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
418*0ac9a9daSXin Li s->tt[nblock] = (UInt32)uc;
419*0ac9a9daSXin Li nblock++;
420*0ac9a9daSXin Li es--;
421*0ac9a9daSXin Li };
422*0ac9a9daSXin Li
423*0ac9a9daSXin Li continue;
424*0ac9a9daSXin Li
425*0ac9a9daSXin Li } else {
426*0ac9a9daSXin Li
427*0ac9a9daSXin Li if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
428*0ac9a9daSXin Li
429*0ac9a9daSXin Li /*-- uc = MTF ( nextSym-1 ) --*/
430*0ac9a9daSXin Li {
431*0ac9a9daSXin Li Int32 ii, jj, kk, pp, lno, off;
432*0ac9a9daSXin Li UInt32 nn;
433*0ac9a9daSXin Li nn = (UInt32)(nextSym - 1);
434*0ac9a9daSXin Li
435*0ac9a9daSXin Li if (nn < MTFL_SIZE) {
436*0ac9a9daSXin Li /* avoid general-case expense */
437*0ac9a9daSXin Li pp = s->mtfbase[0];
438*0ac9a9daSXin Li uc = s->mtfa[pp+nn];
439*0ac9a9daSXin Li while (nn > 3) {
440*0ac9a9daSXin Li Int32 z = pp+nn;
441*0ac9a9daSXin Li s->mtfa[(z) ] = s->mtfa[(z)-1];
442*0ac9a9daSXin Li s->mtfa[(z)-1] = s->mtfa[(z)-2];
443*0ac9a9daSXin Li s->mtfa[(z)-2] = s->mtfa[(z)-3];
444*0ac9a9daSXin Li s->mtfa[(z)-3] = s->mtfa[(z)-4];
445*0ac9a9daSXin Li nn -= 4;
446*0ac9a9daSXin Li }
447*0ac9a9daSXin Li while (nn > 0) {
448*0ac9a9daSXin Li s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
449*0ac9a9daSXin Li };
450*0ac9a9daSXin Li s->mtfa[pp] = uc;
451*0ac9a9daSXin Li } else {
452*0ac9a9daSXin Li /* general case */
453*0ac9a9daSXin Li lno = nn / MTFL_SIZE;
454*0ac9a9daSXin Li off = nn % MTFL_SIZE;
455*0ac9a9daSXin Li pp = s->mtfbase[lno] + off;
456*0ac9a9daSXin Li uc = s->mtfa[pp];
457*0ac9a9daSXin Li while (pp > s->mtfbase[lno]) {
458*0ac9a9daSXin Li s->mtfa[pp] = s->mtfa[pp-1]; pp--;
459*0ac9a9daSXin Li };
460*0ac9a9daSXin Li s->mtfbase[lno]++;
461*0ac9a9daSXin Li while (lno > 0) {
462*0ac9a9daSXin Li s->mtfbase[lno]--;
463*0ac9a9daSXin Li s->mtfa[s->mtfbase[lno]]
464*0ac9a9daSXin Li = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
465*0ac9a9daSXin Li lno--;
466*0ac9a9daSXin Li }
467*0ac9a9daSXin Li s->mtfbase[0]--;
468*0ac9a9daSXin Li s->mtfa[s->mtfbase[0]] = uc;
469*0ac9a9daSXin Li if (s->mtfbase[0] == 0) {
470*0ac9a9daSXin Li kk = MTFA_SIZE-1;
471*0ac9a9daSXin Li for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
472*0ac9a9daSXin Li for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
473*0ac9a9daSXin Li s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
474*0ac9a9daSXin Li kk--;
475*0ac9a9daSXin Li }
476*0ac9a9daSXin Li s->mtfbase[ii] = kk + 1;
477*0ac9a9daSXin Li }
478*0ac9a9daSXin Li }
479*0ac9a9daSXin Li }
480*0ac9a9daSXin Li }
481*0ac9a9daSXin Li /*-- end uc = MTF ( nextSym-1 ) --*/
482*0ac9a9daSXin Li
483*0ac9a9daSXin Li s->unzftab[s->seqToUnseq[uc]]++;
484*0ac9a9daSXin Li if (s->smallDecompress)
485*0ac9a9daSXin Li s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
486*0ac9a9daSXin Li s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
487*0ac9a9daSXin Li nblock++;
488*0ac9a9daSXin Li
489*0ac9a9daSXin Li GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
490*0ac9a9daSXin Li continue;
491*0ac9a9daSXin Li }
492*0ac9a9daSXin Li }
493*0ac9a9daSXin Li
494*0ac9a9daSXin Li /* Now we know what nblock is, we can do a better sanity
495*0ac9a9daSXin Li check on s->origPtr.
496*0ac9a9daSXin Li */
497*0ac9a9daSXin Li if (s->origPtr < 0 || s->origPtr >= nblock)
498*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR);
499*0ac9a9daSXin Li
500*0ac9a9daSXin Li /*-- Set up cftab to facilitate generation of T^(-1) --*/
501*0ac9a9daSXin Li /* Check: unzftab entries in range. */
502*0ac9a9daSXin Li for (i = 0; i <= 255; i++) {
503*0ac9a9daSXin Li if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
504*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR);
505*0ac9a9daSXin Li }
506*0ac9a9daSXin Li /* Actually generate cftab. */
507*0ac9a9daSXin Li s->cftab[0] = 0;
508*0ac9a9daSXin Li for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
509*0ac9a9daSXin Li for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
510*0ac9a9daSXin Li /* Check: cftab entries in range. */
511*0ac9a9daSXin Li for (i = 0; i <= 256; i++) {
512*0ac9a9daSXin Li if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
513*0ac9a9daSXin Li /* s->cftab[i] can legitimately be == nblock */
514*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR);
515*0ac9a9daSXin Li }
516*0ac9a9daSXin Li }
517*0ac9a9daSXin Li /* Check: cftab entries non-descending. */
518*0ac9a9daSXin Li for (i = 1; i <= 256; i++) {
519*0ac9a9daSXin Li if (s->cftab[i-1] > s->cftab[i]) {
520*0ac9a9daSXin Li RETURN(BZ_DATA_ERROR);
521*0ac9a9daSXin Li }
522*0ac9a9daSXin Li }
523*0ac9a9daSXin Li
524*0ac9a9daSXin Li s->state_out_len = 0;
525*0ac9a9daSXin Li s->state_out_ch = 0;
526*0ac9a9daSXin Li BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
527*0ac9a9daSXin Li s->state = BZ_X_OUTPUT;
528*0ac9a9daSXin Li if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
529*0ac9a9daSXin Li
530*0ac9a9daSXin Li if (s->smallDecompress) {
531*0ac9a9daSXin Li
532*0ac9a9daSXin Li /*-- Make a copy of cftab, used in generation of T --*/
533*0ac9a9daSXin Li for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
534*0ac9a9daSXin Li
535*0ac9a9daSXin Li /*-- compute the T vector --*/
536*0ac9a9daSXin Li for (i = 0; i < nblock; i++) {
537*0ac9a9daSXin Li uc = (UChar)(s->ll16[i]);
538*0ac9a9daSXin Li SET_LL(i, s->cftabCopy[uc]);
539*0ac9a9daSXin Li s->cftabCopy[uc]++;
540*0ac9a9daSXin Li }
541*0ac9a9daSXin Li
542*0ac9a9daSXin Li /*-- Compute T^(-1) by pointer reversal on T --*/
543*0ac9a9daSXin Li i = s->origPtr;
544*0ac9a9daSXin Li j = GET_LL(i);
545*0ac9a9daSXin Li do {
546*0ac9a9daSXin Li Int32 tmp = GET_LL(j);
547*0ac9a9daSXin Li SET_LL(j, i);
548*0ac9a9daSXin Li i = j;
549*0ac9a9daSXin Li j = tmp;
550*0ac9a9daSXin Li }
551*0ac9a9daSXin Li while (i != s->origPtr);
552*0ac9a9daSXin Li
553*0ac9a9daSXin Li s->tPos = s->origPtr;
554*0ac9a9daSXin Li s->nblock_used = 0;
555*0ac9a9daSXin Li if (s->blockRandomised) {
556*0ac9a9daSXin Li BZ_RAND_INIT_MASK;
557*0ac9a9daSXin Li BZ_GET_SMALL(s->k0); s->nblock_used++;
558*0ac9a9daSXin Li BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
559*0ac9a9daSXin Li } else {
560*0ac9a9daSXin Li BZ_GET_SMALL(s->k0); s->nblock_used++;
561*0ac9a9daSXin Li }
562*0ac9a9daSXin Li
563*0ac9a9daSXin Li } else {
564*0ac9a9daSXin Li
565*0ac9a9daSXin Li /*-- compute the T^(-1) vector --*/
566*0ac9a9daSXin Li for (i = 0; i < nblock; i++) {
567*0ac9a9daSXin Li uc = (UChar)(s->tt[i] & 0xff);
568*0ac9a9daSXin Li s->tt[s->cftab[uc]] |= (i << 8);
569*0ac9a9daSXin Li s->cftab[uc]++;
570*0ac9a9daSXin Li }
571*0ac9a9daSXin Li
572*0ac9a9daSXin Li s->tPos = s->tt[s->origPtr] >> 8;
573*0ac9a9daSXin Li s->nblock_used = 0;
574*0ac9a9daSXin Li if (s->blockRandomised) {
575*0ac9a9daSXin Li BZ_RAND_INIT_MASK;
576*0ac9a9daSXin Li BZ_GET_FAST(s->k0); s->nblock_used++;
577*0ac9a9daSXin Li BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
578*0ac9a9daSXin Li } else {
579*0ac9a9daSXin Li BZ_GET_FAST(s->k0); s->nblock_used++;
580*0ac9a9daSXin Li }
581*0ac9a9daSXin Li
582*0ac9a9daSXin Li }
583*0ac9a9daSXin Li
584*0ac9a9daSXin Li RETURN(BZ_OK);
585*0ac9a9daSXin Li
586*0ac9a9daSXin Li
587*0ac9a9daSXin Li
588*0ac9a9daSXin Li endhdr_2:
589*0ac9a9daSXin Li
590*0ac9a9daSXin Li GET_UCHAR(BZ_X_ENDHDR_2, uc);
591*0ac9a9daSXin Li if (uc != 0x72) RETURN(BZ_DATA_ERROR);
592*0ac9a9daSXin Li GET_UCHAR(BZ_X_ENDHDR_3, uc);
593*0ac9a9daSXin Li if (uc != 0x45) RETURN(BZ_DATA_ERROR);
594*0ac9a9daSXin Li GET_UCHAR(BZ_X_ENDHDR_4, uc);
595*0ac9a9daSXin Li if (uc != 0x38) RETURN(BZ_DATA_ERROR);
596*0ac9a9daSXin Li GET_UCHAR(BZ_X_ENDHDR_5, uc);
597*0ac9a9daSXin Li if (uc != 0x50) RETURN(BZ_DATA_ERROR);
598*0ac9a9daSXin Li GET_UCHAR(BZ_X_ENDHDR_6, uc);
599*0ac9a9daSXin Li if (uc != 0x90) RETURN(BZ_DATA_ERROR);
600*0ac9a9daSXin Li
601*0ac9a9daSXin Li s->storedCombinedCRC = 0;
602*0ac9a9daSXin Li GET_UCHAR(BZ_X_CCRC_1, uc);
603*0ac9a9daSXin Li s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
604*0ac9a9daSXin Li GET_UCHAR(BZ_X_CCRC_2, uc);
605*0ac9a9daSXin Li s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
606*0ac9a9daSXin Li GET_UCHAR(BZ_X_CCRC_3, uc);
607*0ac9a9daSXin Li s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
608*0ac9a9daSXin Li GET_UCHAR(BZ_X_CCRC_4, uc);
609*0ac9a9daSXin Li s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
610*0ac9a9daSXin Li
611*0ac9a9daSXin Li s->state = BZ_X_IDLE;
612*0ac9a9daSXin Li RETURN(BZ_STREAM_END);
613*0ac9a9daSXin Li
614*0ac9a9daSXin Li default: AssertH ( False, 4001 );
615*0ac9a9daSXin Li }
616*0ac9a9daSXin Li
617*0ac9a9daSXin Li AssertH ( False, 4002 );
618*0ac9a9daSXin Li
619*0ac9a9daSXin Li save_state_and_return:
620*0ac9a9daSXin Li
621*0ac9a9daSXin Li s->save_i = i;
622*0ac9a9daSXin Li s->save_j = j;
623*0ac9a9daSXin Li s->save_t = t;
624*0ac9a9daSXin Li s->save_alphaSize = alphaSize;
625*0ac9a9daSXin Li s->save_nGroups = nGroups;
626*0ac9a9daSXin Li s->save_nSelectors = nSelectors;
627*0ac9a9daSXin Li s->save_EOB = EOB;
628*0ac9a9daSXin Li s->save_groupNo = groupNo;
629*0ac9a9daSXin Li s->save_groupPos = groupPos;
630*0ac9a9daSXin Li s->save_nextSym = nextSym;
631*0ac9a9daSXin Li s->save_nblockMAX = nblockMAX;
632*0ac9a9daSXin Li s->save_nblock = nblock;
633*0ac9a9daSXin Li s->save_es = es;
634*0ac9a9daSXin Li s->save_N = N;
635*0ac9a9daSXin Li s->save_curr = curr;
636*0ac9a9daSXin Li s->save_zt = zt;
637*0ac9a9daSXin Li s->save_zn = zn;
638*0ac9a9daSXin Li s->save_zvec = zvec;
639*0ac9a9daSXin Li s->save_zj = zj;
640*0ac9a9daSXin Li s->save_gSel = gSel;
641*0ac9a9daSXin Li s->save_gMinlen = gMinlen;
642*0ac9a9daSXin Li s->save_gLimit = gLimit;
643*0ac9a9daSXin Li s->save_gBase = gBase;
644*0ac9a9daSXin Li s->save_gPerm = gPerm;
645*0ac9a9daSXin Li
646*0ac9a9daSXin Li return retVal;
647*0ac9a9daSXin Li }
648*0ac9a9daSXin Li
649*0ac9a9daSXin Li
650*0ac9a9daSXin Li /*-------------------------------------------------------------*/
651*0ac9a9daSXin Li /*--- end decompress.c ---*/
652*0ac9a9daSXin Li /*-------------------------------------------------------------*/
653