• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
makeMaps_d(DState * s)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 /*---------------------------------------------------*/
BZ2_decompress(DState * s)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 > 6) RETURN(BZ_DATA_ERROR);
289       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
290       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
291       if (nSelectors > BZ_MAX_SELECTORS) 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); s->nblock_used++;
553             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
554          } else {
555             BZ_GET_SMALL(s->k0); s->nblock_used++;
556          }
557 
558       } else {
559 
560          /*-- compute the T^(-1) vector --*/
561          for (i = 0; i < nblock; i++) {
562             uc = (UChar)(s->tt[i] & 0xff);
563             s->tt[s->cftab[uc]] |= (i << 8);
564             s->cftab[uc]++;
565          }
566 
567          s->tPos = s->tt[s->origPtr] >> 8;
568          s->nblock_used = 0;
569          if (s->blockRandomised) {
570             BZ_RAND_INIT_MASK;
571             BZ_GET_FAST(s->k0); s->nblock_used++;
572             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
573          } else {
574             BZ_GET_FAST(s->k0); s->nblock_used++;
575          }
576 
577       }
578 
579       RETURN(BZ_OK);
580 
581 
582 
583     endhdr_2:
584 
585       GET_UCHAR(BZ_X_ENDHDR_2, uc);
586       if (uc != 0x72) RETURN(BZ_DATA_ERROR);
587       GET_UCHAR(BZ_X_ENDHDR_3, uc);
588       if (uc != 0x45) RETURN(BZ_DATA_ERROR);
589       GET_UCHAR(BZ_X_ENDHDR_4, uc);
590       if (uc != 0x38) RETURN(BZ_DATA_ERROR);
591       GET_UCHAR(BZ_X_ENDHDR_5, uc);
592       if (uc != 0x50) RETURN(BZ_DATA_ERROR);
593       GET_UCHAR(BZ_X_ENDHDR_6, uc);
594       if (uc != 0x90) RETURN(BZ_DATA_ERROR);
595 
596       s->storedCombinedCRC = 0;
597       GET_UCHAR(BZ_X_CCRC_1, uc);
598       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
599       GET_UCHAR(BZ_X_CCRC_2, uc);
600       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
601       GET_UCHAR(BZ_X_CCRC_3, uc);
602       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
603       GET_UCHAR(BZ_X_CCRC_4, uc);
604       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
605 
606       s->state = BZ_X_IDLE;
607       RETURN(BZ_STREAM_END);
608 
609       default: AssertH ( False, 4001 );
610    }
611 
612    AssertH ( False, 4002 );
613 
614    save_state_and_return:
615 
616    s->save_i           = i;
617    s->save_j           = j;
618    s->save_t           = t;
619    s->save_alphaSize   = alphaSize;
620    s->save_nGroups     = nGroups;
621    s->save_nSelectors  = nSelectors;
622    s->save_EOB         = EOB;
623    s->save_groupNo     = groupNo;
624    s->save_groupPos    = groupPos;
625    s->save_nextSym     = nextSym;
626    s->save_nblockMAX   = nblockMAX;
627    s->save_nblock      = nblock;
628    s->save_es          = es;
629    s->save_N           = N;
630    s->save_curr        = curr;
631    s->save_zt          = zt;
632    s->save_zn          = zn;
633    s->save_zvec        = zvec;
634    s->save_zj          = zj;
635    s->save_gSel        = gSel;
636    s->save_gMinlen     = gMinlen;
637    s->save_gLimit      = gLimit;
638    s->save_gBase       = gBase;
639    s->save_gPerm       = gPerm;
640 
641    return retVal;
642 }
643 
644 
645 /*-------------------------------------------------------------*/
646 /*--- end                                      decompress.c ---*/
647 /*-------------------------------------------------------------*/
648