diff options
Diffstat (limited to '7zip/Archive/Cab/LZXDecoder.cpp')
-rwxr-xr-x | 7zip/Archive/Cab/LZXDecoder.cpp | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/7zip/Archive/Cab/LZXDecoder.cpp b/7zip/Archive/Cab/LZXDecoder.cpp deleted file mode 100755 index 49f87ed7..00000000 --- a/7zip/Archive/Cab/LZXDecoder.cpp +++ /dev/null @@ -1,310 +0,0 @@ -// Archive/Cab/LZXDecoder.cpp - -#include "StdAfx.h" - -#include "LZXDecoder.h" - -#include "Common/Defs.h" -#include "Windows/Defs.h" - -namespace NArchive { -namespace NCab { -namespace NLZX { - -static const UInt32 kHistorySize = (1 << 21); - -CDecoder::CDecoder() -{ - m_i86TranslationOutStreamSpec = new Ci86TranslationOutStream; - m_i86TranslationOutStream = m_i86TranslationOutStreamSpec; -} - -void CDecoder::ReleaseStreams() -{ - m_OutWindowStream.ReleaseStream(); - m_InBitStream.ReleaseStream(); - m_i86TranslationOutStreamSpec->ReleaseStream(); -} - -STDMETHODIMP CDecoder::Flush() -{ - RINOK(m_OutWindowStream.Flush()); - return m_i86TranslationOutStreamSpec->Flush(); -} - -void CDecoder::ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols) -{ - Byte levelLevels[kLevelTableSize]; - UInt32 i; - for (i = 0; i < kLevelTableSize; i++) - levelLevels[i] = Byte(m_InBitStream.ReadBits(kNumBitsForPreTreeLevel)); - m_LevelDecoder.SetCodeLengths(levelLevels); - for (i = 0; i < numSymbols;) - { - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); - if (number <= kNumHuffmanBits) - newLevels[i++] = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); - else if (number == kLevelSymbolZeros || number == kLevelSymbolZerosBig) - { - int num; - if (number == kLevelSymbolZeros) - num = kLevelSymbolZerosStartValue + - m_InBitStream.ReadBits(kLevelSymbolZerosNumBits); - else - num = kLevelSymbolZerosBigStartValue + - m_InBitStream.ReadBits(kLevelSymbolZerosBigNumBits); - for (;num > 0 && i < numSymbols; num--, i++) - newLevels[i] = 0; - } - else if (number == kLevelSymbolSame) - { - int num = kLevelSymbolSameStartValue + m_InBitStream.ReadBits(kLevelSymbolSameNumBits); - UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream); - if (number > kNumHuffmanBits) - throw "bad data"; - Byte symbol = Byte((17 + lastLevels[i] - number) % (kNumHuffmanBits + 1)); - for (; num > 0 && i < numSymbols; num--, i++) - newLevels[i] = symbol; - } - else - throw "bad data"; - } - - memmove(lastLevels, newLevels, numSymbols); -} - -void CDecoder::ReadTables(void) -{ - int blockType = m_InBitStream.ReadBits(NBlockType::kNumBits); - - if (blockType != NBlockType::kVerbatim && blockType != NBlockType::kAligned && - blockType != NBlockType::kUncompressed) - throw "bad data"; - - m_UnCompressedBlockSize = m_InBitStream.ReadBitsBig(kUncompressedBlockSizeNumBits); - - if (blockType == NBlockType::kUncompressed) - { - m_UncompressedBlock = true; - UInt32 bitPos = m_InBitStream.GetBitPosition() % 16; - m_InBitStream.ReadBits(16 - bitPos); - for (int i = 0; i < kNumRepDistances; i++) - { - m_RepDistances[i] = 0; - for (int j = 0; j < 4; j++) - m_RepDistances[i] |= (m_InBitStream.DirectReadByte()) << (8 * j); - m_RepDistances[i]--; - } - return; - } - - m_UncompressedBlock = false; - - m_AlignIsUsed = (blockType == NBlockType::kAligned); - - Byte newLevels[kMaxTableSize]; - - if (m_AlignIsUsed) - { - for(int i = 0; i < kAlignTableSize; i++) - newLevels[i] = m_InBitStream.ReadBits(kNumBitsForAlignLevel); - m_AlignDecoder.SetCodeLengths(newLevels); - } - - ReadTable(m_LastByteLevels, newLevels, 256); - ReadTable(m_LastPosLenLevels, newLevels + 256, m_NumPosLenSlots); - for (int i = m_NumPosLenSlots; i < kNumPosSlotLenSlotSymbols; i++) - newLevels[256 + i] = 0; - m_MainDecoder.SetCodeLengths(newLevels); - - ReadTable(m_LastLenLevels, newLevels, kNumLenSymbols); - m_LenDecoder.SetCodeLengths(newLevels); - -} - -class CDecoderFlusher -{ - CDecoder *m_Decoder; -public: - CDecoderFlusher(CDecoder *decoder): m_Decoder(decoder) {} - ~CDecoderFlusher() - { - m_Decoder->Flush(); - m_Decoder->ReleaseStreams(); - } -}; - - -void CDecoder::ClearPrevLeveles() -{ - memset(m_LastByteLevels, 0, 256); - memset(m_LastPosLenLevels, 0, kNumPosSlotLenSlotSymbols); - memset(m_LastLenLevels, 0, kNumLenSymbols); -}; - - -STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, - ISequentialOutStream *outStream, - const UInt64 *inSize, const UInt64 *outSize, - ICompressProgressInfo *progress) -{ - if (outSize == NULL) - return E_INVALIDARG; - UInt64 size = *outSize; - - if (!m_OutWindowStream.Create(kHistorySize)) - return E_OUTOFMEMORY; - if (!m_InBitStream.Create(1 << 20)) - return E_OUTOFMEMORY; - - m_OutWindowStream.SetStream(m_i86TranslationOutStream); - m_OutWindowStream.Init(); - - m_InBitStream.SetStream(inStream); - m_InBitStream.Init(m_ReservedSize, m_NumInDataBlocks); - - CDecoderFlusher flusher(this); - - UInt32 uncompressedCFDataBlockSize; - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - UInt32 uncompressedCFDataCurrentValue = 0; - m_InBitStream.Init(); - - ClearPrevLeveles(); - - if (m_InBitStream.ReadBits(1) == 0) - m_i86TranslationOutStreamSpec->Init(outStream, false, 0); - else - { - UInt32 i86TranslationSize = m_InBitStream.ReadBits(16) << 16; - i86TranslationSize |= m_InBitStream.ReadBits(16); - m_i86TranslationOutStreamSpec->Init(outStream, true , i86TranslationSize); - } - - for(int i = 0 ; i < kNumRepDistances; i++) - m_RepDistances[i] = 0; - - UInt64 nowPos64 = 0; - while(nowPos64 < size) - { - if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) - { - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - m_InBitStream.Init(); - uncompressedCFDataCurrentValue = 0; - } - ReadTables(); - UInt32 nowPos = 0; - UInt32 next = (UInt32)MyMin((UInt64)m_UnCompressedBlockSize, size - nowPos64); - if (m_UncompressedBlock) - { - while(nowPos < next) - { - m_OutWindowStream.PutByte(m_InBitStream.DirectReadByte()); - nowPos++; - uncompressedCFDataCurrentValue++; - if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) - { - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - // m_InBitStream.Init(); - uncompressedCFDataCurrentValue = 0; - continue; - } - } - int bitPos = m_InBitStream.GetBitPosition() % 16; - if (bitPos == 8) - m_InBitStream.DirectReadByte(); - m_InBitStream.Normalize(); - } - else for (;nowPos < next;) - { - if (uncompressedCFDataCurrentValue == uncompressedCFDataBlockSize) - { - bool dataAreCorrect; - RINOK(m_InBitStream.ReadBlock(uncompressedCFDataBlockSize, dataAreCorrect)); - if (!dataAreCorrect) - { - throw "Data Error"; - } - m_InBitStream.Init(); - uncompressedCFDataCurrentValue = 0; - } - UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream); - if (number < 256) - { - m_OutWindowStream.PutByte(Byte(number)); - nowPos++; - uncompressedCFDataCurrentValue++; - // continue; - } - else if (number < 256 + m_NumPosLenSlots) - { - UInt32 posLenSlot = number - 256; - UInt32 posSlot = posLenSlot / kNumLenSlots; - UInt32 lenSlot = posLenSlot % kNumLenSlots; - UInt32 length = 2 + lenSlot; - if (lenSlot == kNumLenSlots - 1) - length += m_LenDecoder.DecodeSymbol(&m_InBitStream); - - if (posSlot < kNumRepDistances) - { - UInt32 distance = m_RepDistances[posSlot]; - m_OutWindowStream.CopyBlock(distance, length); - if (posSlot != 0) - { - m_RepDistances[posSlot] = m_RepDistances[0]; - m_RepDistances[0] = distance; - } - } - else - { - UInt32 pos = kDistStart[posSlot]; - UInt32 posDirectBits = kDistDirectBits[posSlot]; - if (m_AlignIsUsed && posDirectBits >= kNumAlignBits) - { - pos += (m_InBitStream.ReadBits(posDirectBits - kNumAlignBits) << kNumAlignBits); - pos += m_AlignDecoder.DecodeSymbol(&m_InBitStream); - } - else - pos += m_InBitStream.ReadBits(posDirectBits); - UInt32 distance = pos - kNumRepDistances; - if (distance >= nowPos64 + nowPos) - throw 777123; - m_OutWindowStream.CopyBlock(distance, length); - m_RepDistances[2] = m_RepDistances[1]; - m_RepDistances[1] = m_RepDistances[0]; - m_RepDistances[0] = distance; - } - nowPos += length; - uncompressedCFDataCurrentValue += length; - } - else - throw 98112823; - } - if (progress != NULL) - { - UInt64 inSize = m_InBitStream.GetProcessedSize(); - UInt64 outSize = nowPos64 + nowPos; - RINOK(progress->SetRatioInfo(&inSize, &outSize)); - } - nowPos64 += nowPos; - } - return S_OK; -} - -}}} |