Back to index

avfs  1.0.1
decompress.c
Go to the documentation of this file.
00001 
00002 /*-------------------------------------------------------------*/
00003 /*--- Decompression machinery                               ---*/
00004 /*---                                          decompress.c ---*/
00005 /*-------------------------------------------------------------*/
00006 
00007 /* ------------------------------------------------------------------
00008    This file is part of bzip2/libbzip2, a program and library for
00009    lossless, block-sorting data compression.
00010 
00011    bzip2/libbzip2 version 1.0.6 of 6 September 2010
00012    Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
00013 
00014    Please read the WARNING, DISCLAIMER and PATENTS sections in the 
00015    README file.
00016 
00017    This program is released under the terms of the license contained
00018    in the file LICENSE.
00019    ------------------------------------------------------------------ */
00020 
00021 
00022 #include "bzlib_private.h"
00023 
00024 
00025 /*---------------------------------------------------*/
00026 static
00027 void makeMaps_d ( DState* s )
00028 {
00029    Int32 i;
00030    s->nInUse = 0;
00031    for (i = 0; i < 256; i++)
00032       if (s->inUse[i]) {
00033          s->seqToUnseq[s->nInUse] = i;
00034          s->nInUse++;
00035       }
00036 }
00037 
00038 
00039 /*---------------------------------------------------*/
00040 #define RETURN(rrr)                               \
00041    { retVal = rrr; goto save_state_and_return; };
00042 
00043 #define GET_BITS(lll,vvv,nnn)                     \
00044    case lll: s->state = lll;                      \
00045    while (True) {                                 \
00046       if (s->bsLive >= nnn) {                     \
00047          UInt32 v;                                \
00048          v = (s->bsBuff >>                        \
00049              (s->bsLive-nnn)) & ((1 << nnn)-1);   \
00050          s->bsLive -= nnn;                        \
00051          vvv = v;                                 \
00052          break;                                   \
00053       }                                           \
00054       if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
00055       s->bsBuff                                   \
00056          = (s->bsBuff << 8) |                     \
00057            ((UInt32)                              \
00058               (*((UChar*)(s->strm->next_in))));   \
00059       s->bsLive += 8;                             \
00060       s->strm->next_in++;                         \
00061       s->strm->avail_in--;                        \
00062       s->strm->total_in_lo32++;                   \
00063       if (s->strm->total_in_lo32 == 0)            \
00064          s->strm->total_in_hi32++;                \
00065    }
00066 
00067 #define GET_UCHAR(lll,uuu)                        \
00068    GET_BITS(lll,uuu,8)
00069 
00070 #define GET_BIT(lll,uuu)                          \
00071    GET_BITS(lll,uuu,1)
00072 
00073 /*---------------------------------------------------*/
00074 #define GET_MTF_VAL(label1,label2,lval)           \
00075 {                                                 \
00076    if (groupPos == 0) {                           \
00077       groupNo++;                                  \
00078       if (groupNo >= nSelectors)                  \
00079          RETURN(BZ_DATA_ERROR);                   \
00080       groupPos = BZ_G_SIZE;                       \
00081       gSel = s->selector[groupNo];                \
00082       gMinlen = s->minLens[gSel];                 \
00083       gLimit = &(s->limit[gSel][0]);              \
00084       gPerm = &(s->perm[gSel][0]);                \
00085       gBase = &(s->base[gSel][0]);                \
00086    }                                              \
00087    groupPos--;                                    \
00088    zn = gMinlen;                                  \
00089    GET_BITS(label1, zvec, zn);                    \
00090    while (1) {                                    \
00091       if (zn > 20 /* the longest code */)         \
00092          RETURN(BZ_DATA_ERROR);                   \
00093       if (zvec <= gLimit[zn]) break;              \
00094       zn++;                                       \
00095       GET_BIT(label2, zj);                        \
00096       zvec = (zvec << 1) | zj;                    \
00097    };                                             \
00098    if (zvec - gBase[zn] < 0                       \
00099        || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
00100       RETURN(BZ_DATA_ERROR);                      \
00101    lval = gPerm[zvec - gBase[zn]];                \
00102 }
00103 
00104 
00105 /*---------------------------------------------------*/
00106 Int32 BZ2_decompress ( DState* s )
00107 {
00108    UChar      uc;
00109    Int32      retVal;
00110    Int32      minLen, maxLen;
00111    bz_stream* strm = s->strm;
00112 
00113    /* stuff that needs to be saved/restored */
00114    Int32  i;
00115    Int32  j;
00116    Int32  t;
00117    Int32  alphaSize;
00118    Int32  nGroups;
00119    Int32  nSelectors;
00120    Int32  EOB;
00121    Int32  groupNo;
00122    Int32  groupPos;
00123    Int32  nextSym;
00124    Int32  nblockMAX;
00125    Int32  nblock;
00126    Int32  es;
00127    Int32  N;
00128    Int32  curr;
00129    Int32  zt;
00130    Int32  zn; 
00131    Int32  zvec;
00132    Int32  zj;
00133    Int32  gSel;
00134    Int32  gMinlen;
00135    Int32* gLimit;
00136    Int32* gBase;
00137    Int32* gPerm;
00138 
00139    if (s->state == BZ_X_MAGIC_1) {
00140       /*initialise the save area*/
00141       s->save_i           = 0;
00142       s->save_j           = 0;
00143       s->save_t           = 0;
00144       s->save_alphaSize   = 0;
00145       s->save_nGroups     = 0;
00146       s->save_nSelectors  = 0;
00147       s->save_EOB         = 0;
00148       s->save_groupNo     = 0;
00149       s->save_groupPos    = 0;
00150       s->save_nextSym     = 0;
00151       s->save_nblockMAX   = 0;
00152       s->save_nblock      = 0;
00153       s->save_es          = 0;
00154       s->save_N           = 0;
00155       s->save_curr        = 0;
00156       s->save_zt          = 0;
00157       s->save_zn          = 0;
00158       s->save_zvec        = 0;
00159       s->save_zj          = 0;
00160       s->save_gSel        = 0;
00161       s->save_gMinlen     = 0;
00162       s->save_gLimit      = NULL;
00163       s->save_gBase       = NULL;
00164       s->save_gPerm       = NULL;
00165    }
00166 
00167    /*restore from the save area*/
00168    i           = s->save_i;
00169    j           = s->save_j;
00170    t           = s->save_t;
00171    alphaSize   = s->save_alphaSize;
00172    nGroups     = s->save_nGroups;
00173    nSelectors  = s->save_nSelectors;
00174    EOB         = s->save_EOB;
00175    groupNo     = s->save_groupNo;
00176    groupPos    = s->save_groupPos;
00177    nextSym     = s->save_nextSym;
00178    nblockMAX   = s->save_nblockMAX;
00179    nblock      = s->save_nblock;
00180    es          = s->save_es;
00181    N           = s->save_N;
00182    curr        = s->save_curr;
00183    zt          = s->save_zt;
00184    zn          = s->save_zn; 
00185    zvec        = s->save_zvec;
00186    zj          = s->save_zj;
00187    gSel        = s->save_gSel;
00188    gMinlen     = s->save_gMinlen;
00189    gLimit      = s->save_gLimit;
00190    gBase       = s->save_gBase;
00191    gPerm       = s->save_gPerm;
00192 
00193    retVal = BZ_OK;
00194 
00195    switch (s->state) {
00196 
00197       GET_UCHAR(BZ_X_MAGIC_1, uc);
00198       if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
00199 
00200       GET_UCHAR(BZ_X_MAGIC_2, uc);
00201       if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
00202 
00203       GET_UCHAR(BZ_X_MAGIC_3, uc)
00204       if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
00205 
00206       GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
00207       if (s->blockSize100k < (BZ_HDR_0 + 1) || 
00208           s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
00209       s->blockSize100k -= BZ_HDR_0;
00210 
00211       if (s->smallDecompress) {
00212          s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
00213          s->ll4  = BZALLOC( 
00214                       ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
00215                    );
00216          if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
00217       } else {
00218          s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
00219          if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
00220       }
00221 
00222       GET_UCHAR(BZ_X_BLKHDR_1, uc);
00223 
00224       if (uc == 0x17) goto endhdr_2;
00225       if (uc != 0x31) RETURN(BZ_DATA_ERROR);
00226       GET_UCHAR(BZ_X_BLKHDR_2, uc);
00227       if (uc != 0x41) RETURN(BZ_DATA_ERROR);
00228       GET_UCHAR(BZ_X_BLKHDR_3, uc);
00229       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
00230       GET_UCHAR(BZ_X_BLKHDR_4, uc);
00231       if (uc != 0x26) RETURN(BZ_DATA_ERROR);
00232       GET_UCHAR(BZ_X_BLKHDR_5, uc);
00233       if (uc != 0x53) RETURN(BZ_DATA_ERROR);
00234       GET_UCHAR(BZ_X_BLKHDR_6, uc);
00235       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
00236 
00237       s->currBlockNo++;
00238       if (s->verbosity >= 2)
00239          VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
00240  
00241       s->storedBlockCRC = 0;
00242       GET_UCHAR(BZ_X_BCRC_1, uc);
00243       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
00244       GET_UCHAR(BZ_X_BCRC_2, uc);
00245       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
00246       GET_UCHAR(BZ_X_BCRC_3, uc);
00247       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
00248       GET_UCHAR(BZ_X_BCRC_4, uc);
00249       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
00250 
00251       GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
00252 
00253       s->origPtr = 0;
00254       GET_UCHAR(BZ_X_ORIGPTR_1, uc);
00255       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
00256       GET_UCHAR(BZ_X_ORIGPTR_2, uc);
00257       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
00258       GET_UCHAR(BZ_X_ORIGPTR_3, uc);
00259       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
00260 
00261       if (s->origPtr < 0)
00262          RETURN(BZ_DATA_ERROR);
00263       if (s->origPtr > 10 + 100000*s->blockSize100k) 
00264          RETURN(BZ_DATA_ERROR);
00265 
00266       /*--- Receive the mapping table ---*/
00267       for (i = 0; i < 16; i++) {
00268          GET_BIT(BZ_X_MAPPING_1, uc);
00269          if (uc == 1) 
00270             s->inUse16[i] = True; else 
00271             s->inUse16[i] = False;
00272       }
00273 
00274       for (i = 0; i < 256; i++) s->inUse[i] = False;
00275 
00276       for (i = 0; i < 16; i++)
00277          if (s->inUse16[i])
00278             for (j = 0; j < 16; j++) {
00279                GET_BIT(BZ_X_MAPPING_2, uc);
00280                if (uc == 1) s->inUse[i * 16 + j] = True;
00281             }
00282       makeMaps_d ( s );
00283       if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
00284       alphaSize = s->nInUse+2;
00285 
00286       /*--- Now the selectors ---*/
00287       GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
00288       if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
00289       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
00290       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
00291       for (i = 0; i < nSelectors; i++) {
00292          j = 0;
00293          while (True) {
00294             GET_BIT(BZ_X_SELECTOR_3, uc);
00295             if (uc == 0) break;
00296             j++;
00297             if (j >= nGroups) RETURN(BZ_DATA_ERROR);
00298          }
00299          s->selectorMtf[i] = j;
00300       }
00301 
00302       /*--- Undo the MTF values for the selectors. ---*/
00303       {
00304          UChar pos[BZ_N_GROUPS], tmp, v;
00305          for (v = 0; v < nGroups; v++) pos[v] = v;
00306    
00307          for (i = 0; i < nSelectors; i++) {
00308             v = s->selectorMtf[i];
00309             tmp = pos[v];
00310             while (v > 0) { pos[v] = pos[v-1]; v--; }
00311             pos[0] = tmp;
00312             s->selector[i] = tmp;
00313          }
00314       }
00315 
00316       /*--- Now the coding tables ---*/
00317       for (t = 0; t < nGroups; t++) {
00318          GET_BITS(BZ_X_CODING_1, curr, 5);
00319          for (i = 0; i < alphaSize; i++) {
00320             while (True) {
00321                if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
00322                GET_BIT(BZ_X_CODING_2, uc);
00323                if (uc == 0) break;
00324                GET_BIT(BZ_X_CODING_3, uc);
00325                if (uc == 0) curr++; else curr--;
00326             }
00327             s->len[t][i] = curr;
00328          }
00329       }
00330 
00331       /*--- Create the Huffman decoding tables ---*/
00332       for (t = 0; t < nGroups; t++) {
00333          minLen = 32;
00334          maxLen = 0;
00335          for (i = 0; i < alphaSize; i++) {
00336             if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
00337             if (s->len[t][i] < minLen) minLen = s->len[t][i];
00338          }
00339          BZ2_hbCreateDecodeTables ( 
00340             &(s->limit[t][0]), 
00341             &(s->base[t][0]), 
00342             &(s->perm[t][0]), 
00343             &(s->len[t][0]),
00344             minLen, maxLen, alphaSize
00345          );
00346          s->minLens[t] = minLen;
00347       }
00348 
00349       /*--- Now the MTF values ---*/
00350 
00351       EOB      = s->nInUse+1;
00352       nblockMAX = 100000 * s->blockSize100k;
00353       groupNo  = -1;
00354       groupPos = 0;
00355 
00356       for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
00357 
00358       /*-- MTF init --*/
00359       {
00360          Int32 ii, jj, kk;
00361          kk = MTFA_SIZE-1;
00362          for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
00363             for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
00364                s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
00365                kk--;
00366             }
00367             s->mtfbase[ii] = kk + 1;
00368          }
00369       }
00370       /*-- end MTF init --*/
00371 
00372       nblock = 0;
00373       GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
00374 
00375       while (True) {
00376 
00377          if (nextSym == EOB) break;
00378 
00379          if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
00380 
00381             es = -1;
00382             N = 1;
00383             do {
00384                /* Check that N doesn't get too big, so that es doesn't
00385                   go negative.  The maximum value that can be
00386                   RUNA/RUNB encoded is equal to the block size (post
00387                   the initial RLE), viz, 900k, so bounding N at 2
00388                   million should guard against overflow without
00389                   rejecting any legitimate inputs. */
00390                if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
00391                if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
00392                if (nextSym == BZ_RUNB) es = es + (1+1) * N;
00393                N = N * 2;
00394                GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
00395             }
00396                while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
00397 
00398             es++;
00399             uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
00400             s->unzftab[uc] += es;
00401 
00402             if (s->smallDecompress)
00403                while (es > 0) {
00404                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
00405                   s->ll16[nblock] = (UInt16)uc;
00406                   nblock++;
00407                   es--;
00408                }
00409             else
00410                while (es > 0) {
00411                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
00412                   s->tt[nblock] = (UInt32)uc;
00413                   nblock++;
00414                   es--;
00415                };
00416 
00417             continue;
00418 
00419          } else {
00420 
00421             if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
00422 
00423             /*-- uc = MTF ( nextSym-1 ) --*/
00424             {
00425                Int32 ii, jj, kk, pp, lno, off;
00426                UInt32 nn;
00427                nn = (UInt32)(nextSym - 1);
00428 
00429                if (nn < MTFL_SIZE) {
00430                   /* avoid general-case expense */
00431                   pp = s->mtfbase[0];
00432                   uc = s->mtfa[pp+nn];
00433                   while (nn > 3) {
00434                      Int32 z = pp+nn;
00435                      s->mtfa[(z)  ] = s->mtfa[(z)-1];
00436                      s->mtfa[(z)-1] = s->mtfa[(z)-2];
00437                      s->mtfa[(z)-2] = s->mtfa[(z)-3];
00438                      s->mtfa[(z)-3] = s->mtfa[(z)-4];
00439                      nn -= 4;
00440                   }
00441                   while (nn > 0) { 
00442                      s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
00443                   };
00444                   s->mtfa[pp] = uc;
00445                } else { 
00446                   /* general case */
00447                   lno = nn / MTFL_SIZE;
00448                   off = nn % MTFL_SIZE;
00449                   pp = s->mtfbase[lno] + off;
00450                   uc = s->mtfa[pp];
00451                   while (pp > s->mtfbase[lno]) { 
00452                      s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
00453                   };
00454                   s->mtfbase[lno]++;
00455                   while (lno > 0) {
00456                      s->mtfbase[lno]--;
00457                      s->mtfa[s->mtfbase[lno]] 
00458                         = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
00459                      lno--;
00460                   }
00461                   s->mtfbase[0]--;
00462                   s->mtfa[s->mtfbase[0]] = uc;
00463                   if (s->mtfbase[0] == 0) {
00464                      kk = MTFA_SIZE-1;
00465                      for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
00466                         for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
00467                            s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
00468                            kk--;
00469                         }
00470                         s->mtfbase[ii] = kk + 1;
00471                      }
00472                   }
00473                }
00474             }
00475             /*-- end uc = MTF ( nextSym-1 ) --*/
00476 
00477             s->unzftab[s->seqToUnseq[uc]]++;
00478             if (s->smallDecompress)
00479                s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
00480                s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
00481             nblock++;
00482 
00483             GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
00484             continue;
00485          }
00486       }
00487 
00488       /* Now we know what nblock is, we can do a better sanity
00489          check on s->origPtr.
00490       */
00491       if (s->origPtr < 0 || s->origPtr >= nblock)
00492          RETURN(BZ_DATA_ERROR);
00493 
00494       /*-- Set up cftab to facilitate generation of T^(-1) --*/
00495       /* Check: unzftab entries in range. */
00496       for (i = 0; i <= 255; i++) {
00497          if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
00498             RETURN(BZ_DATA_ERROR);
00499       }
00500       /* Actually generate cftab. */
00501       s->cftab[0] = 0;
00502       for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
00503       for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
00504       /* Check: cftab entries in range. */
00505       for (i = 0; i <= 256; i++) {
00506          if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
00507             /* s->cftab[i] can legitimately be == nblock */
00508             RETURN(BZ_DATA_ERROR);
00509          }
00510       }
00511       /* Check: cftab entries non-descending. */
00512       for (i = 1; i <= 256; i++) {
00513          if (s->cftab[i-1] > s->cftab[i]) {
00514             RETURN(BZ_DATA_ERROR);
00515          }
00516       }
00517 
00518       s->state_out_len = 0;
00519       s->state_out_ch  = 0;
00520       BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
00521       s->state = BZ_X_OUTPUT;
00522       if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
00523 
00524       if (s->smallDecompress) {
00525 
00526          /*-- Make a copy of cftab, used in generation of T --*/
00527          for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
00528 
00529          /*-- compute the T vector --*/
00530          for (i = 0; i < nblock; i++) {
00531             uc = (UChar)(s->ll16[i]);
00532             SET_LL(i, s->cftabCopy[uc]);
00533             s->cftabCopy[uc]++;
00534          }
00535 
00536          /*-- Compute T^(-1) by pointer reversal on T --*/
00537          i = s->origPtr;
00538          j = GET_LL(i);
00539          do {
00540             Int32 tmp = GET_LL(j);
00541             SET_LL(j, i);
00542             i = j;
00543             j = tmp;
00544          }
00545             while (i != s->origPtr);
00546 
00547          s->tPos = s->origPtr;
00548          s->nblock_used = 0;
00549          if (s->blockRandomised) {
00550             BZ_RAND_INIT_MASK;
00551             BZ_GET_SMALL(s->k0); s->nblock_used++;
00552             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
00553          } else {
00554             BZ_GET_SMALL(s->k0); s->nblock_used++;
00555          }
00556 
00557       } else {
00558 
00559          /*-- compute the T^(-1) vector --*/
00560          for (i = 0; i < nblock; i++) {
00561             uc = (UChar)(s->tt[i] & 0xff);
00562             s->tt[s->cftab[uc]] |= (i << 8);
00563             s->cftab[uc]++;
00564          }
00565 
00566          s->tPos = s->tt[s->origPtr] >> 8;
00567          s->nblock_used = 0;
00568          if (s->blockRandomised) {
00569             BZ_RAND_INIT_MASK;
00570             BZ_GET_FAST(s->k0); s->nblock_used++;
00571             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
00572          } else {
00573             BZ_GET_FAST(s->k0); s->nblock_used++;
00574          }
00575 
00576       }
00577 
00578       RETURN(BZ_OK);
00579 
00580 
00581 
00582     endhdr_2:
00583 
00584       GET_UCHAR(BZ_X_ENDHDR_2, uc);
00585       if (uc != 0x72) RETURN(BZ_DATA_ERROR);
00586       GET_UCHAR(BZ_X_ENDHDR_3, uc);
00587       if (uc != 0x45) RETURN(BZ_DATA_ERROR);
00588       GET_UCHAR(BZ_X_ENDHDR_4, uc);
00589       if (uc != 0x38) RETURN(BZ_DATA_ERROR);
00590       GET_UCHAR(BZ_X_ENDHDR_5, uc);
00591       if (uc != 0x50) RETURN(BZ_DATA_ERROR);
00592       GET_UCHAR(BZ_X_ENDHDR_6, uc);
00593       if (uc != 0x90) RETURN(BZ_DATA_ERROR);
00594 
00595       s->storedCombinedCRC = 0;
00596       GET_UCHAR(BZ_X_CCRC_1, uc);
00597       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
00598       GET_UCHAR(BZ_X_CCRC_2, uc);
00599       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
00600       GET_UCHAR(BZ_X_CCRC_3, uc);
00601       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
00602       GET_UCHAR(BZ_X_CCRC_4, uc);
00603       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
00604 
00605       s->state = BZ_X_IDLE;
00606       RETURN(BZ_STREAM_END);
00607 
00608       default: AssertH ( False, 4001 );
00609    }
00610 
00611    AssertH ( False, 4002 );
00612 
00613    save_state_and_return:
00614 
00615    s->save_i           = i;
00616    s->save_j           = j;
00617    s->save_t           = t;
00618    s->save_alphaSize   = alphaSize;
00619    s->save_nGroups     = nGroups;
00620    s->save_nSelectors  = nSelectors;
00621    s->save_EOB         = EOB;
00622    s->save_groupNo     = groupNo;
00623    s->save_groupPos    = groupPos;
00624    s->save_nextSym     = nextSym;
00625    s->save_nblockMAX   = nblockMAX;
00626    s->save_nblock      = nblock;
00627    s->save_es          = es;
00628    s->save_N           = N;
00629    s->save_curr        = curr;
00630    s->save_zt          = zt;
00631    s->save_zn          = zn;
00632    s->save_zvec        = zvec;
00633    s->save_zj          = zj;
00634    s->save_gSel        = gSel;
00635    s->save_gMinlen     = gMinlen;
00636    s->save_gLimit      = gLimit;
00637    s->save_gBase       = gBase;
00638    s->save_gPerm       = gPerm;
00639 
00640    return retVal;   
00641 }
00642 
00643 
00644 /*-------------------------------------------------------------*/
00645 /*--- end                                      decompress.c ---*/
00646 /*-------------------------------------------------------------*/