1 |
Unit zInflate;
|
2 |
|
3 |
{ inflate.c -- zlib interface to inflate modules
|
4 |
Copyright (C) 1995-1998 Mark Adler
|
5 |
|
6 |
Pascal tranlastion
|
7 |
Copyright (C) 1998 by Jacques Nomssi Nzali
|
8 |
For conditions of distribution and use, see copyright notice in readme.paszlib
|
9 |
}
|
10 |
|
11 |
interface
|
12 |
|
13 |
{$I zconf.inc}
|
14 |
|
15 |
uses
|
16 |
zutil, zlib, infblock, infutil;
|
17 |
|
18 |
function inflateInit(var z : z_stream) : int;
|
19 |
|
20 |
{ Initializes the internal stream state for decompression. The fields
|
21 |
zalloc, zfree and opaque must be initialized before by the caller. If
|
22 |
zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
|
23 |
allocation functions.
|
24 |
|
25 |
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
|
26 |
enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
|
27 |
with the version assumed by the caller. msg is set to null if there is no
|
28 |
error message. inflateInit does not perform any decompression: this will be
|
29 |
done by inflate(). }
|
30 |
|
31 |
|
32 |
|
33 |
function inflateInit_(z : z_streamp;
|
34 |
const version : string;
|
35 |
stream_size : int) : int;
|
36 |
|
37 |
|
38 |
function inflateInit2_(var z: z_stream;
|
39 |
w : int;
|
40 |
const version : string;
|
41 |
stream_size : int) : int;
|
42 |
|
43 |
function inflateInit2(var z: z_stream;
|
44 |
windowBits : int) : int;
|
45 |
|
46 |
{
|
47 |
This is another version of inflateInit with an extra parameter. The
|
48 |
fields next_in, avail_in, zalloc, zfree and opaque must be initialized
|
49 |
before by the caller.
|
50 |
|
51 |
The windowBits parameter is the base two logarithm of the maximum window
|
52 |
size (the size of the history buffer). It should be in the range 8..15 for
|
53 |
this version of the library. The default value is 15 if inflateInit is used
|
54 |
instead. If a compressed stream with a larger window size is given as
|
55 |
input, inflate() will return with the error code Z_DATA_ERROR instead of
|
56 |
trying to allocate a larger window.
|
57 |
|
58 |
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
59 |
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
|
60 |
memLevel). msg is set to null if there is no error message. inflateInit2
|
61 |
does not perform any decompression apart from reading the zlib header if
|
62 |
present: this will be done by inflate(). (So next_in and avail_in may be
|
63 |
modified, but next_out and avail_out are unchanged.)
|
64 |
}
|
65 |
|
66 |
|
67 |
|
68 |
function inflateEnd(var z : z_stream) : int;
|
69 |
|
70 |
{
|
71 |
All dynamically allocated data structures for this stream are freed.
|
72 |
This function discards any unprocessed input and does not flush any
|
73 |
pending output.
|
74 |
|
75 |
inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
|
76 |
was inconsistent. In the error case, msg may be set but then points to a
|
77 |
static string (which must not be deallocated).
|
78 |
}
|
79 |
|
80 |
function inflateReset(var z : z_stream) : int;
|
81 |
|
82 |
{
|
83 |
This function is equivalent to inflateEnd followed by inflateInit,
|
84 |
but does not free and reallocate all the internal decompression state.
|
85 |
The stream will keep attributes that may have been set by inflateInit2.
|
86 |
|
87 |
inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
|
88 |
stream state was inconsistent (such as zalloc or state being NULL).
|
89 |
}
|
90 |
|
91 |
|
92 |
function inflate(var z : z_stream;
|
93 |
f : int) : int;
|
94 |
{
|
95 |
inflate decompresses as much data as possible, and stops when the input
|
96 |
buffer becomes empty or the output buffer becomes full. It may introduce
|
97 |
some output latency (reading input without producing any output)
|
98 |
except when forced to flush.
|
99 |
|
100 |
The detailed semantics are as follows. inflate performs one or both of the
|
101 |
following actions:
|
102 |
|
103 |
- Decompress more input starting at next_in and update next_in and avail_in
|
104 |
accordingly. If not all input can be processed (because there is not
|
105 |
enough room in the output buffer), next_in is updated and processing
|
106 |
will resume at this point for the next call of inflate().
|
107 |
|
108 |
- Provide more output starting at next_out and update next_out and avail_out
|
109 |
accordingly. inflate() provides as much output as possible, until there
|
110 |
is no more input data or no more space in the output buffer (see below
|
111 |
about the flush parameter).
|
112 |
|
113 |
Before the call of inflate(), the application should ensure that at least
|
114 |
one of the actions is possible, by providing more input and/or consuming
|
115 |
more output, and updating the next_* and avail_* values accordingly.
|
116 |
The application can consume the uncompressed output when it wants, for
|
117 |
example when the output buffer is full (avail_out == 0), or after each
|
118 |
call of inflate(). If inflate returns Z_OK and with zero avail_out, it
|
119 |
must be called again after making room in the output buffer because there
|
120 |
might be more output pending.
|
121 |
|
122 |
If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
|
123 |
output as possible to the output buffer. The flushing behavior of inflate is
|
124 |
not specified for values of the flush parameter other than Z_SYNC_FLUSH
|
125 |
and Z_FINISH, but the current implementation actually flushes as much output
|
126 |
as possible anyway.
|
127 |
|
128 |
inflate() should normally be called until it returns Z_STREAM_END or an
|
129 |
error. However if all decompression is to be performed in a single step
|
130 |
(a single call of inflate), the parameter flush should be set to
|
131 |
Z_FINISH. In this case all pending input is processed and all pending
|
132 |
output is flushed; avail_out must be large enough to hold all the
|
133 |
uncompressed data. (The size of the uncompressed data may have been saved
|
134 |
by the compressor for this purpose.) The next operation on this stream must
|
135 |
be inflateEnd to deallocate the decompression state. The use of Z_FINISH
|
136 |
is never required, but can be used to inform inflate that a faster routine
|
137 |
may be used for the single inflate() call.
|
138 |
|
139 |
If a preset dictionary is needed at this point (see inflateSetDictionary
|
140 |
below), inflate sets strm-adler to the adler32 checksum of the
|
141 |
dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
|
142 |
it sets strm->adler to the adler32 checksum of all output produced
|
143 |
so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
|
144 |
an error code as described below. At the end of the stream, inflate()
|
145 |
checks that its computed adler32 checksum is equal to that saved by the
|
146 |
compressor and returns Z_STREAM_END only if the checksum is correct.
|
147 |
|
148 |
inflate() returns Z_OK if some progress has been made (more input processed
|
149 |
or more output produced), Z_STREAM_END if the end of the compressed data has
|
150 |
been reached and all uncompressed output has been produced, Z_NEED_DICT if a
|
151 |
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
|
152 |
corrupted (input stream not conforming to the zlib format or incorrect
|
153 |
adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
|
154 |
(for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
|
155 |
enough memory, Z_BUF_ERROR if no progress is possible or if there was not
|
156 |
enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
|
157 |
case, the application may then call inflateSync to look for a good
|
158 |
compression block.
|
159 |
}
|
160 |
|
161 |
|
162 |
function inflateSetDictionary(var z : z_stream;
|
163 |
dictionary : pBytef; {const array of byte}
|
164 |
dictLength : uInt) : int;
|
165 |
|
166 |
{
|
167 |
Initializes the decompression dictionary from the given uncompressed byte
|
168 |
sequence. This function must be called immediately after a call of inflate
|
169 |
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
170 |
can be determined from the Adler32 value returned by this call of
|
171 |
inflate. The compressor and decompressor must use exactly the same
|
172 |
dictionary (see deflateSetDictionary).
|
173 |
|
174 |
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
175 |
parameter is invalid (such as NULL dictionary) or the stream state is
|
176 |
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
|
177 |
expected one (incorrect Adler32 value). inflateSetDictionary does not
|
178 |
perform any decompression: this will be done by subsequent calls of
|
179 |
inflate().
|
180 |
}
|
181 |
|
182 |
function inflateSync(var z : z_stream) : int;
|
183 |
|
184 |
{
|
185 |
Skips invalid compressed data until a full flush point (see above the
|
186 |
description of deflate with Z_FULL_FLUSH) can be found, or until all
|
187 |
available input is skipped. No output is provided.
|
188 |
|
189 |
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
|
190 |
if no more input was provided, Z_DATA_ERROR if no flush point has been found,
|
191 |
or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
|
192 |
case, the application may save the current current value of total_in which
|
193 |
indicates where valid compressed data was found. In the error case, the
|
194 |
application may repeatedly call inflateSync, providing more input each time,
|
195 |
until success or end of the input data.
|
196 |
}
|
197 |
|
198 |
|
199 |
function inflateSyncPoint(var z : z_stream) : int;
|
200 |
|
201 |
|
202 |
implementation
|
203 |
|
204 |
uses
|
205 |
adler;
|
206 |
|
207 |
function inflateReset(var z : z_stream) : int;
|
208 |
begin
|
209 |
if (z.state = Z_NULL) then
|
210 |
begin
|
211 |
inflateReset := Z_STREAM_ERROR;
|
212 |
exit;
|
213 |
end;
|
214 |
z.total_out := 0;
|
215 |
z.total_in := 0;
|
216 |
z.msg := '';
|
217 |
if z.state^.nowrap then
|
218 |
z.state^.mode := BLOCKS
|
219 |
else
|
220 |
z.state^.mode := METHOD;
|
221 |
inflate_blocks_reset(z.state^.blocks^, z, Z_NULL);
|
222 |
{$IFDEF DEBUG}
|
223 |
Tracev('inflate: reset');
|
224 |
{$ENDIF}
|
225 |
inflateReset := Z_OK;
|
226 |
end;
|
227 |
|
228 |
|
229 |
function inflateEnd(var z : z_stream) : int;
|
230 |
begin
|
231 |
if (z.state = Z_NULL) or not Assigned(z.zfree) then
|
232 |
begin
|
233 |
inflateEnd := Z_STREAM_ERROR;
|
234 |
exit;
|
235 |
end;
|
236 |
if (z.state^.blocks <> Z_NULL) then
|
237 |
inflate_blocks_free(z.state^.blocks, z);
|
238 |
ZFREE(z, z.state);
|
239 |
z.state := Z_NULL;
|
240 |
{$IFDEF DEBUG}
|
241 |
Tracev('inflate: end');
|
242 |
{$ENDIF}
|
243 |
inflateEnd := Z_OK;
|
244 |
end;
|
245 |
|
246 |
|
247 |
function inflateInit2_(var z: z_stream;
|
248 |
w : int;
|
249 |
const version : string;
|
250 |
stream_size : int) : int;
|
251 |
begin
|
252 |
if (version = '') or (version[1] <> ZLIB_VERSION[1]) or
|
253 |
(stream_size <> sizeof(z_stream)) then
|
254 |
begin
|
255 |
inflateInit2_ := Z_VERSION_ERROR;
|
256 |
exit;
|
257 |
end;
|
258 |
{ initialize state }
|
259 |
{ SetLength(strm.msg, 255); }
|
260 |
z.msg := '';
|
261 |
if not Assigned(z.zalloc) then
|
262 |
begin
|
263 |
{$IFDEF FPC} z.zalloc := @zcalloc; {$ELSE}
|
264 |
z.zalloc := zcalloc;
|
265 |
{$endif}
|
266 |
z.opaque := voidpf(0);
|
267 |
end;
|
268 |
if not Assigned(z.zfree) then
|
269 |
{$IFDEF FPC} z.zfree := @zcfree; {$ELSE}
|
270 |
z.zfree := zcfree;
|
271 |
{$ENDIF}
|
272 |
|
273 |
z.state := pInternal_state( ZALLOC(z,1,sizeof(internal_state)) );
|
274 |
if (z.state = Z_NULL) then
|
275 |
begin
|
276 |
inflateInit2_ := Z_MEM_ERROR;
|
277 |
exit;
|
278 |
end;
|
279 |
|
280 |
z.state^.blocks := Z_NULL;
|
281 |
|
282 |
{ handle undocumented nowrap option (no zlib header or check) }
|
283 |
z.state^.nowrap := FALSE;
|
284 |
if (w < 0) then
|
285 |
begin
|
286 |
w := - w;
|
287 |
z.state^.nowrap := TRUE;
|
288 |
end;
|
289 |
|
290 |
{ set window size }
|
291 |
if (w < 8) or (w > 15) then
|
292 |
begin
|
293 |
inflateEnd(z);
|
294 |
inflateInit2_ := Z_STREAM_ERROR;
|
295 |
exit;
|
296 |
end;
|
297 |
z.state^.wbits := uInt(w);
|
298 |
|
299 |
{ create inflate_blocks state }
|
300 |
if z.state^.nowrap then
|
301 |
z.state^.blocks := inflate_blocks_new(z, NIL, uInt(1) shl w)
|
302 |
else
|
303 |
{$IFDEF FPC}
|
304 |
z.state^.blocks := inflate_blocks_new(z, @adler32, uInt(1) shl w);
|
305 |
{$ELSE}
|
306 |
z.state^.blocks := inflate_blocks_new(z, adler32, uInt(1) shl w);
|
307 |
{$ENDIF}
|
308 |
if (z.state^.blocks = Z_NULL) then
|
309 |
begin
|
310 |
inflateEnd(z);
|
311 |
inflateInit2_ := Z_MEM_ERROR;
|
312 |
exit;
|
313 |
end;
|
314 |
{$IFDEF DEBUG}
|
315 |
Tracev('inflate: allocated');
|
316 |
{$ENDIF}
|
317 |
{ reset state }
|
318 |
inflateReset(z);
|
319 |
inflateInit2_ := Z_OK;
|
320 |
end;
|
321 |
|
322 |
function inflateInit2(var z: z_stream; windowBits : int) : int;
|
323 |
begin
|
324 |
inflateInit2 := inflateInit2_(z, windowBits, ZLIB_VERSION, sizeof(z_stream));
|
325 |
end;
|
326 |
|
327 |
|
328 |
function inflateInit(var z : z_stream) : int;
|
329 |
{ inflateInit is a macro to allow checking the zlib version
|
330 |
and the compiler's view of z_stream: }
|
331 |
begin
|
332 |
inflateInit := inflateInit2_(z, DEF_WBITS, ZLIB_VERSION, sizeof(z_stream));
|
333 |
end;
|
334 |
|
335 |
function inflateInit_(z : z_streamp;
|
336 |
const version : string;
|
337 |
stream_size : int) : int;
|
338 |
begin
|
339 |
{ initialize state }
|
340 |
if (z = Z_NULL) then
|
341 |
inflateInit_ := Z_STREAM_ERROR
|
342 |
else
|
343 |
inflateInit_ := inflateInit2_(z^, DEF_WBITS, version, stream_size);
|
344 |
end;
|
345 |
|
346 |
function inflate(var z : z_stream;
|
347 |
f : int) : int;
|
348 |
var
|
349 |
r : int;
|
350 |
b : uInt;
|
351 |
begin
|
352 |
if (z.state = Z_NULL) or (z.next_in = Z_NULL) then
|
353 |
begin
|
354 |
inflate := Z_STREAM_ERROR;
|
355 |
exit;
|
356 |
end;
|
357 |
if f = Z_FINISH then
|
358 |
f := Z_BUF_ERROR
|
359 |
else
|
360 |
f := Z_OK;
|
361 |
r := Z_BUF_ERROR;
|
362 |
while True do
|
363 |
case (z.state^.mode) of
|
364 |
BLOCKS:
|
365 |
begin
|
366 |
r := inflate_blocks(z.state^.blocks^, z, r);
|
367 |
if (r = Z_DATA_ERROR) then
|
368 |
begin
|
369 |
z.state^.mode := BAD;
|
370 |
z.state^.sub.marker := 0; { can try inflateSync }
|
371 |
continue; { break C-switch }
|
372 |
end;
|
373 |
if (r = Z_OK) then
|
374 |
r := f;
|
375 |
if (r <> Z_STREAM_END) then
|
376 |
begin
|
377 |
inflate := r;
|
378 |
exit;
|
379 |
end;
|
380 |
r := f;
|
381 |
inflate_blocks_reset(z.state^.blocks^, z, @z.state^.sub.check.was);
|
382 |
if (z.state^.nowrap) then
|
383 |
begin
|
384 |
z.state^.mode := DONE;
|
385 |
continue; { break C-switch }
|
386 |
end;
|
387 |
z.state^.mode := CHECK4; { falltrough }
|
388 |
end;
|
389 |
CHECK4:
|
390 |
begin
|
391 |
{NEEDBYTE}
|
392 |
if (z.avail_in = 0) then
|
393 |
begin
|
394 |
inflate := r;
|
395 |
exit;
|
396 |
end;
|
397 |
r := f;
|
398 |
|
399 |
{z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}
|
400 |
Dec(z.avail_in);
|
401 |
Inc(z.total_in);
|
402 |
z.state^.sub.check.need := uLong(z.next_in^) shl 24;
|
403 |
Inc(z.next_in);
|
404 |
|
405 |
z.state^.mode := CHECK3; { falltrough }
|
406 |
end;
|
407 |
CHECK3:
|
408 |
begin
|
409 |
{NEEDBYTE}
|
410 |
if (z.avail_in = 0) then
|
411 |
begin
|
412 |
inflate := r;
|
413 |
exit;
|
414 |
end;
|
415 |
r := f;
|
416 |
{Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}
|
417 |
Dec(z.avail_in);
|
418 |
Inc(z.total_in);
|
419 |
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 16);
|
420 |
Inc(z.next_in);
|
421 |
|
422 |
z.state^.mode := CHECK2; { falltrough }
|
423 |
end;
|
424 |
CHECK2:
|
425 |
begin
|
426 |
{NEEDBYTE}
|
427 |
if (z.avail_in = 0) then
|
428 |
begin
|
429 |
inflate := r;
|
430 |
exit;
|
431 |
end;
|
432 |
r := f;
|
433 |
|
434 |
{Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}
|
435 |
Dec(z.avail_in);
|
436 |
Inc(z.total_in);
|
437 |
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 8);
|
438 |
Inc(z.next_in);
|
439 |
|
440 |
z.state^.mode := CHECK1; { falltrough }
|
441 |
end;
|
442 |
CHECK1:
|
443 |
begin
|
444 |
{NEEDBYTE}
|
445 |
if (z.avail_in = 0) then
|
446 |
begin
|
447 |
inflate := r;
|
448 |
exit;
|
449 |
end;
|
450 |
r := f;
|
451 |
{Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}
|
452 |
Dec(z.avail_in);
|
453 |
Inc(z.total_in);
|
454 |
Inc(z.state^.sub.check.need, uLong(z.next_in^) );
|
455 |
Inc(z.next_in);
|
456 |
|
457 |
|
458 |
if (z.state^.sub.check.was <> z.state^.sub.check.need) then
|
459 |
begin
|
460 |
z.state^.mode := BAD;
|
461 |
z.msg := 'incorrect data check';
|
462 |
z.state^.sub.marker := 5; { can't try inflateSync }
|
463 |
continue; { break C-switch }
|
464 |
end;
|
465 |
{$IFDEF DEBUG}
|
466 |
Tracev('inflate: zlib check ok');
|
467 |
{$ENDIF}
|
468 |
z.state^.mode := DONE; { falltrough }
|
469 |
end;
|
470 |
DONE:
|
471 |
begin
|
472 |
inflate := Z_STREAM_END;
|
473 |
exit;
|
474 |
end;
|
475 |
METHOD:
|
476 |
begin
|
477 |
{NEEDBYTE}
|
478 |
if (z.avail_in = 0) then
|
479 |
begin
|
480 |
inflate := r;
|
481 |
exit;
|
482 |
end;
|
483 |
r := f; {}
|
484 |
|
485 |
{z.state^.sub.method := NEXTBYTE(z);}
|
486 |
Dec(z.avail_in);
|
487 |
Inc(z.total_in);
|
488 |
z.state^.sub.method := z.next_in^;
|
489 |
Inc(z.next_in);
|
490 |
|
491 |
if ((z.state^.sub.method and $0f) <> Z_DEFLATED) then
|
492 |
begin
|
493 |
z.state^.mode := BAD;
|
494 |
z.msg := 'unknown compression method';
|
495 |
z.state^.sub.marker := 5; { can't try inflateSync }
|
496 |
continue; { break C-switch }
|
497 |
end;
|
498 |
if ((z.state^.sub.method shr 4) + 8 > z.state^.wbits) then
|
499 |
begin
|
500 |
z.state^.mode := BAD;
|
501 |
z.msg := 'invalid window size';
|
502 |
z.state^.sub.marker := 5; { can't try inflateSync }
|
503 |
continue; { break C-switch }
|
504 |
end;
|
505 |
z.state^.mode := FLAG;
|
506 |
{ fall trough }
|
507 |
end;
|
508 |
FLAG:
|
509 |
begin
|
510 |
{NEEDBYTE}
|
511 |
if (z.avail_in = 0) then
|
512 |
begin
|
513 |
inflate := r;
|
514 |
exit;
|
515 |
end;
|
516 |
r := f; {}
|
517 |
{b := NEXTBYTE(z);}
|
518 |
Dec(z.avail_in);
|
519 |
Inc(z.total_in);
|
520 |
b := z.next_in^;
|
521 |
Inc(z.next_in);
|
522 |
|
523 |
if (((z.state^.sub.method shl 8) + b) mod 31) <> 0 then {% mod ?}
|
524 |
begin
|
525 |
z.state^.mode := BAD;
|
526 |
z.msg := 'incorrect header check';
|
527 |
z.state^.sub.marker := 5; { can't try inflateSync }
|
528 |
continue; { break C-switch }
|
529 |
end;
|
530 |
{$IFDEF DEBUG}
|
531 |
Tracev('inflate: zlib header ok');
|
532 |
{$ENDIF}
|
533 |
if ((b and PRESET_DICT) = 0) then
|
534 |
begin
|
535 |
z.state^.mode := BLOCKS;
|
536 |
continue; { break C-switch }
|
537 |
end;
|
538 |
z.state^.mode := DICT4;
|
539 |
{ falltrough }
|
540 |
end;
|
541 |
DICT4:
|
542 |
begin
|
543 |
if (z.avail_in = 0) then
|
544 |
begin
|
545 |
inflate := r;
|
546 |
exit;
|
547 |
end;
|
548 |
r := f;
|
549 |
|
550 |
{z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}
|
551 |
Dec(z.avail_in);
|
552 |
Inc(z.total_in);
|
553 |
z.state^.sub.check.need := uLong(z.next_in^) shl 24;
|
554 |
Inc(z.next_in);
|
555 |
|
556 |
z.state^.mode := DICT3; { falltrough }
|
557 |
end;
|
558 |
DICT3:
|
559 |
begin
|
560 |
if (z.avail_in = 0) then
|
561 |
begin
|
562 |
inflate := r;
|
563 |
exit;
|
564 |
end;
|
565 |
r := f;
|
566 |
{Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}
|
567 |
Dec(z.avail_in);
|
568 |
Inc(z.total_in);
|
569 |
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 16);
|
570 |
Inc(z.next_in);
|
571 |
|
572 |
z.state^.mode := DICT2; { falltrough }
|
573 |
end;
|
574 |
DICT2:
|
575 |
begin
|
576 |
if (z.avail_in = 0) then
|
577 |
begin
|
578 |
inflate := r;
|
579 |
exit;
|
580 |
end;
|
581 |
r := f;
|
582 |
|
583 |
{Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}
|
584 |
Dec(z.avail_in);
|
585 |
Inc(z.total_in);
|
586 |
Inc(z.state^.sub.check.need, uLong(z.next_in^) shl 8);
|
587 |
Inc(z.next_in);
|
588 |
|
589 |
z.state^.mode := DICT1; { falltrough }
|
590 |
end;
|
591 |
DICT1:
|
592 |
begin
|
593 |
if (z.avail_in = 0) then
|
594 |
begin
|
595 |
inflate := r;
|
596 |
exit;
|
597 |
end;
|
598 |
{ r := f; --- wird niemals benutzt }
|
599 |
{Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}
|
600 |
Dec(z.avail_in);
|
601 |
Inc(z.total_in);
|
602 |
Inc(z.state^.sub.check.need, uLong(z.next_in^) );
|
603 |
Inc(z.next_in);
|
604 |
|
605 |
z.adler := z.state^.sub.check.need;
|
606 |
z.state^.mode := DICT0;
|
607 |
inflate := Z_NEED_DICT;
|
608 |
exit;
|
609 |
end;
|
610 |
DICT0:
|
611 |
begin
|
612 |
z.state^.mode := BAD;
|
613 |
z.msg := 'need dictionary';
|
614 |
z.state^.sub.marker := 0; { can try inflateSync }
|
615 |
inflate := Z_STREAM_ERROR;
|
616 |
exit;
|
617 |
end;
|
618 |
BAD:
|
619 |
begin
|
620 |
inflate := Z_DATA_ERROR;
|
621 |
exit;
|
622 |
end;
|
623 |
else
|
624 |
begin
|
625 |
inflate := Z_STREAM_ERROR;
|
626 |
exit;
|
627 |
end;
|
628 |
end;
|
629 |
{$ifdef NEED_DUMMY_result}
|
630 |
result := Z_STREAM_ERROR; { Some dumb compilers complain without this }
|
631 |
{$endif}
|
632 |
end;
|
633 |
|
634 |
function inflateSetDictionary(var z : z_stream;
|
635 |
dictionary : pBytef; {const array of byte}
|
636 |
dictLength : uInt) : int;
|
637 |
var
|
638 |
length : uInt;
|
639 |
begin
|
640 |
length := dictLength;
|
641 |
|
642 |
if (z.state = Z_NULL) or (z.state^.mode <> DICT0) then
|
643 |
begin
|
644 |
inflateSetDictionary := Z_STREAM_ERROR;
|
645 |
exit;
|
646 |
end;
|
647 |
if (adler32(Long(1), dictionary, dictLength) <> z.adler) then
|
648 |
begin
|
649 |
inflateSetDictionary := Z_DATA_ERROR;
|
650 |
exit;
|
651 |
end;
|
652 |
z.adler := Long(1);
|
653 |
|
654 |
if (length >= (uInt(1) shl z.state^.wbits)) then
|
655 |
begin
|
656 |
length := (1 shl z.state^.wbits)-1;
|
657 |
Inc( dictionary, dictLength - length);
|
658 |
end;
|
659 |
inflate_set_dictionary(z.state^.blocks^, dictionary^, length);
|
660 |
z.state^.mode := BLOCKS;
|
661 |
inflateSetDictionary := Z_OK;
|
662 |
end;
|
663 |
|
664 |
|
665 |
function inflateSync(var z : z_stream) : int;
|
666 |
const
|
667 |
mark : packed array[0..3] of byte = (0, 0, $ff, $ff);
|
668 |
var
|
669 |
n : uInt; { number of bytes to look at }
|
670 |
p : pBytef; { pointer to bytes }
|
671 |
m : uInt; { number of marker bytes found in a row }
|
672 |
r, w : uLong; { temporaries to save total_in and total_out }
|
673 |
begin
|
674 |
{ set up }
|
675 |
if (z.state = Z_NULL) then
|
676 |
begin
|
677 |
inflateSync := Z_STREAM_ERROR;
|
678 |
exit;
|
679 |
end;
|
680 |
if (z.state^.mode <> BAD) then
|
681 |
begin
|
682 |
z.state^.mode := BAD;
|
683 |
z.state^.sub.marker := 0;
|
684 |
end;
|
685 |
n := z.avail_in;
|
686 |
if (n = 0) then
|
687 |
begin
|
688 |
inflateSync := Z_BUF_ERROR;
|
689 |
exit;
|
690 |
end;
|
691 |
p := z.next_in;
|
692 |
m := z.state^.sub.marker;
|
693 |
|
694 |
{ search }
|
695 |
while (n <> 0) and (m < 4) do
|
696 |
begin
|
697 |
if (p^ = mark[m]) then
|
698 |
Inc(m)
|
699 |
else
|
700 |
if (p^ <> 0) then
|
701 |
m := 0
|
702 |
else
|
703 |
m := 4 - m;
|
704 |
Inc(p);
|
705 |
Dec(n);
|
706 |
end;
|
707 |
|
708 |
{ restore }
|
709 |
Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
|
710 |
z.next_in := p;
|
711 |
z.avail_in := n;
|
712 |
z.state^.sub.marker := m;
|
713 |
|
714 |
|
715 |
{ return no joy or set up to restart on a new block }
|
716 |
if (m <> 4) then
|
717 |
begin
|
718 |
inflateSync := Z_DATA_ERROR;
|
719 |
exit;
|
720 |
end;
|
721 |
r := z.total_in;
|
722 |
w := z.total_out;
|
723 |
inflateReset(z);
|
724 |
z.total_in := r;
|
725 |
z.total_out := w;
|
726 |
z.state^.mode := BLOCKS;
|
727 |
inflateSync := Z_OK;
|
728 |
end;
|
729 |
|
730 |
|
731 |
{
|
732 |
returns true if inflate is currently at the end of a block generated
|
733 |
by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
|
734 |
implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
|
735 |
but removes the length bytes of the resulting empty stored block. When
|
736 |
decompressing, PPP checks that at the end of input packet, inflate is
|
737 |
waiting for these length bytes.
|
738 |
}
|
739 |
|
740 |
function inflateSyncPoint(var z : z_stream) : int;
|
741 |
begin
|
742 |
if (z.state = Z_NULL) or (z.state^.blocks = Z_NULL) then
|
743 |
begin
|
744 |
inflateSyncPoint := Z_STREAM_ERROR;
|
745 |
exit;
|
746 |
end;
|
747 |
inflateSyncPoint := inflate_blocks_sync_point(z.state^.blocks^);
|
748 |
end;
|
749 |
|
750 |
end.
|