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