0
|
1 /* -*-mode:java; c-basic-offset:2; -*- */
|
|
2 /*
|
|
3 Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
|
|
4
|
|
5 Redistribution and use in source and binary forms, with or without
|
|
6 modification, are permitted provided that the following conditions are met:
|
|
7
|
|
8 1. Redistributions of source code must retain the above copyright notice,
|
|
9 this list of conditions and the following disclaimer.
|
|
10
|
|
11 2. Redistributions in binary form must reproduce the above copyright
|
|
12 notice, this list of conditions and the following disclaimer in
|
|
13 the documentation and/or other materials provided with the distribution.
|
|
14
|
|
15 3. The names of the authors may not be used to endorse or promote products
|
|
16 derived from this software without specific prior written permission.
|
|
17
|
|
18 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
19 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
20 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
21 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
27 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28 */
|
|
29 /*
|
|
30 * This program is based on zlib-1.1.3, so all credit should go authors
|
|
31 * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
|
|
32 * and contributors of zlib.
|
|
33 */
|
|
34
|
|
35 package com.jcraft.jzlib;
|
|
36
|
|
37 final class Inflate {
|
|
38
|
|
39 static final private int MAX_WBITS = 15; // 32K LZ77 window
|
|
40
|
|
41 // preset dictionary flag in zlib header
|
|
42 static final private int PRESET_DICT = 0x20;
|
|
43
|
|
44 static final int Z_NO_FLUSH = 0;
|
|
45 static final int Z_PARTIAL_FLUSH = 1;
|
|
46 static final int Z_SYNC_FLUSH = 2;
|
|
47 static final int Z_FULL_FLUSH = 3;
|
|
48 static final int Z_FINISH = 4;
|
|
49
|
|
50 static final private int Z_DEFLATED = 8;
|
|
51
|
|
52 static final private int Z_OK = 0;
|
|
53 static final private int Z_STREAM_END = 1;
|
|
54 static final private int Z_NEED_DICT = 2;
|
|
55 static final private int Z_ERRNO = -1;
|
|
56 static final private int Z_STREAM_ERROR = -2;
|
|
57 static final private int Z_DATA_ERROR = -3;
|
|
58 static final private int Z_MEM_ERROR = -4;
|
|
59 static final private int Z_BUF_ERROR = -5;
|
|
60 static final private int Z_VERSION_ERROR = -6;
|
|
61
|
|
62 static final private int METHOD = 0; // waiting for method byte
|
|
63 static final private int FLAG = 1; // waiting for flag byte
|
|
64 static final private int DICT4 = 2; // four dictionary check bytes to go
|
|
65 static final private int DICT3 = 3; // three dictionary check bytes to go
|
|
66 static final private int DICT2 = 4; // two dictionary check bytes to go
|
|
67 static final private int DICT1 = 5; // one dictionary check byte to go
|
|
68 static final private int DICT0 = 6; // waiting for inflateSetDictionary
|
|
69 static final private int BLOCKS = 7; // decompressing blocks
|
|
70 static final private int CHECK4 = 8; // four check bytes to go
|
|
71 static final private int CHECK3 = 9; // three check bytes to go
|
|
72 static final private int CHECK2 = 10; // two check bytes to go
|
|
73 static final private int CHECK1 = 11; // one check byte to go
|
|
74 static final private int DONE = 12; // finished check, done
|
|
75 static final private int BAD = 13; // got an error--stay here
|
|
76
|
|
77 int mode; // current inflate mode
|
|
78
|
|
79 // mode dependent information
|
|
80 int method; // if FLAGS, method byte
|
|
81
|
|
82 // if CHECK, check values to compare
|
|
83 long[] was = new long[1] ; // computed check value
|
|
84 long need; // stream check value
|
|
85
|
|
86 // if BAD, inflateSync's marker bytes count
|
|
87 int marker;
|
|
88
|
|
89 // mode independent information
|
|
90 int nowrap; // flag for no wrapper
|
|
91 int wbits; // log2(window size) (8..15, defaults to 15)
|
|
92
|
|
93 InfBlocks blocks; // current inflate_blocks state
|
|
94
|
|
95 int inflateReset(ZStream z) {
|
|
96 if (z == null || z.istate == null) return Z_STREAM_ERROR;
|
|
97
|
|
98 z.total_in = z.total_out = 0;
|
|
99 z.msg = null;
|
|
100 z.istate.mode = z.istate.nowrap != 0 ? BLOCKS : METHOD;
|
|
101 z.istate.blocks.reset(z, null);
|
|
102 return Z_OK;
|
|
103 }
|
|
104
|
|
105 int inflateEnd(ZStream z) {
|
|
106 if (blocks != null)
|
|
107 blocks.free(z);
|
|
108
|
|
109 blocks = null;
|
|
110 // ZFREE(z, z->state);
|
|
111 return Z_OK;
|
|
112 }
|
|
113
|
|
114 int inflateInit(ZStream z, int w) {
|
|
115 z.msg = null;
|
|
116 blocks = null;
|
|
117 // handle undocumented nowrap option (no zlib header or check)
|
|
118 nowrap = 0;
|
|
119
|
|
120 if (w < 0) {
|
|
121 w = - w;
|
|
122 nowrap = 1;
|
|
123 }
|
|
124
|
|
125 // set window size
|
|
126 if (w < 8 || w > 15) {
|
|
127 inflateEnd(z);
|
|
128 return Z_STREAM_ERROR;
|
|
129 }
|
|
130
|
|
131 wbits = w;
|
|
132 z.istate.blocks = new InfBlocks(z,
|
|
133 z.istate.nowrap != 0 ? null : this,
|
|
134 1 << w);
|
|
135 // reset state
|
|
136 inflateReset(z);
|
|
137 return Z_OK;
|
|
138 }
|
|
139
|
|
140 int inflate(ZStream z, int f) {
|
|
141 int r;
|
|
142 int b;
|
|
143
|
|
144 if (z == null || z.istate == null || z.next_in == null)
|
|
145 return Z_STREAM_ERROR;
|
|
146
|
|
147 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
|
|
148 r = Z_BUF_ERROR;
|
|
149
|
|
150 while (true) {
|
|
151 //System.out.println("mode: "+z.istate.mode);
|
|
152 switch (z.istate.mode) {
|
|
153 case METHOD:
|
|
154 if (z.avail_in == 0)return r; r = f;
|
|
155
|
|
156 z.avail_in--; z.total_in++;
|
|
157
|
|
158 if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != Z_DEFLATED) {
|
|
159 z.istate.mode = BAD;
|
|
160 z.msg = "unknown compression method";
|
|
161 z.istate.marker = 5; // can't try inflateSync
|
|
162 break;
|
|
163 }
|
|
164
|
|
165 if ((z.istate.method >> 4) + 8 > z.istate.wbits) {
|
|
166 z.istate.mode = BAD;
|
|
167 z.msg = "invalid window size";
|
|
168 z.istate.marker = 5; // can't try inflateSync
|
|
169 break;
|
|
170 }
|
|
171
|
|
172 z.istate.mode = FLAG;
|
|
173
|
|
174 case FLAG:
|
|
175 if (z.avail_in == 0)return r; r = f;
|
|
176
|
|
177 z.avail_in--; z.total_in++;
|
|
178 b = (z.next_in[z.next_in_index++]) & 0xff;
|
|
179
|
|
180 if ((((z.istate.method << 8) + b) % 31) != 0) {
|
|
181 z.istate.mode = BAD;
|
|
182 z.msg = "incorrect header check";
|
|
183 z.istate.marker = 5; // can't try inflateSync
|
|
184 break;
|
|
185 }
|
|
186
|
|
187 if ((b & PRESET_DICT) == 0) {
|
|
188 z.istate.mode = BLOCKS;
|
|
189 break;
|
|
190 }
|
|
191
|
|
192 z.istate.mode = DICT4;
|
|
193
|
|
194 case DICT4:
|
|
195 if (z.avail_in == 0)return r; r = f;
|
|
196
|
|
197 z.avail_in--; z.total_in++;
|
|
198 z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L;
|
|
199 z.istate.mode = DICT3;
|
|
200
|
|
201 case DICT3:
|
|
202 if (z.avail_in == 0)return r; r = f;
|
|
203
|
|
204 z.avail_in--; z.total_in++;
|
|
205 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L;
|
|
206 z.istate.mode = DICT2;
|
|
207
|
|
208 case DICT2:
|
|
209 if (z.avail_in == 0)return r; r = f;
|
|
210
|
|
211 z.avail_in--; z.total_in++;
|
|
212 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L;
|
|
213 z.istate.mode = DICT1;
|
|
214
|
|
215 case DICT1:
|
|
216 if (z.avail_in == 0)return r; r = f;
|
|
217
|
|
218 z.avail_in--; z.total_in++;
|
|
219 z.istate.need += (z.next_in[z.next_in_index++] & 0xffL);
|
|
220 z.adler = z.istate.need;
|
|
221 z.istate.mode = DICT0;
|
|
222 return Z_NEED_DICT;
|
|
223
|
|
224 case DICT0:
|
|
225 z.istate.mode = BAD;
|
|
226 z.msg = "need dictionary";
|
|
227 z.istate.marker = 0; // can try inflateSync
|
|
228 return Z_STREAM_ERROR;
|
|
229
|
|
230 case BLOCKS:
|
|
231 r = z.istate.blocks.proc(z, r);
|
|
232
|
|
233 if (r == Z_DATA_ERROR) {
|
|
234 z.istate.mode = BAD;
|
|
235 z.istate.marker = 0; // can try inflateSync
|
|
236 break;
|
|
237 }
|
|
238
|
|
239 if (r == Z_OK) {
|
|
240 r = f;
|
|
241 }
|
|
242
|
|
243 if (r != Z_STREAM_END) {
|
|
244 return r;
|
|
245 }
|
|
246
|
|
247 r = f;
|
|
248 z.istate.blocks.reset(z, z.istate.was);
|
|
249
|
|
250 if (z.istate.nowrap != 0) {
|
|
251 z.istate.mode = DONE;
|
|
252 break;
|
|
253 }
|
|
254
|
|
255 z.istate.mode = CHECK4;
|
|
256
|
|
257 case CHECK4:
|
|
258 if (z.avail_in == 0)return r; r = f;
|
|
259
|
|
260 z.avail_in--; z.total_in++;
|
|
261 z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L;
|
|
262 z.istate.mode = CHECK3;
|
|
263
|
|
264 case CHECK3:
|
|
265 if (z.avail_in == 0)return r; r = f;
|
|
266
|
|
267 z.avail_in--; z.total_in++;
|
|
268 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L;
|
|
269 z.istate.mode = CHECK2;
|
|
270
|
|
271 case CHECK2:
|
|
272 if (z.avail_in == 0)return r; r = f;
|
|
273
|
|
274 z.avail_in--; z.total_in++;
|
|
275 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L;
|
|
276 z.istate.mode = CHECK1;
|
|
277
|
|
278 case CHECK1:
|
|
279 if (z.avail_in == 0)return r; r = f;
|
|
280
|
|
281 z.avail_in--; z.total_in++;
|
|
282 z.istate.need += (z.next_in[z.next_in_index++] & 0xffL);
|
|
283
|
|
284 if (((int)(z.istate.was[0])) != ((int)(z.istate.need))) {
|
|
285 z.istate.mode = BAD;
|
|
286 z.msg = "incorrect data check";
|
|
287 z.istate.marker = 5; // can't try inflateSync
|
|
288 break;
|
|
289 }
|
|
290
|
|
291 z.istate.mode = DONE;
|
|
292
|
|
293 case DONE:
|
|
294 return Z_STREAM_END;
|
|
295
|
|
296 case BAD:
|
|
297 return Z_DATA_ERROR;
|
|
298
|
|
299 default:
|
|
300 return Z_STREAM_ERROR;
|
|
301 }
|
|
302 }
|
|
303 }
|
|
304
|
|
305
|
|
306 int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) {
|
|
307 int index = 0;
|
|
308 int length = dictLength;
|
|
309
|
|
310 if (z == null || z.istate == null || z.istate.mode != DICT0)
|
|
311 return Z_STREAM_ERROR;
|
|
312
|
|
313 if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler) {
|
|
314 return Z_DATA_ERROR;
|
|
315 }
|
|
316
|
|
317 z.adler = z._adler.adler32(0, null, 0, 0);
|
|
318
|
|
319 if (length >= (1 << z.istate.wbits)) {
|
|
320 length = (1 << z.istate.wbits) - 1;
|
|
321 index = dictLength - length;
|
|
322 }
|
|
323
|
|
324 z.istate.blocks.set_dictionary(dictionary, index, length);
|
|
325 z.istate.mode = BLOCKS;
|
|
326 return Z_OK;
|
|
327 }
|
|
328
|
|
329 static private byte[] mark = { (byte)0, (byte)0, (byte)0xff, (byte)0xff};
|
|
330
|
|
331 int inflateSync(ZStream z) {
|
|
332 int n; // number of bytes to look at
|
|
333 int p; // pointer to bytes
|
|
334 int m; // number of marker bytes found in a row
|
|
335 long r, w; // temporaries to save total_in and total_out
|
|
336
|
|
337 // set up
|
|
338 if (z == null || z.istate == null)
|
|
339 return Z_STREAM_ERROR;
|
|
340
|
|
341 if (z.istate.mode != BAD) {
|
|
342 z.istate.mode = BAD;
|
|
343 z.istate.marker = 0;
|
|
344 }
|
|
345
|
|
346 if ((n = z.avail_in) == 0)
|
|
347 return Z_BUF_ERROR;
|
|
348
|
|
349 p = z.next_in_index;
|
|
350 m = z.istate.marker;
|
|
351
|
|
352 // search
|
|
353 while (n != 0 && m < 4) {
|
|
354 if (z.next_in[p] == mark[m]) {
|
|
355 m++;
|
|
356 }
|
|
357 else if (z.next_in[p] != 0) {
|
|
358 m = 0;
|
|
359 }
|
|
360 else {
|
|
361 m = 4 - m;
|
|
362 }
|
|
363
|
|
364 p++; n--;
|
|
365 }
|
|
366
|
|
367 // restore
|
|
368 z.total_in += p - z.next_in_index;
|
|
369 z.next_in_index = p;
|
|
370 z.avail_in = n;
|
|
371 z.istate.marker = m;
|
|
372
|
|
373 // return no joy or set up to restart on a new block
|
|
374 if (m != 4) {
|
|
375 return Z_DATA_ERROR;
|
|
376 }
|
|
377
|
|
378 r = z.total_in; w = z.total_out;
|
|
379 inflateReset(z);
|
|
380 z.total_in = r; z.total_out = w;
|
|
381 z.istate.mode = BLOCKS;
|
|
382 return Z_OK;
|
|
383 }
|
|
384
|
|
385 // Returns true if inflate is currently at the end of a block generated
|
|
386 // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
|
|
387 // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
|
|
388 // but removes the length bytes of the resulting empty stored block. When
|
|
389 // decompressing, PPP checks that at the end of input packet, inflate is
|
|
390 // waiting for these length bytes.
|
|
391 int inflateSyncPoint(ZStream z) {
|
|
392 if (z == null || z.istate == null || z.istate.blocks == null)
|
|
393 return Z_STREAM_ERROR;
|
|
394
|
|
395 return z.istate.blocks.sync_point();
|
|
396 }
|
|
397 }
|