source: other-projects/trunk/7z-ant/src/LZMA/CRangeDecoder.java@ 17387

Last change on this file since 17387 was 17387, checked in by oranfry, 16 years ago

Modified ant task which works with the updated 7zip API

File size: 4.6 KB
Line 
1package LZMA;
2
3import java.io.InputStream;
4import java.io.IOException;
5
6class CRangeDecoder {
7
8 final static int kNumTopBits = 24;
9 final static int kTopValue = (1 << kNumTopBits);
10 final static int kTopValueMask = ~(kTopValue-1);
11
12 final static int kNumBitModelTotalBits = 11;
13 final static int kBitModelTotal = (1 << kNumBitModelTotalBits);
14 final static int kNumMoveBits = 5;
15
16 InputStream inStream;
17
18 int Range;
19 int Code;
20
21 byte buffer[];
22 int buffer_size;
23 int buffer_ind;
24
25 CRangeDecoder( InputStream iStream ) throws IOException {
26 this.buffer = new byte[1<<14];
27 this.inStream = iStream;
28 this.Code = 0;
29 this.Range = -1; // 0xFFFFFFFFL;
30 for(int i = 0; i < 5; i++)
31 this.Code = (this.Code << 8) | (Readbyte());
32 }
33
34 int Readbyte() throws IOException {
35 if (buffer_size == buffer_ind) {
36 buffer_size = inStream.read(buffer);
37 buffer_ind = 0;
38
39 if (buffer_size < 1)
40 throw new LzmaException ("LZMA : Data Error");
41 }
42 return buffer[buffer_ind++] & 0xFF;
43 }
44
45 int DecodeDirectBits(int numTotalBits) throws IOException {
46 int result = 0;
47 for (int i = numTotalBits; i > 0; i--) {
48 Range >>>= 1;
49 int t = ((Code - Range) >>> 31);
50 Code -= Range & (t - 1);
51 result = (result << 1) | (1 - t);
52
53 if (Range < kTopValue) // because of "Range >>>= 1", 0 <= Range <= 0x7FFFFFFF
54 {
55 Code = (Code << 8) | Readbyte();
56 Range <<= 8;
57 }
58 }
59 return result;
60 }
61
62 int BitDecode(int prob[],int index) throws IOException {
63 int newBound = (this.Range >>> kNumBitModelTotalBits) * prob[index];
64 if ((this.Code & 0xFFFFFFFFL) < (newBound & 0xFFFFFFFFL)) // unsigned comparison
65 {
66 this.Range = newBound;
67 prob[index] += (kBitModelTotal - prob[index]) >>> kNumMoveBits;
68 // if ((this.Range & 0xFFFFFFFFL) < Decoder.kTopValue)
69 if ((this.Range & kTopValueMask) == 0) {
70 this.Code = (this.Code << 8) | Readbyte();
71 this.Range <<= 8;
72 }
73 return 0;
74 } else {
75 this.Range -= newBound;
76 this.Code -= newBound;
77 prob[index] -= (prob[index]) >>> kNumMoveBits;
78 // if ((this.Range & 0xFFFFFFFFL) < Decoder.kTopValue)
79 if ((this.Range & kTopValueMask) == 0) {
80 this.Code = (this.Code << 8) | this.Readbyte();
81 this.Range <<= 8;
82 }
83 return 1;
84 }
85 }
86
87 int BitTreeDecode(int probs [], int index , int numLevels) throws IOException {
88 int mi = 1;
89 for(int i = numLevels; i > 0; i--) {
90 mi = (mi + mi) + BitDecode(probs, index + mi);
91 }
92 return mi - (1 << numLevels);
93 }
94
95 int ReverseBitTreeDecode(int probs[] ,int index, int numLevels) throws IOException {
96 int mi = 1;
97 int symbol = 0;
98
99 for(int i = 0; i < numLevels; i++) {
100 int bit = BitDecode(probs, index + mi);
101 mi = mi + mi + bit;
102 symbol |= (bit << i);
103 }
104 return symbol;
105 }
106
107 byte LzmaLiteralDecode(int probs[],int index) throws IOException {
108 int symbol = 1;
109 do {
110 symbol = (symbol + symbol) | BitDecode(probs, index + symbol);
111 } while (symbol < 0x100);
112
113 return (byte)symbol;
114 }
115
116 byte LzmaLiteralDecodeMatch(int probs [], int index, byte matchbyte) throws IOException {
117 int symbol = 1;
118 do {
119 int matchBit = (matchbyte >> 7) & 1;
120 matchbyte <<= 1;
121 int bit = BitDecode(probs , index + ((1 + matchBit) << 8) + symbol);
122 symbol = (symbol << 1) | bit;
123
124 if (matchBit != bit) {
125 while (symbol < 0x100) {
126 symbol = (symbol + symbol) | BitDecode(probs , index + symbol);
127 }
128 break;
129 }
130 } while (symbol < 0x100);
131
132 return (byte)symbol;
133 }
134
135 final static int kNumPosBitsMax = 4;
136 final static int kNumPosStatesMax = (1 << kNumPosBitsMax);
137
138 final static int kLenNumLowBits = 3;
139 final static int kLenNumLowSymbols = (1 << kLenNumLowBits);
140 final static int kLenNumMidBits = 3;
141 final static int kLenNumMidSymbols = (1 << kLenNumMidBits);
142 final static int kLenNumHighBits = 8;
143 final static int kLenNumHighSymbols = (1 << kLenNumHighBits);
144
145 final static int LenChoice = 0;
146 final static int LenChoice2 = (LenChoice + 1);
147 final static int LenLow = (LenChoice2 + 1);
148 final static int LenMid = (LenLow + (kNumPosStatesMax << kLenNumLowBits));
149 final static int LenHigh = (LenMid + (kNumPosStatesMax << kLenNumMidBits));
150 final static int kNumLenProbs = (LenHigh + kLenNumHighSymbols);
151
152 int LzmaLenDecode(int probs[], int index, int posState) throws IOException {
153 if(BitDecode(probs, index + LenChoice) == 0)
154 return BitTreeDecode(probs, index + LenLow +
155 (posState << kLenNumLowBits), kLenNumLowBits);
156
157 if(BitDecode(probs, index + LenChoice2) == 0)
158 return kLenNumLowSymbols + BitTreeDecode(probs, index + LenMid +
159 (posState << kLenNumMidBits), kLenNumMidBits);
160
161 return kLenNumLowSymbols + kLenNumMidSymbols +
162 BitTreeDecode(probs, index + LenHigh, kLenNumHighBits);
163 }
164}
165
Note: See TracBrowser for help on using the repository browser.