xref: /dflybsd-src/contrib/bzip2/decompress.c (revision d9ad29c0511b752ac1e5cb3f9d537a66f4bfded4)
171e7ee59SPeter Avalos 
271e7ee59SPeter Avalos /*-------------------------------------------------------------*/
371e7ee59SPeter Avalos /*--- Decompression machinery                               ---*/
471e7ee59SPeter Avalos /*---                                          decompress.c ---*/
571e7ee59SPeter Avalos /*-------------------------------------------------------------*/
671e7ee59SPeter Avalos 
771e7ee59SPeter Avalos /* ------------------------------------------------------------------
871e7ee59SPeter Avalos    This file is part of bzip2/libbzip2, a program and library for
971e7ee59SPeter Avalos    lossless, block-sorting data compression.
1071e7ee59SPeter Avalos 
11*86954436SDaniel Fojt    bzip2/libbzip2 version 1.0.8 of 13 July 2019
12*86954436SDaniel Fojt    Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
1371e7ee59SPeter Avalos 
1471e7ee59SPeter Avalos    Please read the WARNING, DISCLAIMER and PATENTS sections in the
1571e7ee59SPeter Avalos    README file.
1671e7ee59SPeter Avalos 
1771e7ee59SPeter Avalos    This program is released under the terms of the license contained
1871e7ee59SPeter Avalos    in the file LICENSE.
1971e7ee59SPeter Avalos    ------------------------------------------------------------------ */
2071e7ee59SPeter Avalos 
2171e7ee59SPeter Avalos 
2271e7ee59SPeter Avalos #include "bzlib_private.h"
2371e7ee59SPeter Avalos 
2471e7ee59SPeter Avalos 
2571e7ee59SPeter Avalos /*---------------------------------------------------*/
2671e7ee59SPeter Avalos static
makeMaps_d(DState * s)2771e7ee59SPeter Avalos void makeMaps_d ( DState* s )
2871e7ee59SPeter Avalos {
2971e7ee59SPeter Avalos    Int32 i;
3071e7ee59SPeter Avalos    s->nInUse = 0;
3171e7ee59SPeter Avalos    for (i = 0; i < 256; i++)
3271e7ee59SPeter Avalos       if (s->inUse[i]) {
3371e7ee59SPeter Avalos          s->seqToUnseq[s->nInUse] = i;
3471e7ee59SPeter Avalos          s->nInUse++;
3571e7ee59SPeter Avalos       }
3671e7ee59SPeter Avalos }
3771e7ee59SPeter Avalos 
3871e7ee59SPeter Avalos 
3971e7ee59SPeter Avalos /*---------------------------------------------------*/
4071e7ee59SPeter Avalos #define RETURN(rrr)                               \
4171e7ee59SPeter Avalos    { retVal = rrr; goto save_state_and_return; };
4271e7ee59SPeter Avalos 
4371e7ee59SPeter Avalos #define GET_BITS(lll,vvv,nnn)                     \
4471e7ee59SPeter Avalos    case lll: s->state = lll;                      \
4571e7ee59SPeter Avalos    while (True) {                                 \
4671e7ee59SPeter Avalos       if (s->bsLive >= nnn) {                     \
4771e7ee59SPeter Avalos          UInt32 v;                                \
4871e7ee59SPeter Avalos          v = (s->bsBuff >>                        \
4971e7ee59SPeter Avalos              (s->bsLive-nnn)) & ((1 << nnn)-1);   \
5071e7ee59SPeter Avalos          s->bsLive -= nnn;                        \
5171e7ee59SPeter Avalos          vvv = v;                                 \
5271e7ee59SPeter Avalos          break;                                   \
5371e7ee59SPeter Avalos       }                                           \
5471e7ee59SPeter Avalos       if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
5571e7ee59SPeter Avalos       s->bsBuff                                   \
5671e7ee59SPeter Avalos          = (s->bsBuff << 8) |                     \
5771e7ee59SPeter Avalos            ((UInt32)                              \
5871e7ee59SPeter Avalos               (*((UChar*)(s->strm->next_in))));   \
5971e7ee59SPeter Avalos       s->bsLive += 8;                             \
6071e7ee59SPeter Avalos       s->strm->next_in++;                         \
6171e7ee59SPeter Avalos       s->strm->avail_in--;                        \
6271e7ee59SPeter Avalos       s->strm->total_in_lo32++;                   \
6371e7ee59SPeter Avalos       if (s->strm->total_in_lo32 == 0)            \
6471e7ee59SPeter Avalos          s->strm->total_in_hi32++;                \
6571e7ee59SPeter Avalos    }
6671e7ee59SPeter Avalos 
6771e7ee59SPeter Avalos #define GET_UCHAR(lll,uuu)                        \
6871e7ee59SPeter Avalos    GET_BITS(lll,uuu,8)
6971e7ee59SPeter Avalos 
7071e7ee59SPeter Avalos #define GET_BIT(lll,uuu)                          \
7171e7ee59SPeter Avalos    GET_BITS(lll,uuu,1)
7271e7ee59SPeter Avalos 
7371e7ee59SPeter Avalos /*---------------------------------------------------*/
7471e7ee59SPeter Avalos #define GET_MTF_VAL(label1,label2,lval)           \
7571e7ee59SPeter Avalos {                                                 \
7671e7ee59SPeter Avalos    if (groupPos == 0) {                           \
7771e7ee59SPeter Avalos       groupNo++;                                  \
7871e7ee59SPeter Avalos       if (groupNo >= nSelectors)                  \
7971e7ee59SPeter Avalos          RETURN(BZ_DATA_ERROR);                   \
8071e7ee59SPeter Avalos       groupPos = BZ_G_SIZE;                       \
8171e7ee59SPeter Avalos       gSel = s->selector[groupNo];                \
8271e7ee59SPeter Avalos       gMinlen = s->minLens[gSel];                 \
8371e7ee59SPeter Avalos       gLimit = &(s->limit[gSel][0]);              \
8471e7ee59SPeter Avalos       gPerm = &(s->perm[gSel][0]);                \
8571e7ee59SPeter Avalos       gBase = &(s->base[gSel][0]);                \
8671e7ee59SPeter Avalos    }                                              \
8771e7ee59SPeter Avalos    groupPos--;                                    \
8871e7ee59SPeter Avalos    zn = gMinlen;                                  \
8971e7ee59SPeter Avalos    GET_BITS(label1, zvec, zn);                    \
9071e7ee59SPeter Avalos    while (1) {                                    \
9171e7ee59SPeter Avalos       if (zn > 20 /* the longest code */)         \
9271e7ee59SPeter Avalos          RETURN(BZ_DATA_ERROR);                   \
9371e7ee59SPeter Avalos       if (zvec <= gLimit[zn]) break;              \
9471e7ee59SPeter Avalos       zn++;                                       \
9571e7ee59SPeter Avalos       GET_BIT(label2, zj);                        \
9671e7ee59SPeter Avalos       zvec = (zvec << 1) | zj;                    \
9771e7ee59SPeter Avalos    };                                             \
9871e7ee59SPeter Avalos    if (zvec - gBase[zn] < 0                       \
9971e7ee59SPeter Avalos        || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
10071e7ee59SPeter Avalos       RETURN(BZ_DATA_ERROR);                      \
10171e7ee59SPeter Avalos    lval = gPerm[zvec - gBase[zn]];                \
10271e7ee59SPeter Avalos }
10371e7ee59SPeter Avalos 
10471e7ee59SPeter Avalos 
10571e7ee59SPeter Avalos /*---------------------------------------------------*/
BZ2_decompress(DState * s)10671e7ee59SPeter Avalos Int32 BZ2_decompress ( DState* s )
10771e7ee59SPeter Avalos {
10871e7ee59SPeter Avalos    UChar      uc;
10971e7ee59SPeter Avalos    Int32      retVal;
11071e7ee59SPeter Avalos    Int32      minLen, maxLen;
11171e7ee59SPeter Avalos    bz_stream* strm = s->strm;
11271e7ee59SPeter Avalos 
11371e7ee59SPeter Avalos    /* stuff that needs to be saved/restored */
11471e7ee59SPeter Avalos    Int32  i;
11571e7ee59SPeter Avalos    Int32  j;
11671e7ee59SPeter Avalos    Int32  t;
11771e7ee59SPeter Avalos    Int32  alphaSize;
11871e7ee59SPeter Avalos    Int32  nGroups;
11971e7ee59SPeter Avalos    Int32  nSelectors;
12071e7ee59SPeter Avalos    Int32  EOB;
12171e7ee59SPeter Avalos    Int32  groupNo;
12271e7ee59SPeter Avalos    Int32  groupPos;
12371e7ee59SPeter Avalos    Int32  nextSym;
12471e7ee59SPeter Avalos    Int32  nblockMAX;
12571e7ee59SPeter Avalos    Int32  nblock;
12671e7ee59SPeter Avalos    Int32  es;
12771e7ee59SPeter Avalos    Int32  N;
12871e7ee59SPeter Avalos    Int32  curr;
12971e7ee59SPeter Avalos    Int32  zt;
13071e7ee59SPeter Avalos    Int32  zn;
13171e7ee59SPeter Avalos    Int32  zvec;
13271e7ee59SPeter Avalos    Int32  zj;
13371e7ee59SPeter Avalos    Int32  gSel;
13471e7ee59SPeter Avalos    Int32  gMinlen;
13571e7ee59SPeter Avalos    Int32* gLimit;
13671e7ee59SPeter Avalos    Int32* gBase;
13771e7ee59SPeter Avalos    Int32* gPerm;
13871e7ee59SPeter Avalos 
13971e7ee59SPeter Avalos    if (s->state == BZ_X_MAGIC_1) {
14071e7ee59SPeter Avalos       /*initialise the save area*/
14171e7ee59SPeter Avalos       s->save_i           = 0;
14271e7ee59SPeter Avalos       s->save_j           = 0;
14371e7ee59SPeter Avalos       s->save_t           = 0;
14471e7ee59SPeter Avalos       s->save_alphaSize   = 0;
14571e7ee59SPeter Avalos       s->save_nGroups     = 0;
14671e7ee59SPeter Avalos       s->save_nSelectors  = 0;
14771e7ee59SPeter Avalos       s->save_EOB         = 0;
14871e7ee59SPeter Avalos       s->save_groupNo     = 0;
14971e7ee59SPeter Avalos       s->save_groupPos    = 0;
15071e7ee59SPeter Avalos       s->save_nextSym     = 0;
15171e7ee59SPeter Avalos       s->save_nblockMAX   = 0;
15271e7ee59SPeter Avalos       s->save_nblock      = 0;
15371e7ee59SPeter Avalos       s->save_es          = 0;
15471e7ee59SPeter Avalos       s->save_N           = 0;
15571e7ee59SPeter Avalos       s->save_curr        = 0;
15671e7ee59SPeter Avalos       s->save_zt          = 0;
15771e7ee59SPeter Avalos       s->save_zn          = 0;
15871e7ee59SPeter Avalos       s->save_zvec        = 0;
15971e7ee59SPeter Avalos       s->save_zj          = 0;
16071e7ee59SPeter Avalos       s->save_gSel        = 0;
16171e7ee59SPeter Avalos       s->save_gMinlen     = 0;
16271e7ee59SPeter Avalos       s->save_gLimit      = NULL;
16371e7ee59SPeter Avalos       s->save_gBase       = NULL;
16471e7ee59SPeter Avalos       s->save_gPerm       = NULL;
16571e7ee59SPeter Avalos    }
16671e7ee59SPeter Avalos 
16771e7ee59SPeter Avalos    /*restore from the save area*/
16871e7ee59SPeter Avalos    i           = s->save_i;
16971e7ee59SPeter Avalos    j           = s->save_j;
17071e7ee59SPeter Avalos    t           = s->save_t;
17171e7ee59SPeter Avalos    alphaSize   = s->save_alphaSize;
17271e7ee59SPeter Avalos    nGroups     = s->save_nGroups;
17371e7ee59SPeter Avalos    nSelectors  = s->save_nSelectors;
17471e7ee59SPeter Avalos    EOB         = s->save_EOB;
17571e7ee59SPeter Avalos    groupNo     = s->save_groupNo;
17671e7ee59SPeter Avalos    groupPos    = s->save_groupPos;
17771e7ee59SPeter Avalos    nextSym     = s->save_nextSym;
17871e7ee59SPeter Avalos    nblockMAX   = s->save_nblockMAX;
17971e7ee59SPeter Avalos    nblock      = s->save_nblock;
18071e7ee59SPeter Avalos    es          = s->save_es;
18171e7ee59SPeter Avalos    N           = s->save_N;
18271e7ee59SPeter Avalos    curr        = s->save_curr;
18371e7ee59SPeter Avalos    zt          = s->save_zt;
18471e7ee59SPeter Avalos    zn          = s->save_zn;
18571e7ee59SPeter Avalos    zvec        = s->save_zvec;
18671e7ee59SPeter Avalos    zj          = s->save_zj;
18771e7ee59SPeter Avalos    gSel        = s->save_gSel;
18871e7ee59SPeter Avalos    gMinlen     = s->save_gMinlen;
18971e7ee59SPeter Avalos    gLimit      = s->save_gLimit;
19071e7ee59SPeter Avalos    gBase       = s->save_gBase;
19171e7ee59SPeter Avalos    gPerm       = s->save_gPerm;
19271e7ee59SPeter Avalos 
19371e7ee59SPeter Avalos    retVal = BZ_OK;
19471e7ee59SPeter Avalos 
19571e7ee59SPeter Avalos    switch (s->state) {
19671e7ee59SPeter Avalos 
19771e7ee59SPeter Avalos       GET_UCHAR(BZ_X_MAGIC_1, uc);
19871e7ee59SPeter Avalos       if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
19971e7ee59SPeter Avalos 
20071e7ee59SPeter Avalos       GET_UCHAR(BZ_X_MAGIC_2, uc);
20171e7ee59SPeter Avalos       if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
20271e7ee59SPeter Avalos 
20371e7ee59SPeter Avalos       GET_UCHAR(BZ_X_MAGIC_3, uc)
20471e7ee59SPeter Avalos       if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
20571e7ee59SPeter Avalos 
20671e7ee59SPeter Avalos       GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
20771e7ee59SPeter Avalos       if (s->blockSize100k < (BZ_HDR_0 + 1) ||
20871e7ee59SPeter Avalos           s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
20971e7ee59SPeter Avalos       s->blockSize100k -= BZ_HDR_0;
21071e7ee59SPeter Avalos 
21171e7ee59SPeter Avalos       if (s->smallDecompress) {
21271e7ee59SPeter Avalos          s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
21371e7ee59SPeter Avalos          s->ll4  = BZALLOC(
21471e7ee59SPeter Avalos                       ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
21571e7ee59SPeter Avalos                    );
21671e7ee59SPeter Avalos          if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
21771e7ee59SPeter Avalos       } else {
21871e7ee59SPeter Avalos          s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
21971e7ee59SPeter Avalos          if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
22071e7ee59SPeter Avalos       }
22171e7ee59SPeter Avalos 
22271e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BLKHDR_1, uc);
22371e7ee59SPeter Avalos 
22471e7ee59SPeter Avalos       if (uc == 0x17) goto endhdr_2;
22571e7ee59SPeter Avalos       if (uc != 0x31) RETURN(BZ_DATA_ERROR);
22671e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BLKHDR_2, uc);
22771e7ee59SPeter Avalos       if (uc != 0x41) RETURN(BZ_DATA_ERROR);
22871e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BLKHDR_3, uc);
22971e7ee59SPeter Avalos       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
23071e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BLKHDR_4, uc);
23171e7ee59SPeter Avalos       if (uc != 0x26) RETURN(BZ_DATA_ERROR);
23271e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BLKHDR_5, uc);
23371e7ee59SPeter Avalos       if (uc != 0x53) RETURN(BZ_DATA_ERROR);
23471e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BLKHDR_6, uc);
23571e7ee59SPeter Avalos       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
23671e7ee59SPeter Avalos 
23771e7ee59SPeter Avalos       s->currBlockNo++;
23871e7ee59SPeter Avalos       if (s->verbosity >= 2)
23971e7ee59SPeter Avalos          VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
24071e7ee59SPeter Avalos 
24171e7ee59SPeter Avalos       s->storedBlockCRC = 0;
24271e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BCRC_1, uc);
24371e7ee59SPeter Avalos       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
24471e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BCRC_2, uc);
24571e7ee59SPeter Avalos       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
24671e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BCRC_3, uc);
24771e7ee59SPeter Avalos       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
24871e7ee59SPeter Avalos       GET_UCHAR(BZ_X_BCRC_4, uc);
24971e7ee59SPeter Avalos       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
25071e7ee59SPeter Avalos 
25171e7ee59SPeter Avalos       GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
25271e7ee59SPeter Avalos 
25371e7ee59SPeter Avalos       s->origPtr = 0;
25471e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ORIGPTR_1, uc);
25571e7ee59SPeter Avalos       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
25671e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ORIGPTR_2, uc);
25771e7ee59SPeter Avalos       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
25871e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ORIGPTR_3, uc);
25971e7ee59SPeter Avalos       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
26071e7ee59SPeter Avalos 
26171e7ee59SPeter Avalos       if (s->origPtr < 0)
26271e7ee59SPeter Avalos          RETURN(BZ_DATA_ERROR);
26371e7ee59SPeter Avalos       if (s->origPtr > 10 + 100000*s->blockSize100k)
26471e7ee59SPeter Avalos          RETURN(BZ_DATA_ERROR);
26571e7ee59SPeter Avalos 
26671e7ee59SPeter Avalos       /*--- Receive the mapping table ---*/
26771e7ee59SPeter Avalos       for (i = 0; i < 16; i++) {
26871e7ee59SPeter Avalos          GET_BIT(BZ_X_MAPPING_1, uc);
26971e7ee59SPeter Avalos          if (uc == 1)
27071e7ee59SPeter Avalos             s->inUse16[i] = True; else
27171e7ee59SPeter Avalos             s->inUse16[i] = False;
27271e7ee59SPeter Avalos       }
27371e7ee59SPeter Avalos 
27471e7ee59SPeter Avalos       for (i = 0; i < 256; i++) s->inUse[i] = False;
27571e7ee59SPeter Avalos 
27671e7ee59SPeter Avalos       for (i = 0; i < 16; i++)
27771e7ee59SPeter Avalos          if (s->inUse16[i])
27871e7ee59SPeter Avalos             for (j = 0; j < 16; j++) {
27971e7ee59SPeter Avalos                GET_BIT(BZ_X_MAPPING_2, uc);
28071e7ee59SPeter Avalos                if (uc == 1) s->inUse[i * 16 + j] = True;
28171e7ee59SPeter Avalos             }
28271e7ee59SPeter Avalos       makeMaps_d ( s );
28371e7ee59SPeter Avalos       if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
28471e7ee59SPeter Avalos       alphaSize = s->nInUse+2;
28571e7ee59SPeter Avalos 
28671e7ee59SPeter Avalos       /*--- Now the selectors ---*/
28771e7ee59SPeter Avalos       GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
288*86954436SDaniel Fojt       if (nGroups < 2 || nGroups > BZ_N_GROUPS) RETURN(BZ_DATA_ERROR);
28971e7ee59SPeter Avalos       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
29071e7ee59SPeter Avalos       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
29171e7ee59SPeter Avalos       for (i = 0; i < nSelectors; i++) {
29271e7ee59SPeter Avalos          j = 0;
29371e7ee59SPeter Avalos          while (True) {
29471e7ee59SPeter Avalos             GET_BIT(BZ_X_SELECTOR_3, uc);
29571e7ee59SPeter Avalos             if (uc == 0) break;
29671e7ee59SPeter Avalos             j++;
29771e7ee59SPeter Avalos             if (j >= nGroups) RETURN(BZ_DATA_ERROR);
29871e7ee59SPeter Avalos          }
299*86954436SDaniel Fojt          /* Having more than BZ_MAX_SELECTORS doesn't make much sense
300*86954436SDaniel Fojt             since they will never be used, but some implementations might
301*86954436SDaniel Fojt             "round up" the number of selectors, so just ignore those. */
302*86954436SDaniel Fojt          if (i < BZ_MAX_SELECTORS)
30371e7ee59SPeter Avalos            s->selectorMtf[i] = j;
30471e7ee59SPeter Avalos       }
305*86954436SDaniel Fojt       if (nSelectors > BZ_MAX_SELECTORS)
306*86954436SDaniel Fojt         nSelectors = BZ_MAX_SELECTORS;
30771e7ee59SPeter Avalos 
30871e7ee59SPeter Avalos       /*--- Undo the MTF values for the selectors. ---*/
30971e7ee59SPeter Avalos       {
31071e7ee59SPeter Avalos          UChar pos[BZ_N_GROUPS], tmp, v;
31171e7ee59SPeter Avalos          for (v = 0; v < nGroups; v++) pos[v] = v;
31271e7ee59SPeter Avalos 
31371e7ee59SPeter Avalos          for (i = 0; i < nSelectors; i++) {
31471e7ee59SPeter Avalos             v = s->selectorMtf[i];
31571e7ee59SPeter Avalos             tmp = pos[v];
31671e7ee59SPeter Avalos             while (v > 0) { pos[v] = pos[v-1]; v--; }
31771e7ee59SPeter Avalos             pos[0] = tmp;
31871e7ee59SPeter Avalos             s->selector[i] = tmp;
31971e7ee59SPeter Avalos          }
32071e7ee59SPeter Avalos       }
32171e7ee59SPeter Avalos 
32271e7ee59SPeter Avalos       /*--- Now the coding tables ---*/
32371e7ee59SPeter Avalos       for (t = 0; t < nGroups; t++) {
32471e7ee59SPeter Avalos          GET_BITS(BZ_X_CODING_1, curr, 5);
32571e7ee59SPeter Avalos          for (i = 0; i < alphaSize; i++) {
32671e7ee59SPeter Avalos             while (True) {
32771e7ee59SPeter Avalos                if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
32871e7ee59SPeter Avalos                GET_BIT(BZ_X_CODING_2, uc);
32971e7ee59SPeter Avalos                if (uc == 0) break;
33071e7ee59SPeter Avalos                GET_BIT(BZ_X_CODING_3, uc);
33171e7ee59SPeter Avalos                if (uc == 0) curr++; else curr--;
33271e7ee59SPeter Avalos             }
33371e7ee59SPeter Avalos             s->len[t][i] = curr;
33471e7ee59SPeter Avalos          }
33571e7ee59SPeter Avalos       }
33671e7ee59SPeter Avalos 
33771e7ee59SPeter Avalos       /*--- Create the Huffman decoding tables ---*/
33871e7ee59SPeter Avalos       for (t = 0; t < nGroups; t++) {
33971e7ee59SPeter Avalos          minLen = 32;
34071e7ee59SPeter Avalos          maxLen = 0;
34171e7ee59SPeter Avalos          for (i = 0; i < alphaSize; i++) {
34271e7ee59SPeter Avalos             if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
34371e7ee59SPeter Avalos             if (s->len[t][i] < minLen) minLen = s->len[t][i];
34471e7ee59SPeter Avalos          }
34571e7ee59SPeter Avalos          BZ2_hbCreateDecodeTables (
34671e7ee59SPeter Avalos             &(s->limit[t][0]),
34771e7ee59SPeter Avalos             &(s->base[t][0]),
34871e7ee59SPeter Avalos             &(s->perm[t][0]),
34971e7ee59SPeter Avalos             &(s->len[t][0]),
35071e7ee59SPeter Avalos             minLen, maxLen, alphaSize
35171e7ee59SPeter Avalos          );
35271e7ee59SPeter Avalos          s->minLens[t] = minLen;
35371e7ee59SPeter Avalos       }
35471e7ee59SPeter Avalos 
35571e7ee59SPeter Avalos       /*--- Now the MTF values ---*/
35671e7ee59SPeter Avalos 
35771e7ee59SPeter Avalos       EOB      = s->nInUse+1;
35871e7ee59SPeter Avalos       nblockMAX = 100000 * s->blockSize100k;
35971e7ee59SPeter Avalos       groupNo  = -1;
36071e7ee59SPeter Avalos       groupPos = 0;
36171e7ee59SPeter Avalos 
36271e7ee59SPeter Avalos       for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
36371e7ee59SPeter Avalos 
36471e7ee59SPeter Avalos       /*-- MTF init --*/
36571e7ee59SPeter Avalos       {
36671e7ee59SPeter Avalos          Int32 ii, jj, kk;
36771e7ee59SPeter Avalos          kk = MTFA_SIZE-1;
36871e7ee59SPeter Avalos          for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
36971e7ee59SPeter Avalos             for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
37071e7ee59SPeter Avalos                s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
37171e7ee59SPeter Avalos                kk--;
37271e7ee59SPeter Avalos             }
37371e7ee59SPeter Avalos             s->mtfbase[ii] = kk + 1;
37471e7ee59SPeter Avalos          }
37571e7ee59SPeter Avalos       }
37671e7ee59SPeter Avalos       /*-- end MTF init --*/
37771e7ee59SPeter Avalos 
37871e7ee59SPeter Avalos       nblock = 0;
37971e7ee59SPeter Avalos       GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
38071e7ee59SPeter Avalos 
38171e7ee59SPeter Avalos       while (True) {
38271e7ee59SPeter Avalos 
38371e7ee59SPeter Avalos          if (nextSym == EOB) break;
38471e7ee59SPeter Avalos 
38571e7ee59SPeter Avalos          if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
38671e7ee59SPeter Avalos 
38771e7ee59SPeter Avalos             es = -1;
38871e7ee59SPeter Avalos             N = 1;
38971e7ee59SPeter Avalos             do {
3908b8098b1SPeter Avalos                /* Check that N doesn't get too big, so that es doesn't
3918b8098b1SPeter Avalos                   go negative.  The maximum value that can be
3928b8098b1SPeter Avalos                   RUNA/RUNB encoded is equal to the block size (post
3938b8098b1SPeter Avalos                   the initial RLE), viz, 900k, so bounding N at 2
3948b8098b1SPeter Avalos                   million should guard against overflow without
3958b8098b1SPeter Avalos                   rejecting any legitimate inputs. */
3968b8098b1SPeter Avalos                if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
39771e7ee59SPeter Avalos                if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
39871e7ee59SPeter Avalos                if (nextSym == BZ_RUNB) es = es + (1+1) * N;
39971e7ee59SPeter Avalos                N = N * 2;
40071e7ee59SPeter Avalos                GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
40171e7ee59SPeter Avalos             }
40271e7ee59SPeter Avalos                while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
40371e7ee59SPeter Avalos 
40471e7ee59SPeter Avalos             es++;
40571e7ee59SPeter Avalos             uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
40671e7ee59SPeter Avalos             s->unzftab[uc] += es;
40771e7ee59SPeter Avalos 
40871e7ee59SPeter Avalos             if (s->smallDecompress)
40971e7ee59SPeter Avalos                while (es > 0) {
41071e7ee59SPeter Avalos                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
41171e7ee59SPeter Avalos                   s->ll16[nblock] = (UInt16)uc;
41271e7ee59SPeter Avalos                   nblock++;
41371e7ee59SPeter Avalos                   es--;
41471e7ee59SPeter Avalos                }
41571e7ee59SPeter Avalos             else
41671e7ee59SPeter Avalos                while (es > 0) {
41771e7ee59SPeter Avalos                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
41871e7ee59SPeter Avalos                   s->tt[nblock] = (UInt32)uc;
41971e7ee59SPeter Avalos                   nblock++;
42071e7ee59SPeter Avalos                   es--;
42171e7ee59SPeter Avalos                };
42271e7ee59SPeter Avalos 
42371e7ee59SPeter Avalos             continue;
42471e7ee59SPeter Avalos 
42571e7ee59SPeter Avalos          } else {
42671e7ee59SPeter Avalos 
42771e7ee59SPeter Avalos             if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
42871e7ee59SPeter Avalos 
42971e7ee59SPeter Avalos             /*-- uc = MTF ( nextSym-1 ) --*/
43071e7ee59SPeter Avalos             {
43171e7ee59SPeter Avalos                Int32 ii, jj, kk, pp, lno, off;
43271e7ee59SPeter Avalos                UInt32 nn;
43371e7ee59SPeter Avalos                nn = (UInt32)(nextSym - 1);
43471e7ee59SPeter Avalos 
43571e7ee59SPeter Avalos                if (nn < MTFL_SIZE) {
43671e7ee59SPeter Avalos                   /* avoid general-case expense */
43771e7ee59SPeter Avalos                   pp = s->mtfbase[0];
43871e7ee59SPeter Avalos                   uc = s->mtfa[pp+nn];
43971e7ee59SPeter Avalos                   while (nn > 3) {
44071e7ee59SPeter Avalos                      Int32 z = pp+nn;
44171e7ee59SPeter Avalos                      s->mtfa[(z)  ] = s->mtfa[(z)-1];
44271e7ee59SPeter Avalos                      s->mtfa[(z)-1] = s->mtfa[(z)-2];
44371e7ee59SPeter Avalos                      s->mtfa[(z)-2] = s->mtfa[(z)-3];
44471e7ee59SPeter Avalos                      s->mtfa[(z)-3] = s->mtfa[(z)-4];
44571e7ee59SPeter Avalos                      nn -= 4;
44671e7ee59SPeter Avalos                   }
44771e7ee59SPeter Avalos                   while (nn > 0) {
44871e7ee59SPeter Avalos                      s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
44971e7ee59SPeter Avalos                   };
45071e7ee59SPeter Avalos                   s->mtfa[pp] = uc;
45171e7ee59SPeter Avalos                } else {
45271e7ee59SPeter Avalos                   /* general case */
45371e7ee59SPeter Avalos                   lno = nn / MTFL_SIZE;
45471e7ee59SPeter Avalos                   off = nn % MTFL_SIZE;
45571e7ee59SPeter Avalos                   pp = s->mtfbase[lno] + off;
45671e7ee59SPeter Avalos                   uc = s->mtfa[pp];
45771e7ee59SPeter Avalos                   while (pp > s->mtfbase[lno]) {
45871e7ee59SPeter Avalos                      s->mtfa[pp] = s->mtfa[pp-1]; pp--;
45971e7ee59SPeter Avalos                   };
46071e7ee59SPeter Avalos                   s->mtfbase[lno]++;
46171e7ee59SPeter Avalos                   while (lno > 0) {
46271e7ee59SPeter Avalos                      s->mtfbase[lno]--;
46371e7ee59SPeter Avalos                      s->mtfa[s->mtfbase[lno]]
46471e7ee59SPeter Avalos                         = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
46571e7ee59SPeter Avalos                      lno--;
46671e7ee59SPeter Avalos                   }
46771e7ee59SPeter Avalos                   s->mtfbase[0]--;
46871e7ee59SPeter Avalos                   s->mtfa[s->mtfbase[0]] = uc;
46971e7ee59SPeter Avalos                   if (s->mtfbase[0] == 0) {
47071e7ee59SPeter Avalos                      kk = MTFA_SIZE-1;
47171e7ee59SPeter Avalos                      for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
47271e7ee59SPeter Avalos                         for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
47371e7ee59SPeter Avalos                            s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
47471e7ee59SPeter Avalos                            kk--;
47571e7ee59SPeter Avalos                         }
47671e7ee59SPeter Avalos                         s->mtfbase[ii] = kk + 1;
47771e7ee59SPeter Avalos                      }
47871e7ee59SPeter Avalos                   }
47971e7ee59SPeter Avalos                }
48071e7ee59SPeter Avalos             }
48171e7ee59SPeter Avalos             /*-- end uc = MTF ( nextSym-1 ) --*/
48271e7ee59SPeter Avalos 
48371e7ee59SPeter Avalos             s->unzftab[s->seqToUnseq[uc]]++;
48471e7ee59SPeter Avalos             if (s->smallDecompress)
48571e7ee59SPeter Avalos                s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
48671e7ee59SPeter Avalos                s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
48771e7ee59SPeter Avalos             nblock++;
48871e7ee59SPeter Avalos 
48971e7ee59SPeter Avalos             GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
49071e7ee59SPeter Avalos             continue;
49171e7ee59SPeter Avalos          }
49271e7ee59SPeter Avalos       }
49371e7ee59SPeter Avalos 
49471e7ee59SPeter Avalos       /* Now we know what nblock is, we can do a better sanity
49571e7ee59SPeter Avalos          check on s->origPtr.
49671e7ee59SPeter Avalos       */
49771e7ee59SPeter Avalos       if (s->origPtr < 0 || s->origPtr >= nblock)
49871e7ee59SPeter Avalos          RETURN(BZ_DATA_ERROR);
49971e7ee59SPeter Avalos 
50071e7ee59SPeter Avalos       /*-- Set up cftab to facilitate generation of T^(-1) --*/
5018b8098b1SPeter Avalos       /* Check: unzftab entries in range. */
5028b8098b1SPeter Avalos       for (i = 0; i <= 255; i++) {
5038b8098b1SPeter Avalos          if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
5048b8098b1SPeter Avalos             RETURN(BZ_DATA_ERROR);
5058b8098b1SPeter Avalos       }
5068b8098b1SPeter Avalos       /* Actually generate cftab. */
50771e7ee59SPeter Avalos       s->cftab[0] = 0;
50871e7ee59SPeter Avalos       for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
50971e7ee59SPeter Avalos       for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
5108b8098b1SPeter Avalos       /* Check: cftab entries in range. */
51171e7ee59SPeter Avalos       for (i = 0; i <= 256; i++) {
51271e7ee59SPeter Avalos          if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
51371e7ee59SPeter Avalos             /* s->cftab[i] can legitimately be == nblock */
51471e7ee59SPeter Avalos             RETURN(BZ_DATA_ERROR);
51571e7ee59SPeter Avalos          }
51671e7ee59SPeter Avalos       }
5178b8098b1SPeter Avalos       /* Check: cftab entries non-descending. */
5188b8098b1SPeter Avalos       for (i = 1; i <= 256; i++) {
5198b8098b1SPeter Avalos          if (s->cftab[i-1] > s->cftab[i]) {
5208b8098b1SPeter Avalos             RETURN(BZ_DATA_ERROR);
5218b8098b1SPeter Avalos          }
5228b8098b1SPeter Avalos       }
52371e7ee59SPeter Avalos 
52471e7ee59SPeter Avalos       s->state_out_len = 0;
52571e7ee59SPeter Avalos       s->state_out_ch  = 0;
52671e7ee59SPeter Avalos       BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
52771e7ee59SPeter Avalos       s->state = BZ_X_OUTPUT;
52871e7ee59SPeter Avalos       if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
52971e7ee59SPeter Avalos 
53071e7ee59SPeter Avalos       if (s->smallDecompress) {
53171e7ee59SPeter Avalos 
53271e7ee59SPeter Avalos          /*-- Make a copy of cftab, used in generation of T --*/
53371e7ee59SPeter Avalos          for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
53471e7ee59SPeter Avalos 
53571e7ee59SPeter Avalos          /*-- compute the T vector --*/
53671e7ee59SPeter Avalos          for (i = 0; i < nblock; i++) {
53771e7ee59SPeter Avalos             uc = (UChar)(s->ll16[i]);
53871e7ee59SPeter Avalos             SET_LL(i, s->cftabCopy[uc]);
53971e7ee59SPeter Avalos             s->cftabCopy[uc]++;
54071e7ee59SPeter Avalos          }
54171e7ee59SPeter Avalos 
54271e7ee59SPeter Avalos          /*-- Compute T^(-1) by pointer reversal on T --*/
54371e7ee59SPeter Avalos          i = s->origPtr;
54471e7ee59SPeter Avalos          j = GET_LL(i);
54571e7ee59SPeter Avalos          do {
54671e7ee59SPeter Avalos             Int32 tmp = GET_LL(j);
54771e7ee59SPeter Avalos             SET_LL(j, i);
54871e7ee59SPeter Avalos             i = j;
54971e7ee59SPeter Avalos             j = tmp;
55071e7ee59SPeter Avalos          }
55171e7ee59SPeter Avalos             while (i != s->origPtr);
55271e7ee59SPeter Avalos 
55371e7ee59SPeter Avalos          s->tPos = s->origPtr;
55471e7ee59SPeter Avalos          s->nblock_used = 0;
55571e7ee59SPeter Avalos          if (s->blockRandomised) {
55671e7ee59SPeter Avalos             BZ_RAND_INIT_MASK;
55771e7ee59SPeter Avalos             BZ_GET_SMALL(s->k0); s->nblock_used++;
55871e7ee59SPeter Avalos             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
55971e7ee59SPeter Avalos          } else {
56071e7ee59SPeter Avalos             BZ_GET_SMALL(s->k0); s->nblock_used++;
56171e7ee59SPeter Avalos          }
56271e7ee59SPeter Avalos 
56371e7ee59SPeter Avalos       } else {
56471e7ee59SPeter Avalos 
56571e7ee59SPeter Avalos          /*-- compute the T^(-1) vector --*/
56671e7ee59SPeter Avalos          for (i = 0; i < nblock; i++) {
56771e7ee59SPeter Avalos             uc = (UChar)(s->tt[i] & 0xff);
56871e7ee59SPeter Avalos             s->tt[s->cftab[uc]] |= (i << 8);
56971e7ee59SPeter Avalos             s->cftab[uc]++;
57071e7ee59SPeter Avalos          }
57171e7ee59SPeter Avalos 
57271e7ee59SPeter Avalos          s->tPos = s->tt[s->origPtr] >> 8;
57371e7ee59SPeter Avalos          s->nblock_used = 0;
57471e7ee59SPeter Avalos          if (s->blockRandomised) {
57571e7ee59SPeter Avalos             BZ_RAND_INIT_MASK;
57671e7ee59SPeter Avalos             BZ_GET_FAST(s->k0); s->nblock_used++;
57771e7ee59SPeter Avalos             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
57871e7ee59SPeter Avalos          } else {
57971e7ee59SPeter Avalos             BZ_GET_FAST(s->k0); s->nblock_used++;
58071e7ee59SPeter Avalos          }
58171e7ee59SPeter Avalos 
58271e7ee59SPeter Avalos       }
58371e7ee59SPeter Avalos 
58471e7ee59SPeter Avalos       RETURN(BZ_OK);
58571e7ee59SPeter Avalos 
58671e7ee59SPeter Avalos 
58771e7ee59SPeter Avalos 
58871e7ee59SPeter Avalos     endhdr_2:
58971e7ee59SPeter Avalos 
59071e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ENDHDR_2, uc);
59171e7ee59SPeter Avalos       if (uc != 0x72) RETURN(BZ_DATA_ERROR);
59271e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ENDHDR_3, uc);
59371e7ee59SPeter Avalos       if (uc != 0x45) RETURN(BZ_DATA_ERROR);
59471e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ENDHDR_4, uc);
59571e7ee59SPeter Avalos       if (uc != 0x38) RETURN(BZ_DATA_ERROR);
59671e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ENDHDR_5, uc);
59771e7ee59SPeter Avalos       if (uc != 0x50) RETURN(BZ_DATA_ERROR);
59871e7ee59SPeter Avalos       GET_UCHAR(BZ_X_ENDHDR_6, uc);
59971e7ee59SPeter Avalos       if (uc != 0x90) RETURN(BZ_DATA_ERROR);
60071e7ee59SPeter Avalos 
60171e7ee59SPeter Avalos       s->storedCombinedCRC = 0;
60271e7ee59SPeter Avalos       GET_UCHAR(BZ_X_CCRC_1, uc);
60371e7ee59SPeter Avalos       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
60471e7ee59SPeter Avalos       GET_UCHAR(BZ_X_CCRC_2, uc);
60571e7ee59SPeter Avalos       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
60671e7ee59SPeter Avalos       GET_UCHAR(BZ_X_CCRC_3, uc);
60771e7ee59SPeter Avalos       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
60871e7ee59SPeter Avalos       GET_UCHAR(BZ_X_CCRC_4, uc);
60971e7ee59SPeter Avalos       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
61071e7ee59SPeter Avalos 
61171e7ee59SPeter Avalos       s->state = BZ_X_IDLE;
61271e7ee59SPeter Avalos       RETURN(BZ_STREAM_END);
61371e7ee59SPeter Avalos 
61471e7ee59SPeter Avalos       default: AssertH ( False, 4001 );
61571e7ee59SPeter Avalos    }
61671e7ee59SPeter Avalos 
61771e7ee59SPeter Avalos    AssertH ( False, 4002 );
61871e7ee59SPeter Avalos 
61971e7ee59SPeter Avalos    save_state_and_return:
62071e7ee59SPeter Avalos 
62171e7ee59SPeter Avalos    s->save_i           = i;
62271e7ee59SPeter Avalos    s->save_j           = j;
62371e7ee59SPeter Avalos    s->save_t           = t;
62471e7ee59SPeter Avalos    s->save_alphaSize   = alphaSize;
62571e7ee59SPeter Avalos    s->save_nGroups     = nGroups;
62671e7ee59SPeter Avalos    s->save_nSelectors  = nSelectors;
62771e7ee59SPeter Avalos    s->save_EOB         = EOB;
62871e7ee59SPeter Avalos    s->save_groupNo     = groupNo;
62971e7ee59SPeter Avalos    s->save_groupPos    = groupPos;
63071e7ee59SPeter Avalos    s->save_nextSym     = nextSym;
63171e7ee59SPeter Avalos    s->save_nblockMAX   = nblockMAX;
63271e7ee59SPeter Avalos    s->save_nblock      = nblock;
63371e7ee59SPeter Avalos    s->save_es          = es;
63471e7ee59SPeter Avalos    s->save_N           = N;
63571e7ee59SPeter Avalos    s->save_curr        = curr;
63671e7ee59SPeter Avalos    s->save_zt          = zt;
63771e7ee59SPeter Avalos    s->save_zn          = zn;
63871e7ee59SPeter Avalos    s->save_zvec        = zvec;
63971e7ee59SPeter Avalos    s->save_zj          = zj;
64071e7ee59SPeter Avalos    s->save_gSel        = gSel;
64171e7ee59SPeter Avalos    s->save_gMinlen     = gMinlen;
64271e7ee59SPeter Avalos    s->save_gLimit      = gLimit;
64371e7ee59SPeter Avalos    s->save_gBase       = gBase;
64471e7ee59SPeter Avalos    s->save_gPerm       = gPerm;
64571e7ee59SPeter Avalos 
64671e7ee59SPeter Avalos    return retVal;
64771e7ee59SPeter Avalos }
64871e7ee59SPeter Avalos 
64971e7ee59SPeter Avalos 
65071e7ee59SPeter Avalos /*-------------------------------------------------------------*/
65171e7ee59SPeter Avalos /*--- end                                      decompress.c ---*/
65271e7ee59SPeter Avalos /*-------------------------------------------------------------*/
653