Blame decompress.c

Packit 71fd91
Packit 71fd91
/*-------------------------------------------------------------*/
Packit 71fd91
/*--- Decompression machinery                               ---*/
Packit 71fd91
/*---                                          decompress.c ---*/
Packit 71fd91
/*-------------------------------------------------------------*/
Packit 71fd91
Packit 71fd91
/* ------------------------------------------------------------------
Packit 71fd91
   This file is part of bzip2/libbzip2, a program and library for
Packit 71fd91
   lossless, block-sorting data compression.
Packit 71fd91
Packit 71fd91
   bzip2/libbzip2 version 1.0.6 of 6 September 2010
Packit 71fd91
   Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
Packit 71fd91
Packit 71fd91
   Please read the WARNING, DISCLAIMER and PATENTS sections in the 
Packit 71fd91
   README file.
Packit 71fd91
Packit 71fd91
   This program is released under the terms of the license contained
Packit 71fd91
   in the file LICENSE.
Packit 71fd91
   ------------------------------------------------------------------ */
Packit 71fd91
Packit 71fd91
Packit 71fd91
#include "bzlib_private.h"
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
static
Packit 71fd91
void makeMaps_d ( DState* s )
Packit 71fd91
{
Packit 71fd91
   Int32 i;
Packit 71fd91
   s->nInUse = 0;
Packit 71fd91
   for (i = 0; i < 256; i++)
Packit 71fd91
      if (s->inUse[i]) {
Packit 71fd91
         s->seqToUnseq[s->nInUse] = i;
Packit 71fd91
         s->nInUse++;
Packit 71fd91
      }
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
#define RETURN(rrr)                               \
Packit 71fd91
   { retVal = rrr; goto save_state_and_return; };
Packit 71fd91
Packit 71fd91
#define GET_BITS(lll,vvv,nnn)                     \
Packit 71fd91
   case lll: s->state = lll;                      \
Packit 71fd91
   while (True) {                                 \
Packit 71fd91
      if (s->bsLive >= nnn) {                     \
Packit 71fd91
         UInt32 v;                                \
Packit 71fd91
         v = (s->bsBuff >>                        \
Packit 71fd91
             (s->bsLive-nnn)) & ((1 << nnn)-1);   \
Packit 71fd91
         s->bsLive -= nnn;                        \
Packit 71fd91
         vvv = v;                                 \
Packit 71fd91
         break;                                   \
Packit 71fd91
      }                                           \
Packit 71fd91
      if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
Packit 71fd91
      s->bsBuff                                   \
Packit 71fd91
         = (s->bsBuff << 8) |                     \
Packit 71fd91
           ((UInt32)                              \
Packit 71fd91
              (*((UChar*)(s->strm->next_in))));   \
Packit 71fd91
      s->bsLive += 8;                             \
Packit 71fd91
      s->strm->next_in++;                         \
Packit 71fd91
      s->strm->avail_in--;                        \
Packit 71fd91
      s->strm->total_in_lo32++;                   \
Packit 71fd91
      if (s->strm->total_in_lo32 == 0)            \
Packit 71fd91
         s->strm->total_in_hi32++;                \
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
#define GET_UCHAR(lll,uuu)                        \
Packit 71fd91
   GET_BITS(lll,uuu,8)
Packit 71fd91
Packit 71fd91
#define GET_BIT(lll,uuu)                          \
Packit 71fd91
   GET_BITS(lll,uuu,1)
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
#define GET_MTF_VAL(label1,label2,lval)           \
Packit 71fd91
{                                                 \
Packit 71fd91
   if (groupPos == 0) {                           \
Packit 71fd91
      groupNo++;                                  \
Packit 71fd91
      if (groupNo >= nSelectors)                  \
Packit 71fd91
         RETURN(BZ_DATA_ERROR);                   \
Packit 71fd91
      groupPos = BZ_G_SIZE;                       \
Packit 71fd91
      gSel = s->selector[groupNo];                \
Packit 71fd91
      gMinlen = s->minLens[gSel];                 \
Packit 71fd91
      gLimit = &(s->limit[gSel][0]);              \
Packit 71fd91
      gPerm = &(s->perm[gSel][0]);                \
Packit 71fd91
      gBase = &(s->base[gSel][0]);                \
Packit 71fd91
   }                                              \
Packit 71fd91
   groupPos--;                                    \
Packit 71fd91
   zn = gMinlen;                                  \
Packit 71fd91
   GET_BITS(label1, zvec, zn);                    \
Packit 71fd91
   while (1) {                                    \
Packit 71fd91
      if (zn > 20 /* the longest code */)         \
Packit 71fd91
         RETURN(BZ_DATA_ERROR);                   \
Packit 71fd91
      if (zvec <= gLimit[zn]) break;              \
Packit 71fd91
      zn++;                                       \
Packit 71fd91
      GET_BIT(label2, zj);                        \
Packit 71fd91
      zvec = (zvec << 1) | zj;                    \
Packit 71fd91
   };                                             \
Packit 71fd91
   if (zvec - gBase[zn] < 0                       \
Packit 71fd91
       || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
Packit 71fd91
      RETURN(BZ_DATA_ERROR);                      \
Packit 71fd91
   lval = gPerm[zvec - gBase[zn]];                \
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*---------------------------------------------------*/
Packit 71fd91
Int32 BZ2_decompress ( DState* s )
Packit 71fd91
{
Packit 71fd91
   UChar      uc;
Packit 71fd91
   Int32      retVal;
Packit 71fd91
   Int32      minLen, maxLen;
Packit 71fd91
   bz_stream* strm = s->strm;
Packit 71fd91
Packit 71fd91
   /* stuff that needs to be saved/restored */
Packit 71fd91
   Int32  i;
Packit 71fd91
   Int32  j;
Packit 71fd91
   Int32  t;
Packit 71fd91
   Int32  alphaSize;
Packit 71fd91
   Int32  nGroups;
Packit 71fd91
   Int32  nSelectors;
Packit 71fd91
   Int32  EOB;
Packit 71fd91
   Int32  groupNo;
Packit 71fd91
   Int32  groupPos;
Packit 71fd91
   Int32  nextSym;
Packit 71fd91
   Int32  nblockMAX;
Packit 71fd91
   Int32  nblock;
Packit 71fd91
   Int32  es;
Packit 71fd91
   Int32  N;
Packit 71fd91
   Int32  curr;
Packit 71fd91
   Int32  zt;
Packit 71fd91
   Int32  zn; 
Packit 71fd91
   Int32  zvec;
Packit 71fd91
   Int32  zj;
Packit 71fd91
   Int32  gSel;
Packit 71fd91
   Int32  gMinlen;
Packit 71fd91
   Int32* gLimit;
Packit 71fd91
   Int32* gBase;
Packit 71fd91
   Int32* gPerm;
Packit 71fd91
Packit 71fd91
   if (s->state == BZ_X_MAGIC_1) {
Packit 71fd91
      /*initialise the save area*/
Packit 71fd91
      s->save_i           = 0;
Packit 71fd91
      s->save_j           = 0;
Packit 71fd91
      s->save_t           = 0;
Packit 71fd91
      s->save_alphaSize   = 0;
Packit 71fd91
      s->save_nGroups     = 0;
Packit 71fd91
      s->save_nSelectors  = 0;
Packit 71fd91
      s->save_EOB         = 0;
Packit 71fd91
      s->save_groupNo     = 0;
Packit 71fd91
      s->save_groupPos    = 0;
Packit 71fd91
      s->save_nextSym     = 0;
Packit 71fd91
      s->save_nblockMAX   = 0;
Packit 71fd91
      s->save_nblock      = 0;
Packit 71fd91
      s->save_es          = 0;
Packit 71fd91
      s->save_N           = 0;
Packit 71fd91
      s->save_curr        = 0;
Packit 71fd91
      s->save_zt          = 0;
Packit 71fd91
      s->save_zn          = 0;
Packit 71fd91
      s->save_zvec        = 0;
Packit 71fd91
      s->save_zj          = 0;
Packit 71fd91
      s->save_gSel        = 0;
Packit 71fd91
      s->save_gMinlen     = 0;
Packit 71fd91
      s->save_gLimit      = NULL;
Packit 71fd91
      s->save_gBase       = NULL;
Packit 71fd91
      s->save_gPerm       = NULL;
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   /*restore from the save area*/
Packit 71fd91
   i           = s->save_i;
Packit 71fd91
   j           = s->save_j;
Packit 71fd91
   t           = s->save_t;
Packit 71fd91
   alphaSize   = s->save_alphaSize;
Packit 71fd91
   nGroups     = s->save_nGroups;
Packit 71fd91
   nSelectors  = s->save_nSelectors;
Packit 71fd91
   EOB         = s->save_EOB;
Packit 71fd91
   groupNo     = s->save_groupNo;
Packit 71fd91
   groupPos    = s->save_groupPos;
Packit 71fd91
   nextSym     = s->save_nextSym;
Packit 71fd91
   nblockMAX   = s->save_nblockMAX;
Packit 71fd91
   nblock      = s->save_nblock;
Packit 71fd91
   es          = s->save_es;
Packit 71fd91
   N           = s->save_N;
Packit 71fd91
   curr        = s->save_curr;
Packit 71fd91
   zt          = s->save_zt;
Packit 71fd91
   zn          = s->save_zn; 
Packit 71fd91
   zvec        = s->save_zvec;
Packit 71fd91
   zj          = s->save_zj;
Packit 71fd91
   gSel        = s->save_gSel;
Packit 71fd91
   gMinlen     = s->save_gMinlen;
Packit 71fd91
   gLimit      = s->save_gLimit;
Packit 71fd91
   gBase       = s->save_gBase;
Packit 71fd91
   gPerm       = s->save_gPerm;
Packit 71fd91
Packit 71fd91
   retVal = BZ_OK;
Packit 71fd91
Packit 71fd91
   switch (s->state) {
Packit 71fd91
Packit 71fd91
      GET_UCHAR(BZ_X_MAGIC_1, uc);
Packit 71fd91
      if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
Packit 71fd91
Packit 71fd91
      GET_UCHAR(BZ_X_MAGIC_2, uc);
Packit 71fd91
      if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
Packit 71fd91
Packit 71fd91
      GET_UCHAR(BZ_X_MAGIC_3, uc)
Packit 71fd91
      if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
Packit 71fd91
Packit 71fd91
      GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
Packit 71fd91
      if (s->blockSize100k < (BZ_HDR_0 + 1) || 
Packit 71fd91
          s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
Packit 71fd91
      s->blockSize100k -= BZ_HDR_0;
Packit 71fd91
Packit 71fd91
      if (s->smallDecompress) {
Packit 71fd91
         s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
Packit 71fd91
         s->ll4  = BZALLOC( 
Packit 71fd91
                      ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) 
Packit 71fd91
                   );
Packit 71fd91
         if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
Packit 71fd91
      } else {
Packit 71fd91
         s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
Packit 71fd91
         if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      GET_UCHAR(BZ_X_BLKHDR_1, uc);
Packit 71fd91
Packit 71fd91
      if (uc == 0x17) goto endhdr_2;
Packit 71fd91
      if (uc != 0x31) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_BLKHDR_2, uc);
Packit 71fd91
      if (uc != 0x41) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_BLKHDR_3, uc);
Packit 71fd91
      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_BLKHDR_4, uc);
Packit 71fd91
      if (uc != 0x26) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_BLKHDR_5, uc);
Packit 71fd91
      if (uc != 0x53) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_BLKHDR_6, uc);
Packit 71fd91
      if (uc != 0x59) RETURN(BZ_DATA_ERROR);
Packit 71fd91
Packit 71fd91
      s->currBlockNo++;
Packit 71fd91
      if (s->verbosity >= 2)
Packit 71fd91
         VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
Packit 71fd91
 
Packit 71fd91
      s->storedBlockCRC = 0;
Packit 71fd91
      GET_UCHAR(BZ_X_BCRC_1, uc);
Packit 71fd91
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_BCRC_2, uc);
Packit 71fd91
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_BCRC_3, uc);
Packit 71fd91
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_BCRC_4, uc);
Packit 71fd91
      s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
