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