Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libbz/decompress.c
1808 views
1
#pragma prototyped
2
3
/*-------------------------------------------------------------*/
4
/*--- Decompression machinery ---*/
5
/*--- decompress.c ---*/
6
/*-------------------------------------------------------------*/
7
8
/*--
9
This file is a part of bzip2 and/or libbzip2, a program and
10
library for lossless, block-sorting data compression.
11
12
Copyright (C) 1996-1998 Julian R Seward. All rights reserved.
13
14
Redistribution and use in source and binary forms, with or without
15
modification, are permitted provided that the following conditions
16
are met:
17
18
1. Redistributions of source code must retain the above copyright
19
notice, this list of conditions and the following disclaimer.
20
21
2. The origin of this software must not be misrepresented; you must
22
not claim that you wrote the original software. If you use this
23
software in a product, an acknowledgment in the product
24
documentation would be appreciated but is not required.
25
26
3. Altered source versions must be plainly marked as such, and must
27
not be misrepresented as being the original software.
28
29
4. The name of the author may not be used to endorse or promote
30
products derived from this software without specific prior written
31
permission.
32
33
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
39
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
45
Julian Seward, Guildford, Surrey, UK.
46
[email protected]
47
bzip2/libbzip2 version 0.9.0c of 18 October 1998
48
49
This program is based on (at least) the work of:
50
Mike Burrows
51
David Wheeler
52
Peter Fenwick
53
Alistair Moffat
54
Radford Neal
55
Ian H. Witten
56
Robert Sedgewick
57
Jon L. Bentley
58
59
For more information on these sources, see the manual.
60
--*/
61
62
63
#include "bzhdr.h"
64
65
66
/*---------------------------------------------------*/
67
static
68
void makeMaps_d ( DState* s )
69
{
70
Int32 i;
71
s->nInUse = 0;
72
for (i = 0; i < 256; i++)
73
if (s->inUse[i]) {
74
s->seqToUnseq[s->nInUse] = i;
75
s->nInUse++;
76
}
77
}
78
79
80
/*---------------------------------------------------*/
81
#define RETURN(rrr) \
82
{ retVal = rrr; goto save_state_and_return; };
83
84
#define GET_BITS(lll,vvv,nnn) \
85
case lll: s->state = lll; \
86
while (True) { \
87
if (s->bsLive >= nnn) { \
88
UInt32 v; \
89
v = (s->bsBuff >> \
90
(s->bsLive-nnn)) & ((1 << nnn)-1); \
91
s->bsLive -= nnn; \
92
vvv = v; \
93
break; \
94
} \
95
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
96
s->bsBuff \
97
= (s->bsBuff << 8) | \
98
((UInt32) \
99
(*((UChar*)(s->strm->next_in)))); \
100
s->bsLive += 8; \
101
s->strm->next_in++; \
102
s->strm->avail_in--; \
103
s->strm->total_in++; \
104
}
105
106
#define GET_UCHAR(lll,uuu) \
107
GET_BITS(lll,uuu,8)
108
109
#define GET_BIT(lll,uuu) \
110
GET_BITS(lll,uuu,1)
111
112
/*---------------------------------------------------*/
113
#define GET_MTF_VAL(label1,label2,lval) \
114
{ \
115
if (groupPos == 0) { \
116
groupNo++; \
117
groupPos = BZ_G_SIZE; \
118
gSel = s->selector[groupNo]; \
119
gMinlen = s->minLens[gSel]; \
120
gLimit = &(s->limit[gSel][0]); \
121
gPerm = &(s->perm[gSel][0]); \
122
gBase = &(s->base[gSel][0]); \
123
} \
124
groupPos--; \
125
zn = gMinlen; \
126
GET_BITS(label1, zvec, zn); \
127
while (zvec > gLimit[zn]) { \
128
zn++; \
129
GET_BIT(label2, zj); \
130
zvec = (zvec << 1) | zj; \
131
}; \
132
lval = gPerm[zvec - gBase[zn]]; \
133
}
134
135
136
/*---------------------------------------------------*/
137
Int32 decompress ( DState* s )
138
{
139
UChar uc;
140
Int32 retVal;
141
Int32 minLen, maxLen;
142
bz_stream* strm = s->strm;
143
144
/* stuff that needs to be saved/restored */
145
Int32 i ;
146
Int32 j;
147
Int32 t;
148
Int32 alphaSize;
149
Int32 nGroups;
150
Int32 nSelectors;
151
Int32 EOB;
152
Int32 groupNo;
153
Int32 groupPos;
154
Int32 nextSym;
155
Int32 nblockMAX;
156
Int32 nblock;
157
Int32 es;
158
Int32 N;
159
Int32 curr;
160
Int32 zt;
161
Int32 zn;
162
Int32 zvec;
163
Int32 zj;
164
Int32 gSel;
165
Int32 gMinlen;
166
Int32* gLimit;
167
Int32* gBase;
168
Int32* gPerm;
169
170
if (s->state == BZ_X_MAGIC_1) {
171
/*initialise the save area*/
172
s->save_i = 0;
173
s->save_j = 0;
174
s->save_t = 0;
175
s->save_alphaSize = 0;
176
s->save_nGroups = 0;
177
s->save_nSelectors = 0;
178
s->save_EOB = 0;
179
s->save_groupNo = 0;
180
s->save_groupPos = 0;
181
s->save_nextSym = 0;
182
s->save_nblockMAX = 0;
183
s->save_nblock = 0;
184
s->save_es = 0;
185
s->save_N = 0;
186
s->save_curr = 0;
187
s->save_zt = 0;
188
s->save_zn = 0;
189
s->save_zvec = 0;
190
s->save_zj = 0;
191
s->save_gSel = 0;
192
s->save_gMinlen = 0;
193
s->save_gLimit = NULL;
194
s->save_gBase = NULL;
195
s->save_gPerm = NULL;
196
}
197
198
/*restore from the save area*/
199
i = s->save_i;
200
j = s->save_j;
201
t = s->save_t;
202
alphaSize = s->save_alphaSize;
203
nGroups = s->save_nGroups;
204
nSelectors = s->save_nSelectors;
205
EOB = s->save_EOB;
206
groupNo = s->save_groupNo;
207
groupPos = s->save_groupPos;
208
nextSym = s->save_nextSym;
209
nblockMAX = s->save_nblockMAX;
210
nblock = s->save_nblock;
211
es = s->save_es;
212
N = s->save_N;
213
curr = s->save_curr;
214
zt = s->save_zt;
215
zn = s->save_zn;
216
zvec = s->save_zvec;
217
zj = s->save_zj;
218
gSel = s->save_gSel;
219
gMinlen = s->save_gMinlen;
220
gLimit = s->save_gLimit;
221
gBase = s->save_gBase;
222
gPerm = s->save_gPerm;
223
224
retVal = BZ_OK;
225
226
switch (s->state) {
227
228
GET_UCHAR(BZ_X_MAGIC_1, uc);
229
if (uc != 'B') RETURN(BZ_DATA_ERROR_MAGIC);
230
231
GET_UCHAR(BZ_X_MAGIC_2, uc);
232
if (uc != 'Z') RETURN(BZ_DATA_ERROR_MAGIC);
233
234
GET_UCHAR(BZ_X_MAGIC_3, uc)
235
if (uc != 'h') RETURN(BZ_DATA_ERROR_MAGIC);
236
237
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
238
if (s->blockSize100k < '1' ||
239
s->blockSize100k > '9') RETURN(BZ_DATA_ERROR_MAGIC);
240
s->blockSize100k -= '0';
241
242
if (s->smallDecompress) {
243
s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
244
s->ll4 = BZALLOC(
245
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
246
);
247
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
248
} else {
249
s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
250
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
251
}
252
253
GET_UCHAR(BZ_X_BLKHDR_1, uc);
254
255
if (uc == 0x17) goto endhdr_2;
256
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
257
GET_UCHAR(BZ_X_BLKHDR_2, uc);
258
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
259
GET_UCHAR(BZ_X_BLKHDR_3, uc);
260
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
261
GET_UCHAR(BZ_X_BLKHDR_4, uc);
262
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
263
GET_UCHAR(BZ_X_BLKHDR_5, uc);
264
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
265
GET_UCHAR(BZ_X_BLKHDR_6, uc);
266
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
267
268
s->currBlockNo++;
269
if (s->verbosity >= 2)
270
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
271
272
s->storedBlockCRC = 0;
273
GET_UCHAR(BZ_X_BCRC_1, uc);
274
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
275
GET_UCHAR(BZ_X_BCRC_2, uc);
276
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
277
GET_UCHAR(BZ_X_BCRC_3, uc);
278
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
279
GET_UCHAR(BZ_X_BCRC_4, uc);
280
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
281
282
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
283
284
s->origPtr = 0;
285
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
286
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
287
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
288
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
289
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
290
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
291
292
/*--- Receive the mapping table ---*/
293
for (i = 0; i < 16; i++) {
294
GET_BIT(BZ_X_MAPPING_1, uc);
295
if (uc == 1)
296
s->inUse16[i] = True; else
297
s->inUse16[i] = False;
298
}
299
300
for (i = 0; i < 256; i++) s->inUse[i] = False;
301
302
for (i = 0; i < 16; i++)
303
if (s->inUse16[i])
304
for (j = 0; j < 16; j++) {
305
GET_BIT(BZ_X_MAPPING_2, uc);
306
if (uc == 1) s->inUse[i * 16 + j] = True;
307
}
308
makeMaps_d ( s );
309
alphaSize = s->nInUse+2;
310
311
/*--- Now the selectors ---*/
312
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
313
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
314
for (i = 0; i < nSelectors; i++) {
315
j = 0;
316
while (True) {
317
GET_BIT(BZ_X_SELECTOR_3, uc);
318
if (uc == 0) break;
319
j++;
320
if (j > 5) RETURN(BZ_DATA_ERROR);
321
}
322
s->selectorMtf[i] = j;
323
}
324
325
/*--- Undo the MTF values for the selectors. ---*/
326
{
327
UChar pos[BZ_N_GROUPS], tmp, v;
328
for (v = 0; v < nGroups; v++) pos[v] = v;
329
330
for (i = 0; i < nSelectors; i++) {
331
v = s->selectorMtf[i];
332
tmp = pos[v];
333
while (v > 0) { pos[v] = pos[v-1]; v--; }
334
pos[0] = tmp;
335
s->selector[i] = tmp;
336
}
337
}
338
339
/*--- Now the coding tables ---*/
340
for (t = 0; t < nGroups; t++) {
341
GET_BITS(BZ_X_CODING_1, curr, 5);
342
for (i = 0; i < alphaSize; i++) {
343
while (True) {
344
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
345
GET_BIT(BZ_X_CODING_2, uc);
346
if (uc == 0) break;
347
GET_BIT(BZ_X_CODING_3, uc);
348
if (uc == 0) curr++; else curr--;
349
}
350
s->len[t][i] = curr;
351
}
352
}
353
354
/*--- Create the Huffman decoding tables ---*/
355
for (t = 0; t < nGroups; t++) {
356
minLen = 32;
357
maxLen = 0;
358
for (i = 0; i < alphaSize; i++) {
359
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
360
if (s->len[t][i] < minLen) minLen = s->len[t][i];
361
}
362
hbCreateDecodeTables (
363
&(s->limit[t][0]),
364
&(s->base[t][0]),
365
&(s->perm[t][0]),
366
&(s->len[t][0]),
367
minLen, maxLen, alphaSize
368
);
369
s->minLens[t] = minLen;
370
}
371
372
/*--- Now the MTF values ---*/
373
374
EOB = s->nInUse+1;
375
nblockMAX = 100000 * s->blockSize100k;
376
groupNo = -1;
377
groupPos = 0;
378
379
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
380
381
/*-- MTF init --*/
382
{
383
Int32 ii, jj, kk;
384
kk = MTFA_SIZE-1;
385
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
386
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
387
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
388
kk--;
389
}
390
s->mtfbase[ii] = kk + 1;
391
}
392
}
393
/*-- end MTF init --*/
394
395
nblock = 0;
396
397
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
398
399
while (True) {
400
401
if (nextSym == EOB) break;
402
403
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
404
405
es = -1;
406
N = 1;
407
do {
408
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
409
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
410
N = N * 2;
411
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
412
}
413
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
414
415
es++;
416
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
417
s->unzftab[uc] += es;
418
419
if (s->smallDecompress)
420
while (es > 0) {
421
s->ll16[nblock] = (UInt16)uc;
422
nblock++;
423
es--;
424
}
425
else
426
while (es > 0) {
427
s->tt[nblock] = (UInt32)uc;
428
nblock++;
429
es--;
430
};
431
432
if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR);
433
continue;
434
435
} else {
436
437
if (nblock > nblockMAX) RETURN(BZ_DATA_ERROR);
438
439
/*-- uc = MTF ( nextSym-1 ) --*/
440
{
441
Int32 ii, jj, kk, pp, lno, off;
442
UInt32 nn;
443
nn = (UInt32)(nextSym - 1);
444
445
if (nn < MTFL_SIZE) {
446
/* avoid general-case expense */
447
pp = s->mtfbase[0];
448
uc = s->mtfa[pp+nn];
449
while (nn > 3) {
450
Int32 z = pp+nn;
451
s->mtfa[(z) ] = s->mtfa[(z)-1];
452
s->mtfa[(z)-1] = s->mtfa[(z)-2];
453
s->mtfa[(z)-2] = s->mtfa[(z)-3];
454
s->mtfa[(z)-3] = s->mtfa[(z)-4];
455
nn -= 4;
456
}
457
while (nn > 0) {
458
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
459
};
460
s->mtfa[pp] = uc;
461
} else {
462
/* general case */
463
lno = nn / MTFL_SIZE;
464
off = nn % MTFL_SIZE;
465
pp = s->mtfbase[lno] + off;
466
uc = s->mtfa[pp];
467
while (pp > s->mtfbase[lno]) {
468
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
469
};
470
s->mtfbase[lno]++;
471
while (lno > 0) {
472
s->mtfbase[lno]--;
473
s->mtfa[s->mtfbase[lno]]
474
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
475
lno--;
476
}
477
s->mtfbase[0]--;
478
s->mtfa[s->mtfbase[0]] = uc;
479
if (s->mtfbase[0] == 0) {
480
kk = MTFA_SIZE-1;
481
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
482
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
483
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
484
kk--;
485
}
486
s->mtfbase[ii] = kk + 1;
487
}
488
}
489
}
490
}
491
/*-- end uc = MTF ( nextSym-1 ) --*/
492
493
s->unzftab[s->seqToUnseq[uc]]++;
494
if (s->smallDecompress)
495
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
496
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
497
nblock++;
498
499
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
500
continue;
501
}
502
}
503
504
s->state_out_len = 0;
505
s->state_out_ch = 0;
506
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
507
s->state = BZ_X_OUTPUT;
508
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
509
510
/*-- Set up cftab to facilitate generation of T^(-1) --*/
511
s->cftab[0] = 0;
512
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
513
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
514
515
if (s->smallDecompress) {
516
517
/*-- Make a copy of cftab, used in generation of T --*/
518
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
519
520
/*-- compute the T vector --*/
521
for (i = 0; i < nblock; i++) {
522
uc = (UChar)(s->ll16[i]);
523
SET_LL(i, s->cftabCopy[uc]);
524
s->cftabCopy[uc]++;
525
}
526
527
/*-- Compute T^(-1) by pointer reversal on T --*/
528
i = s->origPtr;
529
j = GET_LL(i);
530
do {
531
Int32 tmp = GET_LL(j);
532
SET_LL(j, i);
533
i = j;
534
j = tmp;
535
}
536
while (i != s->origPtr);
537
538
s->tPos = s->origPtr;
539
s->nblock_used = 0;
540
if (s->blockRandomised) {
541
BZ_RAND_INIT_MASK;
542
BZ_GET_SMALL(s->k0); s->nblock_used++;
543
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
544
} else {
545
BZ_GET_SMALL(s->k0); s->nblock_used++;
546
}
547
548
} else {
549
550
/*-- compute the T^(-1) vector --*/
551
for (i = 0; i < nblock; i++) {
552
uc = (UChar)(s->tt[i] & 0xff);
553
s->tt[s->cftab[uc]] |= (i << 8);
554
s->cftab[uc]++;
555
}
556
557
s->tPos = s->tt[s->origPtr] >> 8;
558
s->nblock_used = 0;
559
if (s->blockRandomised) {
560
BZ_RAND_INIT_MASK;
561
BZ_GET_FAST(s->k0); s->nblock_used++;
562
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
563
} else {
564
BZ_GET_FAST(s->k0); s->nblock_used++;
565
}
566
567
}
568
569
RETURN(BZ_OK);
570
571
572
573
endhdr_2:
574
575
GET_UCHAR(BZ_X_ENDHDR_2, uc);
576
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
577
GET_UCHAR(BZ_X_ENDHDR_3, uc);
578
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
579
GET_UCHAR(BZ_X_ENDHDR_4, uc);
580
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
581
GET_UCHAR(BZ_X_ENDHDR_5, uc);
582
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
583
GET_UCHAR(BZ_X_ENDHDR_6, uc);
584
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
585
586
s->storedCombinedCRC = 0;
587
GET_UCHAR(BZ_X_CCRC_1, uc);
588
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
589
GET_UCHAR(BZ_X_CCRC_2, uc);
590
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
591
GET_UCHAR(BZ_X_CCRC_3, uc);
592
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
593
GET_UCHAR(BZ_X_CCRC_4, uc);
594
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
595
596
s->state = BZ_X_IDLE;
597
RETURN(BZ_STREAM_END);
598
599
default: AssertH ( False, 4001 );
600
}
601
602
AssertH ( False, 4002 );
603
604
save_state_and_return:
605
606
s->save_i = i;
607
s->save_j = j;
608
s->save_t = t;
609
s->save_alphaSize = alphaSize;
610
s->save_nGroups = nGroups;
611
s->save_nSelectors = nSelectors;
612
s->save_EOB = EOB;
613
s->save_groupNo = groupNo;
614
s->save_groupPos = groupPos;
615
s->save_nextSym = nextSym;
616
s->save_nblockMAX = nblockMAX;
617
s->save_nblock = nblock;
618
s->save_es = es;
619
s->save_N = N;
620
s->save_curr = curr;
621
s->save_zt = zt;
622
s->save_zn = zn;
623
s->save_zvec = zvec;
624
s->save_zj = zj;
625
s->save_gSel = gSel;
626
s->save_gMinlen = gMinlen;
627
s->save_gLimit = gLimit;
628
s->save_gBase = gBase;
629
s->save_gPerm = gPerm;
630
631
return retVal;
632
}
633
634
635
/*-------------------------------------------------------------*/
636
/*--- end decompress.c ---*/
637
/*-------------------------------------------------------------*/
638
639