annotate src/win32/7zip/7z/CPP/7zip/Compress/BitlDecoder.h @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
rev   line source
rlm@1 1 // BitlDecoder.h -- the Least Significant Bit of byte is First
rlm@1 2
rlm@1 3 #ifndef __BITL_DECODER_H
rlm@1 4 #define __BITL_DECODER_H
rlm@1 5
rlm@1 6 #include "../IStream.h"
rlm@1 7
rlm@1 8 namespace NBitl {
rlm@1 9
rlm@1 10 const int kNumBigValueBits = 8 * 4;
rlm@1 11
rlm@1 12 const int kNumValueBytes = 3;
rlm@1 13 const int kNumValueBits = 8 * kNumValueBytes;
rlm@1 14
rlm@1 15 const UInt32 kMask = (1 << kNumValueBits) - 1;
rlm@1 16
rlm@1 17 extern Byte kInvertTable[256];
rlm@1 18
rlm@1 19 template<class TInByte>
rlm@1 20 class CBaseDecoder
rlm@1 21 {
rlm@1 22 protected:
rlm@1 23 int m_BitPos;
rlm@1 24 UInt32 m_Value;
rlm@1 25 TInByte m_Stream;
rlm@1 26 public:
rlm@1 27 UInt32 NumExtraBytes;
rlm@1 28 bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
rlm@1 29 void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); }
rlm@1 30 void ReleaseStream() { m_Stream.ReleaseStream(); }
rlm@1 31 void Init()
rlm@1 32 {
rlm@1 33 m_Stream.Init();
rlm@1 34 m_BitPos = kNumBigValueBits;
rlm@1 35 m_Value = 0;
rlm@1 36 NumExtraBytes = 0;
rlm@1 37 }
rlm@1 38 UInt64 GetProcessedSize() const
rlm@1 39 { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
rlm@1 40 UInt64 GetProcessedBitsSize() const
rlm@1 41 { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
rlm@1 42 int GetBitPosition() const { return (m_BitPos & 7); }
rlm@1 43
rlm@1 44 void Normalize()
rlm@1 45 {
rlm@1 46 for (;m_BitPos >= 8; m_BitPos -= 8)
rlm@1 47 {
rlm@1 48 Byte b = 0;
rlm@1 49 if (!m_Stream.ReadByte(b))
rlm@1 50 {
rlm@1 51 b = 0xFF; // check it
rlm@1 52 NumExtraBytes++;
rlm@1 53 }
rlm@1 54 m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value;
rlm@1 55 }
rlm@1 56 }
rlm@1 57
rlm@1 58 UInt32 ReadBits(int numBits)
rlm@1 59 {
rlm@1 60 Normalize();
rlm@1 61 UInt32 res = m_Value & ((1 << numBits) - 1);
rlm@1 62 m_BitPos += numBits;
rlm@1 63 m_Value >>= numBits;
rlm@1 64 return res;
rlm@1 65 }
rlm@1 66
rlm@1 67 bool ExtraBitsWereRead() const
rlm@1 68 {
rlm@1 69 if (NumExtraBytes == 0)
rlm@1 70 return false;
rlm@1 71 return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
rlm@1 72 }
rlm@1 73 };
rlm@1 74
rlm@1 75 template<class TInByte>
rlm@1 76 class CDecoder: public CBaseDecoder<TInByte>
rlm@1 77 {
rlm@1 78 UInt32 m_NormalValue;
rlm@1 79
rlm@1 80 public:
rlm@1 81 void Init()
rlm@1 82 {
rlm@1 83 CBaseDecoder<TInByte>::Init();
rlm@1 84 m_NormalValue = 0;
rlm@1 85 }
rlm@1 86
rlm@1 87 void Normalize()
rlm@1 88 {
rlm@1 89 for (; this->m_BitPos >= 8; this->m_BitPos -= 8)
rlm@1 90 {
rlm@1 91 Byte b = 0;
rlm@1 92 if (!this->m_Stream.ReadByte(b))
rlm@1 93 {
rlm@1 94 b = 0xFF; // check it
rlm@1 95 this->NumExtraBytes++;
rlm@1 96 }
rlm@1 97 m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue;
rlm@1 98 this->m_Value = (this->m_Value << 8) | kInvertTable[b];
rlm@1 99 }
rlm@1 100 }
rlm@1 101
rlm@1 102 UInt32 GetValue(int numBits)
rlm@1 103 {
rlm@1 104 Normalize();
rlm@1 105 return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits);
rlm@1 106 }
rlm@1 107
rlm@1 108 void MovePos(int numBits)
rlm@1 109 {
rlm@1 110 this->m_BitPos += numBits;
rlm@1 111 m_NormalValue >>= numBits;
rlm@1 112 }
rlm@1 113
rlm@1 114 UInt32 ReadBits(int numBits)
rlm@1 115 {
rlm@1 116 Normalize();
rlm@1 117 UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
rlm@1 118 MovePos(numBits);
rlm@1 119 return res;
rlm@1 120 }
rlm@1 121 };
rlm@1 122
rlm@1 123 }
rlm@1 124
rlm@1 125 #endif