summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/unix/CPP/7zip/Compress/LzxDecoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Compress/LzxDecoder.h')
-rw-r--r--src/libs/7zip/unix/CPP/7zip/Compress/LzxDecoder.h159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/LzxDecoder.h b/src/libs/7zip/unix/CPP/7zip/Compress/LzxDecoder.h
new file mode 100644
index 000000000..73a050619
--- /dev/null
+++ b/src/libs/7zip/unix/CPP/7zip/Compress/LzxDecoder.h
@@ -0,0 +1,159 @@
+// LzxDecoder.h
+
+#ifndef __LZX_DECODER_H
+#define __LZX_DECODER_H
+
+#include "../ICoder.h"
+
+#include "../Common/InBuffer.h"
+
+#include "HuffmanDecoder.h"
+#include "LzOutWindow.h"
+#include "Lzx.h"
+#include "Lzx86Converter.h"
+
+namespace NCompress {
+namespace NLzx {
+
+namespace NBitStream {
+
+const unsigned kNumBigValueBits = 8 * 4;
+const unsigned kNumValueBits = 17;
+const UInt32 kBitDecoderValueMask = (1 << kNumValueBits) - 1;
+
+class CDecoder
+{
+ CInBuffer m_Stream;
+ UInt32 m_Value;
+ unsigned m_BitPos;
+public:
+ CDecoder() {}
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ }
+
+ UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+
+ unsigned GetBitPosition() const { return m_BitPos & 0xF; }
+
+ void Normalize()
+ {
+ for (; m_BitPos >= 16; m_BitPos -= 16)
+ {
+ Byte b0 = m_Stream.ReadByte();
+ Byte b1 = m_Stream.ReadByte();
+ m_Value = (m_Value << 8) | b1;
+ m_Value = (m_Value << 8) | b0;
+ }
+ }
+
+ UInt32 GetValue(unsigned numBits) const
+ {
+ return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(unsigned numBits)
+ {
+ m_BitPos += numBits;
+ Normalize();
+ }
+
+ UInt32 ReadBits(unsigned numBits)
+ {
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+ }
+
+ UInt32 ReadBitsBig(unsigned numBits)
+ {
+ unsigned numBits0 = numBits / 2;
+ unsigned numBits1 = numBits - numBits0;
+ UInt32 res = ReadBits(numBits0) << numBits1;
+ return res + ReadBits(numBits1);
+ }
+
+ bool ReadUInt32(UInt32 &v)
+ {
+ if (m_BitPos != 0)
+ return false;
+ v = ((m_Value >> 16) & 0xFFFF) | ((m_Value << 16) & 0xFFFF0000);
+ m_BitPos = kNumBigValueBits;
+ return true;
+ }
+
+ Byte DirectReadByte() { return m_Stream.ReadByte(); }
+
+};
+}
+
+class CDecoder :
+ public ICompressCoder,
+ public CMyUnknownImp
+{
+ NBitStream::CDecoder m_InBitStream;
+ CLzOutWindow m_OutWindowStream;
+
+ UInt32 m_RepDistances[kNumRepDistances];
+ UInt32 m_NumPosLenSlots;
+
+ bool m_IsUncompressedBlock;
+ bool m_AlignIsUsed;
+
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;
+ NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
+
+ Byte m_LastMainLevels[kMainTableSize];
+ Byte m_LastLenLevels[kNumLenSymbols];
+
+ Cx86ConvertOutStream *m_x86ConvertOutStreamSpec;
+ CMyComPtr<ISequentialOutStream> m_x86ConvertOutStream;
+
+ UInt32 m_UnCompressedBlockSize;
+
+ bool _keepHistory;
+ int _remainLen;
+ bool _skipByte;
+
+ bool _wimMode;
+
+ UInt32 ReadBits(unsigned numBits);
+ bool ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols);
+ bool ReadTables();
+ void ClearPrevLevels();
+
+ HRESULT CodeSpec(UInt32 size);
+
+ HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+public:
+ CDecoder(bool wimMode = false);
+
+ MY_UNKNOWN_IMP
+
+ void ReleaseStreams();
+ STDMETHOD(Flush)();
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
+
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream);
+ STDMETHOD(ReleaseInStream)();
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
+
+ HRESULT SetParams(unsigned numDictBits);
+ void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
+};
+
+}}
+
+#endif