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