Home | History | Annotate | Line # | Download | only in dist
      1 /*	$NetBSD: decompress.c,v 1.4 2019/07/21 11:52:14 maya Exp $	*/
      2 
      3 
      4 /*-------------------------------------------------------------*/
      5 /*--- Decompression machinery                               ---*/
      6 /*---                                          decompress.c ---*/
      7 /*-------------------------------------------------------------*/
      8 
      9 /* ------------------------------------------------------------------
     10    This file is part of bzip2/libbzip2, a program and library for
     11    lossless, block-sorting data compression.
     12 
     13    bzip2/libbzip2 version 1.0.8 of 13 July 2019
     14    Copyright (C) 1996-2019 Julian Seward <jseward (at) acm.org>
     15 
     16    Please read the WARNING, DISCLAIMER and PATENTS sections in the
     17    README file.
     18 
     19    This program is released under the terms of the license contained
     20    in the file LICENSE.
     21    ------------------------------------------------------------------ */
     22 
     23 
     24 #include "bzlib_private.h"
     25 
     26 
     27 /*---------------------------------------------------*/
     28 static
     29 void makeMaps_d ( DState* s )
     30 {
     31    Int32 i;
     32    s->nInUse = 0;
     33    for (i = 0; i < 256; i++)
     34       if (s->inUse[i]) {
     35          s->seqToUnseq[s->nInUse] = i;
     36          s->nInUse++;
     37       }
     38 }
     39 
     40 
     41 /*---------------------------------------------------*/
     42 #define RETURN(rrr)                               \
     43    { retVal = rrr; goto save_state_and_return; };
     44 
     45 #define GET_BITS(lll,vvv,nnn)                     \
     46    case lll: s->state = lll;                      \
     47    while (True) {                                 \
     48       if (s->bsLive >= nnn) {                     \
     49          UInt32 v;                                \
     50          v = (s->bsBuff >>                        \
     51              (s->bsLive-nnn)) & ((1 << nnn)-1);   \
     52          s->bsLive -= nnn;                        \
     53          vvv = v;                                 \
     54          break;                                   \
     55       }                                           \
     56       if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
     57       s->bsBuff                                   \
     58          = (s->bsBuff << 8) |                     \
     59            ((UInt32)                              \
     60               (*((UChar*)(s->strm->next_in))));   \
     61       s->bsLive += 8;                             \
     62       s->strm->next_in++;                         \
     63       s->strm->avail_in--;                        \
     64       s->strm->total_in_lo32++;                   \
     65       if (s->strm->total_in_lo32 == 0)            \
     66          s->strm->total_in_hi32++;                \
     67    }
     68 
     69 #define GET_UCHAR(lll,uuu)                        \
     70    GET_BITS(lll,uuu,8)
     71 
     72 #define GET_BIT(lll,uuu)                          \
     73    GET_BITS(lll,uuu,1)
     74 
     75 /*---------------------------------------------------*/
     76 #define GET_MTF_VAL(label1,label2,lval)           \
     77 {                                                 \
     78    if (groupPos == 0) {                           \
     79       groupNo++;                                  \
     80       if (groupNo >= nSelectors)                  \
     81          RETURN(BZ_DATA_ERROR);                   \
     82       groupPos = BZ_G_SIZE;                       \
     83       gSel = s->selector[groupNo];                \
     84       gMinlen = s->minLens[gSel];                 \
     85       gLimit = &(s->limit[gSel][0]);              \
     86       gPerm = &(s->perm[gSel][0]);                \
     87       gBase = &(s->base[gSel][0]);                \
     88    }                                              \
     89    groupPos--;                                    \
     90    zn = gMinlen;                                  \
     91    GET_BITS(label1, zvec, zn);                    \
     92    while (1) {                                    \
     93       if (zn > 20 /* the longest code */)         \
     94          RETURN(BZ_DATA_ERROR);                   \
     95       if (zvec <= gLimit[zn]) break;              \
     96       zn++;                                       \
     97       GET_BIT(label2, zj);                        \
     98       zvec = (zvec << 1) | zj;                    \
     99    };                                             \
    100    if (zvec - gBase[zn] < 0                       \
    101        || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
    102       RETURN(BZ_DATA_ERROR);                      \
    103    lval = gPerm[zvec - gBase[zn]];                \
    104 }
    105 
    106 
    107 /*---------------------------------------------------*/
    108 Int32 BZ2_decompress ( DState* s )
    109 {
    110    UChar      uc;
    111    Int32      retVal;
    112    Int32      minLen, maxLen;
    113    bz_stream* strm = s->strm;
    114 
    115    /* stuff that needs to be saved/restored */
    116    Int32  i;
    117    Int32  j;
    118    Int32  t;
    119    Int32  alphaSize;
    120    Int32  nGroups;
    121    Int32  nSelectors;
    122    Int32  EOB;
    123    Int32  groupNo;
    124    Int32  groupPos;
    125    Int32  nextSym;
    126    Int32  nblockMAX;
    127    Int32  nblock;
    128    Int32  es;
    129    Int32  N;
    130    Int32  curr;
    131    Int32  zt;
    132    Int32  zn;
    133    Int32  zvec;
    134    Int32  zj;
    135    Int32  gSel;
    136    Int32  gMinlen;
    137    Int32* gLimit;
    138    Int32* gBase;
    139    Int32* gPerm;
    140 
    141    if (s->state == BZ_X_MAGIC_1) {
    142       /*initialise the save area*/
    143       s->save_i           = 0;
    144       s->save_j           = 0;
    145       s->save_t           = 0;
    146       s->save_alphaSize   = 0;
    147       s->save_nGroups     = 0;
    148       s->save_nSelectors  = 0;
    149       s->save_EOB         = 0;
    150       s->save_groupNo     = 0;
    151       s->save_groupPos    = 0;
    152       s->save_nextSym     = 0;
    153       s->save_nblockMAX   = 0;
    154       s->save_nblock      = 0;
    155       s->save_es          = 0;
    156       s->save_N           = 0;
    157       s->save_curr        = 0;
    158       s->save_zt          = 0;
    159       s->save_zn          = 0;
    160       s->save_zvec        = 0;
    161       s->save_zj          = 0;
    162       s->save_gSel        = 0;
    163       s->save_gMinlen     = 0;
    164       s->save_gLimit      = NULL;
    165       s->save_gBase       = NULL;
    166       s->save_gPerm       = NULL;
    167    }
    168 
    169    /*restore from the save area*/
    170    i           = s->save_i;
    171    j           = s->save_j;
    172    t           = s->save_t;
    173    alphaSize   = s->save_alphaSize;
    174    nGroups     = s->save_nGroups;
    175    nSelectors  = s->save_nSelectors;
    176    EOB         = s->save_EOB;
    177    groupNo     = s->save_groupNo;
    178    groupPos    = s->save_groupPos;
    179    nextSym     = s->save_nextSym;
    180    nblockMAX   = s->save_nblockMAX;
    181    nblock      = s->save_nblock;
    182    es          = s->save_es;
    183    N           = s->save_N;
    184    curr        = s->save_curr;
    185    zt          = s->save_zt;
    186    zn          = s->save_zn;
    187    zvec        = s->save_zvec;
    188    zj          = s->save_zj;
    189    gSel        = s->save_gSel;
    190    gMinlen     = s->save_gMinlen;
    191    gLimit      = s->save_gLimit;
    192    gBase       = s->save_gBase;
    193    gPerm       = s->save_gPerm;
    194 
    195    retVal = BZ_OK;
    196 
    197    switch (s->state) {
    198 
    199       GET_UCHAR(BZ_X_MAGIC_1, uc);
    200       if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
    201 
    202       GET_UCHAR(BZ_X_MAGIC_2, uc);
    203       if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
    204 
    205       GET_UCHAR(BZ_X_MAGIC_3, uc)
    206       if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
    207 
    208       GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
    209       if (s->blockSize100k < (BZ_HDR_0 + 1) ||
    210           s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
    211       s->blockSize100k -= BZ_HDR_0;
    212 
    213       if (s->smallDecompress) {
    214          s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
    215          s->ll4  = BZALLOC(
    216                       ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
    217                    );
    218          if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
    219       } else {
    220          s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
    221          if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
    222       }
    223 
    224       GET_UCHAR(BZ_X_BLKHDR_1, uc);
    225 
    226       if (uc == 0x17) goto endhdr_2;
    227       if (uc != 0x31) RETURN(BZ_DATA_ERROR);
    228       GET_UCHAR(BZ_X_BLKHDR_2, uc);
    229       if (uc != 0x41) RETURN(BZ_DATA_ERROR);
    230       GET_UCHAR(BZ_X_BLKHDR_3, uc);
    231       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
    232       GET_UCHAR(BZ_X_BLKHDR_4, uc);
    233       if (uc != 0x26) RETURN(BZ_DATA_ERROR);
    234       GET_UCHAR(BZ_X_BLKHDR_5, uc);
    235       if (uc != 0x53) RETURN(BZ_DATA_ERROR);
    236       GET_UCHAR(BZ_X_BLKHDR_6, uc);
    237       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
    238 
    239       s->currBlockNo++;
    240       if (s->verbosity >= 2)
    241          VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
    242 
    243       s->storedBlockCRC = 0;
    244       GET_UCHAR(BZ_X_BCRC_1, uc);
    245       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
    246       GET_UCHAR(BZ_X_BCRC_2, uc);
    247       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
    248       GET_UCHAR(BZ_X_BCRC_3, uc);
    249       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
    250       GET_UCHAR(BZ_X_BCRC_4, uc);
    251       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
    252 
    253       GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
    254 
    255       s->origPtr = 0;
    256       GET_UCHAR(BZ_X_ORIGPTR_1, uc);
    257       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
    258       GET_UCHAR(BZ_X_ORIGPTR_2, uc);
    259       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
    260       GET_UCHAR(BZ_X_ORIGPTR_3, uc);
    261       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
    262 
    263       if (s->origPtr < 0)
    264          RETURN(BZ_DATA_ERROR);
    265       if (s->origPtr > 10 + 100000*s->blockSize100k)
    266          RETURN(BZ_DATA_ERROR);
    267 
    268       /*--- Receive the mapping table ---*/
    269       for (i = 0; i < 16; i++) {
    270          GET_BIT(BZ_X_MAPPING_1, uc);
    271          if (uc == 1)
    272             s->inUse16[i] = True; else
    273             s->inUse16[i] = False;
    274       }
    275 
    276       for (i = 0; i < 256; i++) s->inUse[i] = False;
    277 
    278       for (i = 0; i < 16; i++)
    279          if (s->inUse16[i])
    280             for (j = 0; j < 16; j++) {
    281                GET_BIT(BZ_X_MAPPING_2, uc);
    282                if (uc == 1) s->inUse[i * 16 + j] = True;
    283             }
    284       makeMaps_d ( s );
    285       if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
    286       alphaSize = s->nInUse+2;
    287 
    288       /*--- Now the selectors ---*/
    289       GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
    290       if (nGroups < 2 || nGroups > BZ_N_GROUPS) RETURN(BZ_DATA_ERROR);
    291       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
    292       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
    293       for (i = 0; i < nSelectors; i++) {
    294          j = 0;
    295          while (True) {
    296             GET_BIT(BZ_X_SELECTOR_3, uc);
    297             if (uc == 0) break;
    298             j++;
    299             if (j >= nGroups) RETURN(BZ_DATA_ERROR);
    300          }
    301          /* Having more than BZ_MAX_SELECTORS doesn't make much sense
    302             since they will never be used, but some implementations might
    303             "round up" the number of selectors, so just ignore those. */
    304          if (i < BZ_MAX_SELECTORS)
    305            s->selectorMtf[i] = j;
    306       }
    307       if (nSelectors > BZ_MAX_SELECTORS)
    308         nSelectors = BZ_MAX_SELECTORS;
    309 
    310       /*--- Undo the MTF values for the selectors. ---*/
    311       {
    312          UChar pos[BZ_N_GROUPS], tmp, v;
    313          for (v = 0; v < nGroups; v++) pos[v] = v;
    314 
    315          for (i = 0; i < nSelectors; i++) {
    316             v = s->selectorMtf[i];
    317             tmp = pos[v];
    318             while (v > 0) { pos[v] = pos[v-1]; v--; }
    319             pos[0] = tmp;
    320             s->selector[i] = tmp;
    321          }
    322       }
    323 
    324       /*--- Now the coding tables ---*/
    325       for (t = 0; t < nGroups; t++) {
    326          GET_BITS(BZ_X_CODING_1, curr, 5);
    327          for (i = 0; i < alphaSize; i++) {
    328             while (True) {
    329                if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
    330                GET_BIT(BZ_X_CODING_2, uc);
    331                if (uc == 0) break;
    332                GET_BIT(BZ_X_CODING_3, uc);
    333                if (uc == 0) curr++; else curr--;
    334             }
    335             s->len[t][i] = curr;
    336          }
    337       }
    338 
    339       /*--- Create the Huffman decoding tables ---*/
    340       for (t = 0; t < nGroups; t++) {
    341          minLen = 32;
    342          maxLen = 0;
    343          for (i = 0; i < alphaSize; i++) {
    344             if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
    345             if (s->len[t][i] < minLen) minLen = s->len[t][i];
    346          }
    347          BZ2_hbCreateDecodeTables (
    348             &(s->limit[t][0]),
    349             &(s->base[t][0]),
    350             &(s->perm[t][0]),
    351             &(s->len[t][0]),
    352             minLen, maxLen, alphaSize
    353          );
    354          s->minLens[t] = minLen;
    355       }
    356 
    357       /*--- Now the MTF values ---*/
    358 
    359       EOB      = s->nInUse+1;
    360       nblockMAX = 100000 * s->blockSize100k;
    361       groupNo  = -1;
    362       groupPos = 0;
    363 
    364       for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
    365 
    366       /*-- MTF init --*/
    367       {
    368          Int32 ii, jj, kk;
    369          kk = MTFA_SIZE-1;
    370          for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
    371             for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
    372                s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
    373                kk--;
    374             }
    375             s->mtfbase[ii] = kk + 1;
    376          }
    377       }
    378       /*-- end MTF init --*/
    379 
    380       nblock = 0;
    381       GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
    382 
    383       while (True) {
    384 
    385          if (nextSym == EOB) break;
    386 
    387          if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
    388 
    389             es = -1;
    390             N = 1;
    391             do {
    392                /* Check that N doesn't get too big, so that es doesn't
    393                   go negative.  The maximum value that can be
    394                   RUNA/RUNB encoded is equal to the block size (post
    395                   the initial RLE), viz, 900k, so bounding N at 2
    396                   million should guard against overflow without
    397                   rejecting any legitimate inputs. */
    398                if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
    399                if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
    400                if (nextSym == BZ_RUNB) es = es + (1+1) * N;
    401                N = N * 2;
    402                GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
    403             }
    404                while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
    405 
    406             es++;
    407             uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
    408             s->unzftab[uc] += es;
    409 
    410             if (s->smallDecompress)
    411                while (es > 0) {
    412                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
    413                   s->ll16[nblock] = (UInt16)uc;
    414                   nblock++;
    415                   es--;
    416                }
    417             else
    418                while (es > 0) {
    419                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
    420                   s->tt[nblock] = (UInt32)uc;
    421                   nblock++;
    422                   es--;
    423                };
    424 
    425             continue;
    426 
    427          } else {
    428 
    429             if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
    430 
    431             /*-- uc = MTF ( nextSym-1 ) --*/
    432             {
    433                Int32 ii, jj, kk, pp, lno, off;
    434                UInt32 nn;
    435                nn = (UInt32)(nextSym - 1);
    436 
    437                if (nn < MTFL_SIZE) {
    438                   /* avoid general-case expense */
    439                   pp = s->mtfbase[0];
    440                   uc = s->mtfa[pp+nn];
    441                   while (nn > 3) {
    442                      Int32 z = pp+nn;
    443                      s->mtfa[(z)  ] = s->mtfa[(z)-1];
    444                      s->mtfa[(z)-1] = s->mtfa[(z)-2];
    445                      s->mtfa[(z)-2] = s->mtfa[(z)-3];
    446                      s->mtfa[(z)-3] = s->mtfa[(z)-4];
    447                      nn -= 4;
    448                   }
    449                   while (nn > 0) {
    450                      s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
    451                   };
    452                   s->mtfa[pp] = uc;
    453                } else {
    454                   /* general case */
    455                   lno = nn / MTFL_SIZE;
    456                   off = nn % MTFL_SIZE;
    457                   pp = s->mtfbase[lno] + off;
    458                   uc = s->mtfa[pp];
    459                   while (pp > s->mtfbase[lno]) {
    460                      s->mtfa[pp] = s->mtfa[pp-1]; pp--;
    461                   };
    462                   s->mtfbase[lno]++;
    463                   while (lno > 0) {
    464                      s->mtfbase[lno]--;
    465                      s->mtfa[s->mtfbase[lno]]
    466                         = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
    467                      lno--;
    468                   }
    469                   s->mtfbase[0]--;
    470                   s->mtfa[s->mtfbase[0]] = uc;
    471                   if (s->mtfbase[0] == 0) {
    472                      kk = MTFA_SIZE-1;
    473                      for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
    474                         for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
    475                            s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
    476                            kk--;
    477                         }
    478                         s->mtfbase[ii] = kk + 1;
    479                      }
    480                   }
    481                }
    482             }
    483             /*-- end uc = MTF ( nextSym-1 ) --*/
    484 
    485             s->unzftab[s->seqToUnseq[uc]]++;
    486             if (s->smallDecompress)
    487                s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
    488                s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
    489             nblock++;
    490 
    491             GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
    492             continue;
    493          }
    494       }
    495 
    496       /* Now we know what nblock is, we can do a better sanity
    497          check on s->origPtr.
    498       */
    499       if (s->origPtr < 0 || s->origPtr >= nblock)
    500          RETURN(BZ_DATA_ERROR);
    501 
    502       /*-- Set up cftab to facilitate generation of T^(-1) --*/
    503       /* Check: unzftab entries in range. */
    504       for (i = 0; i <= 255; i++) {
    505          if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
    506             RETURN(BZ_DATA_ERROR);
    507       }
    508       /* Actually generate cftab. */
    509       s->cftab[0] = 0;
    510       for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
    511       for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
    512       /* Check: cftab entries in range. */
    513       for (i = 0; i <= 256; i++) {
    514          if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
    515             /* s->cftab[i] can legitimately be == nblock */
    516             RETURN(BZ_DATA_ERROR);
    517          }
    518       }
    519       /* Check: cftab entries non-descending. */
    520       for (i = 1; i <= 256; i++) {
    521          if (s->cftab[i-1] > s->cftab[i]) {
    522             RETURN(BZ_DATA_ERROR);
    523          }
    524       }
    525 
    526       s->state_out_len = 0;
    527       s->state_out_ch  = 0;
    528       BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
    529       s->state = BZ_X_OUTPUT;
    530       if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
    531 
    532       if (s->smallDecompress) {
    533 
    534          /*-- Make a copy of cftab, used in generation of T --*/
    535          for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
    536 
    537          /*-- compute the T vector --*/
    538          for (i = 0; i < nblock; i++) {
    539             uc = (UChar)(s->ll16[i]);
    540             SET_LL(i, s->cftabCopy[uc]);
    541             s->cftabCopy[uc]++;
    542          }
    543 
    544          /*-- Compute T^(-1) by pointer reversal on T --*/
    545          i = s->origPtr;
    546          j = GET_LL(i);
    547          do {
    548             Int32 tmp = GET_LL(j);
    549             SET_LL(j, i);
    550             i = j;
    551             j = tmp;
    552          }
    553             while (i != s->origPtr);
    554 
    555          s->tPos = s->origPtr;
    556          s->nblock_used = 0;
    557          if (s->blockRandomised) {
    558             BZ_RAND_INIT_MASK;
    559             BZ_GET_SMALL(s->k0); s->nblock_used++;
    560             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
    561          } else {
    562             BZ_GET_SMALL(s->k0); s->nblock_used++;
    563          }
    564 
    565       } else {
    566 
    567          /*-- compute the T^(-1) vector --*/
    568          for (i = 0; i < nblock; i++) {
    569             uc = (UChar)(s->tt[i] & 0xff);
    570             s->tt[s->cftab[uc]] |= (i << 8);
    571             s->cftab[uc]++;
    572          }
    573 
    574          s->tPos = s->tt[s->origPtr] >> 8;
    575          s->nblock_used = 0;
    576          if (s->blockRandomised) {
    577             BZ_RAND_INIT_MASK;
    578             BZ_GET_FAST(s->k0); s->nblock_used++;
    579             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
    580          } else {
    581             BZ_GET_FAST(s->k0); s->nblock_used++;
    582          }
    583 
    584       }
    585 
    586       RETURN(BZ_OK);
    587 
    588 
    589 
    590     endhdr_2:
    591 
    592       GET_UCHAR(BZ_X_ENDHDR_2, uc);
    593       if (uc != 0x72) RETURN(BZ_DATA_ERROR);
    594       GET_UCHAR(BZ_X_ENDHDR_3, uc);
    595       if (uc != 0x45) RETURN(BZ_DATA_ERROR);
    596       GET_UCHAR(BZ_X_ENDHDR_4, uc);
    597       if (uc != 0x38) RETURN(BZ_DATA_ERROR);
    598       GET_UCHAR(BZ_X_ENDHDR_5, uc);
    599       if (uc != 0x50) RETURN(BZ_DATA_ERROR);
    600       GET_UCHAR(BZ_X_ENDHDR_6, uc);
    601       if (uc != 0x90) RETURN(BZ_DATA_ERROR);
    602 
    603       s->storedCombinedCRC = 0;
    604       GET_UCHAR(BZ_X_CCRC_1, uc);
    605       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
    606       GET_UCHAR(BZ_X_CCRC_2, uc);
    607       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
    608       GET_UCHAR(BZ_X_CCRC_3, uc);
    609       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
    610       GET_UCHAR(BZ_X_CCRC_4, uc);
    611       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
    612 
    613       s->state = BZ_X_IDLE;
    614       RETURN(BZ_STREAM_END);
    615 
    616       default: AssertH ( False, 4001 );
    617    }
    618 
    619    AssertH ( False, 4002 );
    620 
    621    save_state_and_return:
    622 
    623    s->save_i           = i;
    624    s->save_j           = j;
    625    s->save_t           = t;
    626    s->save_alphaSize   = alphaSize;
    627    s->save_nGroups     = nGroups;
    628    s->save_nSelectors  = nSelectors;
    629    s->save_EOB         = EOB;
    630    s->save_groupNo     = groupNo;
    631    s->save_groupPos    = groupPos;
    632    s->save_nextSym     = nextSym;
    633    s->save_nblockMAX   = nblockMAX;
    634    s->save_nblock      = nblock;
    635    s->save_es          = es;
    636    s->save_N           = N;
    637    s->save_curr        = curr;
    638    s->save_zt          = zt;
    639    s->save_zn          = zn;
    640    s->save_zvec        = zvec;
    641    s->save_zj          = zj;
    642    s->save_gSel        = gSel;
    643    s->save_gMinlen     = gMinlen;
    644    s->save_gLimit      = gLimit;
    645    s->save_gBase       = gBase;
    646    s->save_gPerm       = gPerm;
    647 
    648    return retVal;
    649 }
    650 
    651 
    652 /*-------------------------------------------------------------*/
    653 /*--- end                                      decompress.c ---*/
    654 /*-------------------------------------------------------------*/
    655