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