1 /* $NetBSD: decompress.c,v 1.4 2019/07/21 11:52:14 maya 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.8 of 13 July 2019
14 Copyright (C) 1996-2019 Julian Seward <jseward@acm.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 > BZ_N_GROUPS) 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 /* Having more than BZ_MAX_SELECTORS doesn't make much sense
302 since they will never be used, but some implementations might
303 "round up" the number of selectors, so just ignore those. */
304 if (i < BZ_MAX_SELECTORS)
305 s->selectorMtf[i] = j;
306 }
307 if (nSelectors > BZ_MAX_SELECTORS)
308 nSelectors = BZ_MAX_SELECTORS;
309
310 /*--- Undo the MTF values for the selectors. ---*/
311 {
312 UChar pos[BZ_N_GROUPS], tmp, v;
313 for (v = 0; v < nGroups; v++) pos[v] = v;
314
315 for (i = 0; i < nSelectors; i++) {
316 v = s->selectorMtf[i];
317 tmp = pos[v];
318 while (v > 0) { pos[v] = pos[v-1]; v--; }
319 pos[0] = tmp;
320 s->selector[i] = tmp;
321 }
322 }
323
324 /*--- Now the coding tables ---*/
325 for (t = 0; t < nGroups; t++) {
326 GET_BITS(BZ_X_CODING_1, curr, 5);
327 for (i = 0; i < alphaSize; i++) {
328 while (True) {
329 if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
330 GET_BIT(BZ_X_CODING_2, uc);
331 if (uc == 0) break;
332 GET_BIT(BZ_X_CODING_3, uc);
333 if (uc == 0) curr++; else curr--;
334 }
335 s->len[t][i] = curr;
336 }
337 }
338
339 /*--- Create the Huffman decoding tables ---*/
340 for (t = 0; t < nGroups; t++) {
341 minLen = 32;
342 maxLen = 0;
343 for (i = 0; i < alphaSize; i++) {
344 if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
345 if (s->len[t][i] < minLen) minLen = s->len[t][i];
346 }
347 BZ2_hbCreateDecodeTables (
348 &(s->limit[t][0]),
349 &(s->base[t][0]),
350 &(s->perm[t][0]),
351 &(s->len[t][0]),
352 minLen, maxLen, alphaSize
353 );
354 s->minLens[t] = minLen;
355 }
356
357 /*--- Now the MTF values ---*/
358
359 EOB = s->nInUse+1;
360 nblockMAX = 100000 * s->blockSize100k;
361 groupNo = -1;
362 groupPos = 0;
363
364 for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
365
366 /*-- MTF init --*/
367 {
368 Int32 ii, jj, kk;
369 kk = MTFA_SIZE-1;
370 for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
371 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
372 s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
373 kk--;
374 }
375 s->mtfbase[ii] = kk + 1;
376 }
377 }
378 /*-- end MTF init --*/
379
380 nblock = 0;
381 GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
382
383 while (True) {
384
385 if (nextSym == EOB) break;
386
387 if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
388
389 es = -1;
390 N = 1;
391 do {
392 /* Check that N doesn't get too big, so that es doesn't
393 go negative. The maximum value that can be
394 RUNA/RUNB encoded is equal to the block size (post
395 the initial RLE), viz, 900k, so bounding N at 2
396 million should guard against overflow without
397 rejecting any legitimate inputs. */
398 if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
399 if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
400 if (nextSym == BZ_RUNB) es = es + (1+1) * N;
401 N = N * 2;
402 GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
403 }
404 while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
405
406 es++;
407 uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
408 s->unzftab[uc] += es;
409
410 if (s->smallDecompress)
411 while (es > 0) {
412 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
413 s->ll16[nblock] = (UInt16)uc;
414 nblock++;
415 es--;
416 }
417 else
418 while (es > 0) {
419 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
420 s->tt[nblock] = (UInt32)uc;
421 nblock++;
422 es--;
423 };
424
425 continue;
426
427 } else {
428
429 if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
430
431 /*-- uc = MTF ( nextSym-1 ) --*/
432 {
433 Int32 ii, jj, kk, pp, lno, off;
434 UInt32 nn;
435 nn = (UInt32)(nextSym - 1);
436
437 if (nn < MTFL_SIZE) {
438 /* avoid general-case expense */
439 pp = s->mtfbase[0];
440 uc = s->mtfa[pp+nn];
441 while (nn > 3) {
442 Int32 z = pp+nn;
443 s->mtfa[(z) ] = s->mtfa[(z)-1];
444 s->mtfa[(z)-1] = s->mtfa[(z)-2];
445 s->mtfa[(z)-2] = s->mtfa[(z)-3];
446 s->mtfa[(z)-3] = s->mtfa[(z)-4];
447 nn -= 4;
448 }
449 while (nn > 0) {
450 s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
451 };
452 s->mtfa[pp] = uc;
453 } else {
454 /* general case */
455 lno = nn / MTFL_SIZE;
456 off = nn % MTFL_SIZE;
457 pp = s->mtfbase[lno] + off;
458 uc = s->mtfa[pp];
459 while (pp > s->mtfbase[lno]) {
460 s->mtfa[pp] = s->mtfa[pp-1]; pp--;
461 };
462 s->mtfbase[lno]++;
463 while (lno > 0) {
464 s->mtfbase[lno]--;
465 s->mtfa[s->mtfbase[lno]]
466 = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
467 lno--;
468 }
469 s->mtfbase[0]--;
470 s->mtfa[s->mtfbase[0]] = uc;
471 if (s->mtfbase[0] == 0) {
472 kk = MTFA_SIZE-1;
473 for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
474 for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
475 s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
476 kk--;
477 }
478 s->mtfbase[ii] = kk + 1;
479 }
480 }
481 }
482 }
483 /*-- end uc = MTF ( nextSym-1 ) --*/
484
485 s->unzftab[s->seqToUnseq[uc]]++;
486 if (s->smallDecompress)
487 s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
488 s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
489 nblock++;
490
491 GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
492 continue;
493 }
494 }
495
496 /* Now we know what nblock is, we can do a better sanity
497 check on s->origPtr.
498 */
499 if (s->origPtr < 0 || s->origPtr >= nblock)
500 RETURN(BZ_DATA_ERROR);
501
502 /*-- Set up cftab to facilitate generation of T^(-1) --*/
503 /* Check: unzftab entries in range. */
504 for (i = 0; i <= 255; i++) {
505 if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
506 RETURN(BZ_DATA_ERROR);
507 }
508 /* Actually generate cftab. */
509 s->cftab[0] = 0;
510 for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
511 for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
512 /* Check: cftab entries in range. */
513 for (i = 0; i <= 256; i++) {
514 if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
515 /* s->cftab[i] can legitimately be == nblock */
516 RETURN(BZ_DATA_ERROR);
517 }
518 }
519 /* Check: cftab entries non-descending. */
520 for (i = 1; i <= 256; i++) {
521 if (s->cftab[i-1] > s->cftab[i]) {
522 RETURN(BZ_DATA_ERROR);
523 }
524 }
525
526 s->state_out_len = 0;
527 s->state_out_ch = 0;
528 BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
529 s->state = BZ_X_OUTPUT;
530 if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
531
532 if (s->smallDecompress) {
533
534 /*-- Make a copy of cftab, used in generation of T --*/
535 for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
536
537 /*-- compute the T vector --*/
538 for (i = 0; i < nblock; i++) {
539 uc = (UChar)(s->ll16[i]);
540 SET_LL(i, s->cftabCopy[uc]);
541 s->cftabCopy[uc]++;
542 }
543
544 /*-- Compute T^(-1) by pointer reversal on T --*/
545 i = s->origPtr;
546 j = GET_LL(i);
547 do {
548 Int32 tmp = GET_LL(j);
549 SET_LL(j, i);
550 i = j;
551 j = tmp;
552 }
553 while (i != s->origPtr);
554
555 s->tPos = s->origPtr;
556 s->nblock_used = 0;
557 if (s->blockRandomised) {
558 BZ_RAND_INIT_MASK;
559 BZ_GET_SMALL(s->k0); s->nblock_used++;
560 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
561 } else {
562 BZ_GET_SMALL(s->k0); s->nblock_used++;
563 }
564
565 } else {
566
567 /*-- compute the T^(-1) vector --*/
568 for (i = 0; i < nblock; i++) {
569 uc = (UChar)(s->tt[i] & 0xff);
570 s->tt[s->cftab[uc]] |= (i << 8);
571 s->cftab[uc]++;
572 }
573
574 s->tPos = s->tt[s->origPtr] >> 8;
575 s->nblock_used = 0;
576 if (s->blockRandomised) {
577 BZ_RAND_INIT_MASK;
578 BZ_GET_FAST(s->k0); s->nblock_used++;
579 BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
580 } else {
581 BZ_GET_FAST(s->k0); s->nblock_used++;
582 }
583
584 }
585
586 RETURN(BZ_OK);
587
588
589
590 endhdr_2:
591
592 GET_UCHAR(BZ_X_ENDHDR_2, uc);
593 if (uc != 0x72) RETURN(BZ_DATA_ERROR);
594 GET_UCHAR(BZ_X_ENDHDR_3, uc);
595 if (uc != 0x45) RETURN(BZ_DATA_ERROR);
596 GET_UCHAR(BZ_X_ENDHDR_4, uc);
597 if (uc != 0x38) RETURN(BZ_DATA_ERROR);
598 GET_UCHAR(BZ_X_ENDHDR_5, uc);
599 if (uc != 0x50) RETURN(BZ_DATA_ERROR);
600 GET_UCHAR(BZ_X_ENDHDR_6, uc);
601 if (uc != 0x90) RETURN(BZ_DATA_ERROR);
602
603 s->storedCombinedCRC = 0;
604 GET_UCHAR(BZ_X_CCRC_1, uc);
605 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
606 GET_UCHAR(BZ_X_CCRC_2, uc);
607 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
608 GET_UCHAR(BZ_X_CCRC_3, uc);
609 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
610 GET_UCHAR(BZ_X_CCRC_4, uc);
611 s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
612
613 s->state = BZ_X_IDLE;
614 RETURN(BZ_STREAM_END);
615
616 default: AssertH ( False, 4001 );
617 }
618
619 AssertH ( False, 4002 );
620
621 save_state_and_return:
622
623 s->save_i = i;
624 s->save_j = j;
625 s->save_t = t;
626 s->save_alphaSize = alphaSize;
627 s->save_nGroups = nGroups;
628 s->save_nSelectors = nSelectors;
629 s->save_EOB = EOB;
630 s->save_groupNo = groupNo;
631 s->save_groupPos = groupPos;
632 s->save_nextSym = nextSym;
633 s->save_nblockMAX = nblockMAX;
634 s->save_nblock = nblock;
635 s->save_es = es;
636 s->save_N = N;
637 s->save_curr = curr;
638 s->save_zt = zt;
639 s->save_zn = zn;
640 s->save_zvec = zvec;
641 s->save_zj = zj;
642 s->save_gSel = gSel;
643 s->save_gMinlen = gMinlen;
644 s->save_gLimit = gLimit;
645 s->save_gBase = gBase;
646 s->save_gPerm = gPerm;
647
648 return retVal;
649 }
650
651
652 /*-------------------------------------------------------------*/
653 /*--- end decompress.c ---*/
654 /*-------------------------------------------------------------*/
655