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