Encoder.java 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package SevenZip.Compression.RangeCoder;
  2. import java.io.IOException;
  3. public class Encoder
  4. {
  5. static final int kTopMask = ~((1 << 24) - 1);
  6. static final int kNumBitModelTotalBits = 11;
  7. static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
  8. static final int kNumMoveBits = 5;
  9. java.io.OutputStream Stream;
  10. long Low;
  11. int Range;
  12. int _cacheSize;
  13. int _cache;
  14. long _position;
  15. public void SetStream(java.io.OutputStream stream)
  16. {
  17. Stream = stream;
  18. }
  19. public void ReleaseStream()
  20. {
  21. Stream = null;
  22. }
  23. public void Init()
  24. {
  25. _position = 0;
  26. Low = 0;
  27. Range = -1;
  28. _cacheSize = 1;
  29. _cache = 0;
  30. }
  31. public void FlushData() throws IOException
  32. {
  33. for (int i = 0; i < 5; i++)
  34. ShiftLow();
  35. }
  36. public void FlushStream() throws IOException
  37. {
  38. Stream.flush();
  39. }
  40. public void ShiftLow() throws IOException
  41. {
  42. int LowHi = (int)(Low >>> 32);
  43. if (LowHi != 0 || Low < 0xFF000000L)
  44. {
  45. _position += _cacheSize;
  46. int temp = _cache;
  47. do
  48. {
  49. Stream.write(temp + LowHi);
  50. temp = 0xFF;
  51. }
  52. while(--_cacheSize != 0);
  53. _cache = (((int)Low) >>> 24);
  54. }
  55. _cacheSize++;
  56. Low = (Low & 0xFFFFFF) << 8;
  57. }
  58. public void EncodeDirectBits(int v, int numTotalBits) throws IOException
  59. {
  60. for (int i = numTotalBits - 1; i >= 0; i--)
  61. {
  62. Range >>>= 1;
  63. if (((v >>> i) & 1) == 1)
  64. Low += Range;
  65. if ((Range & Encoder.kTopMask) == 0)
  66. {
  67. Range <<= 8;
  68. ShiftLow();
  69. }
  70. }
  71. }
  72. public long GetProcessedSizeAdd()
  73. {
  74. return _cacheSize + _position + 4;
  75. }
  76. static final int kNumMoveReducingBits = 2;
  77. public static final int kNumBitPriceShiftBits = 6;
  78. public static void InitBitModels(short []probs)
  79. {
  80. for (int i = 0; i < probs.length; i++)
  81. probs[i] = (kBitModelTotal >>> 1);
  82. }
  83. public void Encode(short []probs, int index, int symbol) throws IOException
  84. {
  85. int prob = probs[index];
  86. int newBound = (Range >>> kNumBitModelTotalBits) * prob;
  87. if (symbol == 0)
  88. {
  89. Range = newBound;
  90. probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
  91. }
  92. else
  93. {
  94. Low += (newBound & 0xFFFFFFFFL);
  95. Range -= newBound;
  96. probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
  97. }
  98. if ((Range & kTopMask) == 0)
  99. {
  100. Range <<= 8;
  101. ShiftLow();
  102. }
  103. }
  104. private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
  105. static
  106. {
  107. int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
  108. for (int i = kNumBits - 1; i >= 0; i--)
  109. {
  110. int start = 1 << (kNumBits - i - 1);
  111. int end = 1 << (kNumBits - i);
  112. for (int j = start; j < end; j++)
  113. ProbPrices[j] = (i << kNumBitPriceShiftBits) +
  114. (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
  115. }
  116. }
  117. static public int GetPrice(int Prob, int symbol)
  118. {
  119. return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
  120. }
  121. static public int GetPrice0(int Prob)
  122. {
  123. return ProbPrices[Prob >>> kNumMoveReducingBits];
  124. }
  125. static public int GetPrice1(int Prob)
  126. {
  127. return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits];
  128. }
  129. }