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