DEADSOFTWARE

413e9b6d74a47114dbbf8cace98bbdb6b321dd1a
[d2df-sdl.git] / iminfblock.pas
1 Unit iminfblock;
3 { infblock.h and
4 infblock.c -- interpret and process block types to last block
5 Copyright (C) 1995-1998 Mark Adler
7 Pascal tranlastion
8 Copyright (C) 1998 by Jacques Nomssi Nzali
9 For conditions of distribution and use, see copyright notice in readme.txt
10 }
12 interface
14 {$I imzconf.inc}
16 uses
17 {$IFDEF DEBUG}
18 SysUtils, strutils,
19 {$ENDIF}
20 imzutil, impaszlib;
22 function inflate_blocks_new(var z : z_stream;
23 c : check_func; { check function }
24 w : uInt { window size }
25 ) : pInflate_blocks_state;
27 function inflate_blocks (var s : inflate_blocks_state;
28 var z : z_stream;
29 r : int { initial return code }
30 ) : int;
32 procedure inflate_blocks_reset (var s : inflate_blocks_state;
33 var z : z_stream;
34 c : puLong); { check value on output }
37 function inflate_blocks_free(s : pInflate_blocks_state;
38 var z : z_stream) : int;
40 procedure inflate_set_dictionary(var s : inflate_blocks_state;
41 const d : array of byte; { dictionary }
42 n : uInt); { dictionary length }
44 function inflate_blocks_sync_point(var s : inflate_blocks_state) : int;
46 implementation
48 uses
49 iminfcodes, iminftrees, iminfutil;
51 { Tables for deflate from PKZIP's appnote.txt. }
52 Const
53 border : Array [0..18] Of Word { Order of the bit length code lengths }
54 = (16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
56 { Notes beyond the 1.93a appnote.txt:
58 1. Distance pointers never point before the beginning of the output
59 stream.
60 2. Distance pointers can point back across blocks, up to 32k away.
61 3. There is an implied maximum of 7 bits for the bit length table and
62 15 bits for the actual data.
63 4. If only one code exists, then it is encoded using one bit. (Zero
64 would be more efficient, but perhaps a little confusing.) If two
65 codes exist, they are coded using one bit each (0 and 1).
66 5. There is no way of sending zero distance codes--a dummy must be
67 sent if there are none. (History: a pre 2.0 version of PKZIP would
68 store blocks with no distance codes, but this was discovered to be
69 too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
70 zero distance codes, which is sent as one code of zero bits in
71 length.
72 6. There are up to 286 literal/length codes. Code 256 represents the
73 end-of-block. Note however that the static length tree defines
74 288 codes just to fill out the Huffman codes. Codes 286 and 287
75 cannot be used though, since there is no length base or extra bits
76 defined for them. Similarily, there are up to 30 distance codes.
77 However, static trees define 32 codes (all 5 bits) to fill out the
78 Huffman codes, but the last two had better not show up in the data.
79 7. Unzip can check dynamic Huffman blocks for complete code sets.
80 The exception is that a single code would not be complete (see #4).
81 8. The five bits following the block type is really the number of
82 literal codes sent minus 257.
83 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
84 (1+6+6). Therefore, to output three times the length, you output
85 three codes (1+1+1), whereas to output four times the same length,
86 you only need two codes (1+3). Hmm.
87 10. In the tree reconstruction algorithm, Code = Code + Increment
88 only if BitLength(i) is not zero. (Pretty obvious.)
89 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
90 12. Note: length code 284 can represent 227-258, but length code 285
91 really is 258. The last length deserves its own, short code
92 since it gets used a lot in very redundant files. The length
93 258 is special since 258 - 3 (the min match length) is 255.
94 13. The literal/length and distance code bit lengths are read as a
95 single stream of lengths. It is possible (and advantageous) for
96 a repeat code (16, 17, or 18) to go across the boundary between
97 the two sets of lengths. }
100 procedure inflate_blocks_reset (var s : inflate_blocks_state;
101 var z : z_stream;
102 c : puLong); { check value on output }
103 begin
104 if (c <> Z_NULL) then
105 c^ := s.check;
106 if (s.mode = BTREE) or (s.mode = DTREE) then
107 ZFREE(z, s.sub.trees.blens);
108 if (s.mode = CODES) then
109 inflate_codes_free(s.sub.decode.codes, z);
111 s.mode := ZTYPE;
112 s.bitk := 0;
113 s.bitb := 0;
115 s.write := s.window;
116 s.read := s.window;
117 if Assigned(s.checkfn) then
118 begin
119 s.check := s.checkfn(uLong(0), pBytef(NIL), 0);
120 z.adler := s.check;
121 end;
122 {$IFDEF DEBUG}
123 Tracev('inflate: blocks reset');
124 {$ENDIF}
125 end;
128 function inflate_blocks_new(var z : z_stream;
129 c : check_func; { check function }
130 w : uInt { window size }
131 ) : pInflate_blocks_state;
132 var
133 s : pInflate_blocks_state;
134 begin
135 s := pInflate_blocks_state( ZALLOC(z,1, sizeof(inflate_blocks_state)) );
136 if (s = Z_NULL) then
137 begin
138 inflate_blocks_new := s;
139 exit;
140 end;
141 s^.hufts := huft_ptr( ZALLOC(z, sizeof(inflate_huft), MANY) );
143 if (s^.hufts = Z_NULL) then
144 begin
145 ZFREE(z, s);
146 inflate_blocks_new := Z_NULL;
147 exit;
148 end;
150 s^.window := pBytef( ZALLOC(z, 1, w) );
151 if (s^.window = Z_NULL) then
152 begin
153 ZFREE(z, s^.hufts);
154 ZFREE(z, s);
155 inflate_blocks_new := Z_NULL;
156 exit;
157 end;
158 s^.zend := s^.window;
159 Inc(s^.zend, w);
160 s^.checkfn := c;
161 s^.mode := ZTYPE;
162 {$IFDEF DEBUG}
163 Tracev('inflate: blocks allocated');
164 {$ENDIF}
165 inflate_blocks_reset(s^, z, Z_NULL);
166 inflate_blocks_new := s;
167 end;
170 function inflate_blocks (var s : inflate_blocks_state;
171 var z : z_stream;
172 r : int) : int; { initial return code }
173 label
174 start_btree, start_dtree,
175 start_blkdone, start_dry,
176 start_codes;
178 var
179 t : uInt; { temporary storage }
180 b : uLong; { bit buffer }
181 k : uInt; { bits in bit buffer }
182 p : pBytef; { input data pointer }
183 n : uInt; { bytes available there }
184 q : pBytef; { output window write pointer }
185 m : uInt; { bytes to end of window or read pointer }
186 { fixed code blocks }
187 var
188 bl, bd : uInt;
189 tl, td : pInflate_huft;
190 var
191 h : pInflate_huft;
192 i, j, c : uInt;
193 var
194 cs : pInflate_codes_state;
195 begin
196 { copy input/output information to locals }
197 p := z.next_in;
198 n := z.avail_in;
199 b := s.bitb;
200 k := s.bitk;
201 q := s.write;
202 if ptr2int(q) < ptr2int(s.read) then
203 m := uInt(ptr2int(s.read)-ptr2int(q)-1)
204 else
205 m := uInt(ptr2int(s.zend)-ptr2int(q));
207 { decompress an inflated block }
210 { process input based on current state }
211 while True do
212 Case s.mode of
213 ZTYPE:
214 begin
215 {NEEDBITS(3);}
216 while (k < 3) do
217 begin
218 {NEEDBYTE;}
219 if (n <> 0) then
220 r :=Z_OK
221 else
222 begin
223 {UPDATE}
224 s.bitb := b;
225 s.bitk := k;
226 z.avail_in := n;
227 Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));
228 z.next_in := p;
229 s.write := q;
230 inflate_blocks := inflate_flush(s,z,r);
231 exit;
232 end;
233 Dec(n);
234 b := b or (uLong(p^) shl k);
235 Inc(p);
236 Inc(k, 8);
237 end;
239 t := uInt(b) and 7;
240 s.last := boolean(t and 1);
241 case (t shr 1) of
242 0: { stored }
243 begin
244 {$IFDEF DEBUG}
245 if s.last then
246 Tracev('inflate: stored block (last)')
247 else
248 Tracev('inflate: stored block');
249 {$ENDIF}
250 {DUMPBITS(3);}
251 b := b shr 3;
252 Dec(k, 3);
254 t := k and 7; { go to byte boundary }
255 {DUMPBITS(t);}
256 b := b shr t;
257 Dec(k, t);
259 s.mode := LENS; { get length of stored block }
260 end;
261 1: { fixed }
262 begin
263 begin
264 {$IFDEF DEBUG}
265 if s.last then
266 Tracev('inflate: fixed codes blocks (last)')
267 else
268 Tracev('inflate: fixed codes blocks');
269 {$ENDIF}
270 inflate_trees_fixed(bl, bd, tl, td, z);
271 s.sub.decode.codes := inflate_codes_new(bl, bd, tl, td, z);
272 if (s.sub.decode.codes = Z_NULL) then
273 begin
274 r := Z_MEM_ERROR;
275 { update pointers and return }
276 s.bitb := b;
277 s.bitk := k;
278 z.avail_in := n;
279 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
280 z.next_in := p;
281 s.write := q;
282 inflate_blocks := inflate_flush(s,z,r);
283 exit;
284 end;
285 end;
286 {DUMPBITS(3);}
287 b := b shr 3;
288 Dec(k, 3);
290 s.mode := CODES;
291 end;
292 2: { dynamic }
293 begin
294 {$IFDEF DEBUG}
295 if s.last then
296 Tracev('inflate: dynamic codes block (last)')
297 else
298 Tracev('inflate: dynamic codes block');
299 {$ENDIF}
300 {DUMPBITS(3);}
301 b := b shr 3;
302 Dec(k, 3);
304 s.mode := TABLE;
305 end;
306 3:
307 begin { illegal }
308 {DUMPBITS(3);}
309 b := b shr 3;
310 Dec(k, 3);
312 s.mode := BLKBAD;
313 z.msg := 'invalid block type';
314 r := Z_DATA_ERROR;
315 { update pointers and return }
316 s.bitb := b;
317 s.bitk := k;
318 z.avail_in := n;
319 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
320 z.next_in := p;
321 s.write := q;
322 inflate_blocks := inflate_flush(s,z,r);
323 exit;
324 end;
325 end;
326 end;
327 LENS:
328 begin
329 {NEEDBITS(32);}
330 while (k < 32) do
331 begin
332 {NEEDBYTE;}
333 if (n <> 0) then
334 r :=Z_OK
335 else
336 begin
337 {UPDATE}
338 s.bitb := b;
339 s.bitk := k;
340 z.avail_in := n;
341 Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));
342 z.next_in := p;
343 s.write := q;
344 inflate_blocks := inflate_flush(s,z,r);
345 exit;
346 end;
347 Dec(n);
348 b := b or (uLong(p^) shl k);
349 Inc(p);
350 Inc(k, 8);
351 end;
353 if (((not b) shr 16) and $ffff) <> (b and $ffff) then
354 begin
355 s.mode := BLKBAD;
356 z.msg := 'invalid stored block lengths';
357 r := Z_DATA_ERROR;
358 { update pointers and return }
359 s.bitb := b;
360 s.bitk := k;
361 z.avail_in := n;
362 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
363 z.next_in := p;
364 s.write := q;
365 inflate_blocks := inflate_flush(s,z,r);
366 exit;
367 end;
368 s.sub.left := uInt(b) and $ffff;
369 k := 0;
370 b := 0; { dump bits }
371 {$IFDEF DEBUG}
372 Tracev('inflate: stored length '+IntToStr(s.sub.left));
373 {$ENDIF}
374 if s.sub.left <> 0 then
375 s.mode := STORED
376 else
377 if s.last then
378 s.mode := DRY
379 else
380 s.mode := ZTYPE;
381 end;
382 STORED:
383 begin
384 if (n = 0) then
385 begin
386 { update pointers and return }
387 s.bitb := b;
388 s.bitk := k;
389 z.avail_in := n;
390 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
391 z.next_in := p;
392 s.write := q;
393 inflate_blocks := inflate_flush(s,z,r);
394 exit;
395 end;
396 {NEEDOUT}
397 if (m = 0) then
398 begin
399 {WRAP}
400 if (q = s.zend) and (s.read <> s.window) then
401 begin
402 q := s.window;
403 if ptr2int(q) < ptr2int(s.read) then
404 m := uInt(ptr2int(s.read)-ptr2int(q)-1)
405 else
406 m := uInt(ptr2int(s.zend)-ptr2int(q));
407 end;
409 if (m = 0) then
410 begin
411 {FLUSH}
412 s.write := q;
413 r := inflate_flush(s,z,r);
414 q := s.write;
415 if ptr2int(q) < ptr2int(s.read) then
416 m := uInt(ptr2int(s.read)-ptr2int(q)-1)
417 else
418 m := uInt(ptr2int(s.zend)-ptr2int(q));
420 {WRAP}
421 if (q = s.zend) and (s.read <> s.window) then
422 begin
423 q := s.window;
424 if ptr2int(q) < ptr2int(s.read) then
425 m := uInt(ptr2int(s.read)-ptr2int(q)-1)
426 else
427 m := uInt(ptr2int(s.zend)-ptr2int(q));
428 end;
430 if (m = 0) then
431 begin
432 {UPDATE}
433 s.bitb := b;
434 s.bitk := k;
435 z.avail_in := n;
436 Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));
437 z.next_in := p;
438 s.write := q;
439 inflate_blocks := inflate_flush(s,z,r);
440 exit;
441 end;
442 end;
443 end;
444 r := Z_OK;
446 t := s.sub.left;
447 if (t > n) then
448 t := n;
449 if (t > m) then
450 t := m;
451 zmemcpy(q, p, t);
452 Inc(p, t); Dec(n, t);
453 Inc(q, t); Dec(m, t);
454 Dec(s.sub.left, t);
455 if (s.sub.left = 0) then
456 begin
457 {$IFDEF DEBUG}
458 if (ptr2int(q) >= ptr2int(s.read)) then
459 Tracev('inflate: stored end '+
460 IntToStr(z.total_out + ptr2int(q) - ptr2int(s.read)) + ' total out')
461 else
462 Tracev('inflate: stored end '+
463 IntToStr(z.total_out + ptr2int(s.zend) - ptr2int(s.read) +
464 ptr2int(q) - ptr2int(s.window)) + ' total out');
465 {$ENDIF}
466 if s.last then
467 s.mode := DRY
468 else
469 s.mode := ZTYPE;
470 end;
471 end;
472 TABLE:
473 begin
474 {NEEDBITS(14);}
475 while (k < 14) do
476 begin
477 {NEEDBYTE;}
478 if (n <> 0) then
479 r :=Z_OK
480 else
481 begin
482 {UPDATE}
483 s.bitb := b;
484 s.bitk := k;
485 z.avail_in := n;
486 Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));
487 z.next_in := p;
488 s.write := q;
489 inflate_blocks := inflate_flush(s,z,r);
490 exit;
491 end;
492 Dec(n);
493 b := b or (uLong(p^) shl k);
494 Inc(p);
495 Inc(k, 8);
496 end;
498 t := uInt(b) and $3fff;
499 s.sub.trees.table := t;
500 {$ifndef PKZIP_BUG_WORKAROUND}
501 if ((t and $1f) > 29) or (((t shr 5) and $1f) > 29) then
502 begin
503 s.mode := BLKBAD;
504 z.msg := 'too many length or distance symbols';
505 r := Z_DATA_ERROR;
506 { update pointers and return }
507 s.bitb := b;
508 s.bitk := k;
509 z.avail_in := n;
510 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
511 z.next_in := p;
512 s.write := q;
513 inflate_blocks := inflate_flush(s,z,r);
514 exit;
515 end;
516 {$endif}
517 t := 258 + (t and $1f) + ((t shr 5) and $1f);
518 s.sub.trees.blens := puIntArray( ZALLOC(z, t, sizeof(uInt)) );
519 if (s.sub.trees.blens = Z_NULL) then
520 begin
521 r := Z_MEM_ERROR;
522 { update pointers and return }
523 s.bitb := b;
524 s.bitk := k;
525 z.avail_in := n;
526 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
527 z.next_in := p;
528 s.write := q;
529 inflate_blocks := inflate_flush(s,z,r);
530 exit;
531 end;
532 {DUMPBITS(14);}
533 b := b shr 14;
534 Dec(k, 14);
536 s.sub.trees.index := 0;
537 {$IFDEF DEBUG}
538 Tracev('inflate: table sizes ok');
539 {$ENDIF}
540 s.mode := BTREE;
541 { fall trough case is handled by the while }
542 { try GOTO for speed - Nomssi }
543 goto start_btree;
544 end;
545 BTREE:
546 begin
547 start_btree:
548 while (s.sub.trees.index < 4 + (s.sub.trees.table shr 10)) do
549 begin
550 {NEEDBITS(3);}
551 while (k < 3) do
552 begin
553 {NEEDBYTE;}
554 if (n <> 0) then
555 r :=Z_OK
556 else
557 begin
558 {UPDATE}
559 s.bitb := b;
560 s.bitk := k;
561 z.avail_in := n;
562 Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));
563 z.next_in := p;
564 s.write := q;
565 inflate_blocks := inflate_flush(s,z,r);
566 exit;
567 end;
568 Dec(n);
569 b := b or (uLong(p^) shl k);
570 Inc(p);
571 Inc(k, 8);
572 end;
574 s.sub.trees.blens^[border[s.sub.trees.index]] := uInt(b) and 7;
575 Inc(s.sub.trees.index);
576 {DUMPBITS(3);}
577 b := b shr 3;
578 Dec(k, 3);
579 end;
580 while (s.sub.trees.index < 19) do
581 begin
582 s.sub.trees.blens^[border[s.sub.trees.index]] := 0;
583 Inc(s.sub.trees.index);
584 end;
585 s.sub.trees.bb := 7;
586 t := inflate_trees_bits(s.sub.trees.blens^, s.sub.trees.bb,
587 s.sub.trees.tb, s.hufts^, z);
588 if (t <> Z_OK) then
589 begin
590 ZFREE(z, s.sub.trees.blens);
591 r := t;
592 if (r = Z_DATA_ERROR) then
593 s.mode := BLKBAD;
594 { update pointers and return }
595 s.bitb := b;
596 s.bitk := k;
597 z.avail_in := n;
598 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
599 z.next_in := p;
600 s.write := q;
601 inflate_blocks := inflate_flush(s,z,r);
602 exit;
603 end;
604 s.sub.trees.index := 0;
605 {$IFDEF DEBUG}
606 Tracev('inflate: bits tree ok');
607 {$ENDIF}
608 s.mode := DTREE;
609 { fall through again }
610 goto start_dtree;
611 end;
612 DTREE:
613 begin
614 start_dtree:
615 while TRUE do
616 begin
617 t := s.sub.trees.table;
618 if not (s.sub.trees.index < 258 +
619 (t and $1f) + ((t shr 5) and $1f)) then
620 break;
621 t := s.sub.trees.bb;
622 {NEEDBITS(t);}
623 while (k < t) do
624 begin
625 {NEEDBYTE;}
626 if (n <> 0) then
627 r :=Z_OK
628 else
629 begin
630 {UPDATE}
631 s.bitb := b;
632 s.bitk := k;
633 z.avail_in := n;
634 Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));
635 z.next_in := p;
636 s.write := q;
637 inflate_blocks := inflate_flush(s,z,r);
638 exit;
639 end;
640 Dec(n);
641 b := b or (uLong(p^) shl k);
642 Inc(p);
643 Inc(k, 8);
644 end;
646 h := s.sub.trees.tb;
647 Inc(h, uInt(b) and inflate_mask[t]);
648 t := h^.Bits;
649 c := h^.Base;
651 if (c < 16) then
652 begin
653 {DUMPBITS(t);}
654 b := b shr t;
655 Dec(k, t);
657 s.sub.trees.blens^[s.sub.trees.index] := c;
658 Inc(s.sub.trees.index);
659 end
660 else { c = 16..18 }
661 begin
662 if c = 18 then
663 begin
664 i := 7;
665 j := 11;
666 end
667 else
668 begin
669 i := c - 14;
670 j := 3;
671 end;
672 {NEEDBITS(t + i);}
673 while (k < t + i) do
674 begin
675 {NEEDBYTE;}
676 if (n <> 0) then
677 r :=Z_OK
678 else
679 begin
680 {UPDATE}
681 s.bitb := b;
682 s.bitk := k;
683 z.avail_in := n;
684 Inc(z.total_in, ptr2int(p)-ptr2int(z.next_in));
685 z.next_in := p;
686 s.write := q;
687 inflate_blocks := inflate_flush(s,z,r);
688 exit;
689 end;
690 Dec(n);
691 b := b or (uLong(p^) shl k);
692 Inc(p);
693 Inc(k, 8);
694 end;
696 {DUMPBITS(t);}
697 b := b shr t;
698 Dec(k, t);
700 Inc(j, uInt(b) and inflate_mask[i]);
701 {DUMPBITS(i);}
702 b := b shr i;
703 Dec(k, i);
705 i := s.sub.trees.index;
706 t := s.sub.trees.table;
707 if (i + j > 258 + (t and $1f) + ((t shr 5) and $1f)) or
708 ((c = 16) and (i < 1)) then
709 begin
710 ZFREE(z, s.sub.trees.blens);
711 s.mode := BLKBAD;
712 z.msg := 'invalid bit length repeat';
713 r := Z_DATA_ERROR;
714 { update pointers and return }
715 s.bitb := b;
716 s.bitk := k;
717 z.avail_in := n;
718 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
719 z.next_in := p;
720 s.write := q;
721 inflate_blocks := inflate_flush(s,z,r);
722 exit;
723 end;
724 if c = 16 then
725 c := s.sub.trees.blens^[i - 1]
726 else
727 c := 0;
728 repeat
729 s.sub.trees.blens^[i] := c;
730 Inc(i);
731 Dec(j);
732 until (j=0);
733 s.sub.trees.index := i;
734 end;
735 end; { while }
736 s.sub.trees.tb := Z_NULL;
737 begin
738 bl := 9; { must be <= 9 for lookahead assumptions }
739 bd := 6; { must be <= 9 for lookahead assumptions }
740 t := s.sub.trees.table;
741 t := inflate_trees_dynamic(257 + (t and $1f),
742 1 + ((t shr 5) and $1f),
743 s.sub.trees.blens^, bl, bd, tl, td, s.hufts^, z);
744 ZFREE(z, s.sub.trees.blens);
745 if (t <> Z_OK) then
746 begin
747 if (t = uInt(Z_DATA_ERROR)) then
748 s.mode := BLKBAD;
749 r := t;
750 { update pointers and return }
751 s.bitb := b;
752 s.bitk := k;
753 z.avail_in := n;
754 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
755 z.next_in := p;
756 s.write := q;
757 inflate_blocks := inflate_flush(s,z,r);
758 exit;
759 end;
760 {$IFDEF DEBUG}
761 Tracev('inflate: trees ok');
762 {$ENDIF}
763 { c renamed to cs }
764 cs := inflate_codes_new(bl, bd, tl, td, z);
765 if (cs = Z_NULL) then
766 begin
767 r := Z_MEM_ERROR;
768 { update pointers and return }
769 s.bitb := b;
770 s.bitk := k;
771 z.avail_in := n;
772 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
773 z.next_in := p;
774 s.write := q;
775 inflate_blocks := inflate_flush(s,z,r);
776 exit;
777 end;
778 s.sub.decode.codes := cs;
779 end;
780 s.mode := CODES;
781 { yet another falltrough }
782 goto start_codes;
783 end;
784 CODES:
785 begin
786 start_codes:
787 { update pointers }
788 s.bitb := b;
789 s.bitk := k;
790 z.avail_in := n;
791 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
792 z.next_in := p;
793 s.write := q;
795 r := inflate_codes(s, z, r);
796 if (r <> Z_STREAM_END) then
797 begin
798 inflate_blocks := inflate_flush(s, z, r);
799 exit;
800 end;
801 r := Z_OK;
802 inflate_codes_free(s.sub.decode.codes, z);
803 { load local pointers }
804 p := z.next_in;
805 n := z.avail_in;
806 b := s.bitb;
807 k := s.bitk;
808 q := s.write;
809 if ptr2int(q) < ptr2int(s.read) then
810 m := uInt(ptr2int(s.read)-ptr2int(q)-1)
811 else
812 m := uInt(ptr2int(s.zend)-ptr2int(q));
813 {$IFDEF DEBUG}
814 if (ptr2int(q) >= ptr2int(s.read)) then
815 Tracev('inflate: codes end '+
816 IntToStr(z.total_out + ptr2int(q) - ptr2int(s.read)) + ' total out')
817 else
818 Tracev('inflate: codes end '+
819 IntToStr(z.total_out + ptr2int(s.zend) - ptr2int(s.read) +
820 ptr2int(q) - ptr2int(s.window)) + ' total out');
821 {$ENDIF}
822 if (not s.last) then
823 begin
824 s.mode := ZTYPE;
825 continue; { break for switch statement in C-code }
826 end;
827 {$ifndef patch112}
828 if (k > 7) then { return unused byte, if any }
829 begin
830 {$IFDEF DEBUG}
831 Assert(k < 16, 'inflate_codes grabbed too many bytes');
832 {$ENDIF}
833 Dec(k, 8);
834 Inc(n);
835 Dec(p); { can always return one }
836 end;
837 {$endif}
838 s.mode := DRY;
839 { another falltrough }
840 goto start_dry;
841 end;
842 DRY:
843 begin
844 start_dry:
845 {FLUSH}
846 s.write := q;
847 r := inflate_flush(s,z,r);
848 q := s.write;
850 { not needed anymore, we are done:
851 if ptr2int(q) < ptr2int(s.read) then
852 m := uInt(ptr2int(s.read)-ptr2int(q)-1)
853 else
854 m := uInt(ptr2int(s.zend)-ptr2int(q));
857 if (s.read <> s.write) then
858 begin
859 { update pointers and return }
860 s.bitb := b;
861 s.bitk := k;
862 z.avail_in := n;
863 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
864 z.next_in := p;
865 s.write := q;
866 inflate_blocks := inflate_flush(s,z,r);
867 exit;
868 end;
869 s.mode := BLKDONE;
870 goto start_blkdone;
871 end;
872 BLKDONE:
873 begin
874 start_blkdone:
875 r := Z_STREAM_END;
876 { update pointers and return }
877 s.bitb := b;
878 s.bitk := k;
879 z.avail_in := n;
880 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
881 z.next_in := p;
882 s.write := q;
883 inflate_blocks := inflate_flush(s,z,r);
884 exit;
885 end;
886 BLKBAD:
887 begin
888 r := Z_DATA_ERROR;
889 { update pointers and return }
890 s.bitb := b;
891 s.bitk := k;
892 z.avail_in := n;
893 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
894 z.next_in := p;
895 s.write := q;
896 inflate_blocks := inflate_flush(s,z,r);
897 exit;
898 end;
899 else
900 begin
901 r := Z_STREAM_ERROR;
902 { update pointers and return }
903 s.bitb := b;
904 s.bitk := k;
905 z.avail_in := n;
906 Inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
907 z.next_in := p;
908 s.write := q;
909 inflate_blocks := inflate_flush(s,z,r);
910 exit;
911 end;
912 end; { Case s.mode of }
914 end;
917 function inflate_blocks_free(s : pInflate_blocks_state;
918 var z : z_stream) : int;
919 begin
920 inflate_blocks_reset(s^, z, Z_NULL);
921 ZFREE(z, s^.window);
922 ZFREE(z, s^.hufts);
923 ZFREE(z, s);
924 {$IFDEF DEBUG}
925 Trace('inflate: blocks freed');
926 {$ENDIF}
927 inflate_blocks_free := Z_OK;
928 end;
931 procedure inflate_set_dictionary(var s : inflate_blocks_state;
932 const d : array of byte; { dictionary }
933 n : uInt); { dictionary length }
934 begin
935 zmemcpy(s.window, pBytef(@d), n);
936 s.write := s.window;
937 Inc(s.write, n);
938 s.read := s.write;
939 end;
942 { Returns true if inflate is currently at the end of a block generated
943 by Z_SYNC_FLUSH or Z_FULL_FLUSH.
944 IN assertion: s <> Z_NULL }
946 function inflate_blocks_sync_point(var s : inflate_blocks_state) : int;
947 begin
948 inflate_blocks_sync_point := int(s.mode = LENS);
949 end;
951 end.