1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
#ifndef __STREAM_LSBFDECODER_H
#define __STREAM_LSBFDECODER_H
#include "IInOutStreams.h"
namespace NStream {
namespace NLSBF {
const int kNumBigValueBits = 8 * 4;
const int kNumValueBytes = 3;
const int kNumValueBits = 8 * kNumValueBytes;
const int kMask = (1 << kNumValueBits) - 1;
extern BYTE kInvertTable[256];
// the Least Significant Bit of byte is First
template<class TInByte>
class CDecoder
{
UINT32 m_BitPos;
UINT32 m_Value;
UINT32 m_NormalValue;
protected:
TInByte m_Stream;
public:
void Init(ISequentialInStream *aStream)
{
m_Stream.Init(aStream);
Init();
}
void Init()
{
m_BitPos = kNumBigValueBits;
m_NormalValue = 0;
}
void ReleaseStream()
{
m_Stream.ReleaseStream();
}
UINT64 GetProcessedSize() const
{ return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
void Normalize()
{
for (;m_BitPos >= 8; m_BitPos -= 8)
{
BYTE aByte = m_Stream.ReadByte();
m_NormalValue = (aByte << (kNumBigValueBits - m_BitPos)) | m_NormalValue;
m_Value = (m_Value << 8) | kInvertTable[aByte];
}
}
UINT32 GetValue(UINT32 aNumBits)
{
Normalize();
return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - aNumBits);
}
void MovePos(UINT32 aNumBits)
{
m_BitPos += aNumBits;
m_NormalValue >>= aNumBits;
}
UINT32 ReadBits(UINT32 aNumBits)
{
Normalize();
UINT32 aRes = m_NormalValue & ( (1 << aNumBits) - 1);
MovePos(aNumBits);
return aRes;
}
UINT32 GetBitPosition() const
{
return (m_BitPos & 7);
}
};
}}
#endif
|