📄 lzmadecodesize.c
字号:
#define kLzmaStreamWasFinishedId (-1)int LzmaDecode(CLzmaDecoderState *vs, #ifdef _LZMA_IN_CB ILzmaInCallback *InCallback, #else const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, #endif unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed){ CProb *p = vs->Probs; SizeT nowPos = 0; Byte previousByte = 0; UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; int lc = vs->Properties.lc; CRangeDecoder rd; #ifdef _LZMA_OUT_READ int state = vs->State; UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; int len = vs->RemainLen; UInt32 globalPos = vs->GlobalPos; UInt32 distanceLimit = vs->DistanceLimit; Byte *dictionary = vs->Dictionary; UInt32 dictionarySize = vs->Properties.DictionarySize; UInt32 dictionaryPos = vs->DictionaryPos; Byte tempDictionary[4]; rd.Range = vs->Range; rd.Code = vs->Code; #ifdef _LZMA_IN_CB rd.InCallback = InCallback; rd.Buffer = vs->Buffer; rd.BufferLim = vs->BufferLim; #else rd.Buffer = inStream; rd.BufferLim = inStream + inSize; #endif #ifndef _LZMA_IN_CB *inSizeProcessed = 0; #endif *outSizeProcessed = 0; if (len == kLzmaStreamWasFinishedId) return LZMA_RESULT_OK; if (dictionarySize == 0) { dictionary = tempDictionary; dictionarySize = 1; tempDictionary[0] = vs->TempDictionary[0]; } if (len == kLzmaNeedInitId) { { UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); UInt32 i; for (i = 0; i < numProbs; i++) p[i] = kBitModelTotal >> 1; rep0 = rep1 = rep2 = rep3 = 1; state = 0; globalPos = 0; distanceLimit = 0; dictionaryPos = 0; dictionary[dictionarySize - 1] = 0; RangeDecoderInit(&rd #ifndef _LZMA_IN_CB , inStream, inSize #endif ); #ifdef _LZMA_IN_CB if (rd.Result != LZMA_RESULT_OK) return rd.Result; #endif if (rd.ExtraBytes != 0) return LZMA_RESULT_DATA_ERROR; } len = 0; } while(len != 0 && nowPos < outSize) { UInt32 pos = dictionaryPos - rep0; if (pos >= dictionarySize) pos += dictionarySize; outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; if (++dictionaryPos == dictionarySize) dictionaryPos = 0; len--; } if (dictionaryPos == 0) previousByte = dictionary[dictionarySize - 1]; else previousByte = dictionary[dictionaryPos - 1]; #ifdef _LZMA_IN_CB rd.Result = LZMA_RESULT_OK; #endif rd.ExtraBytes = 0; #else /* if !_LZMA_OUT_READ */ int state = 0; UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; int len = 0; #ifndef _LZMA_IN_CB *inSizeProcessed = 0; #endif *outSizeProcessed = 0; { UInt32 i; UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); for (i = 0; i < numProbs; i++) p[i] = kBitModelTotal >> 1; } #ifdef _LZMA_IN_CB rd.InCallback = InCallback; #endif RangeDecoderInit(&rd #ifndef _LZMA_IN_CB , inStream, inSize #endif ); #ifdef _LZMA_IN_CB if (rd.Result != LZMA_RESULT_OK) return rd.Result; #endif if (rd.ExtraBytes != 0) return LZMA_RESULT_DATA_ERROR; #endif /* _LZMA_OUT_READ */ while(nowPos < outSize) { int posState = (int)( (nowPos #ifdef _LZMA_OUT_READ + globalPos #endif ) & posStateMask); #ifdef _LZMA_IN_CB if (rd.Result != LZMA_RESULT_OK) return rd.Result; #endif if (rd.ExtraBytes != 0) return LZMA_RESULT_DATA_ERROR; if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) { CProb *probs = p + Literal + (LZMA_LIT_SIZE * ((( (nowPos #ifdef _LZMA_OUT_READ + globalPos #endif ) & literalPosMask) << lc) + (previousByte >> (8 - lc)))); if (state >= kNumLitStates) { Byte matchByte; #ifdef _LZMA_OUT_READ UInt32 pos = dictionaryPos - rep0; if (pos >= dictionarySize) pos += dictionarySize; matchByte = dictionary[pos]; #else matchByte = outStream[nowPos - rep0]; #endif previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); } else previousByte = LzmaLiteralDecode(probs, &rd); outStream[nowPos++] = previousByte; #ifdef _LZMA_OUT_READ if (distanceLimit < dictionarySize) distanceLimit++; dictionary[dictionaryPos] = previousByte; if (++dictionaryPos == dictionarySize) dictionaryPos = 0; #endif if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; } else { if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) { if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) { if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) { #ifdef _LZMA_OUT_READ UInt32 pos; #endif #ifdef _LZMA_OUT_READ if (distanceLimit == 0) #else if (nowPos == 0) #endif return LZMA_RESULT_DATA_ERROR; state = state < 7 ? 9 : 11; #ifdef _LZMA_OUT_READ pos = dictionaryPos - rep0; if (pos >= dictionarySize) pos += dictionarySize; previousByte = dictionary[pos]; dictionary[dictionaryPos] = previousByte; if (++dictionaryPos == dictionarySize) dictionaryPos = 0; #else previousByte = outStream[nowPos - rep0]; #endif outStream[nowPos++] = previousByte; #ifdef _LZMA_OUT_READ if (distanceLimit < dictionarySize) distanceLimit++; #endif continue; } } else { UInt32 distance; if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) distance = rep1; else { if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) distance = rep2; else { distance = rep3; rep3 = rep2; } rep2 = rep1; } rep1 = rep0; rep0 = distance; } len = LzmaLenDecode(p + RepLenCoder, &rd, posState); state = state < 7 ? 8 : 11; } else { int posSlot; rep3 = rep2; rep2 = rep1; rep1 = rep0; state = state < 7 ? 7 : 10; len = LzmaLenDecode(p + LenCoder, &rd, posState); posSlot = RangeDecoderBitTreeDecode(p + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits), kNumPosSlotBits, &rd); if (posSlot >= kStartPosModelIndex) { int numDirectBits = ((posSlot >> 1) - 1); rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); if (posSlot < kEndPosModelIndex) { rep0 += RangeDecoderReverseBitTreeDecode( p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); } else { rep0 += RangeDecoderDecodeDirectBits(&rd, numDirectBits - kNumAlignBits) << kNumAlignBits; rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); } } else rep0 = posSlot; if (++rep0 == (UInt32)(0)) { /* it's for stream version */ len = kLzmaStreamWasFinishedId; break; } } len += kMatchMinLen; #ifdef _LZMA_OUT_READ if (rep0 > distanceLimit) #else if (rep0 > nowPos) #endif return LZMA_RESULT_DATA_ERROR; #ifdef _LZMA_OUT_READ if (dictionarySize - distanceLimit > (UInt32)len) distanceLimit += len; else distanceLimit = dictionarySize; #endif do { #ifdef _LZMA_OUT_READ UInt32 pos = dictionaryPos - rep0; if (pos >= dictionarySize) pos += dictionarySize; previousByte = dictionary[pos]; dictionary[dictionaryPos] = previousByte; if (++dictionaryPos == dictionarySize) dictionaryPos = 0; #else previousByte = outStream[nowPos - rep0]; #endif len--; outStream[nowPos++] = previousByte; } while(len != 0 && nowPos < outSize); } } #ifdef _LZMA_OUT_READ vs->Range = rd.Range; vs->Code = rd.Code; vs->DictionaryPos = dictionaryPos; vs->GlobalPos = globalPos + (UInt32)nowPos; vs->DistanceLimit = distanceLimit; vs->Reps[0] = rep0; vs->Reps[1] = rep1; vs->Reps[2] = rep2; vs->Reps[3] = rep3; vs->State = state; vs->RemainLen = len; vs->TempDictionary[0] = tempDictionary[0]; #endif #ifdef _LZMA_IN_CB vs->Buffer = rd.Buffer; vs->BufferLim = rd.BufferLim; #else *inSizeProcessed = (SizeT)(rd.Buffer - inStream); #endif *outSizeProcessed = nowPos; return LZMA_RESULT_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -