diff options
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Compress/Rar1Decoder.cpp')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Compress/Rar1Decoder.cpp | 480 |
1 files changed, 0 insertions, 480 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Compress/Rar1Decoder.cpp b/src/libs/7zip/win/CPP/7zip/Compress/Rar1Decoder.cpp deleted file mode 100644 index eadca7b3d..000000000 --- a/src/libs/7zip/win/CPP/7zip/Compress/Rar1Decoder.cpp +++ /dev/null @@ -1,480 +0,0 @@ -// Rar1Decoder.cpp -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#include "StdAfx.h" - -#include "Rar1Decoder.h" - -namespace NCompress { -namespace NRar1 { - -static UInt32 PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32, 256}; -static UInt32 PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36, 256}; -static UInt32 PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33, 257}; -static UInt32 PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127, 257}; -static UInt32 PosHf2[]={0,0,0,0,0,0,2,7,53,117,233, 257,0}; -static UInt32 PosHf3[]={0,0,0,0,0,0,0,2,16,218,251, 257,0}; -static UInt32 PosHf4[]={0,0,0,0,0,0,0,0,0,255, 257,0,0}; - -static const UInt32 kHistorySize = (1 << 16); - -class CCoderReleaser -{ - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *coder): m_Coder(coder) {} - ~CCoderReleaser() { m_Coder->ReleaseStreams(); } -}; - -CDecoder::CDecoder(): m_IsSolid(false) { } - -void CDecoder::InitStructures() -{ - for(int i = 0; i < kNumRepDists; i++) - m_RepDists[i] = 0; - m_RepDistPtr = 0; - LastLength = 0; - LastDist = 0; -} - -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } - -HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len) -{ - if (len == 0) - return S_FALSE; - m_UnpackSize -= len; - return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE; -} - - -UInt32 CDecoder::DecodeNum(const UInt32 *posTab) -{ - UInt32 startPos = 2; - UInt32 num = m_InBitStream.GetValue(12); - for (;;) - { - UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos); - if (num < cur) - break; - startPos++; - num -= cur; - } - m_InBitStream.MovePos(startPos); - return((num >> (12 - startPos)) + posTab[startPos]); -} - -static Byte kShortLen1[] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 }; -static Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 }; -static Byte kShortLen2[] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 }; -static Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 }; -static UInt32 kShortXor1[] = {0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0}; -static UInt32 kShortXor2[] = {0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0}; - -HRESULT CDecoder::ShortLZ() -{ - UInt32 len, saveLen, dist; - int distancePlace; - Byte *kShortLen; - const UInt32 *kShortXor; - NumHuf = 0; - - if (LCount == 2) - { - if (ReadBits(1)) - return CopyBlock(LastDist, LastLength); - LCount = 0; - } - - UInt32 bitField = m_InBitStream.GetValue(8); - - if (AvrLn1 < 37) - { - kShortLen = Buf60 ? kShortLen1a : kShortLen1; - kShortXor = kShortXor1; - } - else - { - kShortLen = Buf60 ? kShortLen2a : kShortLen2; - kShortXor = kShortXor2; - } - - for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len]))) != 0; len++); - m_InBitStream.MovePos(kShortLen[len]); - - if (len >= 9) - { - if (len == 9) - { - LCount++; - return CopyBlock(LastDist, LastLength); - } - if (len == 14) - { - LCount = 0; - len = DecodeNum(PosL2) + 5; - dist = 0x8000 + ReadBits(15) - 1; - LastLength = len; - LastDist = dist; - return CopyBlock(dist, len); - } - - LCount = 0; - saveLen = len; - dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3]; - len = DecodeNum(PosL1) + 2; - if (len == 0x101 && saveLen == 10) - { - Buf60 ^= 1; - return S_OK; - } - if (dist >= 256) - len++; - if (dist >= MaxDist3 - 1) - len++; - } - else - { - LCount = 0; - AvrLn1 += len; - AvrLn1 -= AvrLn1 >> 4; - - distancePlace = DecodeNum(PosHf2) & 0xff; - dist = ChSetA[distancePlace]; - if (--distancePlace != -1) - { - PlaceA[dist]--; - UInt32 lastDistance = ChSetA[distancePlace]; - PlaceA[lastDistance]++; - ChSetA[distancePlace + 1] = lastDistance; - ChSetA[distancePlace] = dist; - } - len += 2; - } - m_RepDists[m_RepDistPtr++] = dist; - m_RepDistPtr &= 3; - LastLength = len; - LastDist = dist; - return CopyBlock(dist, len); -} - - -HRESULT CDecoder::LongLZ() -{ - UInt32 len; - UInt32 dist; - UInt32 distancePlace, newDistancePlace; - UInt32 oldAvr2, oldAvr3; - - NumHuf = 0; - Nlzb += 16; - if (Nlzb > 0xff) - { - Nlzb = 0x90; - Nhfb >>= 1; - } - oldAvr2=AvrLn2; - - if (AvrLn2 >= 122) - len = DecodeNum(PosL2); - else if (AvrLn2 >= 64) - len = DecodeNum(PosL1); - else - { - UInt32 bitField = m_InBitStream.GetValue(16); - if (bitField < 0x100) - { - len = bitField; - m_InBitStream.MovePos(16); - } - else - { - for (len = 0; ((bitField << len) & 0x8000) == 0; len++) - ; - m_InBitStream.MovePos(len + 1); - } - } - - AvrLn2 += len; - AvrLn2 -= AvrLn2 >> 5; - - if (AvrPlcB > 0x28ff) - distancePlace = DecodeNum(PosHf2); - else if (AvrPlcB > 0x6ff) - distancePlace = DecodeNum(PosHf1); - else - distancePlace = DecodeNum(PosHf0); - - AvrPlcB += distancePlace; - AvrPlcB -= AvrPlcB >> 8; - for (;;) - { - dist = ChSetB[distancePlace & 0xff]; - newDistancePlace = NToPlB[dist++ & 0xff]++; - if (!(dist & 0xff)) - CorrHuff(ChSetB,NToPlB); - else - break; - } - - ChSetB[distancePlace] = ChSetB[newDistancePlace]; - ChSetB[newDistancePlace] = dist; - - dist = ((dist & 0xff00) >> 1) | ReadBits(7); - - oldAvr3 = AvrLn3; - if (len != 1 && len != 4) - if (len == 0 && dist <= MaxDist3) - { - AvrLn3++; - AvrLn3 -= AvrLn3 >> 8; - } - else - if (AvrLn3 > 0) - AvrLn3--; - len += 3; - if (dist >= MaxDist3) - len++; - if (dist <= 256) - len += 8; - if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40) - MaxDist3 = 0x7f00; - else - MaxDist3 = 0x2001; - m_RepDists[m_RepDistPtr++] = --dist; - m_RepDistPtr &= 3; - LastLength = len; - LastDist = dist; - return CopyBlock(dist, len); -} - - -HRESULT CDecoder::HuffDecode() -{ - UInt32 curByte, newBytePlace; - UInt32 len; - UInt32 dist; - int bytePlace; - - if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4); - else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3); - else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2); - else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1); - else bytePlace = DecodeNum(PosHf0); - if (StMode) - { - if (--bytePlace == -1) - { - if (ReadBits(1)) - { - NumHuf = StMode = 0; - return S_OK; - } - else - { - len = (ReadBits(1)) ? 4 : 3; - dist = DecodeNum(PosHf2); - dist = (dist << 5) | ReadBits(5); - return CopyBlock(dist - 1, len); - } - } - } - else if (NumHuf++ >= 16 && FlagsCnt == 0) - StMode = 1; - bytePlace &= 0xff; - AvrPlc += bytePlace; - AvrPlc -= AvrPlc >> 8; - Nhfb+=16; - if (Nhfb > 0xff) - { - Nhfb=0x90; - Nlzb >>= 1; - } - - m_UnpackSize --; - m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8)); - - for (;;) - { - curByte = ChSet[bytePlace]; - newBytePlace = NToPl[curByte++ & 0xff]++; - if ((curByte & 0xff) > 0xa1) - CorrHuff(ChSet, NToPl); - else - break; - } - - ChSet[bytePlace] = ChSet[newBytePlace]; - ChSet[newBytePlace] = curByte; - return S_OK; -} - - -void CDecoder::GetFlagsBuf() -{ - UInt32 flags, newFlagsPlace; - UInt32 flagsPlace = DecodeNum(PosHf2); - - for (;;) - { - flags = ChSetC[flagsPlace]; - FlagBuf = flags >> 8; - newFlagsPlace = NToPlC[flags++ & 0xff]++; - if ((flags & 0xff) != 0) - break; - CorrHuff(ChSetC, NToPlC); - } - - ChSetC[flagsPlace] = ChSetC[newFlagsPlace]; - ChSetC[newFlagsPlace] = flags; -} - -void CDecoder::InitData() -{ - if (!m_IsSolid) - { - AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0; - AvrPlc = 0x3500; - MaxDist3 = 0x2001; - Nhfb = Nlzb = 0x80; - } - FlagsCnt = 0; - FlagBuf = 0; - StMode = 0; - LCount = 0; -} - -void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace) -{ - int i; - for (i = 7; i >= 0; i--) - for (int j = 0; j < 32; j++, CharSet++) - *CharSet = (*CharSet & ~0xff) | i; - memset(NumToPlace, 0, sizeof(NToPl)); - for (i = 6; i >= 0; i--) - NumToPlace[i] = (7 - i) * 32; -} - -void CDecoder::InitHuff() -{ - for (UInt32 i = 0; i < 256; i++) - { - Place[i] = PlaceA[i] = PlaceB[i] = i; - PlaceC[i] = (~i + 1) & 0xff; - ChSet[i] = ChSetB[i] = i << 8; - ChSetA[i] = i; - ChSetC[i] = ((~i + 1) & 0xff) << 8; - } - memset(NToPl, 0, sizeof(NToPl)); - memset(NToPlB, 0, sizeof(NToPlB)); - memset(NToPlC, 0, sizeof(NToPlC)); - CorrHuff(ChSetB, NToPlB); -} - -HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /* progress */) -{ - if (inSize == NULL || outSize == NULL) - return E_INVALIDARG; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - m_UnpackSize = (Int64)*outSize; - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(m_IsSolid); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - CCoderReleaser coderReleaser(this); - InitData(); - if (!m_IsSolid) - { - InitStructures(); - InitHuff(); - } - if (m_UnpackSize > 0) - { - GetFlagsBuf(); - FlagsCnt = 8; - } - - while (m_UnpackSize > 0) - { - if (StMode) - { - RINOK(HuffDecode()); - continue; - } - - if (--FlagsCnt < 0) - { - GetFlagsBuf(); - FlagsCnt=7; - } - - if (FlagBuf & 0x80) - { - FlagBuf <<= 1; - if (Nlzb > Nhfb) - { - RINOK(LongLZ()); - } - else - { - RINOK(HuffDecode()); - } - } - else - { - FlagBuf <<= 1; - if (--FlagsCnt < 0) - { - GetFlagsBuf(); - FlagsCnt = 7; - } - if (FlagBuf & 0x80) - { - FlagBuf <<= 1; - if (Nlzb > Nhfb) - { - RINOK(HuffDecode()); - } - else - { - RINOK(LongLZ()); - } - } - else - { - FlagBuf <<= 1; - RINOK(ShortLZ()); - } - } - } - if (m_UnpackSize < 0) - return S_FALSE; - return m_OutWindowStream.Flush(); -} - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) -{ - try { return CodeReal(inStream, outStream, inSize, outSize, progress); } - catch(const CInBufferException &e) { return e.ErrorCode; } - catch(const CLzOutWindowException &e) { return e.ErrorCode; } - catch(...) { return S_FALSE; } -} - -STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) -{ - if (size < 1) - return E_INVALIDARG; - m_IsSolid = (data[0] != 0); - return S_OK; -} - -}} |