Decoder.java 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package SevenZip.Compression.RangeCoder;
  2. import java.io.IOException;
  3. public class Decoder
  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. int Range;
  10. int Code;
  11. java.io.InputStream Stream;
  12. public final void SetStream(java.io.InputStream stream)
  13. {
  14. Stream = stream;
  15. }
  16. public final void ReleaseStream()
  17. {
  18. Stream = null;
  19. }
  20. public final void Init() throws IOException
  21. {
  22. Code = 0;
  23. Range = -1;
  24. for (int i = 0; i < 5; i++)
  25. Code = (Code << 8) | Stream.read();
  26. }
  27. public final int DecodeDirectBits(int numTotalBits) throws IOException
  28. {
  29. int result = 0;
  30. for (int i = numTotalBits; i != 0; i--)
  31. {
  32. Range >>>= 1;
  33. int t = ((Code - Range) >>> 31);
  34. Code -= Range & (t - 1);
  35. result = (result << 1) | (1 - t);
  36. if ((Range & kTopMask) == 0)
  37. {
  38. Code = (Code << 8) | Stream.read();
  39. Range <<= 8;
  40. }
  41. }
  42. return result;
  43. }
  44. public int DecodeBit(short []probs, int index) throws IOException
  45. {
  46. int prob = probs[index];
  47. int newBound = (Range >>> kNumBitModelTotalBits) * prob;
  48. if ((Code ^ 0x80000000) < (newBound ^ 0x80000000))
  49. {
  50. Range = newBound;
  51. probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
  52. if ((Range & kTopMask) == 0)
  53. {
  54. Code = (Code << 8) | Stream.read();
  55. Range <<= 8;
  56. }
  57. return 0;
  58. }
  59. else
  60. {
  61. Range -= newBound;
  62. Code -= newBound;
  63. probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
  64. if ((Range & kTopMask) == 0)
  65. {
  66. Code = (Code << 8) | Stream.read();
  67. Range <<= 8;
  68. }
  69. return 1;
  70. }
  71. }
  72. public static void InitBitModels(short []probs)
  73. {
  74. for (int i = 0; i < probs.length; i++)
  75. probs[i] = (kBitModelTotal >>> 1);
  76. }
  77. }