summaryrefslogtreecommitdiffstats
path: root/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h')
-rw-r--r--other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h127
1 files changed, 127 insertions, 0 deletions
diff --git a/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h
new file mode 100644
index 000000000..6e506859c
--- /dev/null
+++ b/other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h
@@ -0,0 +1,127 @@
+// LSBFDecoder.h
+
+#ifndef __STREAM_LSBFDECODER_H
+#define __STREAM_LSBFDECODER_H
+
+#include "../IStream.h"
+
+namespace NStream {
+namespace NLSBF {
+
+const int kNumBigValueBits = 8 * 4;
+
+const int kNumValueBytes = 3;
+const int kNumValueBits = 8 * kNumValueBytes;
+
+const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+extern Byte kInvertTable[256];
+// the Least Significant Bit of byte is First
+
+template<class TInByte>
+class CBaseDecoder
+{
+protected:
+ int m_BitPos;
+ UInt32 m_Value;
+ TInByte m_Stream;
+public:
+ UInt32 NumExtraBytes;
+ bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
+ void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); }
+ void ReleaseStream() { m_Stream.ReleaseStream(); }
+ void Init()
+ {
+ m_Stream.Init();
+ m_BitPos = kNumBigValueBits;
+ m_Value = 0;
+ NumExtraBytes = 0;
+ }
+ UInt64 GetProcessedSize() const
+ { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
+ UInt64 GetProcessedBitsSize() const
+ { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
+ int GetBitPosition() const { return (m_BitPos & 7); }
+
+ void Normalize()
+ {
+ for (;m_BitPos >= 8; m_BitPos -= 8)
+ {
+ Byte b;
+ if (!m_Stream.ReadByte(b))
+ {
+ b = 0xFF; // check it
+ NumExtraBytes++;
+ }
+ m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value;
+ }
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ Normalize();
+ UInt32 res = m_Value & ((1 << numBits) - 1);
+ m_BitPos += numBits;
+ m_Value >>= numBits;
+ return res;
+ }
+
+ bool ExtraBitsWereRead() const
+ {
+ if (NumExtraBytes == 0)
+ return false;
+ return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
+ }
+};
+
+template<class TInByte>
+class CDecoder: public CBaseDecoder<TInByte>
+{
+ UInt32 m_NormalValue;
+
+public:
+ void Init()
+ {
+ CBaseDecoder<TInByte>::Init();
+ m_NormalValue = 0;
+ }
+
+ void Normalize()
+ {
+ for (;this->m_BitPos >= 8; this->m_BitPos -= 8)
+ {
+ Byte b;
+ if (!this->m_Stream.ReadByte(b))
+ {
+ b = 0xFF; // check it
+ this->NumExtraBytes++;
+ }
+ m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue;
+ this->m_Value = (this->m_Value << 8) | kInvertTable[b];
+ }
+ }
+
+ UInt32 GetValue(int numBits)
+ {
+ Normalize();
+ return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(int numBits)
+ {
+ this->m_BitPos += numBits;
+ m_NormalValue >>= numBits;
+ }
+
+ UInt32 ReadBits(int numBits)
+ {
+ Normalize();
+ UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
+ MovePos(numBits);
+ return res;
+ }
+};
+
+}}
+
+#endif