1#ifndef __COMPRESSION_BITCODER_H
2#define __COMPRESSION_BITCODER_H
3
4#include "rngcoder.h"
5
6namespace NCompression {
7namespace NArithmetic {
8
9const int kNumBitModelTotalBits = 11;
10const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
11
12const int kNumMoveReducingBits = 2;
13
14/////////////////////////////
15// CBitModel
16
17template <int aNumMoveBits>
18class CBitModel
19{
20public:
21 UINT32 m_Probability;
22 void UpdateModel(UINT32 aSymbol)
23 {
24 /*
25 m_Probability -= (m_Probability + ((aSymbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
26 m_Probability += (1 - aSymbol) << (kNumBitModelTotalBits - aNumMoveBits);
27 */
28 if (aSymbol == 0)
29 m_Probability += (kBitModelTotal - m_Probability) >> aNumMoveBits;
30 else
31 m_Probability -= (m_Probability) >> aNumMoveBits;
32 }
33public:
34 void Init() { m_Probability = kBitModelTotal / 2; }
35};
36
37template <int aNumMoveBits>
38class CBitDecoder: public CBitModel<aNumMoveBits>
39{
40public:
41 UINT32 Decode(CRangeDecoder *aRangeDecoder)
42 {
43 UINT32 aNewBound = (aRangeDecoder->m_Range >> kNumBitModelTotalBits) * CBitModel<aNumMoveBits>::m_Probability;
44 if (aRangeDecoder->m_Code < aNewBound)
45 {
46 aRangeDecoder->m_Range = aNewBound;
47 CBitModel<aNumMoveBits>::m_Probability += (kBitModelTotal - CBitModel<aNumMoveBits>::m_Probability) >> aNumMoveBits;
48 if (aRangeDecoder->m_Range < kTopValue)
49 {
50 aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
51 aRangeDecoder->m_Range <<= 8;
52 }
53 return 0;
54 }
55 else
56 {
57 aRangeDecoder->m_Range -= aNewBound;
58 aRangeDecoder->m_Code -= aNewBound;
59 CBitModel<aNumMoveBits>::m_Probability -= (CBitModel<aNumMoveBits>::m_Probability) >> aNumMoveBits;
60 if (aRangeDecoder->m_Range < kTopValue)
61 {
62 aRangeDecoder->m_Code = (aRangeDecoder->m_Code << 8) | aRangeDecoder->m_Stream.ReadByte();
63 aRangeDecoder->m_Range <<= 8;
64 }
65 return 1;
66 }
67 }
68};
69
70}}
71
72
73#endif
74