1 /* 2 * RangeDecoder 3 * 4 * Authors: Lasse Collin <lasse.collin@tukaani.org> 5 * Igor Pavlov <http://7-zip.org/> 6 * 7 * This file has been put into the public domain. 8 * You can do whatever you want with this file. 9 */ 10 11 package org.tukaani.xz.rangecoder; 12 13 import java.io.IOException; 14 15 public abstract class RangeDecoder extends RangeCoder { 16 int range = 0; 17 int code = 0; 18 normalize()19 public abstract void normalize() throws IOException; 20 decodeBit(short[] probs, int index)21 public int decodeBit(short[] probs, int index) throws IOException { 22 normalize(); 23 24 int prob = probs[index]; 25 int bound = (range >>> BIT_MODEL_TOTAL_BITS) * prob; 26 int bit; 27 28 // Compare code and bound as if they were unsigned 32-bit integers. 29 if ((code ^ 0x80000000) < (bound ^ 0x80000000)) { 30 range = bound; 31 probs[index] = (short)( 32 prob + ((BIT_MODEL_TOTAL - prob) >>> MOVE_BITS)); 33 bit = 0; 34 } else { 35 range -= bound; 36 code -= bound; 37 probs[index] = (short)(prob - (prob >>> MOVE_BITS)); 38 bit = 1; 39 } 40 41 return bit; 42 } 43 decodeBitTree(short[] probs)44 public int decodeBitTree(short[] probs) throws IOException { 45 int symbol = 1; 46 47 do { 48 symbol = (symbol << 1) | decodeBit(probs, symbol); 49 } while (symbol < probs.length); 50 51 return symbol - probs.length; 52 } 53 decodeReverseBitTree(short[] probs)54 public int decodeReverseBitTree(short[] probs) throws IOException { 55 int symbol = 1; 56 int i = 0; 57 int result = 0; 58 59 do { 60 int bit = decodeBit(probs, symbol); 61 symbol = (symbol << 1) | bit; 62 result |= bit << i++; 63 } while (symbol < probs.length); 64 65 return result; 66 } 67 decodeDirectBits(int count)68 public int decodeDirectBits(int count) throws IOException { 69 int result = 0; 70 71 do { 72 normalize(); 73 74 range >>>= 1; 75 int t = (code - range) >>> 31; 76 code -= range & (t - 1); 77 result = (result << 1) | (1 - t); 78 } while (--count != 0); 79 80 return result; 81 } 82 } 83