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