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