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