xref: /aosp_15_r20/external/bzip2/decompress.c (revision 0ac9a9daea5cce2e775d5da949508593e2ee9206)
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