Back to index

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