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