RangeCoderBitTree.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. using System;
  2. namespace SharpCompress.Compressors.LZMA.RangeCoder
  3. {
  4. internal struct BitTreeEncoder
  5. {
  6. private readonly BitEncoder[] _models;
  7. private readonly int _numBitLevels;
  8. public BitTreeEncoder(int numBitLevels)
  9. {
  10. _numBitLevels = numBitLevels;
  11. _models = new BitEncoder[1 << numBitLevels];
  12. }
  13. public void Init()
  14. {
  15. for (uint i = 1; i < (1 << _numBitLevels); i++)
  16. {
  17. _models[i].Init();
  18. }
  19. }
  20. public void Encode(Encoder rangeEncoder, UInt32 symbol)
  21. {
  22. UInt32 m = 1;
  23. for (int bitIndex = _numBitLevels; bitIndex > 0;)
  24. {
  25. bitIndex--;
  26. UInt32 bit = (symbol >> bitIndex) & 1;
  27. _models[m].Encode(rangeEncoder, bit);
  28. m = (m << 1) | bit;
  29. }
  30. }
  31. public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol)
  32. {
  33. UInt32 m = 1;
  34. for (UInt32 i = 0; i < _numBitLevels; i++)
  35. {
  36. UInt32 bit = symbol & 1;
  37. _models[m].Encode(rangeEncoder, bit);
  38. m = (m << 1) | bit;
  39. symbol >>= 1;
  40. }
  41. }
  42. public UInt32 GetPrice(UInt32 symbol)
  43. {
  44. UInt32 price = 0;
  45. UInt32 m = 1;
  46. for (int bitIndex = _numBitLevels; bitIndex > 0;)
  47. {
  48. bitIndex--;
  49. UInt32 bit = (symbol >> bitIndex) & 1;
  50. price += _models[m].GetPrice(bit);
  51. m = (m << 1) + bit;
  52. }
  53. return price;
  54. }
  55. public UInt32 ReverseGetPrice(UInt32 symbol)
  56. {
  57. UInt32 price = 0;
  58. UInt32 m = 1;
  59. for (int i = _numBitLevels; i > 0; i--)
  60. {
  61. UInt32 bit = symbol & 1;
  62. symbol >>= 1;
  63. price += _models[m].GetPrice(bit);
  64. m = (m << 1) | bit;
  65. }
  66. return price;
  67. }
  68. public static UInt32 ReverseGetPrice(BitEncoder[] models, UInt32 startIndex,
  69. int numBitLevels, UInt32 symbol)
  70. {
  71. UInt32 price = 0;
  72. UInt32 m = 1;
  73. for (int i = numBitLevels; i > 0; i--)
  74. {
  75. UInt32 bit = symbol & 1;
  76. symbol >>= 1;
  77. price += models[startIndex + m].GetPrice(bit);
  78. m = (m << 1) | bit;
  79. }
  80. return price;
  81. }
  82. public static void ReverseEncode(BitEncoder[] models, UInt32 startIndex,
  83. Encoder rangeEncoder, int numBitLevels, UInt32 symbol)
  84. {
  85. UInt32 m = 1;
  86. for (int i = 0; i < numBitLevels; i++)
  87. {
  88. UInt32 bit = symbol & 1;
  89. models[startIndex + m].Encode(rangeEncoder, bit);
  90. m = (m << 1) | bit;
  91. symbol >>= 1;
  92. }
  93. }
  94. }
  95. internal struct BitTreeDecoder
  96. {
  97. private readonly BitDecoder[] _models;
  98. private readonly int _numBitLevels;
  99. public BitTreeDecoder(int numBitLevels)
  100. {
  101. _numBitLevels = numBitLevels;
  102. _models = new BitDecoder[1 << numBitLevels];
  103. }
  104. public void Init()
  105. {
  106. for (uint i = 1; i < (1 << _numBitLevels); i++)
  107. {
  108. _models[i].Init();
  109. }
  110. }
  111. public uint Decode(Decoder rangeDecoder)
  112. {
  113. uint m = 1;
  114. for (int bitIndex = _numBitLevels; bitIndex > 0; bitIndex--)
  115. {
  116. m = (m << 1) + _models[m].Decode(rangeDecoder);
  117. }
  118. return m - ((uint)1 << _numBitLevels);
  119. }
  120. public uint ReverseDecode(Decoder rangeDecoder)
  121. {
  122. uint m = 1;
  123. uint symbol = 0;
  124. for (int bitIndex = 0; bitIndex < _numBitLevels; bitIndex++)
  125. {
  126. uint bit = _models[m].Decode(rangeDecoder);
  127. m <<= 1;
  128. m += bit;
  129. symbol |= (bit << bitIndex);
  130. }
  131. return symbol;
  132. }
  133. public static uint ReverseDecode(BitDecoder[] models, UInt32 startIndex,
  134. Decoder rangeDecoder, int numBitLevels)
  135. {
  136. uint m = 1;
  137. uint symbol = 0;
  138. for (int bitIndex = 0; bitIndex < numBitLevels; bitIndex++)
  139. {
  140. uint bit = models[startIndex + m].Decode(rangeDecoder);
  141. m <<= 1;
  142. m += bit;
  143. symbol |= (bit << bitIndex);
  144. }
  145. return symbol;
  146. }
  147. }
  148. }