diff options
Diffstat (limited to 'org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/ppm/RangeCoder.java')
-rwxr-xr-x | org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/ppm/RangeCoder.java | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/ppm/RangeCoder.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/ppm/RangeCoder.java new file mode 100755 index 0000000..57b0013 --- /dev/null +++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/junrar/unpack/ppm/RangeCoder.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2007 innoSysTec (R) GmbH, Germany. All rights reserved. + * Original author: Edmund Wagner + * Creation date: 31.05.2007 + * + * Source: $HeadURL$ + * Last changed: $LastChangedDate$ + * + * the unrar licence applies to all junrar source and binary distributions + * you are not allowed to use this source to re-create the RAR compression algorithm + * + * Here some html entities which can be used for escaping javadoc tags: + * "&": "&" or "&" + * "<": "<" or "<" + * ">": ">" or ">" + * "@": "@" + */ +package org.fox.ttcomics2.junrar.unpack.ppm; + +import org.fox.ttcomics2.junrar.exception.RarException; +import org.fox.ttcomics2.junrar.unpack.Unpack; + +import java.io.IOException; + + +public class RangeCoder { + public static final int TOP = 1 << 24; + + public static final int BOT = 1 << 15; + + private static final long uintMask = 0xFFFFffffL; + private final SubRange subRange = new SubRange(); + // uint low, code, range; + private long low, code, range; + private Unpack unpackRead; + + public SubRange getSubRange() { + return subRange; + } + + public void initDecoder(Unpack unpackRead) throws IOException, RarException { + this.unpackRead = unpackRead; + + low = code = 0L; + range = 0xFFFFffffL; + for (int i = 0; i < 4; i++) { + code = ((code << 8) | getChar()) & uintMask; + } + } + + public int getCurrentCount() { + range = (range / subRange.getScale()) & uintMask; + return (int) ((code - low) / (range)); + } + + public long getCurrentShiftCount(int SHIFT) { + range = range >>> SHIFT; + return ((code - low) / (range)) & uintMask; + } + + public void decode() { + low = (low + (range * subRange.getLowCount())) & uintMask; + range = (range * (subRange.getHighCount() - subRange.getLowCount())) & uintMask; + } + + private int getChar() throws IOException, RarException { + return (unpackRead.getChar()); + } + + public void ariDecNormalize() throws IOException, RarException { +// while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true)) +// { +// code = ((code << 8) | unpackRead.getChar()&0xff)&uintMask; +// range = (range << 8)&uintMask; +// low = (low << 8)&uintMask; +// } + + // Rewrote for clarity + boolean c2 = false; + while ((low ^ (low + range)) < TOP || (c2 = range < BOT)) { + if (c2) { + range = (-low & (BOT - 1)) & uintMask; + c2 = false; + } + code = ((code << 8) | getChar()) & uintMask; + range = (range << 8) & uintMask; + low = (low << 8) & uintMask; + } + } + + // Debug + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("RangeCoder["); + buffer.append("\n low="); + buffer.append(low); + buffer.append("\n code="); + buffer.append(code); + buffer.append("\n range="); + buffer.append(range); + buffer.append("\n subrange="); + buffer.append(subRange); + buffer.append("]"); + return buffer.toString(); + } + + public static class SubRange { + // uint LowCount, HighCount, scale; + private long lowCount, highCount, scale; + + public long getHighCount() { + return highCount; + } + + public void setHighCount(long highCount) { + this.highCount = highCount & uintMask; + } + + public long getLowCount() { + return lowCount & uintMask; + } + + public void setLowCount(long lowCount) { + this.lowCount = lowCount & uintMask; + } + + public long getScale() { + return scale; + } + + public void setScale(long scale) { + this.scale = scale & uintMask; + } + + public void incScale(int dScale) { + setScale(getScale() + dScale); + } + + // Debug + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("SubRange["); + buffer.append("\n lowCount="); + buffer.append(lowCount); + buffer.append("\n highCount="); + buffer.append(highCount); + buffer.append("\n scale="); + buffer.append(scale); + buffer.append("]"); + return buffer.toString(); + } + } +} |