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