Home | History | Annotate | Download | only in rangecoder
      1 /*
      2  * RangeDecoder
      3  *
      4  * Authors: Lasse Collin <lasse.collin (at) 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.DataInputStream;
     14 import java.io.IOException;
     15 
     16 public abstract class RangeDecoder extends RangeCoder {
     17     int range = 0;
     18     int code = 0;
     19 
     20     public abstract void normalize() throws IOException;
     21 
     22     public int decodeBit(short[] probs, int index) throws IOException {
     23         normalize();
     24 
     25         int prob = probs[index];
     26         int bound = (range >>> BIT_MODEL_TOTAL_BITS) * prob;
     27         int bit;
     28 
     29         // Compare code and bound as if they were unsigned 32-bit integers.
     30         if ((code ^ 0x80000000) < (bound ^ 0x80000000)) {
     31             range = bound;
     32             probs[index] = (short)(
     33                     prob + ((BIT_MODEL_TOTAL - prob) >>> MOVE_BITS));
     34             bit = 0;
     35         } else {
     36             range -= bound;
     37             code -= bound;
     38             probs[index] = (short)(prob - (prob >>> MOVE_BITS));
     39             bit = 1;
     40         }
     41 
     42         return bit;
     43     }
     44 
     45     public int decodeBitTree(short[] probs) throws IOException {
     46         int symbol = 1;
     47 
     48         do {
     49             symbol = (symbol << 1) | decodeBit(probs, symbol);
     50         } while (symbol < probs.length);
     51 
     52         return symbol - probs.length;
     53     }
     54 
     55     public int decodeReverseBitTree(short[] probs) throws IOException {
     56         int symbol = 1;
     57         int i = 0;
     58         int result = 0;
     59 
     60         do {
     61             int bit = decodeBit(probs, symbol);
     62             symbol = (symbol << 1) | bit;
     63             result |= bit << i++;
     64         } while (symbol < probs.length);
     65 
     66         return result;
     67     }
     68 
     69     public int decodeDirectBits(int count) throws IOException {
     70         int result = 0;
     71 
     72         do {
     73             normalize();
     74 
     75             range >>>= 1;
     76             int t = (code - range) >>> 31;
     77             code -= range & (t - 1);
     78             result = (result << 1) | (1 - t);
     79         } while (--count != 0);
     80 
     81         return result;
     82     }
     83 }
     84