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 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 /*---------------------------------------------------*/ 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