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