/* * RangeDecoder * * Authors: Lasse Collin <lasse.collin@tukaani.org> * Igor Pavlov <http://7-zip.org/> * * This file has been put into the public domain. * You can do whatever you want with this file. */ package org.tukaani.xz.rangecoder; import java.io.DataInputStream; import java.io.IOException; public abstract class RangeDecoder extends RangeCoder { int range = 0; int code = 0; public abstract void normalize() throws IOException; public int decodeBit(short[] probs, int index) throws IOException { normalize(); int prob = probs[index]; int bound = (range >>> BIT_MODEL_TOTAL_BITS) * prob; int bit; // Compare code and bound as if they were unsigned 32-bit integers. if ((code ^ 0x80000000) < (bound ^ 0x80000000)) { range = bound; probs[index] = (short)( prob + ((BIT_MODEL_TOTAL - prob) >>> MOVE_BITS)); bit = 0; } else { range -= bound; code -= bound; probs[index] = (short)(prob - (prob >>> MOVE_BITS)); bit = 1; } return bit; } public int decodeBitTree(short[] probs) throws IOException { int symbol = 1; do { symbol = (symbol << 1) | decodeBit(probs, symbol); } while (symbol < probs.length); return symbol - probs.length; } public int decodeReverseBitTree(short[] probs) throws IOException { int symbol = 1; int i = 0; int result = 0; do { int bit = decodeBit(probs, symbol); symbol = (symbol << 1) | bit; result |= bit << i++; } while (symbol < probs.length); return result; } public int decodeDirectBits(int count) throws IOException { int result = 0; do { normalize(); range >>>= 1; int t = (code - range) >>> 31; code -= range & (t - 1); result = (result << 1) | (1 - t); } while (--count != 0); return result; } }