HRESULT CDecoder::CodeReal(ISequentialInStream *anInStream, ISequentialOutStream *anOutStream, const UINT64 *, const UINT64 *anOutSize) { if (anOutSize == NULL) return E_INVALIDARG; Init(anInStream, anOutStream); CState aState; aState.Init(); bool aPeviousIsMatch = false; BYTE aPreviousByte = 0; UINT32 aRepDistances[kNumRepDistances]; for(UINT32 i = 0 ; i < kNumRepDistances; i++) aRepDistances[i] = 0; UINT64 aNowPos64 = 0; UINT64 aSize = *anOutSize; while(aNowPos64 < aSize) { UINT64 aNext = MyMin(aNowPos64 + (1 << 18), aSize); while(aNowPos64 < aNext) { UINT32 aPosState = UINT32(aNowPos64) & m_PosStateMask; if (m_MainChoiceDecoders[aState.m_Index][aPosState].Decode(&m_RangeDecoder) == (UINT32) kMainChoiceLiteralIndex) { // aCounts[0]++; aState.UpdateChar(); if(aPeviousIsMatch) { BYTE aMatchByte = m_OutWindowStream.GetOneByte(0 - aRepDistances[0] - 1); aPreviousByte = m_LiteralDecoder.DecodeWithMatchByte(&m_RangeDecoder, UINT32(aNowPos64), aPreviousByte, aMatchByte); aPeviousIsMatch = false; } else aPreviousByte = m_LiteralDecoder.DecodeNormal(&m_RangeDecoder, UINT32(aNowPos64), aPreviousByte); m_OutWindowStream.PutOneByte(aPreviousByte); aNowPos64++; } else { aPeviousIsMatch = true; UINT32 aDistance, aLen; if(m_MatchChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == (UINT32) kMatchChoiceRepetitionIndex) { if(m_MatchRepChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0) { if(m_MatchRepShortChoiceDecoders[aState.m_Index][aPosState].Decode(&m_RangeDecoder) == 0) { aState.UpdateShortRep(); aPreviousByte = m_OutWindowStream.GetOneByte(0 - aRepDistances[0] - 1); m_OutWindowStream.PutOneByte(aPreviousByte); aNowPos64++; // aCounts[3 + 4]++; continue; } // aCounts[3 + 0]++; aDistance = aRepDistances[0]; } else { if(m_MatchRep1ChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0) { aDistance = aRepDistances[1]; aRepDistances[1] = aRepDistances[0]; // aCounts[3 + 1]++; } else { if (m_MatchRep2ChoiceDecoders[aState.m_Index].Decode(&m_RangeDecoder) == 0) { // aCounts[3 + 2]++; aDistance = aRepDistances[2]; } else { // aCounts[3 + 3]++; aDistance = aRepDistances[3]; aRepDistances[3] = aRepDistances[2]; } aRepDistances[2] = aRepDistances[1]; aRepDistances[1] = aRepDistances[0]; } aRepDistances[0] = aDistance; } aLen = m_RepMatchLenDecoder.Decode(&m_RangeDecoder, aPosState) + kMatchMinLen; // aCounts[aLen]++; aState.UpdateRep(); } else { aLen = kMatchMinLen + m_LenDecoder.Decode(&m_RangeDecoder, aPosState); aState.UpdateMatch(); UINT32 aPosSlot = m_PosSlotDecoder[GetLenToPosState(aLen)].Decode(&m_RangeDecoder); // aCounts[aPosSlot]++; if (aPosSlot >= (UINT32) kStartPosModelIndex) { aDistance = kDistStart[aPosSlot]; if (aPosSlot < (UINT32) kEndPosModelIndex) aDistance += m_PosDecoders[aPosSlot - kStartPosModelIndex].Decode(&m_RangeDecoder); else { aDistance += (m_RangeDecoder.DecodeDirectBits(kDistDirectBits[aPosSlot] - kNumAlignBits) << kNumAlignBits); aDistance += m_PosAlignDecoder.Decode(&m_RangeDecoder); } } else aDistance = aPosSlot; aRepDistances[3] = aRepDistances[2]; aRepDistances[2] = aRepDistances[1]; aRepDistances[1] = aRepDistances[0]; aRepDistances[0] = aDistance; // UpdateStat(aLen, aPosSlot); } if (aDistance >= aNowPos64) throw E_INVALIDDATA; m_OutWindowStream.CopyBackBlock(aDistance, aLen); aNowPos64 += aLen; aPreviousByte = m_OutWindowStream.GetOneByte(0 - 1); } } } return Flush(); }
HRESULT LzmaDecoderCodeReal( LzmaDecoder *lzmaDecoder, UINT64 *anInSize, UINT64 *anOutSize) { BOOL aPeviousIsMatch = FALSE; BYTE aPreviousByte = 0; UINT32 aRepDistances[kNumRepDistances]; int i; UINT64 aNowPos64 = 0; UINT64 aSize = *anOutSize; ISequentialInStream my_in_stream; // WindowOut out_window; CState aState; CStateInit(&aState); if (anOutSize == NULL) { printf("CodeReal: invalid argument %x\n", (UINT32) anOutSize ); return E_INVALIDARG; } LzmaDecoderInit(lzmaDecoder); my_in_stream.data = in_stream.data; my_in_stream.remainingBytes = in_stream.remainingBytes; for(i = 0 ; i < (int) kNumRepDistances; i++) aRepDistances[i] = 0; //while(aNowPos64 < aSize) while(my_in_stream.remainingBytes > 0) { UINT64 aNext = MyMin(aNowPos64 + (1 << 18), aSize); while(aNowPos64 < aNext) { UINT32 aPosState = (UINT32)(aNowPos64) & lzmaDecoder->m_PosStateMask; if (BitDecode(&my_in_stream, &lzmaDecoder->m_MainChoiceDecoders[aState][aPosState], &lzmaDecoder->m_RangeDecoder) == (UINT32) kMainChoiceLiteralIndex) { CStateUpdateChar(&aState); if(aPeviousIsMatch) { BYTE aMatchByte = OutWindowGetOneByte(0 - aRepDistances[0] - 1); aPreviousByte = LitDecodeWithMatchByte(&my_in_stream, &lzmaDecoder->m_LiteralDecoder, &lzmaDecoder->m_RangeDecoder, (UINT32)(aNowPos64), aPreviousByte, aMatchByte); aPeviousIsMatch = FALSE; } else aPreviousByte = LitDecodeNormal(&my_in_stream, &lzmaDecoder->m_LiteralDecoder, &lzmaDecoder->m_RangeDecoder, (UINT32)(aNowPos64), aPreviousByte); OutWindowPutOneByte(aPreviousByte); aNowPos64++; } else { UINT32 aDistance, aLen; aPeviousIsMatch = TRUE; if(BitDecode(&my_in_stream, &lzmaDecoder->m_MatchChoiceDecoders[aState], &lzmaDecoder->m_RangeDecoder) == (UINT32) kMatchChoiceRepetitionIndex) { if(BitDecode(&my_in_stream, &lzmaDecoder->m_MatchRepChoiceDecoders[aState], &lzmaDecoder->m_RangeDecoder) == 0) { if(BitDecode(&my_in_stream, &lzmaDecoder->m_MatchRepShortChoiceDecoders[aState][aPosState], &lzmaDecoder->m_RangeDecoder) == 0) { CStateUpdateShortRep(&aState); aPreviousByte = OutWindowGetOneByte(0 - aRepDistances[0] - 1); OutWindowPutOneByte(aPreviousByte); aNowPos64++; continue; } aDistance = aRepDistances[0]; } else { if(BitDecode(&my_in_stream, &lzmaDecoder->m_MatchRep1ChoiceDecoders[aState], &lzmaDecoder->m_RangeDecoder) == 0) { aDistance = aRepDistances[1]; aRepDistances[1] = aRepDistances[0]; } else { if (BitDecode(&my_in_stream, &lzmaDecoder->m_MatchRep2ChoiceDecoders[aState], &lzmaDecoder->m_RangeDecoder) == 0) { aDistance = aRepDistances[2]; } else { aDistance = aRepDistances[3]; aRepDistances[3] = aRepDistances[2]; } aRepDistances[2] = aRepDistances[1]; aRepDistances[1] = aRepDistances[0]; } aRepDistances[0] = aDistance; } aLen = LenDecode(&my_in_stream, &lzmaDecoder->m_RepMatchLenDecoder, &lzmaDecoder->m_RangeDecoder, aPosState) + kMatchMinLen; CStateUpdateRep(&aState); } else { UINT32 aPosSlot; aLen = kMatchMinLen + LenDecode(&my_in_stream, &lzmaDecoder->m_LenDecoder, &lzmaDecoder->m_RangeDecoder, aPosState); CStateUpdateMatch(&aState); aPosSlot = BitTreeDecode(&my_in_stream, &lzmaDecoder->m_PosSlotDecoder[GetLenToPosState(aLen)], &lzmaDecoder->m_RangeDecoder); if (aPosSlot >= (UINT32) kStartPosModelIndex) { aDistance = kDistStart[aPosSlot]; if (aPosSlot < (UINT32) kEndPosModelIndex) aDistance += ReverseBitTreeDecoder2Decode(&my_in_stream, &lzmaDecoder->m_PosDecoders[aPosSlot - kStartPosModelIndex], &lzmaDecoder->m_RangeDecoder); else { aDistance += (RangeDecodeDirectBits(&my_in_stream, &lzmaDecoder->m_RangeDecoder, kDistDirectBits[aPosSlot] - kNumAlignBits) << kNumAlignBits); aDistance += ReverseBitTreeDecoderDecode(&my_in_stream, &lzmaDecoder->m_PosAlignDecoder, &lzmaDecoder->m_RangeDecoder); } } else aDistance = aPosSlot; aRepDistances[3] = aRepDistances[2]; aRepDistances[2] = aRepDistances[1]; aRepDistances[1] = aRepDistances[0]; aRepDistances[0] = aDistance; } if (aDistance >= aNowPos64) { printf("CodeReal: invalid data\n" ); return E_INVALIDDATA; } OutWindowCopyBackBlock(aDistance, aLen); aNowPos64 += aLen; aPreviousByte = OutWindowGetOneByte(0 - 1); } } } //BRCM modification LzmaDecoderFreeBuffer(lzmaDecoder); OutWindowFlush(); return S_OK; }