| 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.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 | }
|
|---|