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