1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Compress/RangeCoderBit.h 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 2009-05-30 : Igor Pavlov : Public domain 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef __COMPRESS_RANGE_CODER_BIT_H 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define __COMPRESS_RANGE_CODER_BIT_H 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "RangeCoder.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NCompress { 10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NRangeCoder { 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst int kNumBitModelTotalBits = 11; 13baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits); 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 15baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst int kNumMoveReducingBits = 4; 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 17baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst int kNumBitPriceShiftBits = 4; 18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst UInt32 kBitPrice = 1 << kNumBitPriceShiftBits; 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 20baa3858d3f5d128a5c8466b700098109edcad5f2repo syncextern UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 22baa3858d3f5d128a5c8466b700098109edcad5f2repo synctemplate <int numMoveBits> 23baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBitModel 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 25baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 Prob; 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void UpdateModel(UInt32 symbol) 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits; 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits); 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (symbol == 0) 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Prob += (kBitModelTotal - Prob) >> numMoveBits; 35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Prob -= (Prob) >> numMoveBits; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 38baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Init() { Prob = kBitModelTotal / 2; } 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 42baa3858d3f5d128a5c8466b700098109edcad5f2repo synctemplate <int numMoveBits> 43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBitEncoder: public CBitModel<numMoveBits> 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 45baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Encode(CEncoder *encoder, UInt32 symbol) 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync /* 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol); 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync this->UpdateModel(symbol); 51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync */ 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob; 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (symbol == 0) 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encoder->Range = newBound; 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encoder->Low += newBound; 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encoder->Range -= newBound; 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync this->Prob -= (this->Prob) >> numMoveBits; 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (encoder->Range < kTopValue) 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encoder->Range <<= 8; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync encoder->ShiftLow(); 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetPrice(UInt32 symbol) const 71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ProbPrices[(this->Prob ^ ((-(int)symbol)) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetPrice0() const { return ProbPrices[this->Prob >> kNumMoveReducingBits]; } 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 GetPrice1() const { return ProbPrices[(this->Prob ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]; } 76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 79baa3858d3f5d128a5c8466b700098109edcad5f2repo synctemplate <int numMoveBits> 80baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CBitDecoder: public CBitModel<numMoveBits> 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 82baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 Decode(CDecoder *decoder) 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob; 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (decoder->Code < newBound) 87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder->Range = newBound; 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits; 90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (decoder->Range < kTopValue) 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder->Range <<= 8; 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0; 96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder->Range -= newBound; 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder->Code -= newBound; 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync this->Prob -= (this->Prob) >> numMoveBits; 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (decoder->Range < kTopValue) 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte(); 105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync decoder->Range <<= 8; 106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 1; 108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 115