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