1d86ed7fbStbbdev /*
2*b15aabb3Stbbdev     Copyright (c) 2005-2021 Intel Corporation
3d86ed7fbStbbdev 
4d86ed7fbStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
5d86ed7fbStbbdev     you may not use this file except in compliance with the License.
6d86ed7fbStbbdev     You may obtain a copy of the License at
7d86ed7fbStbbdev 
8d86ed7fbStbbdev         http://www.apache.org/licenses/LICENSE-2.0
9d86ed7fbStbbdev 
10d86ed7fbStbbdev     Unless required by applicable law or agreed to in writing, software
11d86ed7fbStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
12d86ed7fbStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d86ed7fbStbbdev     See the License for the specific language governing permissions and
14d86ed7fbStbbdev     limitations under the License.
15d86ed7fbStbbdev */
16d86ed7fbStbbdev 
17d86ed7fbStbbdev /*-------------------------------------------------------------*/
18d86ed7fbStbbdev /*--- Decompression machinery                               ---*/
19d86ed7fbStbbdev /*---                                        decompress.cpp ---*/
20d86ed7fbStbbdev /*-------------------------------------------------------------*/
21d86ed7fbStbbdev 
22d86ed7fbStbbdev /* ------------------------------------------------------------------
23d86ed7fbStbbdev    The original source for this example:
24d86ed7fbStbbdev    This file is part of bzip2/libbzip2, a program and library for
25d86ed7fbStbbdev    lossless, block-sorting data compression.
26d86ed7fbStbbdev 
27d86ed7fbStbbdev    bzip2/libbzip2 version 1.0.6 of 6 September 2010
28d86ed7fbStbbdev    Copyright (C) 1996-2010 Julian Seward <[email protected]>
29d86ed7fbStbbdev 
30d86ed7fbStbbdev    This program, "bzip2", the associated library "libbzip2", and all
31d86ed7fbStbbdev    documentation, are copyright (C) 1996-2010 Julian R Seward.  All
32d86ed7fbStbbdev    rights reserved.
33d86ed7fbStbbdev 
34d86ed7fbStbbdev    Redistribution and use in source and binary forms, with or without
35d86ed7fbStbbdev    modification, are permitted provided that the following conditions
36d86ed7fbStbbdev    are met:
37d86ed7fbStbbdev 
38d86ed7fbStbbdev    1. Redistributions of source code must retain the above copyright
39d86ed7fbStbbdev    notice, this list of conditions and the following disclaimer.
40d86ed7fbStbbdev 
41d86ed7fbStbbdev    2. The origin of this software must not be misrepresented; you must
42d86ed7fbStbbdev    not claim that you wrote the original software.  If you use this
43d86ed7fbStbbdev    software in a product, an acknowledgment in the product
44d86ed7fbStbbdev    documentation would be appreciated but is not required.
45d86ed7fbStbbdev 
46d86ed7fbStbbdev    3. Altered source versions must be plainly marked as such, and must
47d86ed7fbStbbdev    not be misrepresented as being the original software.
48d86ed7fbStbbdev 
49d86ed7fbStbbdev    4. The name of the author may not be used to endorse or promote
50d86ed7fbStbbdev    products derived from this software without specific prior written
51d86ed7fbStbbdev    permission.
52d86ed7fbStbbdev 
53d86ed7fbStbbdev    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
54d86ed7fbStbbdev    OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55d86ed7fbStbbdev    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56d86ed7fbStbbdev    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
57d86ed7fbStbbdev    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58d86ed7fbStbbdev    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
59d86ed7fbStbbdev    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60d86ed7fbStbbdev    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
61d86ed7fbStbbdev    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62d86ed7fbStbbdev    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63d86ed7fbStbbdev    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64d86ed7fbStbbdev 
65d86ed7fbStbbdev    Julian Seward, [email protected]
66d86ed7fbStbbdev    bzip2/libbzip2 version 1.0.6 of 6 September 2010
67d86ed7fbStbbdev    ------------------------------------------------------------------ */
68d86ed7fbStbbdev 
69d86ed7fbStbbdev #include "bzlib_private.hpp"
70d86ed7fbStbbdev 
71d86ed7fbStbbdev /*---------------------------------------------------*/
makeMaps_d(DState * s)72d86ed7fbStbbdev static void makeMaps_d(DState* s) {
73d86ed7fbStbbdev     Int32 i;
74d86ed7fbStbbdev     s->nInUse = 0;
75d86ed7fbStbbdev     for (i = 0; i < 256; i++)
76d86ed7fbStbbdev         if (s->inUse[i]) {
77d86ed7fbStbbdev             s->seqToUnseq[s->nInUse] = i;
78d86ed7fbStbbdev             s->nInUse++;
79d86ed7fbStbbdev         }
80d86ed7fbStbbdev }
81d86ed7fbStbbdev 
82d86ed7fbStbbdev /*---------------------------------------------------*/
83d86ed7fbStbbdev #define RETURN(rrr)                 \
84d86ed7fbStbbdev     {                               \
85d86ed7fbStbbdev         retVal = rrr;               \
86d86ed7fbStbbdev         goto save_state_and_return; \
87d86ed7fbStbbdev     };
88d86ed7fbStbbdev 
89d86ed7fbStbbdev #define GET_BITS(lll, vvv, nnn)                                                       \
90d86ed7fbStbbdev     case lll:                                                                         \
91d86ed7fbStbbdev         s->state = lll;                                                               \
92d86ed7fbStbbdev         while (True) {                                                                \
93d86ed7fbStbbdev             if (s->bsLive >= nnn) {                                                   \
94d86ed7fbStbbdev                 UInt32 v;                                                             \
95d86ed7fbStbbdev                 v = (s->bsBuff >> (s->bsLive - nnn)) & ((1 << nnn) - 1);              \
96d86ed7fbStbbdev                 s->bsLive -= nnn;                                                     \
97d86ed7fbStbbdev                 vvv = v;                                                              \
98d86ed7fbStbbdev                 break;                                                                \
99d86ed7fbStbbdev             }                                                                         \
100d86ed7fbStbbdev             if (s->strm->avail_in == 0)                                               \
101d86ed7fbStbbdev                 RETURN(BZ_OK);                                                        \
102d86ed7fbStbbdev             s->bsBuff = (s->bsBuff << 8) | ((UInt32)(*((UChar*)(s->strm->next_in)))); \
103d86ed7fbStbbdev             s->bsLive += 8;                                                           \
104d86ed7fbStbbdev             s->strm->next_in++;                                                       \
105d86ed7fbStbbdev             s->strm->avail_in--;                                                      \
106d86ed7fbStbbdev             s->strm->total_in_lo32++;                                                 \
107d86ed7fbStbbdev             if (s->strm->total_in_lo32 == 0)                                          \
108d86ed7fbStbbdev                 s->strm->total_in_hi32++;                                             \
109d86ed7fbStbbdev         }
110d86ed7fbStbbdev 
111d86ed7fbStbbdev #define GET_UCHAR(lll, uuu) GET_BITS(lll, uuu, 8)
112d86ed7fbStbbdev 
113d86ed7fbStbbdev #define GET_BIT(lll, uuu) GET_BITS(lll, uuu, 1)
114d86ed7fbStbbdev 
115d86ed7fbStbbdev /*---------------------------------------------------*/
116d86ed7fbStbbdev #define GET_MTF_VAL(label1, label2, lval)                                  \
117d86ed7fbStbbdev     {                                                                      \
118d86ed7fbStbbdev         if (groupPos == 0) {                                               \
119d86ed7fbStbbdev             groupNo++;                                                     \
120d86ed7fbStbbdev             if (groupNo >= nSelectors)                                     \
121d86ed7fbStbbdev                 RETURN(BZ_DATA_ERROR);                                     \
122d86ed7fbStbbdev             groupPos = BZ_G_SIZE;                                          \
123d86ed7fbStbbdev             gSel = s->selector[groupNo];                                   \
124d86ed7fbStbbdev             gMinlen = s->minLens[gSel];                                    \
125d86ed7fbStbbdev             gLimit = &(s->limit[gSel][0]);                                 \
126d86ed7fbStbbdev             gPerm = &(s->perm[gSel][0]);                                   \
127d86ed7fbStbbdev             gBase = &(s->base[gSel][0]);                                   \
128d86ed7fbStbbdev         }                                                                  \
129d86ed7fbStbbdev         groupPos--;                                                        \
130d86ed7fbStbbdev         zn = gMinlen;                                                      \
131d86ed7fbStbbdev         GET_BITS(label1, zvec, zn);                                        \
132d86ed7fbStbbdev         while (1) {                                                        \
133d86ed7fbStbbdev             if (zn > 20 /* the longest code */)                            \
134d86ed7fbStbbdev                 RETURN(BZ_DATA_ERROR);                                     \
135d86ed7fbStbbdev             if (zvec <= gLimit[zn])                                        \
136d86ed7fbStbbdev                 break;                                                     \
137d86ed7fbStbbdev             zn++;                                                          \
138d86ed7fbStbbdev             GET_BIT(label2, zj);                                           \
139d86ed7fbStbbdev             zvec = (zvec << 1) | zj;                                       \
140d86ed7fbStbbdev         };                                                                 \
141d86ed7fbStbbdev         if (zvec - gBase[zn] < 0 || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
142d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);                                         \
143d86ed7fbStbbdev         lval = gPerm[zvec - gBase[zn]];                                    \
144d86ed7fbStbbdev     }
145d86ed7fbStbbdev 
146d86ed7fbStbbdev /*---------------------------------------------------*/
BZ2_decompress(DState * s)147d86ed7fbStbbdev Int32 BZ2_decompress(DState* s) {
148d86ed7fbStbbdev     UChar uc;
149d86ed7fbStbbdev     Int32 retVal;
150d86ed7fbStbbdev     Int32 minLen, maxLen;
151d86ed7fbStbbdev     bz_stream* strm = s->strm;
152d86ed7fbStbbdev 
153d86ed7fbStbbdev     /* stuff that needs to be saved/restored */
154d86ed7fbStbbdev     Int32 i;
155d86ed7fbStbbdev     Int32 j;
156d86ed7fbStbbdev     Int32 t;
157d86ed7fbStbbdev     Int32 alphaSize;
158d86ed7fbStbbdev     Int32 nGroups;
159d86ed7fbStbbdev     Int32 nSelectors;
160d86ed7fbStbbdev     Int32 EOB;
161d86ed7fbStbbdev     Int32 groupNo;
162d86ed7fbStbbdev     Int32 groupPos;
163d86ed7fbStbbdev     Int32 nextSym;
164d86ed7fbStbbdev     Int32 nblockMAX;
165d86ed7fbStbbdev     Int32 nblock;
166d86ed7fbStbbdev     Int32 es;
167d86ed7fbStbbdev     Int32 N;
168d86ed7fbStbbdev     Int32 curr;
169d86ed7fbStbbdev     Int32 zt;
170d86ed7fbStbbdev     Int32 zn;
171d86ed7fbStbbdev     Int32 zvec;
172d86ed7fbStbbdev     Int32 zj;
173d86ed7fbStbbdev     Int32 gSel;
174d86ed7fbStbbdev     Int32 gMinlen;
175d86ed7fbStbbdev     Int32* gLimit;
176d86ed7fbStbbdev     Int32* gBase;
177d86ed7fbStbbdev     Int32* gPerm;
178d86ed7fbStbbdev 
179d86ed7fbStbbdev     if (s->state == BZ_X_MAGIC_1) {
180d86ed7fbStbbdev         /*initialise the save area*/
181d86ed7fbStbbdev         s->save_i = 0;
182d86ed7fbStbbdev         s->save_j = 0;
183d86ed7fbStbbdev         s->save_t = 0;
184d86ed7fbStbbdev         s->save_alphaSize = 0;
185d86ed7fbStbbdev         s->save_nGroups = 0;
186d86ed7fbStbbdev         s->save_nSelectors = 0;
187d86ed7fbStbbdev         s->save_EOB = 0;
188d86ed7fbStbbdev         s->save_groupNo = 0;
189d86ed7fbStbbdev         s->save_groupPos = 0;
190d86ed7fbStbbdev         s->save_nextSym = 0;
191d86ed7fbStbbdev         s->save_nblockMAX = 0;
192d86ed7fbStbbdev         s->save_nblock = 0;
193d86ed7fbStbbdev         s->save_es = 0;
194d86ed7fbStbbdev         s->save_N = 0;
195d86ed7fbStbbdev         s->save_curr = 0;
196d86ed7fbStbbdev         s->save_zt = 0;
197d86ed7fbStbbdev         s->save_zn = 0;
198d86ed7fbStbbdev         s->save_zvec = 0;
199d86ed7fbStbbdev         s->save_zj = 0;
200d86ed7fbStbbdev         s->save_gSel = 0;
201d86ed7fbStbbdev         s->save_gMinlen = 0;
202d86ed7fbStbbdev         s->save_gLimit = nullptr;
203d86ed7fbStbbdev         s->save_gBase = nullptr;
204d86ed7fbStbbdev         s->save_gPerm = nullptr;
205d86ed7fbStbbdev     }
206d86ed7fbStbbdev 
207d86ed7fbStbbdev     /*restore from the save area*/
208d86ed7fbStbbdev     i = s->save_i;
209d86ed7fbStbbdev     j = s->save_j;
210d86ed7fbStbbdev     t = s->save_t;
211d86ed7fbStbbdev     alphaSize = s->save_alphaSize;
212d86ed7fbStbbdev     nGroups = s->save_nGroups;
213d86ed7fbStbbdev     nSelectors = s->save_nSelectors;
214d86ed7fbStbbdev     EOB = s->save_EOB;
215d86ed7fbStbbdev     groupNo = s->save_groupNo;
216d86ed7fbStbbdev     groupPos = s->save_groupPos;
217d86ed7fbStbbdev     nextSym = s->save_nextSym;
218d86ed7fbStbbdev     nblockMAX = s->save_nblockMAX;
219d86ed7fbStbbdev     nblock = s->save_nblock;
220d86ed7fbStbbdev     es = s->save_es;
221d86ed7fbStbbdev     N = s->save_N;
222d86ed7fbStbbdev     curr = s->save_curr;
223d86ed7fbStbbdev     zt = s->save_zt;
224d86ed7fbStbbdev     zn = s->save_zn;
225d86ed7fbStbbdev     zvec = s->save_zvec;
226d86ed7fbStbbdev     zj = s->save_zj;
227d86ed7fbStbbdev     gSel = s->save_gSel;
228d86ed7fbStbbdev     gMinlen = s->save_gMinlen;
229d86ed7fbStbbdev     gLimit = s->save_gLimit;
230d86ed7fbStbbdev     gBase = s->save_gBase;
231d86ed7fbStbbdev     gPerm = s->save_gPerm;
232d86ed7fbStbbdev 
233d86ed7fbStbbdev     retVal = BZ_OK;
234d86ed7fbStbbdev 
235d86ed7fbStbbdev     switch (s->state) {
236d86ed7fbStbbdev         GET_UCHAR(BZ_X_MAGIC_1, uc);
237d86ed7fbStbbdev         if (uc != BZ_HDR_B)
238d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR_MAGIC);
239d86ed7fbStbbdev 
240d86ed7fbStbbdev         GET_UCHAR(BZ_X_MAGIC_2, uc);
241d86ed7fbStbbdev         if (uc != BZ_HDR_Z)
242d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR_MAGIC);
243d86ed7fbStbbdev 
244d86ed7fbStbbdev         GET_UCHAR(BZ_X_MAGIC_3, uc)
245d86ed7fbStbbdev         if (uc != BZ_HDR_h)
246d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR_MAGIC);
247d86ed7fbStbbdev 
248d86ed7fbStbbdev         GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
249d86ed7fbStbbdev         if (s->blockSize100k < (BZ_HDR_0 + 1) || s->blockSize100k > (BZ_HDR_0 + 9))
250d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR_MAGIC);
251d86ed7fbStbbdev         s->blockSize100k -= BZ_HDR_0;
252d86ed7fbStbbdev 
253d86ed7fbStbbdev         if (s->smallDecompress) {
254d86ed7fbStbbdev             s->ll16 = (UInt16*)BZALLOC(s->blockSize100k * 100000 * sizeof(UInt16));
255d86ed7fbStbbdev             s->ll4 = (UChar*)BZALLOC(((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar));
256d86ed7fbStbbdev             if (s->ll16 == nullptr || s->ll4 == nullptr)
257d86ed7fbStbbdev                 RETURN(BZ_MEM_ERROR);
258d86ed7fbStbbdev         }
259d86ed7fbStbbdev         else {
260d86ed7fbStbbdev             s->tt = (UInt32*)BZALLOC(s->blockSize100k * 100000 * sizeof(Int32));
261d86ed7fbStbbdev             if (s->tt == nullptr)
262d86ed7fbStbbdev                 RETURN(BZ_MEM_ERROR);
263d86ed7fbStbbdev         }
264d86ed7fbStbbdev 
265d86ed7fbStbbdev         GET_UCHAR(BZ_X_BLKHDR_1, uc);
266d86ed7fbStbbdev 
267d86ed7fbStbbdev         if (uc == 0x17)
268d86ed7fbStbbdev             goto endhdr_2;
269d86ed7fbStbbdev         if (uc != 0x31)
270d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
271d86ed7fbStbbdev         GET_UCHAR(BZ_X_BLKHDR_2, uc);
272d86ed7fbStbbdev         if (uc != 0x41)
273d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
274d86ed7fbStbbdev         GET_UCHAR(BZ_X_BLKHDR_3, uc);
275d86ed7fbStbbdev         if (uc != 0x59)
276d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
277d86ed7fbStbbdev         GET_UCHAR(BZ_X_BLKHDR_4, uc);
278d86ed7fbStbbdev         if (uc != 0x26)
279d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
280d86ed7fbStbbdev         GET_UCHAR(BZ_X_BLKHDR_5, uc);
281d86ed7fbStbbdev         if (uc != 0x53)
282d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
283d86ed7fbStbbdev         GET_UCHAR(BZ_X_BLKHDR_6, uc);
284d86ed7fbStbbdev         if (uc != 0x59)
285d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
286d86ed7fbStbbdev 
287d86ed7fbStbbdev         s->currBlockNo++;
288d86ed7fbStbbdev         if (s->verbosity >= 2)
289d86ed7fbStbbdev             VPrintf1("\n    [%d: huff+mtf ", s->currBlockNo);
290d86ed7fbStbbdev 
291d86ed7fbStbbdev         s->storedBlockCRC = 0;
292d86ed7fbStbbdev         GET_UCHAR(BZ_X_BCRC_1, uc);
293d86ed7fbStbbdev         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
294d86ed7fbStbbdev         GET_UCHAR(BZ_X_BCRC_2, uc);
295d86ed7fbStbbdev         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
296d86ed7fbStbbdev         GET_UCHAR(BZ_X_BCRC_3, uc);
297d86ed7fbStbbdev         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
298d86ed7fbStbbdev         GET_UCHAR(BZ_X_BCRC_4, uc);
299d86ed7fbStbbdev         s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
300d86ed7fbStbbdev 
301d86ed7fbStbbdev         GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
302d86ed7fbStbbdev 
303d86ed7fbStbbdev         s->origPtr = 0;
304d86ed7fbStbbdev         GET_UCHAR(BZ_X_ORIGPTR_1, uc);
305d86ed7fbStbbdev         s->origPtr = (s->origPtr << 8) | ((Int32)uc);
306d86ed7fbStbbdev         GET_UCHAR(BZ_X_ORIGPTR_2, uc);
307d86ed7fbStbbdev         s->origPtr = (s->origPtr << 8) | ((Int32)uc);
308d86ed7fbStbbdev         GET_UCHAR(BZ_X_ORIGPTR_3, uc);
309d86ed7fbStbbdev         s->origPtr = (s->origPtr << 8) | ((Int32)uc);
310d86ed7fbStbbdev 
311d86ed7fbStbbdev         if (s->origPtr < 0)
312d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
313d86ed7fbStbbdev         if (s->origPtr > 10 + 100000 * s->blockSize100k)
314d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
315d86ed7fbStbbdev 
316d86ed7fbStbbdev         /*--- Receive the mapping table ---*/
317d86ed7fbStbbdev         for (i = 0; i < 16; i++) {
318d86ed7fbStbbdev             GET_BIT(BZ_X_MAPPING_1, uc);
319d86ed7fbStbbdev             if (uc == 1)
320d86ed7fbStbbdev                 s->inUse16[i] = True;
321d86ed7fbStbbdev             else
322d86ed7fbStbbdev                 s->inUse16[i] = False;
323d86ed7fbStbbdev         }
324d86ed7fbStbbdev 
325d86ed7fbStbbdev         for (i = 0; i < 256; i++)
326d86ed7fbStbbdev             s->inUse[i] = False;
327d86ed7fbStbbdev 
328d86ed7fbStbbdev         for (i = 0; i < 16; i++)
329d86ed7fbStbbdev             if (s->inUse16[i])
330d86ed7fbStbbdev                 for (j = 0; j < 16; j++) {
331d86ed7fbStbbdev                     GET_BIT(BZ_X_MAPPING_2, uc);
332d86ed7fbStbbdev                     if (uc == 1)
333d86ed7fbStbbdev                         s->inUse[i * 16 + j] = True;
334d86ed7fbStbbdev                 }
335d86ed7fbStbbdev         makeMaps_d(s);
336d86ed7fbStbbdev         if (s->nInUse == 0)
337d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
338d86ed7fbStbbdev         alphaSize = s->nInUse + 2;
339d86ed7fbStbbdev 
340d86ed7fbStbbdev         /*--- Now the selectors ---*/
341d86ed7fbStbbdev         GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
342d86ed7fbStbbdev         if (nGroups < 2 || nGroups > 6)
343d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
344d86ed7fbStbbdev         GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
345d86ed7fbStbbdev         if (nSelectors < 1)
346d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
347d86ed7fbStbbdev         for (i = 0; i < nSelectors; i++) {
348d86ed7fbStbbdev             j = 0;
349d86ed7fbStbbdev             while (True) {
350d86ed7fbStbbdev                 GET_BIT(BZ_X_SELECTOR_3, uc);
351d86ed7fbStbbdev                 if (uc == 0)
352d86ed7fbStbbdev                     break;
353d86ed7fbStbbdev                 j++;
354d86ed7fbStbbdev                 if (j >= nGroups)
355d86ed7fbStbbdev                     RETURN(BZ_DATA_ERROR);
356d86ed7fbStbbdev             }
357d86ed7fbStbbdev             s->selectorMtf[i] = j;
358d86ed7fbStbbdev         }
359d86ed7fbStbbdev 
360d86ed7fbStbbdev         /*--- Undo the MTF values for the selectors. ---*/
361d86ed7fbStbbdev         {
362d86ed7fbStbbdev             UChar pos[BZ_N_GROUPS], tmp, v;
363d86ed7fbStbbdev             for (i = 0; i < nGroups; i++)
364d86ed7fbStbbdev                 pos[i] = i;
365d86ed7fbStbbdev 
366d86ed7fbStbbdev             for (i = 0; i < nSelectors; i++) {
367d86ed7fbStbbdev                 v = s->selectorMtf[i];
368d86ed7fbStbbdev                 tmp = pos[v];
369d86ed7fbStbbdev                 while (v > 0) {
370d86ed7fbStbbdev                     pos[v] = pos[v - 1];
371d86ed7fbStbbdev                     v--;
372d86ed7fbStbbdev                 }
373d86ed7fbStbbdev                 pos[0] = tmp;
374d86ed7fbStbbdev                 s->selector[i] = tmp;
375d86ed7fbStbbdev             }
376d86ed7fbStbbdev         }
377d86ed7fbStbbdev 
378d86ed7fbStbbdev         /*--- Now the coding tables ---*/
379d86ed7fbStbbdev         for (j = 0; j < nGroups; j++) {
380d86ed7fbStbbdev             GET_BITS(BZ_X_CODING_1, curr, 5);
381d86ed7fbStbbdev             for (i = 0; i < alphaSize; i++) {
382d86ed7fbStbbdev                 while (True) {
383d86ed7fbStbbdev                     if (curr < 1 || curr > 20)
384d86ed7fbStbbdev                         RETURN(BZ_DATA_ERROR);
385d86ed7fbStbbdev                     GET_BIT(BZ_X_CODING_2, uc);
386d86ed7fbStbbdev                     if (uc == 0)
387d86ed7fbStbbdev                         break;
388d86ed7fbStbbdev                     GET_BIT(BZ_X_CODING_3, uc);
389d86ed7fbStbbdev                     if (uc == 0)
390d86ed7fbStbbdev                         curr++;
391d86ed7fbStbbdev                     else
392d86ed7fbStbbdev                         curr--;
393d86ed7fbStbbdev                 }
394d86ed7fbStbbdev                 s->len[j][i] = curr;
395d86ed7fbStbbdev             }
396d86ed7fbStbbdev         }
397d86ed7fbStbbdev 
398d86ed7fbStbbdev         /*--- Create the Huffman decoding tables ---*/
399d86ed7fbStbbdev         for (j = 0; j < nGroups; j++) {
400d86ed7fbStbbdev             minLen = 32;
401d86ed7fbStbbdev             maxLen = 0;
402d86ed7fbStbbdev             for (i = 0; i < alphaSize; i++) {
403d86ed7fbStbbdev                 if (s->len[j][i] > maxLen)
404d86ed7fbStbbdev                     maxLen = s->len[j][i];
405d86ed7fbStbbdev                 if (s->len[j][i] < minLen)
406d86ed7fbStbbdev                     minLen = s->len[j][i];
407d86ed7fbStbbdev             }
408d86ed7fbStbbdev             BZ2_hbCreateDecodeTables(&(s->limit[j][0]),
409d86ed7fbStbbdev                                      &(s->base[j][0]),
410d86ed7fbStbbdev                                      &(s->perm[j][0]),
411d86ed7fbStbbdev                                      &(s->len[j][0]),
412d86ed7fbStbbdev                                      minLen,
413d86ed7fbStbbdev                                      maxLen,
414d86ed7fbStbbdev                                      alphaSize);
415d86ed7fbStbbdev             s->minLens[j] = minLen;
416d86ed7fbStbbdev         }
417d86ed7fbStbbdev 
418d86ed7fbStbbdev         /*--- Now the MTF values ---*/
419d86ed7fbStbbdev 
420d86ed7fbStbbdev         EOB = s->nInUse + 1;
421d86ed7fbStbbdev         nblockMAX = 100000 * s->blockSize100k;
422d86ed7fbStbbdev         groupNo = -1;
423d86ed7fbStbbdev         groupPos = 0;
424d86ed7fbStbbdev 
425d86ed7fbStbbdev         for (i = 0; i <= 255; i++)
426d86ed7fbStbbdev             s->unzftab[i] = 0;
427d86ed7fbStbbdev 
428d86ed7fbStbbdev         /*-- MTF init --*/
429d86ed7fbStbbdev         {
430d86ed7fbStbbdev             Int32 l, j, k;
431d86ed7fbStbbdev             k = MTFA_SIZE - 1;
432d86ed7fbStbbdev             for (l = 256 / MTFL_SIZE - 1; l >= 0; l--) {
433d86ed7fbStbbdev                 for (j = MTFL_SIZE - 1; j >= 0; j--) {
434d86ed7fbStbbdev                     s->mtfa[k] = (UChar)(l * MTFL_SIZE + j);
435d86ed7fbStbbdev                     k--;
436d86ed7fbStbbdev                 }
437d86ed7fbStbbdev                 s->mtfbase[l] = k + 1;
438d86ed7fbStbbdev             }
439d86ed7fbStbbdev         }
440d86ed7fbStbbdev         /*-- end MTF init --*/
441d86ed7fbStbbdev 
442d86ed7fbStbbdev         nblock = 0;
443d86ed7fbStbbdev         GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
444d86ed7fbStbbdev 
445d86ed7fbStbbdev         while (True) {
446d86ed7fbStbbdev             if (nextSym == EOB)
447d86ed7fbStbbdev                 break;
448d86ed7fbStbbdev 
449d86ed7fbStbbdev             if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
450d86ed7fbStbbdev                 es = -1;
451d86ed7fbStbbdev                 N = 1;
452d86ed7fbStbbdev                 do {
453d86ed7fbStbbdev                     /* Check that N doesn't get too big, so that es doesn't
454d86ed7fbStbbdev                   go negative.  The maximum value that can be
455d86ed7fbStbbdev                   RUNA/RUNB encoded is equal to the block size (post
456d86ed7fbStbbdev                   the initial RLE), viz, 900k, so bounding N at 2
457d86ed7fbStbbdev                   million should guard against overflow without
458d86ed7fbStbbdev                   rejecting any legitimate inputs. */
459d86ed7fbStbbdev                     if (N >= 2 * 1024 * 1024)
460d86ed7fbStbbdev                         RETURN(BZ_DATA_ERROR);
461d86ed7fbStbbdev                     if (nextSym == BZ_RUNA)
462d86ed7fbStbbdev                         es = es + (0 + 1) * N;
463d86ed7fbStbbdev                     else if (nextSym == BZ_RUNB)
464d86ed7fbStbbdev                         es = es + (1 + 1) * N;
465d86ed7fbStbbdev                     N = N * 2;
466d86ed7fbStbbdev                     GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
467d86ed7fbStbbdev                 } while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
468d86ed7fbStbbdev 
469d86ed7fbStbbdev                 es++;
470d86ed7fbStbbdev                 uc = s->seqToUnseq[s->mtfa[s->mtfbase[0]]];
471d86ed7fbStbbdev                 s->unzftab[uc] += es;
472d86ed7fbStbbdev 
473d86ed7fbStbbdev                 if (s->smallDecompress)
474d86ed7fbStbbdev                     while (es > 0) {
475d86ed7fbStbbdev                         if (nblock >= nblockMAX)
476d86ed7fbStbbdev                             RETURN(BZ_DATA_ERROR);
477d86ed7fbStbbdev                         s->ll16[nblock] = (UInt16)uc;
478d86ed7fbStbbdev                         nblock++;
479d86ed7fbStbbdev                         es--;
480d86ed7fbStbbdev                     }
481d86ed7fbStbbdev                 else
482d86ed7fbStbbdev                     while (es > 0) {
483d86ed7fbStbbdev                         if (nblock >= nblockMAX)
484d86ed7fbStbbdev                             RETURN(BZ_DATA_ERROR);
485d86ed7fbStbbdev                         s->tt[nblock] = (UInt32)uc;
486d86ed7fbStbbdev                         nblock++;
487d86ed7fbStbbdev                         es--;
488d86ed7fbStbbdev                     };
489d86ed7fbStbbdev 
490d86ed7fbStbbdev                 continue;
491d86ed7fbStbbdev             }
492d86ed7fbStbbdev             else {
493d86ed7fbStbbdev                 if (nblock >= nblockMAX)
494d86ed7fbStbbdev                     RETURN(BZ_DATA_ERROR);
495d86ed7fbStbbdev 
496d86ed7fbStbbdev                 /*-- uc = MTF ( nextSym-1 ) --*/
497d86ed7fbStbbdev                 {
498d86ed7fbStbbdev                     Int32 i, j, k, l, lno, off;
499d86ed7fbStbbdev                     UInt32 nn;
500d86ed7fbStbbdev                     nn = (UInt32)(nextSym - 1);
501d86ed7fbStbbdev 
502d86ed7fbStbbdev                     if (nn < MTFL_SIZE) {
503d86ed7fbStbbdev                         /* avoid general-case expense */
504d86ed7fbStbbdev                         l = s->mtfbase[0];
505d86ed7fbStbbdev                         uc = s->mtfa[l + nn];
506d86ed7fbStbbdev                         while (nn > 3) {
507d86ed7fbStbbdev                             Int32 z = l + nn;
508d86ed7fbStbbdev                             s->mtfa[(z)] = s->mtfa[(z)-1];
509d86ed7fbStbbdev                             s->mtfa[(z)-1] = s->mtfa[(z)-2];
510d86ed7fbStbbdev                             s->mtfa[(z)-2] = s->mtfa[(z)-3];
511d86ed7fbStbbdev                             s->mtfa[(z)-3] = s->mtfa[(z)-4];
512d86ed7fbStbbdev                             nn -= 4;
513d86ed7fbStbbdev                         }
514d86ed7fbStbbdev                         while (nn > 0) {
515d86ed7fbStbbdev                             s->mtfa[(l + nn)] = s->mtfa[(l + nn) - 1];
516d86ed7fbStbbdev                             nn--;
517d86ed7fbStbbdev                         };
518d86ed7fbStbbdev                         s->mtfa[l] = uc;
519d86ed7fbStbbdev                     }
520d86ed7fbStbbdev                     else {
521d86ed7fbStbbdev                         /* general case */
522d86ed7fbStbbdev                         lno = nn / MTFL_SIZE;
523d86ed7fbStbbdev                         off = nn % MTFL_SIZE;
524d86ed7fbStbbdev                         l = s->mtfbase[lno] + off;
525d86ed7fbStbbdev                         uc = s->mtfa[l];
526d86ed7fbStbbdev                         while (l > s->mtfbase[lno]) {
527d86ed7fbStbbdev                             s->mtfa[l] = s->mtfa[l - 1];
528d86ed7fbStbbdev                             l--;
529d86ed7fbStbbdev                         };
530d86ed7fbStbbdev                         s->mtfbase[lno]++;
531d86ed7fbStbbdev                         while (lno > 0) {
532d86ed7fbStbbdev                             s->mtfbase[lno]--;
533d86ed7fbStbbdev                             s->mtfa[s->mtfbase[lno]] = s->mtfa[s->mtfbase[lno - 1] + MTFL_SIZE - 1];
534d86ed7fbStbbdev                             lno--;
535d86ed7fbStbbdev                         }
536d86ed7fbStbbdev                         s->mtfbase[0]--;
537d86ed7fbStbbdev                         s->mtfa[s->mtfbase[0]] = uc;
538d86ed7fbStbbdev                         if (s->mtfbase[0] == 0) {
539d86ed7fbStbbdev                             k = MTFA_SIZE - 1;
540d86ed7fbStbbdev                             for (i = 256 / MTFL_SIZE - 1; i >= 0; i--) {
541d86ed7fbStbbdev                                 for (j = MTFL_SIZE - 1; j >= 0; j--) {
542d86ed7fbStbbdev                                     s->mtfa[k] = s->mtfa[s->mtfbase[i] + j];
543d86ed7fbStbbdev                                     k--;
544d86ed7fbStbbdev                                 }
545d86ed7fbStbbdev                                 s->mtfbase[i] = k + 1;
546d86ed7fbStbbdev                             }
547d86ed7fbStbbdev                         }
548d86ed7fbStbbdev                     }
549d86ed7fbStbbdev                 }
550d86ed7fbStbbdev                 /*-- end uc = MTF ( nextSym-1 ) --*/
551d86ed7fbStbbdev 
552d86ed7fbStbbdev                 s->unzftab[s->seqToUnseq[uc]]++;
553d86ed7fbStbbdev                 if (s->smallDecompress)
554d86ed7fbStbbdev                     s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]);
555d86ed7fbStbbdev                 else
556d86ed7fbStbbdev                     s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
557d86ed7fbStbbdev                 nblock++;
558d86ed7fbStbbdev 
559d86ed7fbStbbdev                 GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
560d86ed7fbStbbdev                 continue;
561d86ed7fbStbbdev             }
562d86ed7fbStbbdev         }
563d86ed7fbStbbdev 
564d86ed7fbStbbdev         /* Now we know what nblock is, we can do a better sanity
565d86ed7fbStbbdev          check on s->origPtr.
566d86ed7fbStbbdev       */
567d86ed7fbStbbdev         if (s->origPtr < 0 || s->origPtr >= nblock)
568d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
569d86ed7fbStbbdev 
570d86ed7fbStbbdev         /*-- Set up cftab to facilitate generation of T^(-1) --*/
571d86ed7fbStbbdev         /* Check: unzftab entries in range. */
572d86ed7fbStbbdev         for (i = 0; i <= 255; i++) {
573d86ed7fbStbbdev             if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
574d86ed7fbStbbdev                 RETURN(BZ_DATA_ERROR);
575d86ed7fbStbbdev         }
576d86ed7fbStbbdev         /* Actually generate cftab. */
577d86ed7fbStbbdev         s->cftab[0] = 0;
578d86ed7fbStbbdev         for (i = 1; i <= 256; i++)
579d86ed7fbStbbdev             s->cftab[i] = s->unzftab[i - 1];
580d86ed7fbStbbdev         for (i = 1; i <= 256; i++)
581d86ed7fbStbbdev             s->cftab[i] += s->cftab[i - 1];
582d86ed7fbStbbdev         /* Check: cftab entries in range. */
583d86ed7fbStbbdev         for (i = 0; i <= 256; i++) {
584d86ed7fbStbbdev             if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
585d86ed7fbStbbdev                 /* s->cftab[i] can legitimately be == nblock */
586d86ed7fbStbbdev                 RETURN(BZ_DATA_ERROR);
587d86ed7fbStbbdev             }
588d86ed7fbStbbdev         }
589d86ed7fbStbbdev         /* Check: cftab entries non-descending. */
590d86ed7fbStbbdev         for (i = 1; i <= 256; i++) {
591d86ed7fbStbbdev             if (s->cftab[i - 1] > s->cftab[i]) {
592d86ed7fbStbbdev                 RETURN(BZ_DATA_ERROR);
593d86ed7fbStbbdev             }
594d86ed7fbStbbdev         }
595d86ed7fbStbbdev 
596d86ed7fbStbbdev         s->state_out_len = 0;
597d86ed7fbStbbdev         s->state_out_ch = 0;
598d86ed7fbStbbdev         BZ_INITIALISE_CRC(s->calculatedBlockCRC);
599d86ed7fbStbbdev         s->state = BZ_X_OUTPUT;
600d86ed7fbStbbdev         if (s->verbosity >= 2)
601d86ed7fbStbbdev             VPrintf0("rt+rld");
602d86ed7fbStbbdev 
603d86ed7fbStbbdev         if (s->smallDecompress) {
604d86ed7fbStbbdev             /*-- Make a copy of cftab, used in generation of T --*/
605d86ed7fbStbbdev             for (i = 0; i <= 256; i++)
606d86ed7fbStbbdev                 s->cftabCopy[i] = s->cftab[i];
607d86ed7fbStbbdev 
608d86ed7fbStbbdev             /*-- compute the T vector --*/
609d86ed7fbStbbdev             for (i = 0; i < nblock; i++) {
610d86ed7fbStbbdev                 uc = (UChar)(s->ll16[i]);
611d86ed7fbStbbdev                 SET_LL(i, s->cftabCopy[uc]);
612d86ed7fbStbbdev                 s->cftabCopy[uc]++;
613d86ed7fbStbbdev             }
614d86ed7fbStbbdev 
615d86ed7fbStbbdev             /*-- Compute T^(-1) by pointer reversal on T --*/
616d86ed7fbStbbdev             i = s->origPtr;
617d86ed7fbStbbdev             j = GET_LL(i);
618d86ed7fbStbbdev             do {
619d86ed7fbStbbdev                 Int32 tmp = GET_LL(j);
620d86ed7fbStbbdev                 SET_LL(j, i);
621d86ed7fbStbbdev                 i = j;
622d86ed7fbStbbdev                 j = tmp;
623d86ed7fbStbbdev             } while (i != s->origPtr);
624d86ed7fbStbbdev 
625d86ed7fbStbbdev             s->tPos = s->origPtr;
626d86ed7fbStbbdev             s->nblock_used = 0;
627d86ed7fbStbbdev             if (s->blockRandomised) {
628d86ed7fbStbbdev                 BZ_RAND_INIT_MASK;
629d86ed7fbStbbdev                 BZ_GET_SMALL(s->k0);
630d86ed7fbStbbdev                 s->nblock_used++;
631d86ed7fbStbbdev                 BZ_RAND_UPD_MASK;
632d86ed7fbStbbdev                 s->k0 ^= BZ_RAND_MASK;
633d86ed7fbStbbdev             }
634d86ed7fbStbbdev             else {
635d86ed7fbStbbdev                 BZ_GET_SMALL(s->k0);
636d86ed7fbStbbdev                 s->nblock_used++;
637d86ed7fbStbbdev             }
638d86ed7fbStbbdev         }
639d86ed7fbStbbdev         else {
640d86ed7fbStbbdev             /*-- compute the T^(-1) vector --*/
641d86ed7fbStbbdev             for (i = 0; i < nblock; i++) {
642d86ed7fbStbbdev                 uc = (UChar)(s->tt[i] & 0xff);
643d86ed7fbStbbdev                 s->tt[s->cftab[uc]] |= (i << 8);
644d86ed7fbStbbdev                 s->cftab[uc]++;
645d86ed7fbStbbdev             }
646d86ed7fbStbbdev 
647d86ed7fbStbbdev             s->tPos = s->tt[s->origPtr] >> 8;
648d86ed7fbStbbdev             s->nblock_used = 0;
649d86ed7fbStbbdev             if (s->blockRandomised) {
650d86ed7fbStbbdev                 BZ_RAND_INIT_MASK;
651d86ed7fbStbbdev                 BZ_GET_FAST(s->k0);
652d86ed7fbStbbdev                 s->nblock_used++;
653d86ed7fbStbbdev                 BZ_RAND_UPD_MASK;
654d86ed7fbStbbdev                 s->k0 ^= BZ_RAND_MASK;
655d86ed7fbStbbdev             }
656d86ed7fbStbbdev             else {
657d86ed7fbStbbdev                 BZ_GET_FAST(s->k0);
658d86ed7fbStbbdev                 s->nblock_used++;
659d86ed7fbStbbdev             }
660d86ed7fbStbbdev         }
661d86ed7fbStbbdev 
662d86ed7fbStbbdev         RETURN(BZ_OK);
663d86ed7fbStbbdev 
664d86ed7fbStbbdev     endhdr_2:
665d86ed7fbStbbdev 
666d86ed7fbStbbdev         GET_UCHAR(BZ_X_ENDHDR_2, uc);
667d86ed7fbStbbdev         if (uc != 0x72)
668d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
669d86ed7fbStbbdev         GET_UCHAR(BZ_X_ENDHDR_3, uc);
670d86ed7fbStbbdev         if (uc != 0x45)
671d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
672d86ed7fbStbbdev         GET_UCHAR(BZ_X_ENDHDR_4, uc);
673d86ed7fbStbbdev         if (uc != 0x38)
674d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
675d86ed7fbStbbdev         GET_UCHAR(BZ_X_ENDHDR_5, uc);
676d86ed7fbStbbdev         if (uc != 0x50)
677d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
678d86ed7fbStbbdev         GET_UCHAR(BZ_X_ENDHDR_6, uc);
679d86ed7fbStbbdev         if (uc != 0x90)
680d86ed7fbStbbdev             RETURN(BZ_DATA_ERROR);
681d86ed7fbStbbdev 
682d86ed7fbStbbdev         s->storedCombinedCRC = 0;
683d86ed7fbStbbdev         GET_UCHAR(BZ_X_CCRC_1, uc);
684d86ed7fbStbbdev         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
685d86ed7fbStbbdev         GET_UCHAR(BZ_X_CCRC_2, uc);
686d86ed7fbStbbdev         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
687d86ed7fbStbbdev         GET_UCHAR(BZ_X_CCRC_3, uc);
688d86ed7fbStbbdev         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
689d86ed7fbStbbdev         GET_UCHAR(BZ_X_CCRC_4, uc);
690d86ed7fbStbbdev         s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
691d86ed7fbStbbdev 
692d86ed7fbStbbdev         s->state = BZ_X_IDLE;
693d86ed7fbStbbdev         RETURN(BZ_STREAM_END);
694d86ed7fbStbbdev 
695d86ed7fbStbbdev         default: AssertH(False, 4001);
696d86ed7fbStbbdev     }
697d86ed7fbStbbdev 
698d86ed7fbStbbdev     AssertH(False, 4002);
699d86ed7fbStbbdev 
700d86ed7fbStbbdev save_state_and_return:
701d86ed7fbStbbdev 
702d86ed7fbStbbdev     s->save_i = i;
703d86ed7fbStbbdev     s->save_j = j;
704d86ed7fbStbbdev     s->save_t = t;
705d86ed7fbStbbdev     s->save_alphaSize = alphaSize;
706d86ed7fbStbbdev     s->save_nGroups = nGroups;
707d86ed7fbStbbdev     s->save_nSelectors = nSelectors;
708d86ed7fbStbbdev     s->save_EOB = EOB;
709d86ed7fbStbbdev     s->save_groupNo = groupNo;
710d86ed7fbStbbdev     s->save_groupPos = groupPos;
711d86ed7fbStbbdev     s->save_nextSym = nextSym;
712d86ed7fbStbbdev     s->save_nblockMAX = nblockMAX;
713d86ed7fbStbbdev     s->save_nblock = nblock;
714d86ed7fbStbbdev     s->save_es = es;
715d86ed7fbStbbdev     s->save_N = N;
716d86ed7fbStbbdev     s->save_curr = curr;
717d86ed7fbStbbdev     s->save_zt = zt;
718d86ed7fbStbbdev     s->save_zn = zn;
719d86ed7fbStbbdev     s->save_zvec = zvec;
720d86ed7fbStbbdev     s->save_zj = zj;
721d86ed7fbStbbdev     s->save_gSel = gSel;
722d86ed7fbStbbdev     s->save_gMinlen = gMinlen;
723d86ed7fbStbbdev     s->save_gLimit = gLimit;
724d86ed7fbStbbdev     s->save_gBase = gBase;
725d86ed7fbStbbdev     s->save_gPerm = gPerm;
726d86ed7fbStbbdev 
727d86ed7fbStbbdev     return retVal;
728d86ed7fbStbbdev }
729d86ed7fbStbbdev 
730d86ed7fbStbbdev /*-------------------------------------------------------------*/
731d86ed7fbStbbdev /*--- end                                      decompress.c ---*/
732d86ed7fbStbbdev /*-------------------------------------------------------------*/
733