1 // Compress/RangeCoder/RangeCoderBit.h
3 #ifndef __COMPRESS_RANGECODER_BIT_H
4 #define __COMPRESS_RANGECODER_BIT_H
6 #include "RangeCoder.h"
9 namespace NRangeCoder
{
11 const int kNumBitModelTotalBits
= 11;
12 const UInt32 kBitModelTotal
= (1 << kNumBitModelTotalBits
);
14 const int kNumMoveReducingBits
= 2;
16 const int kNumBitPriceShiftBits
= 6;
17 const UInt32 kBitPrice
= 1 << kNumBitPriceShiftBits
;
22 static UInt32 ProbPrices
[kBitModelTotal
>> kNumMoveReducingBits
];
27 template <int numMoveBits
>
32 void UpdateModel(UInt32 symbol
)
35 Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
36 Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
39 Prob
+= (kBitModelTotal
- Prob
) >> numMoveBits
;
41 Prob
-= (Prob
) >> numMoveBits
;
44 void Init() { Prob
= kBitModelTotal
/ 2; }
47 template <int numMoveBits
>
48 class CBitEncoder
: public CBitModel
<numMoveBits
>
51 void Encode(CEncoder
*encoder
, UInt32 symbol
)
54 encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
55 this->UpdateModel(symbol);
57 UInt32 newBound
= (encoder
->Range
>> kNumBitModelTotalBits
) * this->Prob
;
60 encoder
->Range
= newBound
;
61 this->Prob
+= (kBitModelTotal
- this->Prob
) >> numMoveBits
;
65 encoder
->Low
+= newBound
;
66 encoder
->Range
-= newBound
;
67 this->Prob
-= (this->Prob
) >> numMoveBits
;
69 if (encoder
->Range
< kTopValue
)
75 UInt32
GetPrice(UInt32 symbol
) const
77 return CPriceTables::ProbPrices
[
78 (((this->Prob
- symbol
) ^ ((-(int)symbol
))) & (kBitModelTotal
- 1)) >> kNumMoveReducingBits
];
80 UInt32
GetPrice0() const { return CPriceTables::ProbPrices
[this->Prob
>> kNumMoveReducingBits
]; }
81 UInt32
GetPrice1() const { return CPriceTables::ProbPrices
[(kBitModelTotal
- this->Prob
) >> kNumMoveReducingBits
]; }
85 template <int numMoveBits
>
86 class CBitDecoder
: public CBitModel
<numMoveBits
>
89 UInt32
Decode(CDecoder
*decoder
)
91 UInt32 newBound
= (decoder
->Range
>> kNumBitModelTotalBits
) * this->Prob
;
92 if (decoder
->Code
< newBound
)
94 decoder
->Range
= newBound
;
95 this->Prob
+= (kBitModelTotal
- this->Prob
) >> numMoveBits
;
96 if (decoder
->Range
< kTopValue
)
98 decoder
->Code
= (decoder
->Code
<< 8) | decoder
->Stream
.ReadByte();
105 decoder
->Range
-= newBound
;
106 decoder
->Code
-= newBound
;
107 this->Prob
-= (this->Prob
) >> numMoveBits
;
108 if (decoder
->Range
< kTopValue
)
110 decoder
->Code
= (decoder
->Code
<< 8) | decoder
->Stream
.ReadByte();
111 decoder
->Range
<<= 8;