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