3 { inflate.c -- zlib interface to inflate modules
4 Copyright (C) 1995-1998 Mark Adler
7 Copyright (C) 1998 by Jacques Nomssi Nzali
8 For conditions of distribution and use, see copyright notice in readme.txt
16 imzutil
, impaszlib
, iminfblock
, iminfutil
;
18 function inflateInit(var z
: z_stream
) : int
;
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
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
33 function inflateInit_(z
: z_streamp
;
34 const version
: AnsiString;
35 stream_size
: int
) : int
;
38 function inflateInit2_(var z
: z_stream
;
40 const version
: AnsiString;
41 stream_size
: int
) : int
;
43 function inflateInit2(var z
: z_stream
;
44 windowBits
: int
) : int
;
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
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.
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.)
68 function inflateEnd(var z
: z_stream
) : int
;
71 All dynamically allocated data structures for this stream are freed.
72 This function discards any unprocessed input and does not flush any
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).
80 function inflateReset(var z
: z_stream
) : int
;
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.
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).
92 function inflate(var z
: z_stream
;
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.
100 The detailed semantics are as follows. inflate performs one or both of the
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().
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).
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.
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
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.
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.
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
162 function inflateSetDictionary(var z
: z_stream
;
163 dictionary
: pBytef
; {const array of byte}
164 dictLength
: uInt
) : int
;
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).
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
182 function inflateSync(var z
: z_stream
) : int
;
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.
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.
199 function inflateSyncPoint(var z
: z_stream
) : int
;
207 function inflateReset(var z
: z_stream
) : int
;
209 if (z
.state
= Z_NULL
) then
211 inflateReset
:= Z_STREAM_ERROR
;
217 if z
.state
^.nowrap
then
218 z
.state
^.mode
:= BLOCKS
220 z
.state
^.mode
:= METHOD
;
221 inflate_blocks_reset(z
.state
^.blocks
^, z
, Z_NULL
);
223 Tracev('inflate: reset');
225 inflateReset
:= Z_OK
;
229 function inflateEnd(var z
: z_stream
) : int
;
231 if (z
.state
= Z_NULL
) or not Assigned(z
.zfree
) then
233 inflateEnd
:= Z_STREAM_ERROR
;
236 if (z
.state
^.blocks
<> Z_NULL
) then
237 inflate_blocks_free(z
.state
^.blocks
, z
);
241 Tracev('inflate: end');
247 function inflateInit2_(var z
: z_stream
;
249 const version
: AnsiString;
250 stream_size
: int
) : int
;
252 if (version
= '') or (version
[1] <> ZLIB_VERSION
[1]) or
253 (stream_size
<> sizeof(z_stream
)) then
255 inflateInit2_
:= Z_VERSION_ERROR
;
259 { SetLength(strm.msg, 255); }
261 if not Assigned(z
.zalloc
) then
263 {$IFDEF FPC} z
.zalloc
:= @zcalloc
; {$ELSE}
266 z
.opaque
:= voidpf(0);
268 if not Assigned(z
.zfree
) then
269 {$IFDEF FPC} z
.zfree
:= @zcfree
; {$ELSE}
273 z
.state
:= pInternal_state( ZALLOC(z
,1,sizeof(internal_state
)) );
274 if (z
.state
= Z_NULL
) then
276 inflateInit2_
:= Z_MEM_ERROR
;
280 z
.state
^.blocks
:= Z_NULL
;
282 { handle undocumented nowrap option (no zlib header or check) }
283 z
.state
^.nowrap
:= FALSE;
287 z
.state
^.nowrap
:= TRUE;
291 if (w
< 8) or (w
> 15) then
294 inflateInit2_
:= Z_STREAM_ERROR
;
297 z
.state
^.wbits
:= uInt(w
);
299 { create inflate_blocks state }
300 if z
.state
^.nowrap
then
301 z
.state
^.blocks
:= inflate_blocks_new(z
, NIL, uInt(1) shl w
)
304 z
.state
^.blocks
:= inflate_blocks_new(z
, @adler32
, uInt(1) shl w
);
306 z
.state
^.blocks
:= inflate_blocks_new(z
, adler32
, uInt(1) shl w
);
308 if (z
.state
^.blocks
= Z_NULL
) then
311 inflateInit2_
:= Z_MEM_ERROR
;
315 Tracev('inflate: allocated');
319 inflateInit2_
:= Z_OK
;
322 function inflateInit2(var z
: z_stream
; windowBits
: int
) : int
;
324 inflateInit2
:= inflateInit2_(z
, windowBits
, ZLIB_VERSION
, sizeof(z_stream
));
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: }
332 inflateInit
:= inflateInit2_(z
, DEF_WBITS
, ZLIB_VERSION
, sizeof(z_stream
));
335 function inflateInit_(z
: z_streamp
;
336 const version
: AnsiString;
337 stream_size
: int
) : int
;
341 inflateInit_
:= Z_STREAM_ERROR
343 inflateInit_
:= inflateInit2_(z
^, DEF_WBITS
, version
, stream_size
);
346 function inflate(var z
: z_stream
;
352 if (z
.state
= Z_NULL
) or (z
.next_in
= Z_NULL
) then
354 inflate
:= Z_STREAM_ERROR
;
363 case (z
.state
^.mode
) of
366 r
:= inflate_blocks(z
.state
^.blocks
^, z
, r
);
367 if (r
= Z_DATA_ERROR
) then
369 z
.state
^.mode
:= BAD
;
370 z
.state
^.sub
.marker
:= 0; { can try inflateSync }
371 continue
; { break C-switch }
375 if (r
<> Z_STREAM_END
) then
381 inflate_blocks_reset(z
.state
^.blocks
^, z
, @z
.state
^.sub
.check
.was
);
382 if (z
.state
^.nowrap
) then
384 z
.state
^.mode
:= DONE
;
385 continue
; { break C-switch }
387 z
.state
^.mode
:= CHECK4
; { falltrough }
392 if (z
.avail_in
= 0) then
399 {z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}
402 z
.state
^.sub
.check
.need
:= uLong(z
.next_in
^) shl 24;
405 z
.state
^.mode
:= CHECK3
; { falltrough }
410 if (z
.avail_in
= 0) then
416 {Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}
419 Inc(z
.state
^.sub
.check
.need
, uLong(z
.next_in
^) shl 16);
422 z
.state
^.mode
:= CHECK2
; { falltrough }
427 if (z
.avail_in
= 0) then
434 {Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}
437 Inc(z
.state
^.sub
.check
.need
, uLong(z
.next_in
^) shl 8);
440 z
.state
^.mode
:= CHECK1
; { falltrough }
445 if (z
.avail_in
= 0) then
451 {Inc( z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}
454 Inc(z
.state
^.sub
.check
.need
, uLong(z
.next_in
^) );
458 if (z
.state
^.sub
.check
.was
<> z
.state
^.sub
.check
.need
) then
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 }
466 Tracev('inflate: zlib check ok');
468 z
.state
^.mode
:= DONE
; { falltrough }
472 inflate
:= Z_STREAM_END
;
478 if (z
.avail_in
= 0) then
485 {z.state^.sub.method := NEXTBYTE(z);}
488 z
.state
^.sub
.method
:= z
.next_in
^;
491 if ((z
.state
^.sub
.method
and $0f) <> Z_DEFLATED
) then
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 }
498 if ((z
.state
^.sub
.method
shr 4) + 8 > z
.state
^.wbits
) then
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 }
505 z
.state
^.mode
:= FLAG
;
511 if (z
.avail_in
= 0) then
523 if (((z
.state
^.sub
.method
shl 8) + b
) mod 31) <> 0 then {% mod ?}
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 }
531 Tracev('inflate: zlib header ok');
533 if ((b
and PRESET_DICT
) = 0) then
535 z
.state
^.mode
:= BLOCKS
;
536 continue
; { break C-switch }
538 z
.state
^.mode
:= DICT4
;
543 if (z
.avail_in
= 0) then
550 {z.state^.sub.check.need := uLong(NEXTBYTE(z)) shl 24;}
553 z
.state
^.sub
.check
.need
:= uLong(z
.next_in
^) shl 24;
556 z
.state
^.mode
:= DICT3
; { falltrough }
560 if (z
.avail_in
= 0) then
566 {Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 16);}
569 Inc(z
.state
^.sub
.check
.need
, uLong(z
.next_in
^) shl 16);
572 z
.state
^.mode
:= DICT2
; { falltrough }
576 if (z
.avail_in
= 0) then
583 {Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) shl 8);}
586 Inc(z
.state
^.sub
.check
.need
, uLong(z
.next_in
^) shl 8);
589 z
.state
^.mode
:= DICT1
; { falltrough }
593 if (z
.avail_in
= 0) then
598 { r := f; --- wird niemals benutzt }
599 {Inc(z.state^.sub.check.need, uLong(NEXTBYTE(z)) );}
602 Inc(z
.state
^.sub
.check
.need
, uLong(z
.next_in
^) );
605 z
.adler
:= z
.state
^.sub
.check
.need
;
606 z
.state
^.mode
:= DICT0
;
607 inflate
:= Z_NEED_DICT
;
612 z
.state
^.mode
:= BAD
;
613 z
.msg
:= 'need dictionary';
614 z
.state
^.sub
.marker
:= 0; { can try inflateSync }
615 inflate
:= Z_STREAM_ERROR
;
620 inflate
:= Z_DATA_ERROR
;
625 inflate
:= Z_STREAM_ERROR
;
629 {$ifdef NEED_DUMMY_result}
630 result
:= Z_STREAM_ERROR
; { Some dumb compilers complain without this }
634 function inflateSetDictionary(var z
: z_stream
;
635 dictionary
: pBytef
; {const array of byte}
636 dictLength
: uInt
) : int
;
640 length
:= dictLength
;
642 if (z
.state
= Z_NULL
) or (z
.state
^.mode
<> DICT0
) then
644 inflateSetDictionary
:= Z_STREAM_ERROR
;
647 if (adler32(Long(1), dictionary
, dictLength
) <> z
.adler
) then
649 inflateSetDictionary
:= Z_DATA_ERROR
;
654 if (length
>= (uInt(1) shl z
.state
^.wbits
)) then
656 length
:= (1 shl z
.state
^.wbits
)-1;
657 Inc( dictionary
, dictLength
- length
);
659 inflate_set_dictionary(z
.state
^.blocks
^, dictionary
^, length
);
660 z
.state
^.mode
:= BLOCKS
;
661 inflateSetDictionary
:= Z_OK
;
665 function inflateSync(var z
: z_stream
) : int
;
667 mark
: packed array[0..3] of byte = (0, 0, $ff, $ff);
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 }
675 if (z
.state
= Z_NULL
) then
677 inflateSync
:= Z_STREAM_ERROR
;
680 if (z
.state
^.mode
<> BAD
) then
682 z
.state
^.mode
:= BAD
;
683 z
.state
^.sub
.marker
:= 0;
688 inflateSync
:= Z_BUF_ERROR
;
692 m
:= z
.state
^.sub
.marker
;
695 while (n
<> 0) and (m
< 4) do
697 if (p
^ = mark
[m
]) then
709 Inc(z
.total_in
, ptr2int(p
) - ptr2int(z
.next_in
));
712 z
.state
^.sub
.marker
:= m
;
715 { return no joy or set up to restart on a new block }
718 inflateSync
:= Z_DATA_ERROR
;
726 z
.state
^.mode
:= BLOCKS
;
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.
740 function inflateSyncPoint(var z
: z_stream
) : int
;
742 if (z
.state
= Z_NULL
) or (z
.state
^.blocks
= Z_NULL
) then
744 inflateSyncPoint
:= Z_STREAM_ERROR
;
747 inflateSyncPoint
:= inflate_blocks_sync_point(z
.state
^.blocks
^);