| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // Compress/RangeCoder/RangeCoderBit.h
- #ifndef __COMPRESS_RANGECODER_BIT_H
- #define __COMPRESS_RANGECODER_BIT_H
- #include "RangeCoder.h"
- namespace NCompress {
- namespace NRangeCoder {
- const int kNumBitModelTotalBits = 11;
- const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
- const int kNumMoveReducingBits = 2;
- const int kNumBitPriceShiftBits = 6;
- const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
- class CPriceTables
- {
- public:
- static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
- static void Init();
- CPriceTables();
- };
- template <int numMoveBits>
- class CBitModel
- {
- public:
- UInt32 Prob;
- void UpdateModel(UInt32 symbol)
- {
- /*
- Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
- Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
- */
- if (symbol == 0)
- Prob += (kBitModelTotal - Prob) >> numMoveBits;
- else
- Prob -= (Prob) >> numMoveBits;
- }
- public:
- void Init() { Prob = kBitModelTotal / 2; }
- };
- template <int numMoveBits>
- class CBitEncoder: public CBitModel<numMoveBits>
- {
- public:
- void Encode(CEncoder *encoder, UInt32 symbol)
- {
- /*
- encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
- this->UpdateModel(symbol);
- */
- UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
- if (symbol == 0)
- {
- encoder->Range = newBound;
- this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
- }
- else
- {
- encoder->Low += newBound;
- encoder->Range -= newBound;
- this->Prob -= (this->Prob) >> numMoveBits;
- }
- if (encoder->Range < kTopValue)
- {
- encoder->Range <<= 8;
- encoder->ShiftLow();
- }
- }
- UInt32 GetPrice(UInt32 symbol) const
- {
- return CPriceTables::ProbPrices[
- (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
- }
- UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
- UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
- };
- template <int numMoveBits>
- class CBitDecoder: public CBitModel<numMoveBits>
- {
- public:
- UInt32 Decode(CDecoder *decoder)
- {
- UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
- if (decoder->Code < newBound)
- {
- decoder->Range = newBound;
- this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
- if (decoder->Range < kTopValue)
- {
- decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
- decoder->Range <<= 8;
- }
- return 0;
- }
- else
- {
- decoder->Range -= newBound;
- decoder->Code -= newBound;
- this->Prob -= (this->Prob) >> numMoveBits;
- if (decoder->Range < kTopValue)
- {
- decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
- decoder->Range <<= 8;
- }
- return 1;
- }
- }
- };
- }}
- #endif
|