RangeCoderBit.h 2.9 KB

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