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/*---------------------------------------------------*/
26static
27void 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/*---------------------------------------------------*/
107Int32 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 = (UInt16*) BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
214         s->ll4  = (UChar*) 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  = (UInt32*) 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 > BZ_N_GROUPS) 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         /* Having more than BZ_MAX_SELECTORS doesn't make much sense
301            since they will never be used, but some implementations might
302            "round up" the number of selectors, so just ignore those. */
303         if (i < BZ_MAX_SELECTORS)
304           s->selectorMtf[i] = j;
305      }
306      if (nSelectors > BZ_MAX_SELECTORS)
307        nSelectors = BZ_MAX_SELECTORS;
308
309      /*--- Undo the MTF values for the selectors. ---*/
310      {
311         UChar pos[BZ_N_GROUPS], tmp, v;
312         for (v = 0; v < nGroups; v++) pos[v] = v;
313
314         for (i = 0; i < nSelectors; i++) {
315            v = s->selectorMtf[i];
316            tmp = pos[v];
317            while (v > 0) { pos[v] = pos[v-1]; v--; }
318            pos[0] = tmp;
319            s->selector[i] = tmp;
320         }
321      }
322
323      /*--- Now the coding tables ---*/
324      for (t = 0; t < nGroups; t++) {
325         GET_BITS(BZ_X_CODING_1, curr, 5);
326         for (i = 0; i < alphaSize; i++) {
327            while (True) {
328               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
329               GET_BIT(BZ_X_CODING_2, uc);
330               if (uc == 0) break;
331               GET_BIT(BZ_X_CODING_3, uc);
332               if (uc == 0) curr++; else curr--;
333            }
334            s->len[t][i] = curr;
335         }
336      }
337
338      /*--- Create the Huffman decoding tables ---*/
339      for (t = 0; t < nGroups; t++) {
340         minLen = 32;
341         maxLen = 0;
342         for (i = 0; i < alphaSize; i++) {
343            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
344            if (s->len[t][i] < minLen) minLen = s->len[t][i];
345         }
346         BZ2_hbCreateDecodeTables (
347            &(s->limit[t][0]),
348            &(s->base[t][0]),
349            &(s->perm[t][0]),
350            &(s->len[t][0]),
351            minLen, maxLen, alphaSize
352         );
353         s->minLens[t] = minLen;
354      }
355
356      /*--- Now the MTF values ---*/
357
358      EOB      = s->nInUse+1;
359      nblockMAX = 100000 * s->blockSize100k;
360      groupNo  = -1;
361      groupPos = 0;
362
363      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
364
365      /*-- MTF init --*/
366      {
367         Int32 ii, jj, kk;
368         kk = MTFA_SIZE-1;
369         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
370            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
371               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
372               kk--;
373            }
374            s->mtfbase[ii] = kk + 1;
375         }
376      }
377      /*-- end MTF init --*/
378
379      nblock = 0;
380      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
381
382      while (True) {
383
384         if (nextSym == EOB) break;
385
386         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
387
388            es = -1;
389            N = 1;
390            do {
391               /* Check that N doesn't get too big, so that es doesn't
392                  go negative.  The maximum value that can be
393                  RUNA/RUNB encoded is equal to the block size (post
394                  the initial RLE), viz, 900k, so bounding N at 2
395                  million should guard against overflow without
396                  rejecting any legitimate inputs. */
397               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
398               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
399               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
400               N = N * 2;
401               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
402            }
403               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
404
405            es++;
406            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
407            s->unzftab[uc] += es;
408
409            if (s->smallDecompress)
410               while (es > 0) {
411                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
412                  s->ll16[nblock] = (UInt16)uc;
413                  nblock++;
414                  es--;
415               }
416            else
417               while (es > 0) {
418                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
419                  s->tt[nblock] = (UInt32)uc;
420                  nblock++;
421                  es--;
422               };
423
424            continue;
425
426         } else {
427
428            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
429
430            /*-- uc = MTF ( nextSym-1 ) --*/
431            {
432               Int32 ii, jj, kk, pp, lno, off;
433               UInt32 nn;
434               nn = (UInt32)(nextSym - 1);
435
436               if (nn < MTFL_SIZE) {
437                  /* avoid general-case expense */
438                  pp = s->mtfbase[0];
439                  uc = s->mtfa[pp+nn];
440                  while (nn > 3) {
441                     Int32 z = pp+nn;
442                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
443                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
444                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
445                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
446                     nn -= 4;
447                  }
448                  while (nn > 0) {
449                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
450                  };
451                  s->mtfa[pp] = uc;
452               } else {
453                  /* general case */
454                  lno = nn / MTFL_SIZE;
455                  off = nn % MTFL_SIZE;
456                  pp = s->mtfbase[lno] + off;
457                  uc = s->mtfa[pp];
458                  while (pp > s->mtfbase[lno]) {
459                     s->mtfa[pp] = s->mtfa[pp-1]; pp--;
460                  };
461                  s->mtfbase[lno]++;
462                  while (lno > 0) {
463                     s->mtfbase[lno]--;
464                     s->mtfa[s->mtfbase[lno]]
465                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
466                     lno--;
467                  }
468                  s->mtfbase[0]--;
469                  s->mtfa[s->mtfbase[0]] = uc;
470                  if (s->mtfbase[0] == 0) {
471                     kk = MTFA_SIZE-1;
472                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
473                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
474                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
475                           kk--;
476                        }
477                        s->mtfbase[ii] = kk + 1;
478                     }
479                  }
480               }
481            }
482            /*-- end uc = MTF ( nextSym-1 ) --*/
483
484            s->unzftab[s->seqToUnseq[uc]]++;
485            if (s->smallDecompress)
486               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
487               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
488            nblock++;
489
490            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
491            continue;
492         }
493      }
494
495      /* Now we know what nblock is, we can do a better sanity
496         check on s->origPtr.
497      */
498      if (s->origPtr < 0 || s->origPtr >= nblock)
499         RETURN(BZ_DATA_ERROR);
500
501      /*-- Set up cftab to facilitate generation of T^(-1) --*/
502      /* Check: unzftab entries in range. */
503      for (i = 0; i <= 255; i++) {
504         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
505            RETURN(BZ_DATA_ERROR);
506      }
507      /* Actually generate cftab. */
508      s->cftab[0] = 0;
509      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
510      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
511      /* Check: cftab entries in range. */
512      for (i = 0; i <= 256; i++) {
513         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
514            /* s->cftab[i] can legitimately be == nblock */
515            RETURN(BZ_DATA_ERROR);
516         }
517      }
518      /* Check: cftab entries non-descending. */
519      for (i = 1; i <= 256; i++) {
520         if (s->cftab[i-1] > s->cftab[i]) {
521            RETURN(BZ_DATA_ERROR);
522         }
523      }
524
525      s->state_out_len = 0;
526      s->state_out_ch  = 0;
527      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
528      s->state = BZ_X_OUTPUT;
529      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
530
531      if (s->smallDecompress) {
532
533         /*-- Make a copy of cftab, used in generation of T --*/
534         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
535
536         /*-- compute the T vector --*/
537         for (i = 0; i < nblock; i++) {
538            uc = (UChar)(s->ll16[i]);
539            SET_LL(i, s->cftabCopy[uc]);
540            s->cftabCopy[uc]++;
541         }
542
543         /*-- Compute T^(-1) by pointer reversal on T --*/
544         i = s->origPtr;
545         j = GET_LL(i);
546         do {
547            Int32 tmp = GET_LL(j);
548            SET_LL(j, i);
549            i = j;
550            j = tmp;
551         }
552            while (i != s->origPtr);
553
554         s->tPos = s->origPtr;
555         s->nblock_used = 0;
556         if (s->blockRandomised) {
557            BZ_RAND_INIT_MASK;
558            BZ_GET_SMALL(s->k0); s->nblock_used++;
559            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
560         } else {
561            BZ_GET_SMALL(s->k0); s->nblock_used++;
562         }
563
564      } else {
565
566         /*-- compute the T^(-1) vector --*/
567         for (i = 0; i < nblock; i++) {
568            uc = (UChar)(s->tt[i] & 0xff);
569            s->tt[s->cftab[uc]] |= (i << 8);
570            s->cftab[uc]++;
571         }
572
573         s->tPos = s->tt[s->origPtr] >> 8;
574         s->nblock_used = 0;
575         if (s->blockRandomised) {
576            BZ_RAND_INIT_MASK;
577            BZ_GET_FAST(s->k0); s->nblock_used++;
578            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
579         } else {
580            BZ_GET_FAST(s->k0); s->nblock_used++;
581         }
582
583      }
584
585      RETURN(BZ_OK);
586
587
588
589    endhdr_2:
590
591      GET_UCHAR(BZ_X_ENDHDR_2, uc);
592      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
593      GET_UCHAR(BZ_X_ENDHDR_3, uc);
594      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
595      GET_UCHAR(BZ_X_ENDHDR_4, uc);
596      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
597      GET_UCHAR(BZ_X_ENDHDR_5, uc);
598      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
599      GET_UCHAR(BZ_X_ENDHDR_6, uc);
600      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
601
602      s->storedCombinedCRC = 0;
603      GET_UCHAR(BZ_X_CCRC_1, uc);
604      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
605      GET_UCHAR(BZ_X_CCRC_2, uc);
606      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
607      GET_UCHAR(BZ_X_CCRC_3, uc);
608      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
609      GET_UCHAR(BZ_X_CCRC_4, uc);
610      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
611
612      s->state = BZ_X_IDLE;
613      RETURN(BZ_STREAM_END);
614
615      default: AssertH ( False, 4001 );
616   }
617
618   AssertH ( False, 4002 );
619
620   save_state_and_return:
621
622   s->save_i           = i;
623   s->save_j           = j;
624   s->save_t           = t;
625   s->save_alphaSize   = alphaSize;
626   s->save_nGroups     = nGroups;
627   s->save_nSelectors  = nSelectors;
628   s->save_EOB         = EOB;
629   s->save_groupNo     = groupNo;
630   s->save_groupPos    = groupPos;
631   s->save_nextSym     = nextSym;
632   s->save_nblockMAX   = nblockMAX;
633   s->save_nblock      = nblock;
634   s->save_es          = es;
635   s->save_N           = N;
636   s->save_curr        = curr;
637   s->save_zt          = zt;
638   s->save_zn          = zn;
639   s->save_zvec        = zvec;
640   s->save_zj          = zj;
641   s->save_gSel        = gSel;
642   s->save_gMinlen     = gMinlen;
643   s->save_gLimit      = gLimit;
644   s->save_gBase       = gBase;
645   s->save_gPerm       = gPerm;
646
647   return retVal;
648}
649
650
651/*-------------------------------------------------------------*/
652/*--- end                                      decompress.c ---*/
653/*-------------------------------------------------------------*/
654