package org.jcodec.codecs.common.biari; import java.io.IOException; import java.io.InputStream; /** * This class is part of JCodec ( www.jcodec.org ) * This software is distributed under FreeBSD License * * Binary ariphmetic decoder * * Half-way to MQ Coder * * @author The JCodec project */ public class MQDecoder { // 24bit 'C' register private int range; // 16bit 'A' register private int value; // 't' variable private int availableBits; // 'T' variable private int lastByte; // 'L' variable private int decodedBytes; private InputStream is; public MQDecoder(InputStream is) throws IOException { this.is = is; range = 0x8000; value = 0; fetchByte(); value <<= 8; fetchByte(); value <<= (availableBits - 1); availableBits = 1; } public int decode(Context cm) throws IOException { int rangeLps = MQConst.pLps[cm.getState()]; int decoded; if (value > rangeLps) { // MPS range -= rangeLps; value -= rangeLps; if (range < 0x8000) { while (range < 0x8000) renormalize(); cm.setState(MQConst.transitMPS[cm.getState()]); } decoded = cm.getMps(); } else { // LPS range = rangeLps; while (range < 0x8000) renormalize(); if (MQConst.mpsSwitch[cm.getState()] != 0) cm.setMps(1 - cm.getMps()); cm.setState(MQConst.transitLPS[cm.getState()]); decoded = 1 - cm.getMps(); } return decoded; } private void fetchByte() throws IOException { availableBits = 8; if (decodedBytes > 0 && lastByte == 0xff) { availableBits = 7; } lastByte = is.read(); int shiftCarry = 8 - availableBits; value += (lastByte << shiftCarry); ++decodedBytes; } private void renormalize() throws IOException { value <<= 1; range <<= 1; range &= 0xffff; --availableBits; if (availableBits == 0) fetchByte(); } }