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