43 |
private static final int DNUM = 1; |
private static final int DNUM = 1; |
44 |
private static final int BLNUM = 2; |
private static final int BLNUM = 2; |
45 |
private static final int BLLENS = 3; |
private static final int BLLENS = 3; |
46 |
private static final int LLENS = 4; |
private static final int LENS = 4; |
47 |
private static final int DLENS = 5; |
private static final int REPS = 5; |
48 |
private static final int LREPS = 6; |
|
49 |
private static final int DREPS = 7; |
private static final int repMin[] = { 3, 3, 11 }; |
50 |
private static final int FINISH = 8; |
private static final int repBits[] = { 2, 3, 7 }; |
51 |
|
|
52 |
|
|
53 |
private byte[] blLens; |
private byte[] blLens; |
54 |
private byte[] litlenLens; |
private byte[] litdistLens; |
|
private byte[] distLens; |
|
55 |
|
|
56 |
private InflaterHuffmanTree blTree; |
private InflaterHuffmanTree blTree; |
57 |
|
|
58 |
private int mode; |
private int mode; |
59 |
private int lnum, dnum, blnum; |
private int lnum, dnum, blnum, num; |
60 |
private int repBits; |
private int repSymbol; |
61 |
private byte repeatedLen; |
private byte lastLen; |
62 |
private int ptr; |
private int ptr; |
63 |
|
|
64 |
private static final int[] BL_ORDER = |
private static final int[] BL_ORDER = |
81 |
return false; |
return false; |
82 |
lnum += 257; |
lnum += 257; |
83 |
input.dropBits(5); |
input.dropBits(5); |
|
litlenLens = new byte[lnum]; |
|
84 |
// System.err.println("LNUM: "+lnum); |
// System.err.println("LNUM: "+lnum); |
85 |
mode = DNUM; |
mode = DNUM; |
86 |
/* fall through */ |
/* fall through */ |
90 |
return false; |
return false; |
91 |
dnum++; |
dnum++; |
92 |
input.dropBits(5); |
input.dropBits(5); |
|
distLens = new byte[dnum]; |
|
93 |
// System.err.println("DNUM: "+dnum); |
// System.err.println("DNUM: "+dnum); |
94 |
|
num = lnum+dnum; |
95 |
|
litdistLens = new byte[num]; |
96 |
mode = BLNUM; |
mode = BLNUM; |
97 |
/* fall through */ |
/* fall through */ |
98 |
case BLNUM: |
case BLNUM: |
120 |
blTree = new InflaterHuffmanTree(blLens); |
blTree = new InflaterHuffmanTree(blLens); |
121 |
blLens = null; |
blLens = null; |
122 |
ptr = 0; |
ptr = 0; |
123 |
mode = LLENS; |
mode = LENS; |
|
/* fall through */ |
|
|
case LLENS: |
|
|
while (ptr < lnum) |
|
|
{ |
|
|
int symbol = blTree.getSymbol(input); |
|
|
if (symbol < 0) |
|
|
return false; |
|
|
switch (symbol) |
|
|
{ |
|
|
default: |
|
|
// System.err.println("litlenLens["+ptr+"]: "+symbol); |
|
|
litlenLens[ptr++] = (byte) symbol; |
|
|
break; |
|
|
case 16: /* repeat last len 3-6 times */ |
|
|
if (ptr == 0) |
|
|
throw new DataFormatException |
|
|
("Repeating, but no prev len"); |
|
|
// System.err.println("litlenLens["+ptr+"]: repeat"); |
|
|
repeatedLen = litlenLens[ptr-1]; |
|
|
repBits = 2; |
|
|
for (int i = 3; i-- > 0; ) |
|
|
{ |
|
|
if (ptr >= lnum) |
|
|
throw new DataFormatException(); |
|
|
litlenLens[ptr++] = repeatedLen; |
|
|
} |
|
|
mode = LREPS; |
|
|
continue decode_loop; |
|
|
case 17: /* repeat zero 3-10 times */ |
|
|
// System.err.println("litlenLens["+ptr+"]: zero repeat"); |
|
|
repeatedLen = 0; |
|
|
repBits = 3; |
|
|
for (int i = 3; i-- > 0; ) |
|
|
{ |
|
|
if (ptr >= lnum) |
|
|
throw new DataFormatException(); |
|
|
litlenLens[ptr++] = repeatedLen; |
|
|
} |
|
|
mode = LREPS; |
|
|
continue decode_loop; |
|
|
case 18: /* repeat zero 11-138 times */ |
|
|
// System.err.println("litlenLens["+ptr+"]: zero repeat"); |
|
|
repeatedLen = 0; |
|
|
repBits = 7; |
|
|
for (int i = 11; i-- > 0; ) |
|
|
{ |
|
|
if (ptr >= lnum) |
|
|
throw new DataFormatException(); |
|
|
litlenLens[ptr++] = repeatedLen; |
|
|
} |
|
|
mode = LREPS; |
|
|
continue decode_loop; |
|
|
} |
|
|
} |
|
|
ptr = 0; |
|
|
mode = DLENS; |
|
124 |
/* fall through */ |
/* fall through */ |
125 |
case DLENS: |
case LENS: |
|
while (ptr < dnum) |
|
|
{ |
|
|
int symbol = blTree.getSymbol(input); |
|
|
if (symbol < 0) |
|
|
return false; |
|
|
switch (symbol) |
|
|
{ |
|
|
default: |
|
|
distLens[ptr++] = (byte) symbol; |
|
|
// System.err.println("distLens["+ptr+"]: "+symbol); |
|
|
break; |
|
|
case 16: /* repeat last len 3-6 times */ |
|
|
if (ptr == 0) |
|
|
throw new DataFormatException |
|
|
("Repeating, but no prev len"); |
|
|
// System.err.println("distLens["+ptr+"]: repeat"); |
|
|
repeatedLen = distLens[ptr-1]; |
|
|
repBits = 2; |
|
|
for (int i = 3; i-- > 0; ) |
|
|
{ |
|
|
if (ptr >= dnum) |
|
|
throw new DataFormatException(); |
|
|
distLens[ptr++] = repeatedLen; |
|
|
} |
|
|
mode = DREPS; |
|
|
continue decode_loop; |
|
|
case 17: /* repeat zero 3-10 times */ |
|
|
// System.err.println("distLens["+ptr+"]: repeat zero"); |
|
|
repeatedLen = 0; |
|
|
repBits = 3; |
|
|
for (int i = 3; i-- > 0; ) |
|
|
{ |
|
|
if (ptr >= dnum) |
|
|
throw new DataFormatException(); |
|
|
distLens[ptr++] = repeatedLen; |
|
|
} |
|
|
mode = DREPS; |
|
|
continue decode_loop; |
|
|
case 18: /* repeat zero 11-138 times */ |
|
|
// System.err.println("distLens["+ptr+"]: repeat zero"); |
|
|
repeatedLen = 0; |
|
|
repBits = 7; |
|
|
for (int i = 11; i-- > 0; ) |
|
|
{ |
|
|
if (ptr >= dnum) |
|
|
throw new DataFormatException(); |
|
|
distLens[ptr++] = repeatedLen; |
|
|
} |
|
|
mode = DREPS; |
|
|
continue decode_loop; |
|
|
} |
|
|
} |
|
|
mode = FINISH; |
|
|
return true; |
|
|
case LREPS: |
|
126 |
{ |
{ |
127 |
int count = input.peekBits(repBits); |
int symbol; |
128 |
if (count < 0) |
while (((symbol = blTree.getSymbol(input)) & ~15) == 0) |
129 |
|
{ |
130 |
|
/* Normal case: symbol in [0..15] */ |
131 |
|
|
132 |
|
// System.err.println("litdistLens["+ptr+"]: "+symbol); |
133 |
|
litdistLens[ptr++] = lastLen = (byte) symbol; |
134 |
|
|
135 |
|
if (ptr == num) |
136 |
|
{ |
137 |
|
/* Finished */ |
138 |
|
return true; |
139 |
|
} |
140 |
|
} |
141 |
|
|
142 |
|
/* need more input ? */ |
143 |
|
if (symbol < 0) |
144 |
return false; |
return false; |
145 |
input.dropBits(repBits); |
|
146 |
// System.err.println("litlenLens repeat: "+repBits); |
/* otherwise repeat code */ |
147 |
while (count-- > 0) |
if (symbol >= 17) |
148 |
|
{ |
149 |
|
/* repeat zero */ |
150 |
|
// System.err.println("repeating zero"); |
151 |
|
lastLen = 0; |
152 |
|
} |
153 |
|
else |
154 |
{ |
{ |
155 |
if (ptr >= lnum) |
if (ptr == 0) |
156 |
throw new DataFormatException(); |
throw new DataFormatException(); |
|
litlenLens[ptr++] = repeatedLen; |
|
157 |
} |
} |
158 |
|
repSymbol = symbol-16; |
159 |
|
mode = REPS; |
160 |
} |
} |
161 |
mode = LLENS; |
/* fall through */ |
162 |
continue decode_loop; |
|
163 |
case DREPS: |
case REPS: |
164 |
{ |
{ |
165 |
int count = input.peekBits(repBits); |
int bits = repBits[repSymbol]; |
166 |
|
int count = input.peekBits(bits); |
167 |
if (count < 0) |
if (count < 0) |
168 |
return false; |
return false; |
169 |
input.dropBits(repBits); |
input.dropBits(bits); |
170 |
|
count += repMin[repSymbol]; |
171 |
|
// System.err.println("litdistLens repeated: "+count); |
172 |
|
|
173 |
|
if (ptr + count > num) |
174 |
|
throw new DataFormatException(); |
175 |
while (count-- > 0) |
while (count-- > 0) |
176 |
|
litdistLens[ptr++] = lastLen; |
177 |
|
|
178 |
|
if (ptr == num) |
179 |
{ |
{ |
180 |
if (ptr >= dnum) |
/* Finished */ |
181 |
throw new DataFormatException(); |
return true; |
|
distLens[ptr++] = repeatedLen; |
|
182 |
} |
} |
183 |
} |
} |
184 |
mode = DLENS; |
mode = LENS; |
185 |
continue decode_loop; |
continue decode_loop; |
186 |
} |
} |
187 |
} |
} |
189 |
|
|
190 |
public InflaterHuffmanTree buildLitLenTree() throws DataFormatException |
public InflaterHuffmanTree buildLitLenTree() throws DataFormatException |
191 |
{ |
{ |
192 |
|
byte[] litlenLens = new byte[lnum]; |
193 |
|
System.arraycopy(litdistLens, 0, litlenLens, 0, lnum); |
194 |
return new InflaterHuffmanTree(litlenLens); |
return new InflaterHuffmanTree(litlenLens); |
195 |
} |
} |
196 |
|
|
197 |
public InflaterHuffmanTree buildDistTree() throws DataFormatException |
public InflaterHuffmanTree buildDistTree() throws DataFormatException |
198 |
{ |
{ |
199 |
|
byte[] distLens = new byte[dnum]; |
200 |
|
System.arraycopy(litdistLens, lnum, distLens, 0, dnum); |
201 |
return new InflaterHuffmanTree(distLens); |
return new InflaterHuffmanTree(distLens); |
202 |
} |
} |
203 |
} |
} |