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