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