1*b1efbcd6SAlok Aggarwal /* 2*b1efbcd6SAlok Aggarwal * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3*b1efbcd6SAlok Aggarwal * Use is subject to license terms. 4*b1efbcd6SAlok Aggarwal */ 5*b1efbcd6SAlok Aggarwal 6*b1efbcd6SAlok Aggarwal /* LzmaDec.c -- LZMA Decoder 7*b1efbcd6SAlok Aggarwal 2008-11-06 : Igor Pavlov : Public domain */ 8*b1efbcd6SAlok Aggarwal 9*b1efbcd6SAlok Aggarwal #include "LzmaDec.h" 10*b1efbcd6SAlok Aggarwal 11*b1efbcd6SAlok Aggarwal #ifndef _KERNEL 12*b1efbcd6SAlok Aggarwal #include <string.h> 13*b1efbcd6SAlok Aggarwal #endif /* _KERNEL */ 14*b1efbcd6SAlok Aggarwal 15*b1efbcd6SAlok Aggarwal #define kNumTopBits 24 16*b1efbcd6SAlok Aggarwal #define kTopValue ((UInt32)1 << kNumTopBits) 17*b1efbcd6SAlok Aggarwal 18*b1efbcd6SAlok Aggarwal #define kNumBitModelTotalBits 11 19*b1efbcd6SAlok Aggarwal #define kBitModelTotal (1 << kNumBitModelTotalBits) 20*b1efbcd6SAlok Aggarwal #define kNumMoveBits 5 21*b1efbcd6SAlok Aggarwal 22*b1efbcd6SAlok Aggarwal #define RC_INIT_SIZE 5 23*b1efbcd6SAlok Aggarwal 24*b1efbcd6SAlok Aggarwal #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } 25*b1efbcd6SAlok Aggarwal 26*b1efbcd6SAlok Aggarwal #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 27*b1efbcd6SAlok Aggarwal #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); 28*b1efbcd6SAlok Aggarwal #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); 29*b1efbcd6SAlok Aggarwal #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ 30*b1efbcd6SAlok Aggarwal { UPDATE_0(p); i = (i + i); A0; } else \ 31*b1efbcd6SAlok Aggarwal { UPDATE_1(p); i = (i + i) + 1; A1; } 32*b1efbcd6SAlok Aggarwal #define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) 33*b1efbcd6SAlok Aggarwal 34*b1efbcd6SAlok Aggarwal #define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } 35*b1efbcd6SAlok Aggarwal #define TREE_DECODE(probs, limit, i) \ 36*b1efbcd6SAlok Aggarwal { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } 37*b1efbcd6SAlok Aggarwal 38*b1efbcd6SAlok Aggarwal /* #define _LZMA_SIZE_OPT */ 39*b1efbcd6SAlok Aggarwal 40*b1efbcd6SAlok Aggarwal #ifdef _LZMA_SIZE_OPT 41*b1efbcd6SAlok Aggarwal #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) 42*b1efbcd6SAlok Aggarwal #else 43*b1efbcd6SAlok Aggarwal #define TREE_6_DECODE(probs, i) \ 44*b1efbcd6SAlok Aggarwal { i = 1; \ 45*b1efbcd6SAlok Aggarwal TREE_GET_BIT(probs, i); \ 46*b1efbcd6SAlok Aggarwal TREE_GET_BIT(probs, i); \ 47*b1efbcd6SAlok Aggarwal TREE_GET_BIT(probs, i); \ 48*b1efbcd6SAlok Aggarwal TREE_GET_BIT(probs, i); \ 49*b1efbcd6SAlok Aggarwal TREE_GET_BIT(probs, i); \ 50*b1efbcd6SAlok Aggarwal TREE_GET_BIT(probs, i); \ 51*b1efbcd6SAlok Aggarwal i -= 0x40; } 52*b1efbcd6SAlok Aggarwal #endif 53*b1efbcd6SAlok Aggarwal 54*b1efbcd6SAlok Aggarwal #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } 55*b1efbcd6SAlok Aggarwal 56*b1efbcd6SAlok Aggarwal #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 57*b1efbcd6SAlok Aggarwal #define UPDATE_0_CHECK range = bound; 58*b1efbcd6SAlok Aggarwal #define UPDATE_1_CHECK range -= bound; code -= bound; 59*b1efbcd6SAlok Aggarwal #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ 60*b1efbcd6SAlok Aggarwal { UPDATE_0_CHECK; i = (i + i); A0; } else \ 61*b1efbcd6SAlok Aggarwal { UPDATE_1_CHECK; i = (i + i) + 1; A1; } 62*b1efbcd6SAlok Aggarwal #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) 63*b1efbcd6SAlok Aggarwal #define TREE_DECODE_CHECK(probs, limit, i) \ 64*b1efbcd6SAlok Aggarwal { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } 65*b1efbcd6SAlok Aggarwal 66*b1efbcd6SAlok Aggarwal 67*b1efbcd6SAlok Aggarwal #define kNumPosBitsMax 4 68*b1efbcd6SAlok Aggarwal #define kNumPosStatesMax (1 << kNumPosBitsMax) 69*b1efbcd6SAlok Aggarwal 70*b1efbcd6SAlok Aggarwal #define kLenNumLowBits 3 71*b1efbcd6SAlok Aggarwal #define kLenNumLowSymbols (1 << kLenNumLowBits) 72*b1efbcd6SAlok Aggarwal #define kLenNumMidBits 3 73*b1efbcd6SAlok Aggarwal #define kLenNumMidSymbols (1 << kLenNumMidBits) 74*b1efbcd6SAlok Aggarwal #define kLenNumHighBits 8 75*b1efbcd6SAlok Aggarwal #define kLenNumHighSymbols (1 << kLenNumHighBits) 76*b1efbcd6SAlok Aggarwal 77*b1efbcd6SAlok Aggarwal #define LenChoice 0 78*b1efbcd6SAlok Aggarwal #define LenChoice2 (LenChoice + 1) 79*b1efbcd6SAlok Aggarwal #define LenLow (LenChoice2 + 1) 80*b1efbcd6SAlok Aggarwal #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) 81*b1efbcd6SAlok Aggarwal #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) 82*b1efbcd6SAlok Aggarwal #define kNumLenProbs (LenHigh + kLenNumHighSymbols) 83*b1efbcd6SAlok Aggarwal 84*b1efbcd6SAlok Aggarwal 85*b1efbcd6SAlok Aggarwal #define kNumStates 12 86*b1efbcd6SAlok Aggarwal #define kNumLitStates 7 87*b1efbcd6SAlok Aggarwal 88*b1efbcd6SAlok Aggarwal #define kStartPosModelIndex 4 89*b1efbcd6SAlok Aggarwal #define kEndPosModelIndex 14 90*b1efbcd6SAlok Aggarwal #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) 91*b1efbcd6SAlok Aggarwal 92*b1efbcd6SAlok Aggarwal #define kNumPosSlotBits 6 93*b1efbcd6SAlok Aggarwal #define kNumLenToPosStates 4 94*b1efbcd6SAlok Aggarwal 95*b1efbcd6SAlok Aggarwal #define kNumAlignBits 4 96*b1efbcd6SAlok Aggarwal #define kAlignTableSize (1 << kNumAlignBits) 97*b1efbcd6SAlok Aggarwal 98*b1efbcd6SAlok Aggarwal #define kMatchMinLen 2 99*b1efbcd6SAlok Aggarwal #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) 100*b1efbcd6SAlok Aggarwal 101*b1efbcd6SAlok Aggarwal #define IsMatch 0 102*b1efbcd6SAlok Aggarwal #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) 103*b1efbcd6SAlok Aggarwal #define IsRepG0 (IsRep + kNumStates) 104*b1efbcd6SAlok Aggarwal #define IsRepG1 (IsRepG0 + kNumStates) 105*b1efbcd6SAlok Aggarwal #define IsRepG2 (IsRepG1 + kNumStates) 106*b1efbcd6SAlok Aggarwal #define IsRep0Long (IsRepG2 + kNumStates) 107*b1efbcd6SAlok Aggarwal #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) 108*b1efbcd6SAlok Aggarwal #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) 109*b1efbcd6SAlok Aggarwal #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) 110*b1efbcd6SAlok Aggarwal #define LenCoder (Align + kAlignTableSize) 111*b1efbcd6SAlok Aggarwal #define RepLenCoder (LenCoder + kNumLenProbs) 112*b1efbcd6SAlok Aggarwal #define Literal (RepLenCoder + kNumLenProbs) 113*b1efbcd6SAlok Aggarwal 114*b1efbcd6SAlok Aggarwal #define LZMA_BASE_SIZE 1846 115*b1efbcd6SAlok Aggarwal #define LZMA_LIT_SIZE 768 116*b1efbcd6SAlok Aggarwal 117*b1efbcd6SAlok Aggarwal #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) 118*b1efbcd6SAlok Aggarwal 119*b1efbcd6SAlok Aggarwal #if Literal != LZMA_BASE_SIZE 120*b1efbcd6SAlok Aggarwal StopCompilingDueBUG 121*b1efbcd6SAlok Aggarwal #endif 122*b1efbcd6SAlok Aggarwal 123*b1efbcd6SAlok Aggarwal static const Byte kLiteralNextStates[kNumStates * 2] = 124*b1efbcd6SAlok Aggarwal { 125*b1efbcd6SAlok Aggarwal 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, 126*b1efbcd6SAlok Aggarwal 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 127*b1efbcd6SAlok Aggarwal }; 128*b1efbcd6SAlok Aggarwal 129*b1efbcd6SAlok Aggarwal #ifdef _KERNEL 130*b1efbcd6SAlok Aggarwal extern void *memcpy(void *, const void *, size_t); 131*b1efbcd6SAlok Aggarwal #endif /* _KERNEL */ 132*b1efbcd6SAlok Aggarwal 133*b1efbcd6SAlok Aggarwal #define LZMA_DIC_MIN (1 << 12) 134*b1efbcd6SAlok Aggarwal 135*b1efbcd6SAlok Aggarwal /* First LZMA-symbol is always decoded. 136*b1efbcd6SAlok Aggarwal And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization 137*b1efbcd6SAlok Aggarwal Out: 138*b1efbcd6SAlok Aggarwal Result: 139*b1efbcd6SAlok Aggarwal SZ_OK - OK 140*b1efbcd6SAlok Aggarwal SZ_ERROR_DATA - Error 141*b1efbcd6SAlok Aggarwal p->remainLen: 142*b1efbcd6SAlok Aggarwal < kMatchSpecLenStart : normal remain 143*b1efbcd6SAlok Aggarwal = kMatchSpecLenStart : finished 144*b1efbcd6SAlok Aggarwal = kMatchSpecLenStart + 1 : Flush marker 145*b1efbcd6SAlok Aggarwal = kMatchSpecLenStart + 2 : State Init Marker 146*b1efbcd6SAlok Aggarwal */ 147*b1efbcd6SAlok Aggarwal 148*b1efbcd6SAlok Aggarwal static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 149*b1efbcd6SAlok Aggarwal { 150*b1efbcd6SAlok Aggarwal CLzmaProb *probs = p->probs; 151*b1efbcd6SAlok Aggarwal 152*b1efbcd6SAlok Aggarwal unsigned state = p->state; 153*b1efbcd6SAlok Aggarwal UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; 154*b1efbcd6SAlok Aggarwal unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; 155*b1efbcd6SAlok Aggarwal unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; 156*b1efbcd6SAlok Aggarwal unsigned lc = p->prop.lc; 157*b1efbcd6SAlok Aggarwal 158*b1efbcd6SAlok Aggarwal Byte *dic = p->dic; 159*b1efbcd6SAlok Aggarwal SizeT dicBufSize = p->dicBufSize; 160*b1efbcd6SAlok Aggarwal SizeT dicPos = p->dicPos; 161*b1efbcd6SAlok Aggarwal 162*b1efbcd6SAlok Aggarwal UInt32 processedPos = p->processedPos; 163*b1efbcd6SAlok Aggarwal UInt32 checkDicSize = p->checkDicSize; 164*b1efbcd6SAlok Aggarwal unsigned len = 0; 165*b1efbcd6SAlok Aggarwal 166*b1efbcd6SAlok Aggarwal const Byte *buf = p->buf; 167*b1efbcd6SAlok Aggarwal UInt32 range = p->range; 168*b1efbcd6SAlok Aggarwal UInt32 code = p->code; 169*b1efbcd6SAlok Aggarwal 170*b1efbcd6SAlok Aggarwal do 171*b1efbcd6SAlok Aggarwal { 172*b1efbcd6SAlok Aggarwal CLzmaProb *prob; 173*b1efbcd6SAlok Aggarwal UInt32 bound; 174*b1efbcd6SAlok Aggarwal unsigned ttt; 175*b1efbcd6SAlok Aggarwal unsigned posState = processedPos & pbMask; 176*b1efbcd6SAlok Aggarwal 177*b1efbcd6SAlok Aggarwal prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 178*b1efbcd6SAlok Aggarwal IF_BIT_0(prob) 179*b1efbcd6SAlok Aggarwal { 180*b1efbcd6SAlok Aggarwal unsigned symbol; 181*b1efbcd6SAlok Aggarwal UPDATE_0(prob); 182*b1efbcd6SAlok Aggarwal prob = probs + Literal; 183*b1efbcd6SAlok Aggarwal if (checkDicSize != 0 || processedPos != 0) 184*b1efbcd6SAlok Aggarwal prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + 185*b1efbcd6SAlok Aggarwal (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); 186*b1efbcd6SAlok Aggarwal 187*b1efbcd6SAlok Aggarwal if (state < kNumLitStates) 188*b1efbcd6SAlok Aggarwal { 189*b1efbcd6SAlok Aggarwal symbol = 1; 190*b1efbcd6SAlok Aggarwal do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); 191*b1efbcd6SAlok Aggarwal } 192*b1efbcd6SAlok Aggarwal else 193*b1efbcd6SAlok Aggarwal { 194*b1efbcd6SAlok Aggarwal unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 195*b1efbcd6SAlok Aggarwal unsigned offs = 0x100; 196*b1efbcd6SAlok Aggarwal symbol = 1; 197*b1efbcd6SAlok Aggarwal do 198*b1efbcd6SAlok Aggarwal { 199*b1efbcd6SAlok Aggarwal unsigned bit; 200*b1efbcd6SAlok Aggarwal CLzmaProb *probLit; 201*b1efbcd6SAlok Aggarwal matchByte <<= 1; 202*b1efbcd6SAlok Aggarwal bit = (matchByte & offs); 203*b1efbcd6SAlok Aggarwal probLit = prob + offs + bit + symbol; 204*b1efbcd6SAlok Aggarwal GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) 205*b1efbcd6SAlok Aggarwal } 206*b1efbcd6SAlok Aggarwal while (symbol < 0x100); 207*b1efbcd6SAlok Aggarwal } 208*b1efbcd6SAlok Aggarwal dic[dicPos++] = (Byte)symbol; 209*b1efbcd6SAlok Aggarwal processedPos++; 210*b1efbcd6SAlok Aggarwal 211*b1efbcd6SAlok Aggarwal state = kLiteralNextStates[state]; 212*b1efbcd6SAlok Aggarwal /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ 213*b1efbcd6SAlok Aggarwal continue; 214*b1efbcd6SAlok Aggarwal } 215*b1efbcd6SAlok Aggarwal else 216*b1efbcd6SAlok Aggarwal { 217*b1efbcd6SAlok Aggarwal UPDATE_1(prob); 218*b1efbcd6SAlok Aggarwal prob = probs + IsRep + state; 219*b1efbcd6SAlok Aggarwal IF_BIT_0(prob) 220*b1efbcd6SAlok Aggarwal { 221*b1efbcd6SAlok Aggarwal UPDATE_0(prob); 222*b1efbcd6SAlok Aggarwal state += kNumStates; 223*b1efbcd6SAlok Aggarwal prob = probs + LenCoder; 224*b1efbcd6SAlok Aggarwal } 225*b1efbcd6SAlok Aggarwal else 226*b1efbcd6SAlok Aggarwal { 227*b1efbcd6SAlok Aggarwal UPDATE_1(prob); 228*b1efbcd6SAlok Aggarwal if (checkDicSize == 0 && processedPos == 0) 229*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 230*b1efbcd6SAlok Aggarwal prob = probs + IsRepG0 + state; 231*b1efbcd6SAlok Aggarwal IF_BIT_0(prob) 232*b1efbcd6SAlok Aggarwal { 233*b1efbcd6SAlok Aggarwal UPDATE_0(prob); 234*b1efbcd6SAlok Aggarwal prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 235*b1efbcd6SAlok Aggarwal IF_BIT_0(prob) 236*b1efbcd6SAlok Aggarwal { 237*b1efbcd6SAlok Aggarwal UPDATE_0(prob); 238*b1efbcd6SAlok Aggarwal dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 239*b1efbcd6SAlok Aggarwal dicPos++; 240*b1efbcd6SAlok Aggarwal processedPos++; 241*b1efbcd6SAlok Aggarwal state = state < kNumLitStates ? 9 : 11; 242*b1efbcd6SAlok Aggarwal continue; 243*b1efbcd6SAlok Aggarwal } 244*b1efbcd6SAlok Aggarwal UPDATE_1(prob); 245*b1efbcd6SAlok Aggarwal } 246*b1efbcd6SAlok Aggarwal else 247*b1efbcd6SAlok Aggarwal { 248*b1efbcd6SAlok Aggarwal UInt32 distance; 249*b1efbcd6SAlok Aggarwal UPDATE_1(prob); 250*b1efbcd6SAlok Aggarwal prob = probs + IsRepG1 + state; 251*b1efbcd6SAlok Aggarwal IF_BIT_0(prob) 252*b1efbcd6SAlok Aggarwal { 253*b1efbcd6SAlok Aggarwal UPDATE_0(prob); 254*b1efbcd6SAlok Aggarwal distance = rep1; 255*b1efbcd6SAlok Aggarwal } 256*b1efbcd6SAlok Aggarwal else 257*b1efbcd6SAlok Aggarwal { 258*b1efbcd6SAlok Aggarwal UPDATE_1(prob); 259*b1efbcd6SAlok Aggarwal prob = probs + IsRepG2 + state; 260*b1efbcd6SAlok Aggarwal IF_BIT_0(prob) 261*b1efbcd6SAlok Aggarwal { 262*b1efbcd6SAlok Aggarwal UPDATE_0(prob); 263*b1efbcd6SAlok Aggarwal distance = rep2; 264*b1efbcd6SAlok Aggarwal } 265*b1efbcd6SAlok Aggarwal else 266*b1efbcd6SAlok Aggarwal { 267*b1efbcd6SAlok Aggarwal UPDATE_1(prob); 268*b1efbcd6SAlok Aggarwal distance = rep3; 269*b1efbcd6SAlok Aggarwal rep3 = rep2; 270*b1efbcd6SAlok Aggarwal } 271*b1efbcd6SAlok Aggarwal rep2 = rep1; 272*b1efbcd6SAlok Aggarwal } 273*b1efbcd6SAlok Aggarwal rep1 = rep0; 274*b1efbcd6SAlok Aggarwal rep0 = distance; 275*b1efbcd6SAlok Aggarwal } 276*b1efbcd6SAlok Aggarwal state = state < kNumLitStates ? 8 : 11; 277*b1efbcd6SAlok Aggarwal prob = probs + RepLenCoder; 278*b1efbcd6SAlok Aggarwal } 279*b1efbcd6SAlok Aggarwal { 280*b1efbcd6SAlok Aggarwal unsigned limit, offset; 281*b1efbcd6SAlok Aggarwal CLzmaProb *probLen = prob + LenChoice; 282*b1efbcd6SAlok Aggarwal IF_BIT_0(probLen) 283*b1efbcd6SAlok Aggarwal { 284*b1efbcd6SAlok Aggarwal UPDATE_0(probLen); 285*b1efbcd6SAlok Aggarwal probLen = prob + LenLow + (posState << kLenNumLowBits); 286*b1efbcd6SAlok Aggarwal offset = 0; 287*b1efbcd6SAlok Aggarwal limit = (1 << kLenNumLowBits); 288*b1efbcd6SAlok Aggarwal } 289*b1efbcd6SAlok Aggarwal else 290*b1efbcd6SAlok Aggarwal { 291*b1efbcd6SAlok Aggarwal UPDATE_1(probLen); 292*b1efbcd6SAlok Aggarwal probLen = prob + LenChoice2; 293*b1efbcd6SAlok Aggarwal IF_BIT_0(probLen) 294*b1efbcd6SAlok Aggarwal { 295*b1efbcd6SAlok Aggarwal UPDATE_0(probLen); 296*b1efbcd6SAlok Aggarwal probLen = prob + LenMid + (posState << kLenNumMidBits); 297*b1efbcd6SAlok Aggarwal offset = kLenNumLowSymbols; 298*b1efbcd6SAlok Aggarwal limit = (1 << kLenNumMidBits); 299*b1efbcd6SAlok Aggarwal } 300*b1efbcd6SAlok Aggarwal else 301*b1efbcd6SAlok Aggarwal { 302*b1efbcd6SAlok Aggarwal UPDATE_1(probLen); 303*b1efbcd6SAlok Aggarwal probLen = prob + LenHigh; 304*b1efbcd6SAlok Aggarwal offset = kLenNumLowSymbols + kLenNumMidSymbols; 305*b1efbcd6SAlok Aggarwal limit = (1 << kLenNumHighBits); 306*b1efbcd6SAlok Aggarwal } 307*b1efbcd6SAlok Aggarwal } 308*b1efbcd6SAlok Aggarwal TREE_DECODE(probLen, limit, len); 309*b1efbcd6SAlok Aggarwal len += offset; 310*b1efbcd6SAlok Aggarwal } 311*b1efbcd6SAlok Aggarwal 312*b1efbcd6SAlok Aggarwal if (state >= kNumStates) 313*b1efbcd6SAlok Aggarwal { 314*b1efbcd6SAlok Aggarwal UInt32 distance; 315*b1efbcd6SAlok Aggarwal prob = probs + PosSlot + 316*b1efbcd6SAlok Aggarwal ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); 317*b1efbcd6SAlok Aggarwal TREE_6_DECODE(prob, distance); 318*b1efbcd6SAlok Aggarwal if (distance >= kStartPosModelIndex) 319*b1efbcd6SAlok Aggarwal { 320*b1efbcd6SAlok Aggarwal unsigned posSlot = (unsigned)distance; 321*b1efbcd6SAlok Aggarwal int numDirectBits = (int)(((distance >> 1) - 1)); 322*b1efbcd6SAlok Aggarwal distance = (2 | (distance & 1)); 323*b1efbcd6SAlok Aggarwal if (posSlot < kEndPosModelIndex) 324*b1efbcd6SAlok Aggarwal { 325*b1efbcd6SAlok Aggarwal distance <<= numDirectBits; 326*b1efbcd6SAlok Aggarwal prob = probs + SpecPos + distance - posSlot - 1; 327*b1efbcd6SAlok Aggarwal { 328*b1efbcd6SAlok Aggarwal UInt32 mask = 1; 329*b1efbcd6SAlok Aggarwal unsigned i = 1; 330*b1efbcd6SAlok Aggarwal do 331*b1efbcd6SAlok Aggarwal { 332*b1efbcd6SAlok Aggarwal GET_BIT2(prob + i, i, ; , distance |= mask); 333*b1efbcd6SAlok Aggarwal mask <<= 1; 334*b1efbcd6SAlok Aggarwal } 335*b1efbcd6SAlok Aggarwal while (--numDirectBits != 0); 336*b1efbcd6SAlok Aggarwal } 337*b1efbcd6SAlok Aggarwal } 338*b1efbcd6SAlok Aggarwal else 339*b1efbcd6SAlok Aggarwal { 340*b1efbcd6SAlok Aggarwal numDirectBits -= kNumAlignBits; 341*b1efbcd6SAlok Aggarwal do 342*b1efbcd6SAlok Aggarwal { 343*b1efbcd6SAlok Aggarwal NORMALIZE 344*b1efbcd6SAlok Aggarwal range >>= 1; 345*b1efbcd6SAlok Aggarwal 346*b1efbcd6SAlok Aggarwal { 347*b1efbcd6SAlok Aggarwal UInt32 t; 348*b1efbcd6SAlok Aggarwal code -= range; 349*b1efbcd6SAlok Aggarwal t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ 350*b1efbcd6SAlok Aggarwal distance = (distance << 1) + (t + 1); 351*b1efbcd6SAlok Aggarwal code += range & t; 352*b1efbcd6SAlok Aggarwal } 353*b1efbcd6SAlok Aggarwal /* 354*b1efbcd6SAlok Aggarwal distance <<= 1; 355*b1efbcd6SAlok Aggarwal if (code >= range) 356*b1efbcd6SAlok Aggarwal { 357*b1efbcd6SAlok Aggarwal code -= range; 358*b1efbcd6SAlok Aggarwal distance |= 1; 359*b1efbcd6SAlok Aggarwal } 360*b1efbcd6SAlok Aggarwal */ 361*b1efbcd6SAlok Aggarwal } 362*b1efbcd6SAlok Aggarwal while (--numDirectBits != 0); 363*b1efbcd6SAlok Aggarwal prob = probs + Align; 364*b1efbcd6SAlok Aggarwal distance <<= kNumAlignBits; 365*b1efbcd6SAlok Aggarwal { 366*b1efbcd6SAlok Aggarwal unsigned i = 1; 367*b1efbcd6SAlok Aggarwal GET_BIT2(prob + i, i, ; , distance |= 1); 368*b1efbcd6SAlok Aggarwal GET_BIT2(prob + i, i, ; , distance |= 2); 369*b1efbcd6SAlok Aggarwal GET_BIT2(prob + i, i, ; , distance |= 4); 370*b1efbcd6SAlok Aggarwal GET_BIT2(prob + i, i, ; , distance |= 8); 371*b1efbcd6SAlok Aggarwal } 372*b1efbcd6SAlok Aggarwal if (distance == (UInt32)0xFFFFFFFF) 373*b1efbcd6SAlok Aggarwal { 374*b1efbcd6SAlok Aggarwal len += kMatchSpecLenStart; 375*b1efbcd6SAlok Aggarwal state -= kNumStates; 376*b1efbcd6SAlok Aggarwal break; 377*b1efbcd6SAlok Aggarwal } 378*b1efbcd6SAlok Aggarwal } 379*b1efbcd6SAlok Aggarwal } 380*b1efbcd6SAlok Aggarwal rep3 = rep2; 381*b1efbcd6SAlok Aggarwal rep2 = rep1; 382*b1efbcd6SAlok Aggarwal rep1 = rep0; 383*b1efbcd6SAlok Aggarwal rep0 = distance + 1; 384*b1efbcd6SAlok Aggarwal if (checkDicSize == 0) 385*b1efbcd6SAlok Aggarwal { 386*b1efbcd6SAlok Aggarwal if (distance >= processedPos) 387*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 388*b1efbcd6SAlok Aggarwal } 389*b1efbcd6SAlok Aggarwal else if (distance >= checkDicSize) 390*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 391*b1efbcd6SAlok Aggarwal state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; 392*b1efbcd6SAlok Aggarwal /* state = kLiteralNextStates[state]; */ 393*b1efbcd6SAlok Aggarwal } 394*b1efbcd6SAlok Aggarwal 395*b1efbcd6SAlok Aggarwal len += kMatchMinLen; 396*b1efbcd6SAlok Aggarwal 397*b1efbcd6SAlok Aggarwal if (limit == dicPos) 398*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 399*b1efbcd6SAlok Aggarwal { 400*b1efbcd6SAlok Aggarwal SizeT rem = limit - dicPos; 401*b1efbcd6SAlok Aggarwal unsigned curLen = ((rem < len) ? (unsigned)rem : len); 402*b1efbcd6SAlok Aggarwal SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); 403*b1efbcd6SAlok Aggarwal 404*b1efbcd6SAlok Aggarwal processedPos += curLen; 405*b1efbcd6SAlok Aggarwal 406*b1efbcd6SAlok Aggarwal len -= curLen; 407*b1efbcd6SAlok Aggarwal if (pos + curLen <= dicBufSize) 408*b1efbcd6SAlok Aggarwal { 409*b1efbcd6SAlok Aggarwal Byte *dest = dic + dicPos; 410*b1efbcd6SAlok Aggarwal ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; 411*b1efbcd6SAlok Aggarwal const Byte *lim = dest + curLen; 412*b1efbcd6SAlok Aggarwal dicPos += curLen; 413*b1efbcd6SAlok Aggarwal do 414*b1efbcd6SAlok Aggarwal *(dest) = (Byte)*(dest + src); 415*b1efbcd6SAlok Aggarwal while (++dest != lim); 416*b1efbcd6SAlok Aggarwal } 417*b1efbcd6SAlok Aggarwal else 418*b1efbcd6SAlok Aggarwal { 419*b1efbcd6SAlok Aggarwal do 420*b1efbcd6SAlok Aggarwal { 421*b1efbcd6SAlok Aggarwal dic[dicPos++] = dic[pos]; 422*b1efbcd6SAlok Aggarwal if (++pos == dicBufSize) 423*b1efbcd6SAlok Aggarwal pos = 0; 424*b1efbcd6SAlok Aggarwal } 425*b1efbcd6SAlok Aggarwal while (--curLen != 0); 426*b1efbcd6SAlok Aggarwal } 427*b1efbcd6SAlok Aggarwal } 428*b1efbcd6SAlok Aggarwal } 429*b1efbcd6SAlok Aggarwal } 430*b1efbcd6SAlok Aggarwal while (dicPos < limit && buf < bufLimit); 431*b1efbcd6SAlok Aggarwal NORMALIZE; 432*b1efbcd6SAlok Aggarwal p->buf = buf; 433*b1efbcd6SAlok Aggarwal p->range = range; 434*b1efbcd6SAlok Aggarwal p->code = code; 435*b1efbcd6SAlok Aggarwal p->remainLen = len; 436*b1efbcd6SAlok Aggarwal p->dicPos = dicPos; 437*b1efbcd6SAlok Aggarwal p->processedPos = processedPos; 438*b1efbcd6SAlok Aggarwal p->reps[0] = rep0; 439*b1efbcd6SAlok Aggarwal p->reps[1] = rep1; 440*b1efbcd6SAlok Aggarwal p->reps[2] = rep2; 441*b1efbcd6SAlok Aggarwal p->reps[3] = rep3; 442*b1efbcd6SAlok Aggarwal p->state = state; 443*b1efbcd6SAlok Aggarwal 444*b1efbcd6SAlok Aggarwal return SZ_OK; 445*b1efbcd6SAlok Aggarwal } 446*b1efbcd6SAlok Aggarwal 447*b1efbcd6SAlok Aggarwal static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) 448*b1efbcd6SAlok Aggarwal { 449*b1efbcd6SAlok Aggarwal if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) 450*b1efbcd6SAlok Aggarwal { 451*b1efbcd6SAlok Aggarwal Byte *dic = p->dic; 452*b1efbcd6SAlok Aggarwal SizeT dicPos = p->dicPos; 453*b1efbcd6SAlok Aggarwal SizeT dicBufSize = p->dicBufSize; 454*b1efbcd6SAlok Aggarwal unsigned len = p->remainLen; 455*b1efbcd6SAlok Aggarwal UInt32 rep0 = p->reps[0]; 456*b1efbcd6SAlok Aggarwal if (limit - dicPos < len) 457*b1efbcd6SAlok Aggarwal len = (unsigned)(limit - dicPos); 458*b1efbcd6SAlok Aggarwal 459*b1efbcd6SAlok Aggarwal if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) 460*b1efbcd6SAlok Aggarwal p->checkDicSize = p->prop.dicSize; 461*b1efbcd6SAlok Aggarwal 462*b1efbcd6SAlok Aggarwal p->processedPos += len; 463*b1efbcd6SAlok Aggarwal p->remainLen -= len; 464*b1efbcd6SAlok Aggarwal while (len-- != 0) 465*b1efbcd6SAlok Aggarwal { 466*b1efbcd6SAlok Aggarwal dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 467*b1efbcd6SAlok Aggarwal dicPos++; 468*b1efbcd6SAlok Aggarwal } 469*b1efbcd6SAlok Aggarwal p->dicPos = dicPos; 470*b1efbcd6SAlok Aggarwal } 471*b1efbcd6SAlok Aggarwal } 472*b1efbcd6SAlok Aggarwal 473*b1efbcd6SAlok Aggarwal static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 474*b1efbcd6SAlok Aggarwal { 475*b1efbcd6SAlok Aggarwal do 476*b1efbcd6SAlok Aggarwal { 477*b1efbcd6SAlok Aggarwal SizeT limit2 = limit; 478*b1efbcd6SAlok Aggarwal if (p->checkDicSize == 0) 479*b1efbcd6SAlok Aggarwal { 480*b1efbcd6SAlok Aggarwal UInt32 rem = p->prop.dicSize - p->processedPos; 481*b1efbcd6SAlok Aggarwal if (limit - p->dicPos > rem) 482*b1efbcd6SAlok Aggarwal limit2 = p->dicPos + rem; 483*b1efbcd6SAlok Aggarwal } 484*b1efbcd6SAlok Aggarwal RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); 485*b1efbcd6SAlok Aggarwal if (p->processedPos >= p->prop.dicSize) 486*b1efbcd6SAlok Aggarwal p->checkDicSize = p->prop.dicSize; 487*b1efbcd6SAlok Aggarwal LzmaDec_WriteRem(p, limit); 488*b1efbcd6SAlok Aggarwal } 489*b1efbcd6SAlok Aggarwal while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); 490*b1efbcd6SAlok Aggarwal 491*b1efbcd6SAlok Aggarwal if (p->remainLen > kMatchSpecLenStart) 492*b1efbcd6SAlok Aggarwal { 493*b1efbcd6SAlok Aggarwal p->remainLen = kMatchSpecLenStart; 494*b1efbcd6SAlok Aggarwal } 495*b1efbcd6SAlok Aggarwal return 0; 496*b1efbcd6SAlok Aggarwal } 497*b1efbcd6SAlok Aggarwal 498*b1efbcd6SAlok Aggarwal typedef enum 499*b1efbcd6SAlok Aggarwal { 500*b1efbcd6SAlok Aggarwal DUMMY_ERROR, /* unexpected end of input stream */ 501*b1efbcd6SAlok Aggarwal DUMMY_LIT, 502*b1efbcd6SAlok Aggarwal DUMMY_MATCH, 503*b1efbcd6SAlok Aggarwal DUMMY_REP 504*b1efbcd6SAlok Aggarwal } ELzmaDummy; 505*b1efbcd6SAlok Aggarwal 506*b1efbcd6SAlok Aggarwal static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) 507*b1efbcd6SAlok Aggarwal { 508*b1efbcd6SAlok Aggarwal UInt32 range = p->range; 509*b1efbcd6SAlok Aggarwal UInt32 code = p->code; 510*b1efbcd6SAlok Aggarwal const Byte *bufLimit = buf + inSize; 511*b1efbcd6SAlok Aggarwal CLzmaProb *probs = p->probs; 512*b1efbcd6SAlok Aggarwal unsigned state = p->state; 513*b1efbcd6SAlok Aggarwal ELzmaDummy res; 514*b1efbcd6SAlok Aggarwal 515*b1efbcd6SAlok Aggarwal { 516*b1efbcd6SAlok Aggarwal CLzmaProb *prob; 517*b1efbcd6SAlok Aggarwal UInt32 bound; 518*b1efbcd6SAlok Aggarwal unsigned ttt; 519*b1efbcd6SAlok Aggarwal unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); 520*b1efbcd6SAlok Aggarwal 521*b1efbcd6SAlok Aggarwal prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 522*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(prob) 523*b1efbcd6SAlok Aggarwal { 524*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK 525*b1efbcd6SAlok Aggarwal 526*b1efbcd6SAlok Aggarwal /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ 527*b1efbcd6SAlok Aggarwal 528*b1efbcd6SAlok Aggarwal prob = probs + Literal; 529*b1efbcd6SAlok Aggarwal if (p->checkDicSize != 0 || p->processedPos != 0) 530*b1efbcd6SAlok Aggarwal prob += (LZMA_LIT_SIZE * 531*b1efbcd6SAlok Aggarwal ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + 532*b1efbcd6SAlok Aggarwal (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); 533*b1efbcd6SAlok Aggarwal 534*b1efbcd6SAlok Aggarwal if (state < kNumLitStates) 535*b1efbcd6SAlok Aggarwal { 536*b1efbcd6SAlok Aggarwal unsigned symbol = 1; 537*b1efbcd6SAlok Aggarwal do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); 538*b1efbcd6SAlok Aggarwal } 539*b1efbcd6SAlok Aggarwal else 540*b1efbcd6SAlok Aggarwal { 541*b1efbcd6SAlok Aggarwal unsigned matchByte = p->dic[p->dicPos - p->reps[0] + 542*b1efbcd6SAlok Aggarwal ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; 543*b1efbcd6SAlok Aggarwal unsigned offs = 0x100; 544*b1efbcd6SAlok Aggarwal unsigned symbol = 1; 545*b1efbcd6SAlok Aggarwal do 546*b1efbcd6SAlok Aggarwal { 547*b1efbcd6SAlok Aggarwal unsigned bit; 548*b1efbcd6SAlok Aggarwal CLzmaProb *probLit; 549*b1efbcd6SAlok Aggarwal matchByte <<= 1; 550*b1efbcd6SAlok Aggarwal bit = (matchByte & offs); 551*b1efbcd6SAlok Aggarwal probLit = prob + offs + bit + symbol; 552*b1efbcd6SAlok Aggarwal GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) 553*b1efbcd6SAlok Aggarwal } 554*b1efbcd6SAlok Aggarwal while (symbol < 0x100); 555*b1efbcd6SAlok Aggarwal } 556*b1efbcd6SAlok Aggarwal res = DUMMY_LIT; 557*b1efbcd6SAlok Aggarwal } 558*b1efbcd6SAlok Aggarwal else 559*b1efbcd6SAlok Aggarwal { 560*b1efbcd6SAlok Aggarwal unsigned len; 561*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 562*b1efbcd6SAlok Aggarwal 563*b1efbcd6SAlok Aggarwal prob = probs + IsRep + state; 564*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(prob) 565*b1efbcd6SAlok Aggarwal { 566*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK; 567*b1efbcd6SAlok Aggarwal state = 0; 568*b1efbcd6SAlok Aggarwal prob = probs + LenCoder; 569*b1efbcd6SAlok Aggarwal res = DUMMY_MATCH; 570*b1efbcd6SAlok Aggarwal } 571*b1efbcd6SAlok Aggarwal else 572*b1efbcd6SAlok Aggarwal { 573*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 574*b1efbcd6SAlok Aggarwal res = DUMMY_REP; 575*b1efbcd6SAlok Aggarwal prob = probs + IsRepG0 + state; 576*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(prob) 577*b1efbcd6SAlok Aggarwal { 578*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK; 579*b1efbcd6SAlok Aggarwal prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 580*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(prob) 581*b1efbcd6SAlok Aggarwal { 582*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK; 583*b1efbcd6SAlok Aggarwal NORMALIZE_CHECK; 584*b1efbcd6SAlok Aggarwal return DUMMY_REP; 585*b1efbcd6SAlok Aggarwal } 586*b1efbcd6SAlok Aggarwal else 587*b1efbcd6SAlok Aggarwal { 588*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 589*b1efbcd6SAlok Aggarwal } 590*b1efbcd6SAlok Aggarwal } 591*b1efbcd6SAlok Aggarwal else 592*b1efbcd6SAlok Aggarwal { 593*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 594*b1efbcd6SAlok Aggarwal prob = probs + IsRepG1 + state; 595*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(prob) 596*b1efbcd6SAlok Aggarwal { 597*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK; 598*b1efbcd6SAlok Aggarwal } 599*b1efbcd6SAlok Aggarwal else 600*b1efbcd6SAlok Aggarwal { 601*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 602*b1efbcd6SAlok Aggarwal prob = probs + IsRepG2 + state; 603*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(prob) 604*b1efbcd6SAlok Aggarwal { 605*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK; 606*b1efbcd6SAlok Aggarwal } 607*b1efbcd6SAlok Aggarwal else 608*b1efbcd6SAlok Aggarwal { 609*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 610*b1efbcd6SAlok Aggarwal } 611*b1efbcd6SAlok Aggarwal } 612*b1efbcd6SAlok Aggarwal } 613*b1efbcd6SAlok Aggarwal state = kNumStates; 614*b1efbcd6SAlok Aggarwal prob = probs + RepLenCoder; 615*b1efbcd6SAlok Aggarwal } 616*b1efbcd6SAlok Aggarwal { 617*b1efbcd6SAlok Aggarwal unsigned limit, offset; 618*b1efbcd6SAlok Aggarwal CLzmaProb *probLen = prob + LenChoice; 619*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(probLen) 620*b1efbcd6SAlok Aggarwal { 621*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK; 622*b1efbcd6SAlok Aggarwal probLen = prob + LenLow + (posState << kLenNumLowBits); 623*b1efbcd6SAlok Aggarwal offset = 0; 624*b1efbcd6SAlok Aggarwal limit = 1 << kLenNumLowBits; 625*b1efbcd6SAlok Aggarwal } 626*b1efbcd6SAlok Aggarwal else 627*b1efbcd6SAlok Aggarwal { 628*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 629*b1efbcd6SAlok Aggarwal probLen = prob + LenChoice2; 630*b1efbcd6SAlok Aggarwal IF_BIT_0_CHECK(probLen) 631*b1efbcd6SAlok Aggarwal { 632*b1efbcd6SAlok Aggarwal UPDATE_0_CHECK; 633*b1efbcd6SAlok Aggarwal probLen = prob + LenMid + (posState << kLenNumMidBits); 634*b1efbcd6SAlok Aggarwal offset = kLenNumLowSymbols; 635*b1efbcd6SAlok Aggarwal limit = 1 << kLenNumMidBits; 636*b1efbcd6SAlok Aggarwal } 637*b1efbcd6SAlok Aggarwal else 638*b1efbcd6SAlok Aggarwal { 639*b1efbcd6SAlok Aggarwal UPDATE_1_CHECK; 640*b1efbcd6SAlok Aggarwal probLen = prob + LenHigh; 641*b1efbcd6SAlok Aggarwal offset = kLenNumLowSymbols + kLenNumMidSymbols; 642*b1efbcd6SAlok Aggarwal limit = 1 << kLenNumHighBits; 643*b1efbcd6SAlok Aggarwal } 644*b1efbcd6SAlok Aggarwal } 645*b1efbcd6SAlok Aggarwal TREE_DECODE_CHECK(probLen, limit, len); 646*b1efbcd6SAlok Aggarwal len += offset; 647*b1efbcd6SAlok Aggarwal } 648*b1efbcd6SAlok Aggarwal 649*b1efbcd6SAlok Aggarwal if (state < 4) 650*b1efbcd6SAlok Aggarwal { 651*b1efbcd6SAlok Aggarwal unsigned posSlot; 652*b1efbcd6SAlok Aggarwal prob = probs + PosSlot + 653*b1efbcd6SAlok Aggarwal ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 654*b1efbcd6SAlok Aggarwal kNumPosSlotBits); 655*b1efbcd6SAlok Aggarwal TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); 656*b1efbcd6SAlok Aggarwal if (posSlot >= kStartPosModelIndex) 657*b1efbcd6SAlok Aggarwal { 658*b1efbcd6SAlok Aggarwal int numDirectBits = ((posSlot >> 1) - 1); 659*b1efbcd6SAlok Aggarwal 660*b1efbcd6SAlok Aggarwal /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ 661*b1efbcd6SAlok Aggarwal 662*b1efbcd6SAlok Aggarwal if (posSlot < kEndPosModelIndex) 663*b1efbcd6SAlok Aggarwal { 664*b1efbcd6SAlok Aggarwal prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; 665*b1efbcd6SAlok Aggarwal } 666*b1efbcd6SAlok Aggarwal else 667*b1efbcd6SAlok Aggarwal { 668*b1efbcd6SAlok Aggarwal numDirectBits -= kNumAlignBits; 669*b1efbcd6SAlok Aggarwal do 670*b1efbcd6SAlok Aggarwal { 671*b1efbcd6SAlok Aggarwal NORMALIZE_CHECK 672*b1efbcd6SAlok Aggarwal range >>= 1; 673*b1efbcd6SAlok Aggarwal code -= range & (((code - range) >> 31) - 1); 674*b1efbcd6SAlok Aggarwal /* if (code >= range) code -= range; */ 675*b1efbcd6SAlok Aggarwal } 676*b1efbcd6SAlok Aggarwal while (--numDirectBits != 0); 677*b1efbcd6SAlok Aggarwal prob = probs + Align; 678*b1efbcd6SAlok Aggarwal numDirectBits = kNumAlignBits; 679*b1efbcd6SAlok Aggarwal } 680*b1efbcd6SAlok Aggarwal { 681*b1efbcd6SAlok Aggarwal unsigned i = 1; 682*b1efbcd6SAlok Aggarwal do 683*b1efbcd6SAlok Aggarwal { 684*b1efbcd6SAlok Aggarwal GET_BIT_CHECK(prob + i, i); 685*b1efbcd6SAlok Aggarwal } 686*b1efbcd6SAlok Aggarwal while (--numDirectBits != 0); 687*b1efbcd6SAlok Aggarwal } 688*b1efbcd6SAlok Aggarwal } 689*b1efbcd6SAlok Aggarwal } 690*b1efbcd6SAlok Aggarwal } 691*b1efbcd6SAlok Aggarwal } 692*b1efbcd6SAlok Aggarwal NORMALIZE_CHECK; 693*b1efbcd6SAlok Aggarwal return res; 694*b1efbcd6SAlok Aggarwal } 695*b1efbcd6SAlok Aggarwal 696*b1efbcd6SAlok Aggarwal 697*b1efbcd6SAlok Aggarwal static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) 698*b1efbcd6SAlok Aggarwal { 699*b1efbcd6SAlok Aggarwal p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); 700*b1efbcd6SAlok Aggarwal p->range = 0xFFFFFFFF; 701*b1efbcd6SAlok Aggarwal p->needFlush = 0; 702*b1efbcd6SAlok Aggarwal } 703*b1efbcd6SAlok Aggarwal 704*b1efbcd6SAlok Aggarwal void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) 705*b1efbcd6SAlok Aggarwal { 706*b1efbcd6SAlok Aggarwal p->needFlush = 1; 707*b1efbcd6SAlok Aggarwal p->remainLen = 0; 708*b1efbcd6SAlok Aggarwal p->tempBufSize = 0; 709*b1efbcd6SAlok Aggarwal 710*b1efbcd6SAlok Aggarwal if (initDic) 711*b1efbcd6SAlok Aggarwal { 712*b1efbcd6SAlok Aggarwal p->processedPos = 0; 713*b1efbcd6SAlok Aggarwal p->checkDicSize = 0; 714*b1efbcd6SAlok Aggarwal p->needInitState = 1; 715*b1efbcd6SAlok Aggarwal } 716*b1efbcd6SAlok Aggarwal if (initState) 717*b1efbcd6SAlok Aggarwal p->needInitState = 1; 718*b1efbcd6SAlok Aggarwal } 719*b1efbcd6SAlok Aggarwal 720*b1efbcd6SAlok Aggarwal void LzmaDec_Init(CLzmaDec *p) 721*b1efbcd6SAlok Aggarwal { 722*b1efbcd6SAlok Aggarwal p->dicPos = 0; 723*b1efbcd6SAlok Aggarwal LzmaDec_InitDicAndState(p, True, True); 724*b1efbcd6SAlok Aggarwal } 725*b1efbcd6SAlok Aggarwal 726*b1efbcd6SAlok Aggarwal static void LzmaDec_InitStateReal(CLzmaDec *p) 727*b1efbcd6SAlok Aggarwal { 728*b1efbcd6SAlok Aggarwal UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); 729*b1efbcd6SAlok Aggarwal UInt32 i; 730*b1efbcd6SAlok Aggarwal CLzmaProb *probs = p->probs; 731*b1efbcd6SAlok Aggarwal for (i = 0; i < numProbs; i++) 732*b1efbcd6SAlok Aggarwal probs[i] = kBitModelTotal >> 1; 733*b1efbcd6SAlok Aggarwal p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; 734*b1efbcd6SAlok Aggarwal p->state = 0; 735*b1efbcd6SAlok Aggarwal p->needInitState = 0; 736*b1efbcd6SAlok Aggarwal } 737*b1efbcd6SAlok Aggarwal 738*b1efbcd6SAlok Aggarwal SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, 739*b1efbcd6SAlok Aggarwal ELzmaFinishMode finishMode, ELzmaStatus *status) 740*b1efbcd6SAlok Aggarwal { 741*b1efbcd6SAlok Aggarwal SizeT inSize = *srcLen; 742*b1efbcd6SAlok Aggarwal (*srcLen) = 0; 743*b1efbcd6SAlok Aggarwal LzmaDec_WriteRem(p, dicLimit); 744*b1efbcd6SAlok Aggarwal 745*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NOT_SPECIFIED; 746*b1efbcd6SAlok Aggarwal 747*b1efbcd6SAlok Aggarwal while (p->remainLen != kMatchSpecLenStart) 748*b1efbcd6SAlok Aggarwal { 749*b1efbcd6SAlok Aggarwal int checkEndMarkNow; 750*b1efbcd6SAlok Aggarwal 751*b1efbcd6SAlok Aggarwal if (p->needFlush != 0) 752*b1efbcd6SAlok Aggarwal { 753*b1efbcd6SAlok Aggarwal for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) 754*b1efbcd6SAlok Aggarwal p->tempBuf[p->tempBufSize++] = *src++; 755*b1efbcd6SAlok Aggarwal if (p->tempBufSize < RC_INIT_SIZE) 756*b1efbcd6SAlok Aggarwal { 757*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NEEDS_MORE_INPUT; 758*b1efbcd6SAlok Aggarwal return SZ_OK; 759*b1efbcd6SAlok Aggarwal } 760*b1efbcd6SAlok Aggarwal if (p->tempBuf[0] != 0) 761*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 762*b1efbcd6SAlok Aggarwal 763*b1efbcd6SAlok Aggarwal LzmaDec_InitRc(p, p->tempBuf); 764*b1efbcd6SAlok Aggarwal p->tempBufSize = 0; 765*b1efbcd6SAlok Aggarwal } 766*b1efbcd6SAlok Aggarwal 767*b1efbcd6SAlok Aggarwal checkEndMarkNow = 0; 768*b1efbcd6SAlok Aggarwal if (p->dicPos >= dicLimit) 769*b1efbcd6SAlok Aggarwal { 770*b1efbcd6SAlok Aggarwal if (p->remainLen == 0 && p->code == 0) 771*b1efbcd6SAlok Aggarwal { 772*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; 773*b1efbcd6SAlok Aggarwal return SZ_OK; 774*b1efbcd6SAlok Aggarwal } 775*b1efbcd6SAlok Aggarwal if (finishMode == LZMA_FINISH_ANY) 776*b1efbcd6SAlok Aggarwal { 777*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NOT_FINISHED; 778*b1efbcd6SAlok Aggarwal return SZ_OK; 779*b1efbcd6SAlok Aggarwal } 780*b1efbcd6SAlok Aggarwal if (p->remainLen != 0) 781*b1efbcd6SAlok Aggarwal { 782*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NOT_FINISHED; 783*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 784*b1efbcd6SAlok Aggarwal } 785*b1efbcd6SAlok Aggarwal checkEndMarkNow = 1; 786*b1efbcd6SAlok Aggarwal } 787*b1efbcd6SAlok Aggarwal 788*b1efbcd6SAlok Aggarwal if (p->needInitState) 789*b1efbcd6SAlok Aggarwal LzmaDec_InitStateReal(p); 790*b1efbcd6SAlok Aggarwal 791*b1efbcd6SAlok Aggarwal if (p->tempBufSize == 0) 792*b1efbcd6SAlok Aggarwal { 793*b1efbcd6SAlok Aggarwal SizeT processed; 794*b1efbcd6SAlok Aggarwal const Byte *bufLimit; 795*b1efbcd6SAlok Aggarwal if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 796*b1efbcd6SAlok Aggarwal { 797*b1efbcd6SAlok Aggarwal int dummyRes = LzmaDec_TryDummy(p, src, inSize); 798*b1efbcd6SAlok Aggarwal if (dummyRes == DUMMY_ERROR) 799*b1efbcd6SAlok Aggarwal { 800*b1efbcd6SAlok Aggarwal (void) memcpy(p->tempBuf, src, inSize); 801*b1efbcd6SAlok Aggarwal p->tempBufSize = (unsigned)inSize; 802*b1efbcd6SAlok Aggarwal (*srcLen) += inSize; 803*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NEEDS_MORE_INPUT; 804*b1efbcd6SAlok Aggarwal return SZ_OK; 805*b1efbcd6SAlok Aggarwal } 806*b1efbcd6SAlok Aggarwal if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 807*b1efbcd6SAlok Aggarwal { 808*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NOT_FINISHED; 809*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 810*b1efbcd6SAlok Aggarwal } 811*b1efbcd6SAlok Aggarwal bufLimit = src; 812*b1efbcd6SAlok Aggarwal } 813*b1efbcd6SAlok Aggarwal else 814*b1efbcd6SAlok Aggarwal bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; 815*b1efbcd6SAlok Aggarwal p->buf = src; 816*b1efbcd6SAlok Aggarwal if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) 817*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 818*b1efbcd6SAlok Aggarwal /*LINTED*/ 819*b1efbcd6SAlok Aggarwal processed = (SizeT)(p->buf - src); 820*b1efbcd6SAlok Aggarwal (*srcLen) += processed; 821*b1efbcd6SAlok Aggarwal src += processed; 822*b1efbcd6SAlok Aggarwal inSize -= processed; 823*b1efbcd6SAlok Aggarwal } 824*b1efbcd6SAlok Aggarwal else 825*b1efbcd6SAlok Aggarwal { 826*b1efbcd6SAlok Aggarwal unsigned rem = p->tempBufSize, lookAhead = 0; 827*b1efbcd6SAlok Aggarwal while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) 828*b1efbcd6SAlok Aggarwal p->tempBuf[rem++] = src[lookAhead++]; 829*b1efbcd6SAlok Aggarwal p->tempBufSize = rem; 830*b1efbcd6SAlok Aggarwal if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 831*b1efbcd6SAlok Aggarwal { 832*b1efbcd6SAlok Aggarwal int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); 833*b1efbcd6SAlok Aggarwal if (dummyRes == DUMMY_ERROR) 834*b1efbcd6SAlok Aggarwal { 835*b1efbcd6SAlok Aggarwal (*srcLen) += lookAhead; 836*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NEEDS_MORE_INPUT; 837*b1efbcd6SAlok Aggarwal return SZ_OK; 838*b1efbcd6SAlok Aggarwal } 839*b1efbcd6SAlok Aggarwal if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 840*b1efbcd6SAlok Aggarwal { 841*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_NOT_FINISHED; 842*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 843*b1efbcd6SAlok Aggarwal } 844*b1efbcd6SAlok Aggarwal } 845*b1efbcd6SAlok Aggarwal p->buf = p->tempBuf; 846*b1efbcd6SAlok Aggarwal if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) 847*b1efbcd6SAlok Aggarwal return SZ_ERROR_DATA; 848*b1efbcd6SAlok Aggarwal /*LINTED*/ 849*b1efbcd6SAlok Aggarwal lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); 850*b1efbcd6SAlok Aggarwal (*srcLen) += lookAhead; 851*b1efbcd6SAlok Aggarwal src += lookAhead; 852*b1efbcd6SAlok Aggarwal inSize -= lookAhead; 853*b1efbcd6SAlok Aggarwal p->tempBufSize = 0; 854*b1efbcd6SAlok Aggarwal } 855*b1efbcd6SAlok Aggarwal } 856*b1efbcd6SAlok Aggarwal if (p->code == 0) 857*b1efbcd6SAlok Aggarwal *status = LZMA_STATUS_FINISHED_WITH_MARK; 858*b1efbcd6SAlok Aggarwal return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; 859*b1efbcd6SAlok Aggarwal } 860*b1efbcd6SAlok Aggarwal 861*b1efbcd6SAlok Aggarwal SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 862*b1efbcd6SAlok Aggarwal { 863*b1efbcd6SAlok Aggarwal SizeT outSize = *destLen; 864*b1efbcd6SAlok Aggarwal SizeT inSize = *srcLen; 865*b1efbcd6SAlok Aggarwal *srcLen = *destLen = 0; 866*b1efbcd6SAlok Aggarwal for (;;) 867*b1efbcd6SAlok Aggarwal { 868*b1efbcd6SAlok Aggarwal SizeT inSizeCur = inSize, outSizeCur, dicPos; 869*b1efbcd6SAlok Aggarwal ELzmaFinishMode curFinishMode; 870*b1efbcd6SAlok Aggarwal SRes res; 871*b1efbcd6SAlok Aggarwal if (p->dicPos == p->dicBufSize) 872*b1efbcd6SAlok Aggarwal p->dicPos = 0; 873*b1efbcd6SAlok Aggarwal dicPos = p->dicPos; 874*b1efbcd6SAlok Aggarwal if (outSize > p->dicBufSize - dicPos) 875*b1efbcd6SAlok Aggarwal { 876*b1efbcd6SAlok Aggarwal outSizeCur = p->dicBufSize; 877*b1efbcd6SAlok Aggarwal curFinishMode = LZMA_FINISH_ANY; 878*b1efbcd6SAlok Aggarwal } 879*b1efbcd6SAlok Aggarwal else 880*b1efbcd6SAlok Aggarwal { 881*b1efbcd6SAlok Aggarwal outSizeCur = dicPos + outSize; 882*b1efbcd6SAlok Aggarwal curFinishMode = finishMode; 883*b1efbcd6SAlok Aggarwal } 884*b1efbcd6SAlok Aggarwal 885*b1efbcd6SAlok Aggarwal res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); 886*b1efbcd6SAlok Aggarwal src += inSizeCur; 887*b1efbcd6SAlok Aggarwal inSize -= inSizeCur; 888*b1efbcd6SAlok Aggarwal *srcLen += inSizeCur; 889*b1efbcd6SAlok Aggarwal outSizeCur = p->dicPos - dicPos; 890*b1efbcd6SAlok Aggarwal (void) memcpy(dest, p->dic + dicPos, outSizeCur); 891*b1efbcd6SAlok Aggarwal dest += outSizeCur; 892*b1efbcd6SAlok Aggarwal outSize -= outSizeCur; 893*b1efbcd6SAlok Aggarwal *destLen += outSizeCur; 894*b1efbcd6SAlok Aggarwal if (res != 0) 895*b1efbcd6SAlok Aggarwal return res; 896*b1efbcd6SAlok Aggarwal if (outSizeCur == 0 || outSize == 0) 897*b1efbcd6SAlok Aggarwal return SZ_OK; 898*b1efbcd6SAlok Aggarwal } 899*b1efbcd6SAlok Aggarwal } 900*b1efbcd6SAlok Aggarwal 901*b1efbcd6SAlok Aggarwal void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) 902*b1efbcd6SAlok Aggarwal { 903*b1efbcd6SAlok Aggarwal if (p->probs != 0) 904*b1efbcd6SAlok Aggarwal alloc->Free(alloc, p->probs, (p->numProbs * sizeof (*p->probs))); 905*b1efbcd6SAlok Aggarwal p->probs = 0; 906*b1efbcd6SAlok Aggarwal } 907*b1efbcd6SAlok Aggarwal 908*b1efbcd6SAlok Aggarwal static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) 909*b1efbcd6SAlok Aggarwal { 910*b1efbcd6SAlok Aggarwal if (p->dic != 0) 911*b1efbcd6SAlok Aggarwal alloc->Free(alloc, p->dic, ((p->prop).dicSize * sizeof (*p->dic))); 912*b1efbcd6SAlok Aggarwal p->dic = 0; 913*b1efbcd6SAlok Aggarwal } 914*b1efbcd6SAlok Aggarwal 915*b1efbcd6SAlok Aggarwal void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) 916*b1efbcd6SAlok Aggarwal { 917*b1efbcd6SAlok Aggarwal LzmaDec_FreeProbs(p, alloc); 918*b1efbcd6SAlok Aggarwal LzmaDec_FreeDict(p, alloc); 919*b1efbcd6SAlok Aggarwal } 920*b1efbcd6SAlok Aggarwal 921*b1efbcd6SAlok Aggarwal SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) 922*b1efbcd6SAlok Aggarwal { 923*b1efbcd6SAlok Aggarwal UInt32 dicSize; 924*b1efbcd6SAlok Aggarwal Byte d; 925*b1efbcd6SAlok Aggarwal 926*b1efbcd6SAlok Aggarwal if (size < LZMA_PROPS_SIZE) 927*b1efbcd6SAlok Aggarwal return SZ_ERROR_UNSUPPORTED; 928*b1efbcd6SAlok Aggarwal else 929*b1efbcd6SAlok Aggarwal dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); 930*b1efbcd6SAlok Aggarwal 931*b1efbcd6SAlok Aggarwal if (dicSize < LZMA_DIC_MIN) 932*b1efbcd6SAlok Aggarwal dicSize = LZMA_DIC_MIN; 933*b1efbcd6SAlok Aggarwal p->dicSize = dicSize; 934*b1efbcd6SAlok Aggarwal 935*b1efbcd6SAlok Aggarwal d = data[0]; 936*b1efbcd6SAlok Aggarwal if (d >= (9 * 5 * 5)) 937*b1efbcd6SAlok Aggarwal return SZ_ERROR_UNSUPPORTED; 938*b1efbcd6SAlok Aggarwal 939*b1efbcd6SAlok Aggarwal p->lc = d % 9; 940*b1efbcd6SAlok Aggarwal d /= 9; 941*b1efbcd6SAlok Aggarwal p->pb = d / 5; 942*b1efbcd6SAlok Aggarwal p->lp = d % 5; 943*b1efbcd6SAlok Aggarwal 944*b1efbcd6SAlok Aggarwal return SZ_OK; 945*b1efbcd6SAlok Aggarwal } 946*b1efbcd6SAlok Aggarwal 947*b1efbcd6SAlok Aggarwal static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) 948*b1efbcd6SAlok Aggarwal { 949*b1efbcd6SAlok Aggarwal UInt32 numProbs = LzmaProps_GetNumProbs(propNew); 950*b1efbcd6SAlok Aggarwal if (p->probs == 0 || numProbs != p->numProbs) 951*b1efbcd6SAlok Aggarwal { 952*b1efbcd6SAlok Aggarwal LzmaDec_FreeProbs(p, alloc); 953*b1efbcd6SAlok Aggarwal p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); 954*b1efbcd6SAlok Aggarwal p->numProbs = numProbs; 955*b1efbcd6SAlok Aggarwal if (p->probs == 0) 956*b1efbcd6SAlok Aggarwal return SZ_ERROR_MEM; 957*b1efbcd6SAlok Aggarwal } 958*b1efbcd6SAlok Aggarwal return SZ_OK; 959*b1efbcd6SAlok Aggarwal } 960*b1efbcd6SAlok Aggarwal 961*b1efbcd6SAlok Aggarwal SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 962*b1efbcd6SAlok Aggarwal { 963*b1efbcd6SAlok Aggarwal CLzmaProps propNew; 964*b1efbcd6SAlok Aggarwal RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 965*b1efbcd6SAlok Aggarwal RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 966*b1efbcd6SAlok Aggarwal p->prop = propNew; 967*b1efbcd6SAlok Aggarwal return SZ_OK; 968*b1efbcd6SAlok Aggarwal } 969*b1efbcd6SAlok Aggarwal 970*b1efbcd6SAlok Aggarwal SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 971*b1efbcd6SAlok Aggarwal { 972*b1efbcd6SAlok Aggarwal CLzmaProps propNew; 973*b1efbcd6SAlok Aggarwal SizeT dicBufSize; 974*b1efbcd6SAlok Aggarwal RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 975*b1efbcd6SAlok Aggarwal RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 976*b1efbcd6SAlok Aggarwal dicBufSize = propNew.dicSize; 977*b1efbcd6SAlok Aggarwal if (p->dic == 0 || dicBufSize != p->dicBufSize) 978*b1efbcd6SAlok Aggarwal { 979*b1efbcd6SAlok Aggarwal LzmaDec_FreeDict(p, alloc); 980*b1efbcd6SAlok Aggarwal p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); 981*b1efbcd6SAlok Aggarwal if (p->dic == 0) 982*b1efbcd6SAlok Aggarwal { 983*b1efbcd6SAlok Aggarwal LzmaDec_FreeProbs(p, alloc); 984*b1efbcd6SAlok Aggarwal return SZ_ERROR_MEM; 985*b1efbcd6SAlok Aggarwal } 986*b1efbcd6SAlok Aggarwal } 987*b1efbcd6SAlok Aggarwal p->dicBufSize = dicBufSize; 988*b1efbcd6SAlok Aggarwal p->prop = propNew; 989*b1efbcd6SAlok Aggarwal return SZ_OK; 990*b1efbcd6SAlok Aggarwal } 991*b1efbcd6SAlok Aggarwal 992*b1efbcd6SAlok Aggarwal SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 993*b1efbcd6SAlok Aggarwal const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 994*b1efbcd6SAlok Aggarwal ELzmaStatus *status, ISzAlloc *alloc) 995*b1efbcd6SAlok Aggarwal { 996*b1efbcd6SAlok Aggarwal CLzmaDec p; 997*b1efbcd6SAlok Aggarwal SRes res; 998*b1efbcd6SAlok Aggarwal SizeT inSize = *srcLen; 999*b1efbcd6SAlok Aggarwal SizeT outSize = *destLen; 1000*b1efbcd6SAlok Aggarwal *srcLen = *destLen = 0; 1001*b1efbcd6SAlok Aggarwal if (inSize < RC_INIT_SIZE) 1002*b1efbcd6SAlok Aggarwal return SZ_ERROR_INPUT_EOF; 1003*b1efbcd6SAlok Aggarwal 1004*b1efbcd6SAlok Aggarwal LzmaDec_Construct(&p); 1005*b1efbcd6SAlok Aggarwal res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); 1006*b1efbcd6SAlok Aggarwal if (res != 0) 1007*b1efbcd6SAlok Aggarwal return res; 1008*b1efbcd6SAlok Aggarwal p.dic = dest; 1009*b1efbcd6SAlok Aggarwal p.dicBufSize = outSize; 1010*b1efbcd6SAlok Aggarwal 1011*b1efbcd6SAlok Aggarwal LzmaDec_Init(&p); 1012*b1efbcd6SAlok Aggarwal 1013*b1efbcd6SAlok Aggarwal *srcLen = inSize; 1014*b1efbcd6SAlok Aggarwal res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 1015*b1efbcd6SAlok Aggarwal 1016*b1efbcd6SAlok Aggarwal if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 1017*b1efbcd6SAlok Aggarwal res = SZ_ERROR_INPUT_EOF; 1018*b1efbcd6SAlok Aggarwal 1019*b1efbcd6SAlok Aggarwal (*destLen) = p.dicPos; 1020*b1efbcd6SAlok Aggarwal LzmaDec_FreeProbs(&p, alloc); 1021*b1efbcd6SAlok Aggarwal return res; 1022*b1efbcd6SAlok Aggarwal } 1023