diff options
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Compress/Rar2Decoder.cpp')
-rw-r--r-- | src/libs/7zip/unix/CPP/7zip/Compress/Rar2Decoder.cpp | 391 |
1 files changed, 0 insertions, 391 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/Rar2Decoder.cpp b/src/libs/7zip/unix/CPP/7zip/Compress/Rar2Decoder.cpp deleted file mode 100644 index 4e669bd64..000000000 --- a/src/libs/7zip/unix/CPP/7zip/Compress/Rar2Decoder.cpp +++ /dev/null @@ -1,391 +0,0 @@ -// Rar2Decoder.cpp -// According to unRAR license, this code may not be used to develop -// a program that creates RAR archives - -#include "StdAfx.h" - -#include "Rar2Decoder.h" - -namespace NCompress { -namespace NRar2 { - -namespace NMultimedia { - -Byte CFilter::Decode(int &channelDelta, Byte deltaByte) -{ - D4 = D3; - D3 = D2; - D2 = LastDelta - D1; - D1 = LastDelta; - int predictedValue = ((8 * LastChar + K1 * D1 + K2 * D2 + K3 * D3 + K4 * D4 + K5 * channelDelta) >> 3); - - Byte realValue = (Byte)(predictedValue - deltaByte); - int i = ((int)(signed char)deltaByte) << 3; - - Dif[0] += abs(i); - Dif[1] += abs(i - D1); - Dif[2] += abs(i + D1); - Dif[3] += abs(i - D2); - Dif[4] += abs(i + D2); - Dif[5] += abs(i - D3); - Dif[6] += abs(i + D3); - Dif[7] += abs(i - D4); - Dif[8] += abs(i + D4); - Dif[9] += abs(i - channelDelta); - Dif[10] += abs(i + channelDelta); - - channelDelta = LastDelta = (signed char)(realValue - LastChar); - LastChar = realValue; - - if (((++ByteCount) & 0x1F) == 0) - { - UInt32 minDif = Dif[0]; - UInt32 numMinDif = 0; - Dif[0] = 0; - for (i = 1; i < sizeof(Dif) / sizeof(Dif[0]); i++) - { - if (Dif[i] < minDif) - { - minDif = Dif[i]; - numMinDif = i; - } - Dif[i] = 0; - } - switch(numMinDif) - { - case 1: if (K1 >= -16) K1--; break; - case 2: if (K1 < 16) K1++; break; - case 3: if (K2 >= -16) K2--; break; - case 4: if (K2 < 16) K2++; break; - case 5: if (K3 >= -16) K3--; break; - case 6: if (K3 < 16) K3++; break; - case 7: if (K4 >= -16) K4--; break; - case 8: if (K4 < 16) K4++; break; - case 9: if (K5 >= -16) K5--; break; - case 10:if (K5 < 16) K5++; break; - } - } - return realValue; -} -} - -static const char *kNumberErrorMessage = "Number error"; - -static const UInt32 kHistorySize = 1 << 20; - -static const int kNumStats = 11; - -static const UInt32 kWindowReservSize = (1 << 22) + 256; - -CDecoder::CDecoder(): - m_IsSolid(false) -{ -} - -void CDecoder::InitStructures() -{ - m_MmFilter.Init(); - for(int i = 0; i < kNumRepDists; i++) - m_RepDists[i] = 0; - m_RepDistPtr = 0; - m_LastLength = 0; - memset(m_LastLevels, 0, kMaxTableSize); -} - -UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.ReadBits(numBits); } - -#define RIF(x) { if (!(x)) return false; } - -bool CDecoder::ReadTables(void) -{ - Byte levelLevels[kLevelTableSize]; - Byte newLevels[kMaxTableSize]; - m_AudioMode = (ReadBits(1) == 1); - - if (ReadBits(1) == 0) - memset(m_LastLevels, 0, kMaxTableSize); - int numLevels; - if (m_AudioMode) - { - m_NumChannels = ReadBits(2) + 1; - if (m_MmFilter.CurrentChannel >= m_NumChannels) - m_MmFilter.CurrentChannel = 0; - numLevels = m_NumChannels * kMMTableSize; - } - else - numLevels = kHeapTablesSizesSum; - - int i; - for (i = 0; i < kLevelTableSize; i++) - levelLevels[i] = (Byte)ReadBits(4); - RIF(m_LevelDecoder.SetCodeLengths(levelLevels)); - i = 0; - while (i < numLevels) - { - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); - if (number < kTableDirectLevels) - { - newLevels[i] = (Byte)((number + m_LastLevels[i]) & kLevelMask); - i++; - } - else - { - if (number == kTableLevelRepNumber) - { - int t = ReadBits(2) + 3; - for (int reps = t; reps > 0 && i < numLevels ; reps--, i++) - newLevels[i] = newLevels[i - 1]; - } - else - { - int num; - if (number == kTableLevel0Number) - num = ReadBits(3) + 3; - else if (number == kTableLevel0Number2) - num = ReadBits(7) + 11; - else - return false; - for (;num > 0 && i < numLevels; num--) - newLevels[i++] = 0; - } - } - } - if (m_AudioMode) - for (i = 0; i < m_NumChannels; i++) - { - RIF(m_MMDecoders[i].SetCodeLengths(&newLevels[i * kMMTableSize])); - } - else - { - RIF(m_MainDecoder.SetCodeLengths(&newLevels[0])); - RIF(m_DistDecoder.SetCodeLengths(&newLevels[kMainTableSize])); - RIF(m_LenDecoder.SetCodeLengths(&newLevels[kMainTableSize + kDistTableSize])); - } - memcpy(m_LastLevels, newLevels, kMaxTableSize); - return true; -} - -bool CDecoder::ReadLastTables() -{ - // it differs a little from pure RAR sources; - // UInt64 ttt = m_InBitStream.GetProcessedSize() + 2; - // + 2 works for: return 0xFF; in CInBuffer::ReadByte. - if (m_InBitStream.GetProcessedSize() + 7 <= m_PackSize) // test it: probably incorrect; - // if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; - if (m_AudioMode) - { - UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream); - if (symbol == 256) - return ReadTables(); - if (symbol >= kMMTableSize) - return false; - } - else - { - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); - if (number == kReadTableNumber) - return ReadTables(); - if (number >= kMainTableSize) - return false; - } - return true; -} - -class CCoderReleaser -{ - CDecoder *m_Coder; -public: - CCoderReleaser(CDecoder *coder): m_Coder(coder) {} - ~CCoderReleaser() - { - m_Coder->ReleaseStreams(); - } -}; - -bool CDecoder::DecodeMm(UInt32 pos) -{ - while (pos-- > 0) - { - UInt32 symbol = m_MMDecoders[m_MmFilter.CurrentChannel].DecodeSymbol(&m_InBitStream); - if (symbol == 256) - return true; - if (symbol >= kMMTableSize) - return false; - /* - Byte byPredict = m_Predictor.Predict(); - Byte byReal = (Byte)(byPredict - (Byte)symbol); - m_Predictor.Update(byReal, byPredict); - */ - Byte byReal = m_MmFilter.Decode((Byte)symbol); - m_OutWindowStream.PutByte(byReal); - if (++m_MmFilter.CurrentChannel == m_NumChannels) - m_MmFilter.CurrentChannel = 0; - } - return true; -} - -bool CDecoder::DecodeLz(Int32 pos) -{ - while (pos > 0) - { - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); - UInt32 length, distance; - if (number < 256) - { - m_OutWindowStream.PutByte(Byte(number)); - pos--; - continue; - } - else if (number >= kMatchNumber) - { - number -= kMatchNumber; - length = kNormalMatchMinLen + UInt32(kLenStart[number]) + - m_InBitStream.ReadBits(kLenDirectBits[number]); - number = m_DistDecoder.DecodeSymbol(&m_InBitStream); - if (number >= kDistTableSize) - return false; - distance = kDistStart[number] + m_InBitStream.ReadBits(kDistDirectBits[number]); - if (distance >= kDistLimit3) - { - length += 2 - ((distance - kDistLimit4) >> 31); - // length++; - // if (distance >= kDistLimit4) - // length++; - } - } - else if (number == kRepBothNumber) - { - length = m_LastLength; - if (length == 0) - return false; - distance = m_RepDists[(m_RepDistPtr + 4 - 1) & 3]; - } - else if (number < kLen2Number) - { - distance = m_RepDists[(m_RepDistPtr - (number - kRepNumber + 1)) & 3]; - number = m_LenDecoder.DecodeSymbol(&m_InBitStream); - if (number >= kLenTableSize) - return false; - length = 2 + kLenStart[number] + m_InBitStream.ReadBits(kLenDirectBits[number]); - if (distance >= kDistLimit2) - { - length++; - if (distance >= kDistLimit3) - { - length += 2 - ((distance - kDistLimit4) >> 31); - // length++; - // if (distance >= kDistLimit4) - // length++; - } - } - } - else if (number < kReadTableNumber) - { - number -= kLen2Number; - distance = kLen2DistStarts[number] + - m_InBitStream.ReadBits(kLen2DistDirectBits[number]); - length = 2; - } - else if (number == kReadTableNumber) - return true; - else - return false; - m_RepDists[m_RepDistPtr++ & 3] = distance; - m_LastLength = length; - if (!m_OutWindowStream.CopyBlock(distance, length)) - return false; - pos -= length; - } - return true; -} - -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_PackSize = *inSize; - - UInt64 pos = 0, unPackSize = *outSize; - - m_OutWindowStream.SetStream(outStream); - m_OutWindowStream.Init(m_IsSolid); - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(); - - CCoderReleaser coderReleaser(this); - if (!m_IsSolid) - { - InitStructures(); - if (unPackSize == 0) - { - if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect; - if (!ReadTables()) - return S_FALSE; - return S_OK; - } - if (!ReadTables()) - return S_FALSE; - } - - UInt64 startPos = m_OutWindowStream.GetProcessedSize(); - while(pos < unPackSize) - { - UInt32 blockSize = 1 << 20; - if (blockSize > unPackSize - pos) - blockSize = (UInt32)(unPackSize - pos); - UInt64 blockStartPos = m_OutWindowStream.GetProcessedSize(); - if (m_AudioMode) - { - if (!DecodeMm(blockSize)) - return S_FALSE; - } - else - { - if (!DecodeLz((Int32)blockSize)) - return S_FALSE; - } - UInt64 globalPos = m_OutWindowStream.GetProcessedSize(); - pos = globalPos - blockStartPos; - if (pos < blockSize) - if (!ReadTables()) - return S_FALSE; - pos = globalPos - startPos; - if (progress != 0) - { - UInt64 packSize = m_InBitStream.GetProcessedSize(); - RINOK(progress->SetRatioInfo(&packSize, &pos)); - } - } - if (pos > unPackSize) - return S_FALSE; - - if (!ReadLastTables()) - 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; -} - -}} |