#ifndef __LENCODER_H #define __LENCODER_H #include "BitTreeCoder.h" namespace NLength { const int kNumPosStatesBitsMax = 4; const int kNumPosStatesMax = (1 << kNumPosStatesBitsMax); const int kNumPosStatesBitsEncodingMax = 4; const int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); const int kNumMoveBits = 5; const int kNumLenBits = 3; const int kNumLowSymbols = 1 << kNumLenBits; const int kNumMidBits = 3; const int kNumMidSymbols = 1 << kNumMidBits; const int kNumHighBits = 8; const int kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits); class CEncoder { CMyBitEncoder m_Choice; CBitTreeEncoder m_LowCoder[kNumPosStatesEncodingMax]; CMyBitEncoder m_Choice2; CBitTreeEncoder m_MidCoder[kNumPosStatesEncodingMax]; CBitTreeEncoder m_HighCoder; protected: UINT32 m_NumPosStates; public: void Create(UINT32 aNumPosStates) { m_NumPosStates = aNumPosStates; } void Init(); void Encode(CMyRangeEncoder *aRangeEncoder, UINT32 aSymbol, UINT32 aPosState); UINT32 GetPrice(UINT32 aSymbol, UINT32 aPosState) const; }; const int kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols; class CPriceTableEncoder: public CEncoder { UINT32 m_Prices[kNumSymbolsTotal][kNumPosStatesEncodingMax]; UINT32 m_TableSize; UINT32 m_Counters[kNumPosStatesEncodingMax]; public: void SetTableSize(UINT32 aTableSize) { m_TableSize = aTableSize; } UINT32 GetPrice(UINT32 aSymbol, UINT32 aPosState) const { return m_Prices[aSymbol][aPosState]; } void UpdateTable(UINT32 aPosState) { for (UINT32 aLen = 0; aLen < m_TableSize; aLen++) m_Prices[aLen][aPosState] = CEncoder::GetPrice(aLen , aPosState); m_Counters[aPosState] = m_TableSize; } void UpdateTables() { for (UINT32 aPosState = 0; aPosState < m_NumPosStates; aPosState++) UpdateTable(aPosState); } void Encode(CMyRangeEncoder *aRangeEncoder, UINT32 aSymbol, UINT32 aPosState) { CEncoder::Encode(aRangeEncoder, aSymbol, aPosState); if (--m_Counters[aPosState] == 0) UpdateTable(aPosState); } }; class CDecoder { CMyBitDecoder m_Choice; CBitTreeDecoder m_LowCoder[kNumPosStatesMax]; CMyBitDecoder m_Choice2; CBitTreeDecoder m_MidCoder[kNumPosStatesMax]; CBitTreeDecoder m_HighCoder; UINT32 m_NumPosStates; public: void Create(UINT32 aNumPosStates) { m_NumPosStates = aNumPosStates; } void Init() { m_Choice.Init(); for (UINT32 aPosState = 0; aPosState < m_NumPosStates; aPosState++) { m_LowCoder[aPosState].Init(); m_MidCoder[aPosState].Init(); } m_Choice2.Init(); m_HighCoder.Init(); } UINT32 Decode(CMyRangeDecoder *aRangeDecoder, UINT32 aPosState) { if(m_Choice.Decode(aRangeDecoder) == 0) return m_LowCoder[aPosState].Decode(aRangeDecoder); else { UINT32 aSymbol = kNumLowSymbols; if(m_Choice2.Decode(aRangeDecoder) == 0) aSymbol += m_MidCoder[aPosState].Decode(aRangeDecoder); else { aSymbol += kNumMidSymbols; aSymbol += m_HighCoder.Decode(aRangeDecoder); } return aSymbol; } } }; } #endif