Packit 71fd91
Packit 71fd91
      GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
Packit 71fd91
Packit 71fd91
      s->origPtr = 0;
Packit 71fd91
      GET_UCHAR(BZ_X_ORIGPTR_1, uc);
Packit 71fd91
      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_ORIGPTR_2, uc);
Packit 71fd91
      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_ORIGPTR_3, uc);
Packit 71fd91
      s->origPtr = (s->origPtr << 8) | ((Int32)uc);
Packit 71fd91
Packit 71fd91
      if (s->origPtr < 0)
Packit 71fd91
         RETURN(BZ_DATA_ERROR);
Packit 71fd91
      if (s->origPtr > 10 + 100000*s->blockSize100k) 
Packit 71fd91
         RETURN(BZ_DATA_ERROR);
Packit 71fd91
Packit 71fd91
      /*--- Receive the mapping table ---*/
Packit 71fd91
      for (i = 0; i < 16; i++) {
Packit 71fd91
         GET_BIT(BZ_X_MAPPING_1, uc);
Packit 71fd91
         if (uc == 1) 
Packit 71fd91
            s->inUse16[i] = True; else 
Packit 71fd91
            s->inUse16[i] = False;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      for (i = 0; i < 256; i++) s->inUse[i] = False;
Packit 71fd91
Packit 71fd91
      for (i = 0; i < 16; i++)
Packit 71fd91
         if (s->inUse16[i])
Packit 71fd91
            for (j = 0; j < 16; j++) {
Packit 71fd91
               GET_BIT(BZ_X_MAPPING_2, uc);
Packit 71fd91
               if (uc == 1) s->inUse[i * 16 + j] = True;
Packit 71fd91
            }
Packit 71fd91
      makeMaps_d ( s );
Packit 71fd91
      if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      alphaSize = s->nInUse+2;
Packit 71fd91
Packit 71fd91
      /*--- Now the selectors ---*/
Packit 71fd91
      GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
Packit 71fd91
      if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
Packit 71fd91
      if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      for (i = 0; i < nSelectors; i++) {
Packit 71fd91
         j = 0;
Packit 71fd91
         while (True) {
Packit 71fd91
            GET_BIT(BZ_X_SELECTOR_3, uc);
Packit 71fd91
            if (uc == 0) break;
Packit 71fd91
            j++;
Packit 71fd91
            if (j >= nGroups) RETURN(BZ_DATA_ERROR);
Packit 71fd91
         }
Packit 71fd91
         s->selectorMtf[i] = j;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      /*--- Undo the MTF values for the selectors. ---*/
Packit 71fd91
      {
Packit 71fd91
         UChar pos[BZ_N_GROUPS], tmp, v;
Packit 71fd91
         for (v = 0; v < nGroups; v++) pos[v] = v;
Packit 71fd91
   
Packit 71fd91
         for (i = 0; i < nSelectors; i++) {
Packit 71fd91
            v = s->selectorMtf[i];
Packit 71fd91
            tmp = pos[v];
Packit 71fd91
            while (v > 0) { pos[v] = pos[v-1]; v--; }
Packit 71fd91
            pos[0] = tmp;
Packit 71fd91
            s->selector[i] = tmp;
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      /*--- Now the coding tables ---*/
Packit 71fd91
      for (t = 0; t < nGroups; t++) {
Packit 71fd91
         GET_BITS(BZ_X_CODING_1, curr, 5);
Packit 71fd91
         for (i = 0; i < alphaSize; i++) {
Packit 71fd91
            while (True) {
Packit 71fd91
               if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
Packit 71fd91
               GET_BIT(BZ_X_CODING_2, uc);
Packit 71fd91
               if (uc == 0) break;
Packit 71fd91
               GET_BIT(BZ_X_CODING_3, uc);
Packit 71fd91
               if (uc == 0) curr++; else curr--;
Packit 71fd91
            }
Packit 71fd91
            s->len[t][i] = curr;
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      /*--- Create the Huffman decoding tables ---*/
Packit 71fd91
      for (t = 0; t < nGroups; t++) {
Packit 71fd91
         minLen = 32;
Packit 71fd91
         maxLen = 0;
Packit 71fd91
         for (i = 0; i < alphaSize; i++) {
Packit 71fd91
            if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
Packit 71fd91
            if (s->len[t][i] < minLen) minLen = s->len[t][i];
Packit 71fd91
         }
Packit 71fd91
         BZ2_hbCreateDecodeTables ( 
Packit 71fd91
            &(s->limit[t][0]), 
Packit 71fd91
            &(s->base[t][0]), 
Packit 71fd91
            &(s->perm[t][0]), 
Packit 71fd91
            &(s->len[t][0]),
Packit 71fd91
            minLen, maxLen, alphaSize
Packit 71fd91
         );
Packit 71fd91
         s->minLens[t] = minLen;
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      /*--- Now the MTF values ---*/
Packit 71fd91
Packit 71fd91
      EOB      = s->nInUse+1;
Packit 71fd91
      nblockMAX = 100000 * s->blockSize100k;
Packit 71fd91
      groupNo  = -1;
Packit 71fd91
      groupPos = 0;
Packit 71fd91
Packit 71fd91
      for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
Packit 71fd91
Packit 71fd91
      /*-- MTF init --*/
Packit 71fd91
      {
Packit 71fd91
         Int32 ii, jj, kk;
Packit 71fd91
         kk = MTFA_SIZE-1;
Packit 71fd91
         for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
Packit 71fd91
            for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
Packit 71fd91
               s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
Packit 71fd91
               kk--;
Packit 71fd91
            }
Packit 71fd91
            s->mtfbase[ii] = kk + 1;
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
      /*-- end MTF init --*/
Packit 71fd91
Packit 71fd91
      nblock = 0;
Packit 71fd91
      GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
Packit 71fd91
Packit 71fd91
      while (True) {
Packit 71fd91
Packit 71fd91
         if (nextSym == EOB) break;
Packit 71fd91
Packit 71fd91
         if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
Packit 71fd91
Packit 71fd91
            es = -1;
Packit 71fd91
            N = 1;
Packit 71fd91
            do {
Packit 71fd91
               /* Check that N doesn't get too big, so that es doesn't
Packit 71fd91
                  go negative.  The maximum value that can be
Packit 71fd91
                  RUNA/RUNB encoded is equal to the block size (post
Packit 71fd91
                  the initial RLE), viz, 900k, so bounding N at 2
Packit 71fd91
                  million should guard against overflow without
Packit 71fd91
                  rejecting any legitimate inputs. */
Packit 71fd91
               if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
Packit 71fd91
               if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
Packit 71fd91
               if (nextSym == BZ_RUNB) es = es + (1+1) * N;
Packit 71fd91
               N = N * 2;
Packit 71fd91
               GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
Packit 71fd91
            }
Packit 71fd91
               while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
Packit 71fd91
Packit 71fd91
            es++;
Packit 71fd91
            uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
Packit 71fd91
            s->unzftab[uc] += es;
Packit 71fd91
Packit 71fd91
            if (s->smallDecompress)
Packit 71fd91
               while (es > 0) {
Packit 71fd91
                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
Packit 71fd91
                  s->ll16[nblock] = (UInt16)uc;
Packit 71fd91
                  nblock++;
Packit 71fd91
                  es--;
Packit 71fd91
               }
Packit 71fd91
            else
Packit 71fd91
               while (es > 0) {
Packit 71fd91
                  if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
Packit 71fd91
                  s->tt[nblock] = (UInt32)uc;
Packit 71fd91
                  nblock++;
Packit 71fd91
                  es--;
Packit 71fd91
               };
Packit 71fd91
Packit 71fd91
            continue;
Packit 71fd91
Packit 71fd91
         } else {
Packit 71fd91
Packit 71fd91
            if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
Packit 71fd91
Packit 71fd91
            /*-- uc = MTF ( nextSym-1 ) --*/
Packit 71fd91
            {
Packit 71fd91
               Int32 ii, jj, kk, pp, lno, off;
Packit 71fd91
               UInt32 nn;
Packit 71fd91
               nn = (UInt32)(nextSym - 1);
Packit 71fd91
Packit 71fd91
               if (nn < MTFL_SIZE) {
Packit 71fd91
                  /* avoid general-case expense */
Packit 71fd91
                  pp = s->mtfbase[0];
Packit 71fd91
                  uc = s->mtfa[pp+nn];
Packit 71fd91
                  while (nn > 3) {
Packit 71fd91
                     Int32 z = pp+nn;
Packit 71fd91
                     s->mtfa[(z)  ] = s->mtfa[(z)-1];
Packit 71fd91
                     s->mtfa[(z)-1] = s->mtfa[(z)-2];
Packit 71fd91
                     s->mtfa[(z)-2] = s->mtfa[(z)-3];
Packit 71fd91
                     s->mtfa[(z)-3] = s->mtfa[(z)-4];
Packit 71fd91
                     nn -= 4;
Packit 71fd91
                  }
Packit 71fd91
                  while (nn > 0) { 
Packit 71fd91
                     s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; 
Packit 71fd91
                  };
Packit 71fd91
                  s->mtfa[pp] = uc;
Packit 71fd91
               } else { 
Packit 71fd91
                  /* general case */
Packit 71fd91
                  lno = nn / MTFL_SIZE;
Packit 71fd91
                  off = nn % MTFL_SIZE;
Packit 71fd91
                  pp = s->mtfbase[lno] + off;
Packit 71fd91
                  uc = s->mtfa[pp];
Packit 71fd91
                  while (pp > s->mtfbase[lno]) { 
Packit 71fd91
                     s->mtfa[pp] = s->mtfa[pp-1]; pp--; 
Packit 71fd91
                  };
Packit 71fd91
                  s->mtfbase[lno]++;
Packit 71fd91
                  while (lno > 0) {
Packit 71fd91
                     s->mtfbase[lno]--;
Packit 71fd91
                     s->mtfa[s->mtfbase[lno]] 
Packit 71fd91
                        = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
Packit 71fd91
                     lno--;
Packit 71fd91
                  }
Packit 71fd91
                  s->mtfbase[0]--;
Packit 71fd91
                  s->mtfa[s->mtfbase[0]] = uc;
Packit 71fd91
                  if (s->mtfbase[0] == 0) {
Packit 71fd91
                     kk = MTFA_SIZE-1;
Packit 71fd91
                     for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
Packit 71fd91
                        for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
Packit 71fd91
                           s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
Packit 71fd91
                           kk--;
Packit 71fd91
                        }
Packit 71fd91
                        s->mtfbase[ii] = kk + 1;
Packit 71fd91
                     }
Packit 71fd91
                  }
Packit 71fd91
               }
Packit 71fd91
            }
Packit 71fd91
            /*-- end uc = MTF ( nextSym-1 ) --*/
Packit 71fd91
Packit 71fd91
            s->unzftab[s->seqToUnseq[uc]]++;
Packit 71fd91
            if (s->smallDecompress)
Packit 71fd91
               s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
Packit 71fd91
               s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
Packit 71fd91
            nblock++;
Packit 71fd91
Packit 71fd91
            GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
Packit 71fd91
            continue;
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      /* Now we know what nblock is, we can do a better sanity
Packit 71fd91
         check on s->origPtr.
Packit 71fd91
      */
Packit 71fd91
      if (s->origPtr < 0 || s->origPtr >= nblock)
Packit 71fd91
         RETURN(BZ_DATA_ERROR);
Packit 71fd91
Packit 71fd91
      /*-- Set up cftab to facilitate generation of T^(-1) --*/
Packit 71fd91
      /* Check: unzftab entries in range. */
Packit 71fd91
      for (i = 0; i <= 255; i++) {
Packit 71fd91
         if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
Packit 71fd91
            RETURN(BZ_DATA_ERROR);
Packit 71fd91
      }
Packit 71fd91
      /* Actually generate cftab. */
Packit 71fd91
      s->cftab[0] = 0;
Packit 71fd91
      for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
Packit 71fd91
      for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
Packit 71fd91
      /* Check: cftab entries in range. */
Packit 71fd91
      for (i = 0; i <= 256; i++) {
Packit 71fd91
         if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
Packit 71fd91
            /* s->cftab[i] can legitimately be == nblock */
Packit 71fd91
            RETURN(BZ_DATA_ERROR);
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
      /* Check: cftab entries non-descending. */
Packit 71fd91
      for (i = 1; i <= 256; i++) {
Packit 71fd91
         if (s->cftab[i-1] > s->cftab[i]) {
Packit 71fd91
            RETURN(BZ_DATA_ERROR);
Packit 71fd91
         }
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      s->state_out_len = 0;
Packit 71fd91
      s->state_out_ch  = 0;
Packit 71fd91
      BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
Packit 71fd91
      s->state = BZ_X_OUTPUT;
Packit 71fd91
      if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
Packit 71fd91
Packit 71fd91
      if (s->smallDecompress) {
Packit 71fd91
Packit 71fd91
         /*-- Make a copy of cftab, used in generation of T --*/
Packit 71fd91
         for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
Packit 71fd91
Packit 71fd91
         /*-- compute the T vector --*/
Packit 71fd91
         for (i = 0; i < nblock; i++) {
Packit 71fd91
            uc = (UChar)(s->ll16[i]);
Packit 71fd91
            SET_LL(i, s->cftabCopy[uc]);
Packit 71fd91
            s->cftabCopy[uc]++;
Packit 71fd91
         }
Packit 71fd91
Packit 71fd91
         /*-- Compute T^(-1) by pointer reversal on T --*/
Packit 71fd91
         i = s->origPtr;
Packit 71fd91
         j = GET_LL(i);
Packit 71fd91
         do {
Packit 71fd91
            Int32 tmp = GET_LL(j);
Packit 71fd91
            SET_LL(j, i);
Packit 71fd91
            i = j;
Packit 71fd91
            j = tmp;
Packit 71fd91
         }
Packit 71fd91
            while (i != s->origPtr);
Packit 71fd91
Packit 71fd91
         s->tPos = s->origPtr;
Packit 71fd91
         s->nblock_used = 0;
Packit 71fd91
         if (s->blockRandomised) {
Packit 71fd91
            BZ_RAND_INIT_MASK;
Packit 71fd91
            BZ_GET_SMALL(s->k0); s->nblock_used++;
Packit 71fd91
            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
Packit 71fd91
         } else {
Packit 71fd91
            BZ_GET_SMALL(s->k0); s->nblock_used++;
Packit 71fd91
         }
Packit 71fd91
Packit 71fd91
      } else {
Packit 71fd91
Packit 71fd91
         /*-- compute the T^(-1) vector --*/
Packit 71fd91
         for (i = 0; i < nblock; i++) {
Packit 71fd91
            uc = (UChar)(s->tt[i] & 0xff);
Packit 71fd91
            s->tt[s->cftab[uc]] |= (i << 8);
Packit 71fd91
            s->cftab[uc]++;
Packit 71fd91
         }
Packit 71fd91
Packit 71fd91
         s->tPos = s->tt[s->origPtr] >> 8;
Packit 71fd91
         s->nblock_used = 0;
Packit 71fd91
         if (s->blockRandomised) {
Packit 71fd91
            BZ_RAND_INIT_MASK;
Packit 71fd91
            BZ_GET_FAST(s->k0); s->nblock_used++;
Packit 71fd91
            BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; 
Packit 71fd91
         } else {
Packit 71fd91
            BZ_GET_FAST(s->k0); s->nblock_used++;
Packit 71fd91
         }
Packit 71fd91
Packit 71fd91
      }
Packit 71fd91
Packit 71fd91
      RETURN(BZ_OK);
Packit 71fd91
Packit 71fd91
Packit 71fd91
Packit 71fd91
    endhdr_2:
Packit 71fd91
Packit 71fd91
      GET_UCHAR(BZ_X_ENDHDR_2, uc);
Packit 71fd91
      if (uc != 0x72) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_ENDHDR_3, uc);
Packit 71fd91
      if (uc != 0x45) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_ENDHDR_4, uc);
Packit 71fd91
      if (uc != 0x38) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_ENDHDR_5, uc);
Packit 71fd91
      if (uc != 0x50) RETURN(BZ_DATA_ERROR);
Packit 71fd91
      GET_UCHAR(BZ_X_ENDHDR_6, uc);
Packit 71fd91
      if (uc != 0x90) RETURN(BZ_DATA_ERROR);
Packit 71fd91
Packit 71fd91
      s->storedCombinedCRC = 0;
Packit 71fd91
      GET_UCHAR(BZ_X_CCRC_1, uc);
Packit 71fd91
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_CCRC_2, uc);
Packit 71fd91
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_CCRC_3, uc);
Packit 71fd91
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
Packit 71fd91
      GET_UCHAR(BZ_X_CCRC_4, uc);
Packit 71fd91
      s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
Packit 71fd91
Packit 71fd91
      s->state = BZ_X_IDLE;
Packit 71fd91
      RETURN(BZ_STREAM_END);
Packit 71fd91
Packit 71fd91
      default: AssertH ( False, 4001 );
Packit 71fd91
   }
Packit 71fd91
Packit 71fd91
   AssertH ( False, 4002 );
Packit 71fd91
Packit 71fd91
   save_state_and_return:
Packit 71fd91
Packit 71fd91
   s->save_i           = i;
Packit 71fd91
   s->save_j           = j;
Packit 71fd91
   s->save_t           = t;
Packit 71fd91
   s->save_alphaSize   = alphaSize;
Packit 71fd91
   s->save_nGroups     = nGroups;
Packit 71fd91
   s->save_nSelectors  = nSelectors;
Packit 71fd91
   s->save_EOB         = EOB;
Packit 71fd91
   s->save_groupNo     = groupNo;
Packit 71fd91
   s->save_groupPos    = groupPos;
Packit 71fd91
   s->save_nextSym     = nextSym;
Packit 71fd91
   s->save_nblockMAX   = nblockMAX;
Packit 71fd91
   s->save_nblock      = nblock;
Packit 71fd91
   s->save_es          = es;
Packit 71fd91
   s->save_N           = N;
Packit 71fd91
   s->save_curr        = curr;
Packit 71fd91
   s->save_zt          = zt;
Packit 71fd91
   s->save_zn          = zn;
Packit 71fd91
   s->save_zvec        = zvec;
Packit 71fd91
   s->save_zj          = zj;
Packit 71fd91
   s->save_gSel        = gSel;
Packit 71fd91
   s->save_gMinlen     = gMinlen;
Packit 71fd91
   s->save_gLimit      = gLimit;
Packit 71fd91
   s->save_gBase       = gBase;
Packit 71fd91
   s->save_gPerm       = gPerm;
Packit 71fd91
Packit 71fd91
   return retVal;   
Packit 71fd91
}
Packit 71fd91
Packit 71fd91
Packit 71fd91
/*-------------------------------------------------------------*/
Packit 71fd91
/*--- end                                      decompress.c ---*/
Packit 71fd91
/*-------------------------------------------------------------*/