1
// Compress/RangeCoderBit.h
3
#ifndef __COMPRESS_RANGE_CODER_BIT_H
4
#define __COMPRESS_RANGE_CODER_BIT_H
6
#include "RangeCoder.h"
9
namespace NRangeCoder {
11
const int kNumBitModelTotalBits = 11;
12
const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
14
const int kNumMoveReducingBits = 4;
16
const int kNumBitPriceShiftBits = 4;
17
const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
19
extern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
21
template <int numMoveBits>
26
void UpdateModel(UInt32 symbol)
29
Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
30
Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
33
Prob += (kBitModelTotal - Prob) >> numMoveBits;
35
Prob -= (Prob) >> numMoveBits;
38
void Init() { Prob = kBitModelTotal / 2; }
41
template <int numMoveBits>
42
class CBitEncoder: public CBitModel<numMoveBits>
45
void Encode(CEncoder *encoder, UInt32 symbol)
48
encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
49
this->UpdateModel(symbol);
51
UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
54
encoder->Range = newBound;
55
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
59
encoder->Low += newBound;
60
encoder->Range -= newBound;
61
this->Prob -= (this->Prob) >> numMoveBits;
63
if (encoder->Range < kTopValue)
69
UInt32 GetPrice(UInt32 symbol) const
71
return ProbPrices[(this->Prob ^ ((-(int)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
73
UInt32 GetPrice0() const { return ProbPrices[this->Prob >> kNumMoveReducingBits]; }
74
UInt32 GetPrice1() const { return ProbPrices[(this->Prob ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]; }
78
template <int numMoveBits>
79
class CBitDecoder: public CBitModel<numMoveBits>
82
UInt32 Decode(CDecoder *decoder)
84
UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
85
if (decoder->Code < newBound)
87
decoder->Range = newBound;
88
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
89
if (decoder->Range < kTopValue)
91
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
98
decoder->Range -= newBound;
99
decoder->Code -= newBound;
100
this->Prob -= (this->Prob) >> numMoveBits;
101
if (decoder->Range < kTopValue)
103
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
104
decoder->Range <<= 8;