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