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