001: package SevenZip.Compression.RangeCoder;
002:
003: import java.io.IOException;
004:
005: public class Encoder {
006: static final int kTopMask = ~((1 << 24) - 1);
007:
008: static final int kNumBitModelTotalBits = 11;
009: static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
010: static final int kNumMoveBits = 5;
011:
012: java.io.OutputStream Stream;
013:
014: long Low;
015: int Range;
016: int _cacheSize;
017: int _cache;
018:
019: long _position;
020:
021: public void SetStream(java.io.OutputStream stream) {
022: Stream = stream;
023: }
024:
025: public void ReleaseStream() {
026: Stream = null;
027: }
028:
029: public void Init() {
030: _position = 0;
031: Low = 0;
032: Range = -1;
033: _cacheSize = 1;
034: _cache = 0;
035: }
036:
037: public void FlushData() throws IOException {
038: for (int i = 0; i < 5; i++)
039: ShiftLow();
040: }
041:
042: public void FlushStream() throws IOException {
043: Stream.flush();
044: }
045:
046: public void ShiftLow() throws IOException {
047: int LowHi = (int) (Low >>> 32);
048: if (LowHi != 0 || Low < 0xFF000000L) {
049: _position += _cacheSize;
050: int temp = _cache;
051: do {
052: Stream.write(temp + LowHi);
053: temp = 0xFF;
054: } while (--_cacheSize != 0);
055: _cache = (((int) Low) >>> 24);
056: }
057: _cacheSize++;
058: Low = (Low & 0xFFFFFF) << 8;
059: }
060:
061: public void EncodeDirectBits(int v, int numTotalBits)
062: throws IOException {
063: for (int i = numTotalBits - 1; i >= 0; i--) {
064: Range >>>= 1;
065: if (((v >>> i) & 1) == 1)
066: Low += Range;
067: if ((Range & Encoder.kTopMask) == 0) {
068: Range <<= 8;
069: ShiftLow();
070: }
071: }
072: }
073:
074: public long GetProcessedSizeAdd() {
075: return _cacheSize + _position + 4;
076: }
077:
078: static final int kNumMoveReducingBits = 2;
079: public static final int kNumBitPriceShiftBits = 6;
080:
081: public static void InitBitModels(short[] probs) {
082: for (int i = 0; i < probs.length; i++)
083: probs[i] = (kBitModelTotal >>> 1);
084: }
085:
086: public void Encode(short[] probs, int index, int symbol)
087: throws IOException {
088: int prob = probs[index];
089: int newBound = (Range >>> kNumBitModelTotalBits) * prob;
090: if (symbol == 0) {
091: Range = newBound;
092: probs[index] = (short) (prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
093: } else {
094: Low += (newBound & 0xFFFFFFFFL);
095: Range -= newBound;
096: probs[index] = (short) (prob - ((prob) >>> kNumMoveBits));
097: }
098: if ((Range & kTopMask) == 0) {
099: Range <<= 8;
100: ShiftLow();
101: }
102: }
103:
104: private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];
105:
106: static {
107: int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
108: for (int i = kNumBits - 1; i >= 0; i--) {
109: int start = 1 << (kNumBits - i - 1);
110: int end = 1 << (kNumBits - i);
111: for (int j = start; j < end; j++)
112: ProbPrices[j] = (i << kNumBitPriceShiftBits)
113: + (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits
114: - i - 1));
115: }
116: }
117:
118: static public int GetPrice(int Prob, int symbol) {
119: return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
120: }
121:
122: static public int GetPrice0(int Prob) {
123: return ProbPrices[Prob >>> kNumMoveReducingBits];
124: }
125:
126: static public int GetPrice1(int Prob) {
127: return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits];
128: }
129: }
|