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