RangeCoderBit.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. using System;
  2. namespace SharpCompress.Compressors.LZMA.RangeCoder
  3. {
  4. internal struct BitEncoder
  5. {
  6. public const int K_NUM_BIT_MODEL_TOTAL_BITS = 11;
  7. public const uint K_BIT_MODEL_TOTAL = (1 << K_NUM_BIT_MODEL_TOTAL_BITS);
  8. private const int K_NUM_MOVE_BITS = 5;
  9. private const int K_NUM_MOVE_REDUCING_BITS = 2;
  10. public const int K_NUM_BIT_PRICE_SHIFT_BITS = 6;
  11. private uint _prob;
  12. public void Init()
  13. {
  14. _prob = K_BIT_MODEL_TOTAL >> 1;
  15. }
  16. public void UpdateModel(uint symbol)
  17. {
  18. if (symbol == 0)
  19. {
  20. _prob += (K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_BITS;
  21. }
  22. else
  23. {
  24. _prob -= (_prob) >> K_NUM_MOVE_BITS;
  25. }
  26. }
  27. public void Encode(Encoder encoder, uint symbol)
  28. {
  29. // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol);
  30. // UpdateModel(symbol);
  31. uint newBound = (encoder._range >> K_NUM_BIT_MODEL_TOTAL_BITS) * _prob;
  32. if (symbol == 0)
  33. {
  34. encoder._range = newBound;
  35. _prob += (K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_BITS;
  36. }
  37. else
  38. {
  39. encoder._low += newBound;
  40. encoder._range -= newBound;
  41. _prob -= (_prob) >> K_NUM_MOVE_BITS;
  42. }
  43. if (encoder._range < Encoder.K_TOP_VALUE)
  44. {
  45. encoder._range <<= 8;
  46. encoder.ShiftLow();
  47. }
  48. }
  49. private static readonly UInt32[] PROB_PRICES = new UInt32[K_BIT_MODEL_TOTAL >> K_NUM_MOVE_REDUCING_BITS];
  50. static BitEncoder()
  51. {
  52. const int kNumBits = (K_NUM_BIT_MODEL_TOTAL_BITS - K_NUM_MOVE_REDUCING_BITS);
  53. for (int i = kNumBits - 1; i >= 0; i--)
  54. {
  55. UInt32 start = (UInt32)1 << (kNumBits - i - 1);
  56. UInt32 end = (UInt32)1 << (kNumBits - i);
  57. for (UInt32 j = start; j < end; j++)
  58. {
  59. PROB_PRICES[j] = ((UInt32)i << K_NUM_BIT_PRICE_SHIFT_BITS) +
  60. (((end - j) << K_NUM_BIT_PRICE_SHIFT_BITS) >> (kNumBits - i - 1));
  61. }
  62. }
  63. }
  64. public uint GetPrice(uint symbol)
  65. {
  66. return PROB_PRICES[(((_prob - symbol) ^ ((-(int)symbol))) & (K_BIT_MODEL_TOTAL - 1)) >> K_NUM_MOVE_REDUCING_BITS];
  67. }
  68. public uint GetPrice0()
  69. {
  70. return PROB_PRICES[_prob >> K_NUM_MOVE_REDUCING_BITS];
  71. }
  72. public uint GetPrice1()
  73. {
  74. return PROB_PRICES[(K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_REDUCING_BITS];
  75. }
  76. }
  77. internal struct BitDecoder
  78. {
  79. public const int K_NUM_BIT_MODEL_TOTAL_BITS = 11;
  80. public const uint K_BIT_MODEL_TOTAL = (1 << K_NUM_BIT_MODEL_TOTAL_BITS);
  81. private const int K_NUM_MOVE_BITS = 5;
  82. private uint _prob;
  83. public void UpdateModel(int numMoveBits, uint symbol)
  84. {
  85. if (symbol == 0)
  86. {
  87. _prob += (K_BIT_MODEL_TOTAL - _prob) >> numMoveBits;
  88. }
  89. else
  90. {
  91. _prob -= (_prob) >> numMoveBits;
  92. }
  93. }
  94. public void Init()
  95. {
  96. _prob = K_BIT_MODEL_TOTAL >> 1;
  97. }
  98. public uint Decode(Decoder rangeDecoder)
  99. {
  100. uint newBound = (rangeDecoder._range >> K_NUM_BIT_MODEL_TOTAL_BITS) * _prob;
  101. if (rangeDecoder._code < newBound)
  102. {
  103. rangeDecoder._range = newBound;
  104. _prob += (K_BIT_MODEL_TOTAL - _prob) >> K_NUM_MOVE_BITS;
  105. if (rangeDecoder._range < Decoder.K_TOP_VALUE)
  106. {
  107. rangeDecoder._code = (rangeDecoder._code << 8) | (byte)rangeDecoder._stream.ReadByte();
  108. rangeDecoder._range <<= 8;
  109. rangeDecoder._total++;
  110. }
  111. return 0;
  112. }
  113. rangeDecoder._range -= newBound;
  114. rangeDecoder._code -= newBound;
  115. _prob -= (_prob) >> K_NUM_MOVE_BITS;
  116. if (rangeDecoder._range < Decoder.K_TOP_VALUE)
  117. {
  118. rangeDecoder._code = (rangeDecoder._code << 8) | (byte)rangeDecoder._stream.ReadByte();
  119. rangeDecoder._range <<= 8;
  120. rangeDecoder._total++;
  121. }
  122. return 1;
  123. }
  124. }
  125. }