xref: /netbsd-src/external/bsd/bzip2/dist/decompress.c (revision c4f47eb4fbbce2c384f784d0295d2f037ed4819c)
1*c4f47eb4Smaya /*	$NetBSD: decompress.c,v 1.4 2019/07/21 11:52:14 maya Exp $	*/
24f9a1459Swiz 
34f9a1459Swiz 
44f9a1459Swiz /*-------------------------------------------------------------*/
54f9a1459Swiz /*--- Decompression machinery                               ---*/
64f9a1459Swiz /*---                                          decompress.c ---*/
74f9a1459Swiz /*-------------------------------------------------------------*/
84f9a1459Swiz 
94f9a1459Swiz /* ------------------------------------------------------------------
104f9a1459Swiz    This file is part of bzip2/libbzip2, a program and library for
114f9a1459Swiz    lossless, block-sorting data compression.
124f9a1459Swiz 
13*c4f47eb4Smaya    bzip2/libbzip2 version 1.0.8 of 13 July 2019
14*c4f47eb4Smaya    Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
154f9a1459Swiz 
164f9a1459Swiz    Please read the WARNING, DISCLAIMER and PATENTS sections in the
174f9a1459Swiz    README file.
184f9a1459Swiz 
194f9a1459Swiz    This program is released under the terms of the license contained
204f9a1459Swiz    in the file LICENSE.
214f9a1459Swiz    ------------------------------------------------------------------ */
224f9a1459Swiz 
234f9a1459Swiz 
244f9a1459Swiz #include "bzlib_private.h"
254f9a1459Swiz 
264f9a1459Swiz 
274f9a1459Swiz /*---------------------------------------------------*/
284f9a1459Swiz static
makeMaps_d(DState * s)294f9a1459Swiz void makeMaps_d ( DState* s )
304f9a1459Swiz {
314f9a1459Swiz    Int32 i;
324f9a1459Swiz    s->nInUse = 0;
334f9a1459Swiz    for (i = 0; i < 256; i++)
344f9a1459Swiz       if (s->inUse[i]) {
354f9a1459Swiz          s->seqToUnseq[s->nInUse] = i;
364f9a1459Swiz          s->nInUse++;
374f9a1459Swiz       }
384f9a1459Swiz }
394f9a1459Swiz 
404f9a1459Swiz 
414f9a1459Swiz /*---------------------------------------------------*/
424f9a1459Swiz #define RETURN(rrr)                               \
434f9a1459Swiz    { retVal = rrr; goto save_state_and_return; };
444f9a1459Swiz 
454f9a1459Swiz #define GET_BITS(lll,vvv,nnn)                     \
464f9a1459Swiz    case lll: s->state = lll;                      \
474f9a1459Swiz    while (True) {                                 \
484f9a1459Swiz       if (s->bsLive >= nnn) {                     \
494f9a1459Swiz          UInt32 v;                                \
504f9a1459Swiz          v = (s->bsBuff >>                        \
514f9a1459Swiz              (s->bsLive-nnn)) & ((1 << nnn)-1);   \
524f9a1459Swiz          s->bsLive -= nnn;                        \
534f9a1459Swiz          vvv = v;                                 \
544f9a1459Swiz          break;                                   \
554f9a1459Swiz       }                                           \
564f9a1459Swiz       if (s->strm->avail_in == 0) RETURN(BZ_OK);  \
574f9a1459Swiz       s->bsBuff                                   \
584f9a1459Swiz          = (s->bsBuff << 8) |                     \
594f9a1459Swiz            ((UInt32)                              \
604f9a1459Swiz               (*((UChar*)(s->strm->next_in))));   \
614f9a1459Swiz       s->bsLive += 8;                             \
624f9a1459Swiz       s->strm->next_in++;                         \
634f9a1459Swiz       s->strm->avail_in--;                        \
644f9a1459Swiz       s->strm->total_in_lo32++;                   \
654f9a1459Swiz       if (s->strm->total_in_lo32 == 0)            \
664f9a1459Swiz          s->strm->total_in_hi32++;                \
674f9a1459Swiz    }
684f9a1459Swiz 
694f9a1459Swiz #define GET_UCHAR(lll,uuu)                        \
704f9a1459Swiz    GET_BITS(lll,uuu,8)
714f9a1459Swiz 
724f9a1459Swiz #define GET_BIT(lll,uuu)                          \
734f9a1459Swiz    GET_BITS(lll,uuu,1)
744f9a1459Swiz 
754f9a1459Swiz /*---------------------------------------------------*/
764f9a1459Swiz #define GET_MTF_VAL(label1,label2,lval)           \
774f9a1459Swiz {                                                 \
784f9a1459Swiz    if (groupPos == 0) {                           \
794f9a1459Swiz       groupNo++;                                  \
804f9a1459Swiz       if (groupNo >= nSelectors)                  \
814f9a1459Swiz          RETURN(BZ_DATA_ERROR);                   \
824f9a1459Swiz       groupPos = BZ_G_SIZE;                       \
834f9a1459Swiz       gSel = s->selector[groupNo];                \
844f9a1459Swiz       gMinlen = s->minLens[gSel];                 \
854f9a1459Swiz       gLimit = &(s->limit[gSel][0]);              \
864f9a1459Swiz       gPerm = &(s->perm[gSel][0]);                \
874f9a1459Swiz       gBase = &(s->base[gSel][0]);                \
884f9a1459Swiz    }                                              \
894f9a1459Swiz    groupPos--;                                    \
904f9a1459Swiz    zn = gMinlen;                                  \
914f9a1459Swiz    GET_BITS(label1, zvec, zn);                    \
924f9a1459Swiz    while (1) {                                    \
934f9a1459Swiz       if (zn > 20 /* the longest code */)         \
944f9a1459Swiz          RETURN(BZ_DATA_ERROR);                   \
954f9a1459Swiz       if (zvec <= gLimit[zn]) break;              \
964f9a1459Swiz       zn++;                                       \
974f9a1459Swiz       GET_BIT(label2, zj);                        \
984f9a1459Swiz       zvec = (zvec << 1) | zj;                    \
994f9a1459Swiz    };                                             \
1004f9a1459Swiz    if (zvec - gBase[zn] < 0                       \
1014f9a1459Swiz        || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE)  \
1024f9a1459Swiz       RETURN(BZ_DATA_ERROR);                      \
1034f9a1459Swiz    lval = gPerm[zvec - gBase[zn]];                \
1044f9a1459Swiz }
1054f9a1459Swiz 
1064f9a1459Swiz 
1074f9a1459Swiz /*---------------------------------------------------*/
BZ2_decompress(DState * s)1084f9a1459Swiz Int32 BZ2_decompress ( DState* s )
1094f9a1459Swiz {
1104f9a1459Swiz    UChar      uc;
1114f9a1459Swiz    Int32      retVal;
1124f9a1459Swiz    Int32      minLen, maxLen;
1134f9a1459Swiz    bz_stream* strm = s->strm;
1144f9a1459Swiz 
1154f9a1459Swiz    /* stuff that needs to be saved/restored */
1164f9a1459Swiz    Int32  i;
1174f9a1459Swiz    Int32  j;
1184f9a1459Swiz    Int32  t;
1194f9a1459Swiz    Int32  alphaSize;
1204f9a1459Swiz    Int32  nGroups;
1214f9a1459Swiz    Int32  nSelectors;
1224f9a1459Swiz    Int32  EOB;
1234f9a1459Swiz    Int32  groupNo;
1244f9a1459Swiz    Int32  groupPos;
1254f9a1459Swiz    Int32  nextSym;
1264f9a1459Swiz    Int32  nblockMAX;
1274f9a1459Swiz    Int32  nblock;
1284f9a1459Swiz    Int32  es;
1294f9a1459Swiz    Int32  N;
1304f9a1459Swiz    Int32  curr;
1314f9a1459Swiz    Int32  zt;
1324f9a1459Swiz    Int32  zn;
1334f9a1459Swiz    Int32  zvec;
1344f9a1459Swiz    Int32  zj;
1354f9a1459Swiz    Int32  gSel;
1364f9a1459Swiz    Int32  gMinlen;
1374f9a1459Swiz    Int32* gLimit;
1384f9a1459Swiz    Int32* gBase;
1394f9a1459Swiz    Int32* gPerm;
1404f9a1459Swiz 
1414f9a1459Swiz    if (s->state == BZ_X_MAGIC_1) {
1424f9a1459Swiz       /*initialise the save area*/
1434f9a1459Swiz       s->save_i           = 0;
1444f9a1459Swiz       s->save_j           = 0;
1454f9a1459Swiz       s->save_t           = 0;
1464f9a1459Swiz       s->save_alphaSize   = 0;
1474f9a1459Swiz       s->save_nGroups     = 0;
1484f9a1459Swiz       s->save_nSelectors  = 0;
1494f9a1459Swiz       s->save_EOB         = 0;
1504f9a1459Swiz       s->save_groupNo     = 0;
1514f9a1459Swiz       s->save_groupPos    = 0;
1524f9a1459Swiz       s->save_nextSym     = 0;
1534f9a1459Swiz       s->save_nblockMAX   = 0;
1544f9a1459Swiz       s->save_nblock      = 0;
1554f9a1459Swiz       s->save_es          = 0;
1564f9a1459Swiz       s->save_N           = 0;
1574f9a1459Swiz       s->save_curr        = 0;
1584f9a1459Swiz       s->save_zt          = 0;
1594f9a1459Swiz       s->save_zn          = 0;
1604f9a1459Swiz       s->save_zvec        = 0;
1614f9a1459Swiz       s->save_zj          = 0;
1624f9a1459Swiz       s->save_gSel        = 0;
1634f9a1459Swiz       s->save_gMinlen     = 0;
1644f9a1459Swiz       s->save_gLimit      = NULL;
1654f9a1459Swiz       s->save_gBase       = NULL;
1664f9a1459Swiz       s->save_gPerm       = NULL;
1674f9a1459Swiz    }
1684f9a1459Swiz 
1694f9a1459Swiz    /*restore from the save area*/
1704f9a1459Swiz    i           = s->save_i;
1714f9a1459Swiz    j           = s->save_j;
1724f9a1459Swiz    t           = s->save_t;
1734f9a1459Swiz    alphaSize   = s->save_alphaSize;
1744f9a1459Swiz    nGroups     = s->save_nGroups;
1754f9a1459Swiz    nSelectors  = s->save_nSelectors;
1764f9a1459Swiz    EOB         = s->save_EOB;
1774f9a1459Swiz    groupNo     = s->save_groupNo;
1784f9a1459Swiz    groupPos    = s->save_groupPos;
1794f9a1459Swiz    nextSym     = s->save_nextSym;
1804f9a1459Swiz    nblockMAX   = s->save_nblockMAX;
1814f9a1459Swiz    nblock      = s->save_nblock;
1824f9a1459Swiz    es          = s->save_es;
1834f9a1459Swiz    N           = s->save_N;
1844f9a1459Swiz    curr        = s->save_curr;
1854f9a1459Swiz    zt          = s->save_zt;
1864f9a1459Swiz    zn          = s->save_zn;
1874f9a1459Swiz    zvec        = s->save_zvec;
1884f9a1459Swiz    zj          = s->save_zj;
1894f9a1459Swiz    gSel        = s->save_gSel;
1904f9a1459Swiz    gMinlen     = s->save_gMinlen;
1914f9a1459Swiz    gLimit      = s->save_gLimit;
1924f9a1459Swiz    gBase       = s->save_gBase;
1934f9a1459Swiz    gPerm       = s->save_gPerm;
1944f9a1459Swiz 
1954f9a1459Swiz    retVal = BZ_OK;
1964f9a1459Swiz 
1974f9a1459Swiz    switch (s->state) {
1984f9a1459Swiz 
1994f9a1459Swiz       GET_UCHAR(BZ_X_MAGIC_1, uc);
2004f9a1459Swiz       if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
2014f9a1459Swiz 
2024f9a1459Swiz       GET_UCHAR(BZ_X_MAGIC_2, uc);
2034f9a1459Swiz       if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
2044f9a1459Swiz 
2054f9a1459Swiz       GET_UCHAR(BZ_X_MAGIC_3, uc)
2064f9a1459Swiz       if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
2074f9a1459Swiz 
2084f9a1459Swiz       GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
2094f9a1459Swiz       if (s->blockSize100k < (BZ_HDR_0 + 1) ||
2104f9a1459Swiz           s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
2114f9a1459Swiz       s->blockSize100k -= BZ_HDR_0;
2124f9a1459Swiz 
2134f9a1459Swiz       if (s->smallDecompress) {
2144f9a1459Swiz          s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
2154f9a1459Swiz          s->ll4  = BZALLOC(
2164f9a1459Swiz                       ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
2174f9a1459Swiz                    );
2184f9a1459Swiz          if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
2194f9a1459Swiz       } else {
2204f9a1459Swiz          s->tt  = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
2214f9a1459Swiz          if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
2224f9a1459Swiz       }
2234f9a1459Swiz 
2244f9a1459Swiz       GET_UCHAR(BZ_X_BLKHDR_1, uc);
2254f9a1459Swiz 
2264f9a1459Swiz       if (uc == 0x17) goto endhdr_2;
2274f9a1459Swiz       if (uc != 0x31) RETURN(BZ_DATA_ERROR);
2284f9a1459Swiz       GET_UCHAR(BZ_X_BLKHDR_2, uc);
2294f9a1459Swiz       if (uc != 0x41) RETURN(BZ_DATA_ERROR);
2304f9a1459Swiz       GET_UCHAR(BZ_X_BLKHDR_3, uc);
2314f9a1459Swiz       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
2324f9a1459Swiz       GET_UCHAR(BZ_X_BLKHDR_4, uc);
2334f9a1459Swiz       if (uc != 0x26) RETURN(BZ_DATA_ERROR);
2344f9a1459Swiz       GET_UCHAR(BZ_X_BLKHDR_5, uc);
2354f9a1459Swiz       if (uc != 0x53) RETURN(BZ_DATA_ERROR);
2364f9a1459Swiz       GET_UCHAR(BZ_X_BLKHDR_6, uc);
2374f9a1459Swiz       if (uc != 0x59) RETURN(BZ_DATA_ERROR);
2384f9a1459Swiz 
2394f9a1459Swiz       s->currBlockNo++;
2404f9a1459Swiz       if (s->verbosity >= 2)
2414f9a1459Swiz          VPrintf1 ( "\n    [%d: huff+mtf ", s->currBlockNo );
2424f9a1459Swiz 
2434f9a1459Swiz       s->storedBlockCRC = 0;
2444f9a1459Swiz       GET_UCHAR(BZ_X_BCRC_1, uc);
2454f9a1459Swiz       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
2464f9a1459Swiz       GET_UCHAR(BZ_X_BCRC_2, uc);
2474f9a1459Swiz       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
2484f9a1459Swiz       GET_UCHAR(BZ_X_BCRC_3, uc);
2494f9a1459Swiz       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
2504f9a1459Swiz       GET_UCHAR(BZ_X_BCRC_4, uc);
2514f9a1459Swiz       s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
2524f9a1459Swiz 
2534f9a1459Swiz       GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
2544f9a1459Swiz 
2554f9a1459Swiz       s->origPtr = 0;
2564f9a1459Swiz       GET_UCHAR(BZ_X_ORIGPTR_1, uc);
2574f9a1459Swiz       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
2584f9a1459Swiz       GET_UCHAR(BZ_X_ORIGPTR_2, uc);
2594f9a1459Swiz       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
2604f9a1459Swiz       GET_UCHAR(BZ_X_ORIGPTR_3, uc);
2614f9a1459Swiz       s->origPtr = (s->origPtr << 8) | ((Int32)uc);
2624f9a1459Swiz 
2634f9a1459Swiz       if (s->origPtr < 0)
2644f9a1459Swiz          RETURN(BZ_DATA_ERROR);
2654f9a1459Swiz       if (s->origPtr > 10 + 100000*s->blockSize100k)
2664f9a1459Swiz          RETURN(BZ_DATA_ERROR);
2674f9a1459Swiz 
2684f9a1459Swiz       /*--- Receive the mapping table ---*/
2694f9a1459Swiz       for (i = 0; i < 16; i++) {
2704f9a1459Swiz          GET_BIT(BZ_X_MAPPING_1, uc);
2714f9a1459Swiz          if (uc == 1)
2724f9a1459Swiz             s->inUse16[i] = True; else
2734f9a1459Swiz             s->inUse16[i] = False;
2744f9a1459Swiz       }
2754f9a1459Swiz 
2764f9a1459Swiz       for (i = 0; i < 256; i++) s->inUse[i] = False;
2774f9a1459Swiz 
2784f9a1459Swiz       for (i = 0; i < 16; i++)
2794f9a1459Swiz          if (s->inUse16[i])
2804f9a1459Swiz             for (j = 0; j < 16; j++) {
2814f9a1459Swiz                GET_BIT(BZ_X_MAPPING_2, uc);
2824f9a1459Swiz                if (uc == 1) s->inUse[i * 16 + j] = True;
2834f9a1459Swiz             }
2844f9a1459Swiz       makeMaps_d ( s );
2854f9a1459Swiz       if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
2864f9a1459Swiz       alphaSize = s->nInUse+2;
2874f9a1459Swiz 
2884f9a1459Swiz       /*--- Now the selectors ---*/
2894f9a1459Swiz       GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
290*c4f47eb4Smaya       if (nGroups < 2 || nGroups > BZ_N_GROUPS) RETURN(BZ_DATA_ERROR);
2914f9a1459Swiz       GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
2924f9a1459Swiz       if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
2934f9a1459Swiz       for (i = 0; i < nSelectors; i++) {
2944f9a1459Swiz          j = 0;
2954f9a1459Swiz          while (True) {
2964f9a1459Swiz             GET_BIT(BZ_X_SELECTOR_3, uc);
2974f9a1459Swiz             if (uc == 0) break;
2984f9a1459Swiz             j++;
2994f9a1459Swiz             if (j >= nGroups) RETURN(BZ_DATA_ERROR);
3004f9a1459Swiz          }
301*c4f47eb4Smaya          /* Having more than BZ_MAX_SELECTORS doesn't make much sense
302*c4f47eb4Smaya             since they will never be used, but some implementations might
303*c4f47eb4Smaya             "round up" the number of selectors, so just ignore those. */
304*c4f47eb4Smaya          if (i < BZ_MAX_SELECTORS)
3054f9a1459Swiz            s->selectorMtf[i] = j;
3064f9a1459Swiz       }
307*c4f47eb4Smaya       if (nSelectors > BZ_MAX_SELECTORS)
308*c4f47eb4Smaya         nSelectors = BZ_MAX_SELECTORS;
3094f9a1459Swiz 
3104f9a1459Swiz       /*--- Undo the MTF values for the selectors. ---*/
3114f9a1459Swiz       {
3124f9a1459Swiz          UChar pos[BZ_N_GROUPS], tmp, v;
3134f9a1459Swiz          for (v = 0; v < nGroups; v++) pos[v] = v;
3144f9a1459Swiz 
3154f9a1459Swiz          for (i = 0; i < nSelectors; i++) {
3164f9a1459Swiz             v = s->selectorMtf[i];
3174f9a1459Swiz             tmp = pos[v];
3184f9a1459Swiz             while (v > 0) { pos[v] = pos[v-1]; v--; }
3194f9a1459Swiz             pos[0] = tmp;
3204f9a1459Swiz             s->selector[i] = tmp;
3214f9a1459Swiz          }
3224f9a1459Swiz       }
3234f9a1459Swiz 
3244f9a1459Swiz       /*--- Now the coding tables ---*/
3254f9a1459Swiz       for (t = 0; t < nGroups; t++) {
3264f9a1459Swiz          GET_BITS(BZ_X_CODING_1, curr, 5);
3274f9a1459Swiz          for (i = 0; i < alphaSize; i++) {
3284f9a1459Swiz             while (True) {
3294f9a1459Swiz                if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
3304f9a1459Swiz                GET_BIT(BZ_X_CODING_2, uc);
3314f9a1459Swiz                if (uc == 0) break;
3324f9a1459Swiz                GET_BIT(BZ_X_CODING_3, uc);
3334f9a1459Swiz                if (uc == 0) curr++; else curr--;
3344f9a1459Swiz             }
3354f9a1459Swiz             s->len[t][i] = curr;
3364f9a1459Swiz          }
3374f9a1459Swiz       }
3384f9a1459Swiz 
3394f9a1459Swiz       /*--- Create the Huffman decoding tables ---*/
3404f9a1459Swiz       for (t = 0; t < nGroups; t++) {
3414f9a1459Swiz          minLen = 32;
3424f9a1459Swiz          maxLen = 0;
3434f9a1459Swiz          for (i = 0; i < alphaSize; i++) {
3444f9a1459Swiz             if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
3454f9a1459Swiz             if (s->len[t][i] < minLen) minLen = s->len[t][i];
3464f9a1459Swiz          }
3474f9a1459Swiz          BZ2_hbCreateDecodeTables (
3484f9a1459Swiz             &(s->limit[t][0]),
3494f9a1459Swiz             &(s->base[t][0]),
3504f9a1459Swiz             &(s->perm[t][0]),
3514f9a1459Swiz             &(s->len[t][0]),
3524f9a1459Swiz             minLen, maxLen, alphaSize
3534f9a1459Swiz          );
3544f9a1459Swiz          s->minLens[t] = minLen;
3554f9a1459Swiz       }
3564f9a1459Swiz 
3574f9a1459Swiz       /*--- Now the MTF values ---*/
3584f9a1459Swiz 
3594f9a1459Swiz       EOB      = s->nInUse+1;
3604f9a1459Swiz       nblockMAX = 100000 * s->blockSize100k;
3614f9a1459Swiz       groupNo  = -1;
3624f9a1459Swiz       groupPos = 0;
3634f9a1459Swiz 
3644f9a1459Swiz       for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
3654f9a1459Swiz 
3664f9a1459Swiz       /*-- MTF init --*/
3674f9a1459Swiz       {
3684f9a1459Swiz          Int32 ii, jj, kk;
3694f9a1459Swiz          kk = MTFA_SIZE-1;
3704f9a1459Swiz          for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
3714f9a1459Swiz             for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
3724f9a1459Swiz                s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
3734f9a1459Swiz                kk--;
3744f9a1459Swiz             }
3754f9a1459Swiz             s->mtfbase[ii] = kk + 1;
3764f9a1459Swiz          }
3774f9a1459Swiz       }
3784f9a1459Swiz       /*-- end MTF init --*/
3794f9a1459Swiz 
3804f9a1459Swiz       nblock = 0;
3814f9a1459Swiz       GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
3824f9a1459Swiz 
3834f9a1459Swiz       while (True) {
3844f9a1459Swiz 
3854f9a1459Swiz          if (nextSym == EOB) break;
3864f9a1459Swiz 
3874f9a1459Swiz          if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
3884f9a1459Swiz 
3894f9a1459Swiz             es = -1;
3904f9a1459Swiz             N = 1;
3914f9a1459Swiz             do {
3920449b68bSwiz                /* Check that N doesn't get too big, so that es doesn't
3930449b68bSwiz                   go negative.  The maximum value that can be
3940449b68bSwiz                   RUNA/RUNB encoded is equal to the block size (post
3950449b68bSwiz                   the initial RLE), viz, 900k, so bounding N at 2
3960449b68bSwiz                   million should guard against overflow without
3970449b68bSwiz                   rejecting any legitimate inputs. */
3980449b68bSwiz                if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
3994f9a1459Swiz                if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
4004f9a1459Swiz                if (nextSym == BZ_RUNB) es = es + (1+1) * N;
4014f9a1459Swiz                N = N * 2;
4024f9a1459Swiz                GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
4034f9a1459Swiz             }
4044f9a1459Swiz                while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
4054f9a1459Swiz 
4064f9a1459Swiz             es++;
4074f9a1459Swiz             uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
4084f9a1459Swiz             s->unzftab[uc] += es;
4094f9a1459Swiz 
4104f9a1459Swiz             if (s->smallDecompress)
4114f9a1459Swiz                while (es > 0) {
4124f9a1459Swiz                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
4134f9a1459Swiz                   s->ll16[nblock] = (UInt16)uc;
4144f9a1459Swiz                   nblock++;
4154f9a1459Swiz                   es--;
4164f9a1459Swiz                }
4174f9a1459Swiz             else
4184f9a1459Swiz                while (es > 0) {
4194f9a1459Swiz                   if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
4204f9a1459Swiz                   s->tt[nblock] = (UInt32)uc;
4214f9a1459Swiz                   nblock++;
4224f9a1459Swiz                   es--;
4234f9a1459Swiz                };
4244f9a1459Swiz 
4254f9a1459Swiz             continue;
4264f9a1459Swiz 
4274f9a1459Swiz          } else {
4284f9a1459Swiz 
4294f9a1459Swiz             if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
4304f9a1459Swiz 
4314f9a1459Swiz             /*-- uc = MTF ( nextSym-1 ) --*/
4324f9a1459Swiz             {
4334f9a1459Swiz                Int32 ii, jj, kk, pp, lno, off;
4344f9a1459Swiz                UInt32 nn;
4354f9a1459Swiz                nn = (UInt32)(nextSym - 1);
4364f9a1459Swiz 
4374f9a1459Swiz                if (nn < MTFL_SIZE) {
4384f9a1459Swiz                   /* avoid general-case expense */
4394f9a1459Swiz                   pp = s->mtfbase[0];
4404f9a1459Swiz                   uc = s->mtfa[pp+nn];
4414f9a1459Swiz                   while (nn > 3) {
4424f9a1459Swiz                      Int32 z = pp+nn;
4434f9a1459Swiz                      s->mtfa[(z)  ] = s->mtfa[(z)-1];
4444f9a1459Swiz                      s->mtfa[(z)-1] = s->mtfa[(z)-2];
4454f9a1459Swiz                      s->mtfa[(z)-2] = s->mtfa[(z)-3];
4464f9a1459Swiz                      s->mtfa[(z)-3] = s->mtfa[(z)-4];
4474f9a1459Swiz                      nn -= 4;
4484f9a1459Swiz                   }
4494f9a1459Swiz                   while (nn > 0) {
4504f9a1459Swiz                      s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
4514f9a1459Swiz                   };
4524f9a1459Swiz                   s->mtfa[pp] = uc;
4534f9a1459Swiz                } else {
4544f9a1459Swiz                   /* general case */
4554f9a1459Swiz                   lno = nn / MTFL_SIZE;
4564f9a1459Swiz                   off = nn % MTFL_SIZE;
4574f9a1459Swiz                   pp = s->mtfbase[lno] + off;
4584f9a1459Swiz                   uc = s->mtfa[pp];
4594f9a1459Swiz                   while (pp > s->mtfbase[lno]) {
4604f9a1459Swiz                      s->mtfa[pp] = s->mtfa[pp-1]; pp--;
4614f9a1459Swiz                   };
4624f9a1459Swiz                   s->mtfbase[lno]++;
4634f9a1459Swiz                   while (lno > 0) {
4644f9a1459Swiz                      s->mtfbase[lno]--;
4654f9a1459Swiz                      s->mtfa[s->mtfbase[lno]]
4664f9a1459Swiz                         = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
4674f9a1459Swiz                      lno--;
4684f9a1459Swiz                   }
4694f9a1459Swiz                   s->mtfbase[0]--;
4704f9a1459Swiz                   s->mtfa[s->mtfbase[0]] = uc;
4714f9a1459Swiz                   if (s->mtfbase[0] == 0) {
4724f9a1459Swiz                      kk = MTFA_SIZE-1;
4734f9a1459Swiz                      for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
4744f9a1459Swiz                         for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
4754f9a1459Swiz                            s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
4764f9a1459Swiz                            kk--;
4774f9a1459Swiz                         }
4784f9a1459Swiz                         s->mtfbase[ii] = kk + 1;
4794f9a1459Swiz                      }
4804f9a1459Swiz                   }
4814f9a1459Swiz                }
4824f9a1459Swiz             }
4834f9a1459Swiz             /*-- end uc = MTF ( nextSym-1 ) --*/
4844f9a1459Swiz 
4854f9a1459Swiz             s->unzftab[s->seqToUnseq[uc]]++;
4864f9a1459Swiz             if (s->smallDecompress)
4874f9a1459Swiz                s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
4884f9a1459Swiz                s->tt[nblock]   = (UInt32)(s->seqToUnseq[uc]);
4894f9a1459Swiz             nblock++;
4904f9a1459Swiz 
4914f9a1459Swiz             GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
4924f9a1459Swiz             continue;
4934f9a1459Swiz          }
4944f9a1459Swiz       }
4954f9a1459Swiz 
4964f9a1459Swiz       /* Now we know what nblock is, we can do a better sanity
4974f9a1459Swiz          check on s->origPtr.
4984f9a1459Swiz       */
4994f9a1459Swiz       if (s->origPtr < 0 || s->origPtr >= nblock)
5004f9a1459Swiz          RETURN(BZ_DATA_ERROR);
5014f9a1459Swiz 
5024f9a1459Swiz       /*-- Set up cftab to facilitate generation of T^(-1) --*/
503e3116df7Swiz       /* Check: unzftab entries in range. */
504e3116df7Swiz       for (i = 0; i <= 255; i++) {
505e3116df7Swiz          if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
506e3116df7Swiz             RETURN(BZ_DATA_ERROR);
507e3116df7Swiz       }
508e3116df7Swiz       /* Actually generate cftab. */
5094f9a1459Swiz       s->cftab[0] = 0;
5104f9a1459Swiz       for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
5114f9a1459Swiz       for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
512e3116df7Swiz       /* Check: cftab entries in range. */
5134f9a1459Swiz       for (i = 0; i <= 256; i++) {
5144f9a1459Swiz          if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
5154f9a1459Swiz             /* s->cftab[i] can legitimately be == nblock */
5164f9a1459Swiz             RETURN(BZ_DATA_ERROR);
5174f9a1459Swiz          }
5184f9a1459Swiz       }
519e3116df7Swiz       /* Check: cftab entries non-descending. */
520e3116df7Swiz       for (i = 1; i <= 256; i++) {
521e3116df7Swiz          if (s->cftab[i-1] > s->cftab[i]) {
522e3116df7Swiz             RETURN(BZ_DATA_ERROR);
523e3116df7Swiz          }
524e3116df7Swiz       }
5254f9a1459Swiz 
5264f9a1459Swiz       s->state_out_len = 0;
5274f9a1459Swiz       s->state_out_ch  = 0;
5284f9a1459Swiz       BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
5294f9a1459Swiz       s->state = BZ_X_OUTPUT;
5304f9a1459Swiz       if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
5314f9a1459Swiz 
5324f9a1459Swiz       if (s->smallDecompress) {
5334f9a1459Swiz 
5344f9a1459Swiz          /*-- Make a copy of cftab, used in generation of T --*/
5354f9a1459Swiz          for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
5364f9a1459Swiz 
5374f9a1459Swiz          /*-- compute the T vector --*/
5384f9a1459Swiz          for (i = 0; i < nblock; i++) {
5394f9a1459Swiz             uc = (UChar)(s->ll16[i]);
5404f9a1459Swiz             SET_LL(i, s->cftabCopy[uc]);
5414f9a1459Swiz             s->cftabCopy[uc]++;
5424f9a1459Swiz          }
5434f9a1459Swiz 
5444f9a1459Swiz          /*-- Compute T^(-1) by pointer reversal on T --*/
5454f9a1459Swiz          i = s->origPtr;
5464f9a1459Swiz          j = GET_LL(i);
5474f9a1459Swiz          do {
5484f9a1459Swiz             Int32 tmp = GET_LL(j);
5494f9a1459Swiz             SET_LL(j, i);
5504f9a1459Swiz             i = j;
5514f9a1459Swiz             j = tmp;
5524f9a1459Swiz          }
5534f9a1459Swiz             while (i != s->origPtr);
5544f9a1459Swiz 
5554f9a1459Swiz          s->tPos = s->origPtr;
5564f9a1459Swiz          s->nblock_used = 0;
5574f9a1459Swiz          if (s->blockRandomised) {
5584f9a1459Swiz             BZ_RAND_INIT_MASK;
5594f9a1459Swiz             BZ_GET_SMALL(s->k0); s->nblock_used++;
5604f9a1459Swiz             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
5614f9a1459Swiz          } else {
5624f9a1459Swiz             BZ_GET_SMALL(s->k0); s->nblock_used++;
5634f9a1459Swiz          }
5644f9a1459Swiz 
5654f9a1459Swiz       } else {
5664f9a1459Swiz 
5674f9a1459Swiz          /*-- compute the T^(-1) vector --*/
5684f9a1459Swiz          for (i = 0; i < nblock; i++) {
5694f9a1459Swiz             uc = (UChar)(s->tt[i] & 0xff);
5704f9a1459Swiz             s->tt[s->cftab[uc]] |= (i << 8);
5714f9a1459Swiz             s->cftab[uc]++;
5724f9a1459Swiz          }
5734f9a1459Swiz 
5744f9a1459Swiz          s->tPos = s->tt[s->origPtr] >> 8;
5754f9a1459Swiz          s->nblock_used = 0;
5764f9a1459Swiz          if (s->blockRandomised) {
5774f9a1459Swiz             BZ_RAND_INIT_MASK;
5784f9a1459Swiz             BZ_GET_FAST(s->k0); s->nblock_used++;
5794f9a1459Swiz             BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
5804f9a1459Swiz          } else {
5814f9a1459Swiz             BZ_GET_FAST(s->k0); s->nblock_used++;
5824f9a1459Swiz          }
5834f9a1459Swiz 
5844f9a1459Swiz       }
5854f9a1459Swiz 
5864f9a1459Swiz       RETURN(BZ_OK);
5874f9a1459Swiz 
5884f9a1459Swiz 
5894f9a1459Swiz 
5904f9a1459Swiz     endhdr_2:
5914f9a1459Swiz 
5924f9a1459Swiz       GET_UCHAR(BZ_X_ENDHDR_2, uc);
5934f9a1459Swiz       if (uc != 0x72) RETURN(BZ_DATA_ERROR);
5944f9a1459Swiz       GET_UCHAR(BZ_X_ENDHDR_3, uc);
5954f9a1459Swiz       if (uc != 0x45) RETURN(BZ_DATA_ERROR);
5964f9a1459Swiz       GET_UCHAR(BZ_X_ENDHDR_4, uc);
5974f9a1459Swiz       if (uc != 0x38) RETURN(BZ_DATA_ERROR);
5984f9a1459Swiz       GET_UCHAR(BZ_X_ENDHDR_5, uc);
5994f9a1459Swiz       if (uc != 0x50) RETURN(BZ_DATA_ERROR);
6004f9a1459Swiz       GET_UCHAR(BZ_X_ENDHDR_6, uc);
6014f9a1459Swiz       if (uc != 0x90) RETURN(BZ_DATA_ERROR);
6024f9a1459Swiz 
6034f9a1459Swiz       s->storedCombinedCRC = 0;
6044f9a1459Swiz       GET_UCHAR(BZ_X_CCRC_1, uc);
6054f9a1459Swiz       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
6064f9a1459Swiz       GET_UCHAR(BZ_X_CCRC_2, uc);
6074f9a1459Swiz       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
6084f9a1459Swiz       GET_UCHAR(BZ_X_CCRC_3, uc);
6094f9a1459Swiz       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
6104f9a1459Swiz       GET_UCHAR(BZ_X_CCRC_4, uc);
6114f9a1459Swiz       s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
6124f9a1459Swiz 
6134f9a1459Swiz       s->state = BZ_X_IDLE;
6144f9a1459Swiz       RETURN(BZ_STREAM_END);
6154f9a1459Swiz 
6164f9a1459Swiz       default: AssertH ( False, 4001 );
6174f9a1459Swiz    }
6184f9a1459Swiz 
6194f9a1459Swiz    AssertH ( False, 4002 );
6204f9a1459Swiz 
6214f9a1459Swiz    save_state_and_return:
6224f9a1459Swiz 
6234f9a1459Swiz    s->save_i           = i;
6244f9a1459Swiz    s->save_j           = j;
6254f9a1459Swiz    s->save_t           = t;
6264f9a1459Swiz    s->save_alphaSize   = alphaSize;
6274f9a1459Swiz    s->save_nGroups     = nGroups;
6284f9a1459Swiz    s->save_nSelectors  = nSelectors;
6294f9a1459Swiz    s->save_EOB         = EOB;
6304f9a1459Swiz    s->save_groupNo     = groupNo;
6314f9a1459Swiz    s->save_groupPos    = groupPos;
6324f9a1459Swiz    s->save_nextSym     = nextSym;
6334f9a1459Swiz    s->save_nblockMAX   = nblockMAX;
6344f9a1459Swiz    s->save_nblock      = nblock;
6354f9a1459Swiz    s->save_es          = es;
6364f9a1459Swiz    s->save_N           = N;
6374f9a1459Swiz    s->save_curr        = curr;
6384f9a1459Swiz    s->save_zt          = zt;
6394f9a1459Swiz    s->save_zn          = zn;
6404f9a1459Swiz    s->save_zvec        = zvec;
6414f9a1459Swiz    s->save_zj          = zj;
6424f9a1459Swiz    s->save_gSel        = gSel;
6434f9a1459Swiz    s->save_gMinlen     = gMinlen;
6444f9a1459Swiz    s->save_gLimit      = gLimit;
6454f9a1459Swiz    s->save_gBase       = gBase;
6464f9a1459Swiz    s->save_gPerm       = gPerm;
6474f9a1459Swiz 
6484f9a1459Swiz    return retVal;
6494f9a1459Swiz }
6504f9a1459Swiz 
6514f9a1459Swiz 
6524f9a1459Swiz /*-------------------------------------------------------------*/
6534f9a1459Swiz /*--- end                                      decompress.c ---*/
6544f9a1459Swiz /*-------------------------------------------------------------*/
655