Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | daniel-mar | 1 | (* **************************************************************** *) |
2 | (* SFX for DelZip v1.8 *) |
||
3 | (* Copyright 1997, Microchip Systems / Carl Bunton *) |
||
4 | (* e-mail: Twojags@cris.com *) |
||
5 | (* Web-page: http://www.concentric.net/~twojags *) |
||
6 | (* *) |
||
7 | (* This code is not for redistribution in whole or in part. It *) |
||
8 | (* may be used in compiled program format only. *) |
||
9 | (* *) |
||
10 | (* modified by Markus Stephany *) |
||
11 | (* modified by Russell Peters, Roger Aelbrecht |
||
12 | This library is free software; you can redistribute it and/or |
||
13 | modify it under the terms of the GNU Lesser General Public |
||
14 | License as published by the Free Software Foundation; either |
||
15 | version 2.1 of the License, or (at your option) any later version. |
||
16 | |||
17 | This library is distributed in the hope that it will be useful, |
||
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
20 | Lesser General Public License (licence.txt) for more details. |
||
21 | |||
22 | You should have received a copy of the GNU Lesser General Public |
||
23 | License along with this library; if not, write to the Free Software |
||
24 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||
25 | |||
26 | contact: problems AT delphizip DOT org |
||
27 | updates: http://www.delphizip.org |
||
28 | |||
29 | modified 30-Jan-2008 |
||
30 | --------------------------------------------------------------------------- *) |
||
31 | |||
32 | unit ZMSFXInflate19; |
||
33 | |||
34 | { |
||
35 | INFLATE method |
||
36 | |||
37 | } |
||
38 | |||
39 | interface |
||
40 | |||
41 | uses ZMSFXDefs19, Windows; |
||
42 | {$DEFINE PKZIP_BUG_WORKAROUND} |
||
43 | procedure Inflate(mem: pointer; size: Integer); |
||
44 | |||
45 | implementation |
||
46 | |||
47 | uses ZMSFXVars19, ZMSFXProcs19, ZMSFXStructs19; |
||
48 | |||
49 | var |
||
50 | hufts: WORD; |
||
51 | bb: LONGINT; { bit buffer (Static) } |
||
52 | bk: WORD; { bits in bit buffer (Static) } |
||
53 | InBuf: BufPtr; |
||
54 | Slide: BufPtr; |
||
55 | InPTR: WORD; { Index FOR ZipFile input buffer } |
||
56 | ZipCount: Cardinal; { Count OF bytes in ZipFile input buffer } |
||
57 | InfMem: boolean; |
||
58 | |||
59 | WP: WORD; { Static Global } |
||
60 | fixed_tl, fixed_td: PT; { Static Global } |
||
61 | |||
62 | function GetNextByte: Integer; |
||
63 | var |
||
64 | i: Integer; |
||
65 | begin |
||
66 | { EndFile := false; } |
||
67 | if InPTR >= ZipCount then |
||
68 | begin |
||
69 | if not InfMem then |
||
70 | ZipCount := FRead(InBuf^, Min(VInt_BytesToGo, WSIZE)); |
||
71 | |||
72 | if ((VRec_ZipHeader.Flag and 1) = 1) and (ZipCount > 0) then |
||
73 | begin |
||
74 | for i := 0 to ZipCount - 1 do |
||
75 | begin |
||
76 | InBuf[i] := InBuf[i] xor decrypt_byte; |
||
77 | UpdateKeys(BYTE(InBuf[i])); |
||
78 | end; |
||
79 | end; |
||
80 | InPTR := 0; |
||
81 | end; |
||
82 | |||
83 | if ZipCount = 0 then |
||
84 | begin |
||
85 | { EndFile := TRUE; } |
||
86 | VInt_BytesToGo := 0; |
||
87 | InPTR := 0; |
||
88 | GetNextByte := -1; |
||
89 | end |
||
90 | else |
||
91 | begin |
||
92 | GetNextByte := InBuf^[InPTR]; |
||
93 | Inc(InPTR); |
||
94 | end; |
||
95 | end; |
||
96 | (* -------------------------------------------------------------------------- *) |
||
97 | |||
98 | function Get_Compressed: Integer; |
||
99 | begin |
||
100 | (* Unshrink & UnReduce & Explode & Inflate *) |
||
101 | |||
102 | if VInt_BytesToGo <= 0 then |
||
103 | Result := -1 |
||
104 | else |
||
105 | begin |
||
106 | Result := GetNextByte; |
||
107 | Dec(VInt_BytesToGo); |
||
108 | end; |
||
109 | end; |
||
110 | (* -------------------------------------------------------------------------- *) |
||
111 | |||
112 | procedure NEEDBITS(n: WORD; var b: LONGINT; var k: WORD); |
||
113 | var |
||
114 | c: Integer; |
||
115 | begin |
||
116 | while (k < n) do |
||
117 | begin |
||
118 | c := Get_Compressed; |
||
119 | b := b or LONGINT(c) shl k; { no parens!! } |
||
120 | Inc(k, 8); |
||
121 | end; |
||
122 | end; |
||
123 | (* -------------------------------------------------------------------------- *) |
||
124 | |||
125 | procedure DUMPBITS(n: WORD; var b: LONGINT; var k: WORD); |
||
126 | begin |
||
127 | b := b shr n; |
||
128 | k := k - n; |
||
129 | end; |
||
130 | (* -------------------------------------------------------------------------- *) |
||
131 | |||
132 | { "decompress" an inflated type 0 (stored) block. } |
||
133 | |||
134 | procedure inflate_stored; |
||
135 | var |
||
136 | n: WORD; { number OF bytes in block } |
||
137 | w: WORD; { current window position } |
||
138 | b: LONGINT; { bit buffer } |
||
139 | k: WORD; { number OF bits in bit buffer } |
||
140 | begin |
||
141 | |||
142 | { make local copies OF globals } |
||
143 | b := bb; { initialize bit buffer } |
||
144 | k := bk; |
||
145 | w := WP; { initialize window position } |
||
146 | |||
147 | { go TO BYTE boundary } |
||
148 | n := k and 7; |
||
149 | DUMPBITS(n, b, k); |
||
150 | |||
151 | { get the length AND its complement } |
||
152 | NEEDBITS(16, b, k); |
||
153 | n := (WORD(b) and $FFFF); |
||
154 | DUMPBITS(16, b, k); |
||
155 | NEEDBITS(16, b, k); |
||
156 | |||
157 | if (n <> (not WORD(b)) and $FFFF) then |
||
158 | begin |
||
159 | WP := 0; |
||
160 | |||
161 | (* *********** REM'D RAISE ************* *) |
||
162 | // raise E_RAISE.Create(LoadStr(E_BADBLOCK)); |
||
163 | end; |
||
164 | |||
165 | DUMPBITS(16, b, k); |
||
166 | |||
167 | { read AND output the compressed data } |
||
168 | while (n <> 0) do |
||
169 | begin |
||
170 | Dec(n); |
||
171 | NEEDBITS(8, b, k); |
||
172 | Slide^[w] := WORD(b); |
||
173 | Inc(w); |
||
174 | |||
175 | if (w = WORD(WSIZE)) then |
||
176 | begin |
||
177 | CheckFWrite(VH_OutFile, Slide^, w, VStr_OutFile); |
||
178 | |||
179 | crc32_buf(PByte(Slide), w, VDW_CRC32Val); |
||
180 | w := 0; |
||
181 | end; |
||
182 | DUMPBITS(8, b, k); |
||
183 | end; |
||
184 | |||
185 | { restore the globals from the locals } |
||
186 | WP := w; { restore global window pointer } |
||
187 | bb := b; { restore global bit buffer } |
||
188 | bk := k; |
||
189 | end; |
||
190 | (* -------------------------------------------------------------------------- *) |
||
191 | |||
192 | function huft_free(t: PT): Integer; |
||
193 | { Free the malloc'ed tables built by huft_build(), which makes a linked |
||
194 | list OF the tables it made, with the links in a dummy first entry OF |
||
195 | each table. } |
||
196 | var |
||
197 | p, q: PT; |
||
198 | begin |
||
199 | { Go through linked list, freeing from the malloced (t[-1]) address. } |
||
200 | p := t; |
||
201 | { p :=t.next; } |
||
202 | while (p <> nil) do |
||
203 | begin |
||
204 | Dec(p); |
||
205 | q := p^.Next; |
||
206 | FreeMem(p); |
||
207 | p := q; |
||
208 | end; |
||
209 | Result := 0; |
||
210 | end; |
||
211 | (* -------------------------------------------------------------------------- *) |
||
212 | |||
213 | function huft_build(var b: array of WORD; n, s: WORD; const d: array of WORD; |
||
214 | const e: array of BYTE; var t, HF: PT; var m: Integer): Integer; |
||
215 | const |
||
216 | BMAX = 16; |
||
217 | var |
||
218 | a: WORD; |
||
219 | c: array [0 .. BMAX] of WORD; { bit length count table } |
||
220 | el: WORD; |
||
221 | f: WORD; |
||
222 | g: Integer; { maximum code length } |
||
223 | h: Integer; { table level } |
||
224 | i: WORD; { counter, current code / counter } |
||
225 | j: WORD; { counter } |
||
226 | k: Integer; { number OF bits in current code } |
||
227 | lx: array [-1 .. BMAX + 1] of Integer; |
||
228 | p: ^WORD; |
||
229 | q: PT; |
||
230 | r: Thuft; |
||
231 | u: array [0 .. BMAX] of PT; |
||
232 | v: array [0 .. N_MAX] of WORD; { values in order OF bit length } |
||
233 | w: WORD; |
||
234 | x: array [0 .. BMAX + 1] of WORD; { bit offsets, THEN code stack } |
||
235 | xp: ^WORD; |
||
236 | y: Integer; |
||
237 | z: WORD; |
||
238 | begin |
||
239 | { Generate counts FOR each bit length } |
||
240 | if n > 256 then { set length OF EOB code, IF any } |
||
241 | el := b[256] |
||
242 | else |
||
243 | el := BMAX; |
||
244 | |||
245 | FillChar(c[0], SizeOf(c), 0); |
||
246 | |||
247 | p := @b; |
||
248 | i := n; |
||
249 | |||
250 | repeat |
||
251 | Inc(c[p^]); { assume all entries <= BMAX } |
||
252 | Inc(p); |
||
253 | Dec(i); |
||
254 | until (i = 0); |
||
255 | |||
256 | { null input--all zero length codes } |
||
257 | if c[0] = n then |
||
258 | begin |
||
259 | t := nil; |
||
260 | m := 0; |
||
261 | Result := 0; |
||
262 | Exit; |
||
263 | end; |
||
264 | |||
265 | { Find minimum AND maximum length, bound *m by those } |
||
266 | for j := 1 to BMAX do |
||
267 | if c[j] <> 0 then |
||
268 | Break; |
||
269 | |||
270 | k := j; { minimum code length } |
||
271 | |||
272 | if (WORD(m) < j) then |
||
273 | { m := INTEGER(j); } |
||
274 | m := j; |
||
275 | |||
276 | for i := BMAX downto 1 do |
||
277 | if c[i] <> 0 then |
||
278 | Break; |
||
279 | |||
280 | g := i; { maximum code length } |
||
281 | |||
282 | if WORD(m) > i then |
||
283 | m := Integer(i); |
||
284 | |||
285 | { Adjust last length count TO fill out codes, IF needed } |
||
286 | y := 1 shl j; |
||
287 | for j := j to i - 1 do |
||
288 | begin |
||
289 | y := y - c[j]; |
||
290 | if y < 0 then |
||
291 | begin |
||
292 | Result := 2; { bad input: more codes than bits } |
||
293 | Exit; |
||
294 | end; |
||
295 | y := y shl 1; |
||
296 | end; |
||
297 | |||
298 | y := y - c[i]; |
||
299 | if y < 0 then |
||
300 | begin |
||
301 | Result := 2; |
||
302 | Exit; |
||
303 | end; |
||
304 | |||
305 | Inc(c[i], y); |
||
306 | |||
307 | { Generate starting offsets into the value table FOR each length } |
||
308 | x[1] := 0; |
||
309 | j := 0; |
||
310 | |||
311 | p := @c[1]; |
||
312 | xp := @x[2]; |
||
313 | |||
314 | Dec(i); { note that i = g from above } |
||
315 | while (i > 0) do |
||
316 | begin |
||
317 | Inc(j, p^); |
||
318 | xp^ := j; |
||
319 | Inc(p); |
||
320 | Inc(xp); |
||
321 | Dec(i); |
||
322 | end; |
||
323 | |||
324 | { Make a table OF values in order OF bit lengths } |
||
325 | p := @b; |
||
326 | i := 0; |
||
327 | repeat |
||
328 | j := p^; |
||
329 | if (j <> 0) then |
||
330 | begin |
||
331 | v[x[j]] := i; |
||
332 | Inc(x[j]); |
||
333 | end; |
||
334 | Inc(p); |
||
335 | Inc(i); |
||
336 | until i >= n; |
||
337 | |||
338 | { Generate the Huffman codes AND FOR each, make the table entries } |
||
339 | h := -1; { no tables yet--level -1 } |
||
340 | i := 0; |
||
341 | lx[-1] := 0; { ditto } |
||
342 | p := @v; { grab values in bit order } |
||
343 | q := nil; { ditto } |
||
344 | t := nil; |
||
345 | u[0] := nil; { just TO keep compilers happy } |
||
346 | w := 0; { no bits decoded yet } |
||
347 | x[0] := 0; { first Huffman code is zero } |
||
348 | z := 0; { ditto } |
||
349 | |||
350 | { go through the bit lengths (k already is bits in shortest code) } |
||
351 | for k := k to g do |
||
352 | begin |
||
353 | a := c[k]; |
||
354 | while (a <> 0) do |
||
355 | begin |
||
356 | Dec(a); |
||
357 | |||
358 | { here i is the Huffman code OF length k bits FOR value *p } |
||
359 | { make tables up TO required level } |
||
360 | { WHILE k > INTEGER(w + lx[h]) DO } |
||
361 | while k > (w + lx[h]) do |
||
362 | begin |
||
363 | Inc(w, lx[h]); { add bits already decoded } |
||
364 | Inc(h); |
||
365 | |||
366 | { compute minimum size table less than or equal TO *m bits } |
||
367 | z := g - w; { upper limit } |
||
368 | { IF z > WORD(m) } |
||
369 | if z > m then |
||
370 | { z :=WORD(m); } |
||
371 | z := m; |
||
372 | |||
373 | { j := WORD(k - w); } |
||
374 | j := k - w; |
||
375 | f := 1 shl j; |
||
376 | if f > (a + 1) then { TRY a k-w bit table } |
||
377 | begin { too few codes FOR k-w bit table } |
||
378 | Dec(f, a + 1); { deduct codes from patterns left } |
||
379 | xp := @c[k]; |
||
380 | Inc(j); |
||
381 | while (j < z) do { TRY smaller tables up TO z bits } |
||
382 | begin |
||
383 | Inc(xp); |
||
384 | f := f shl 1; |
||
385 | if f <= xp^ then |
||
386 | Break; { enough codes TO use up j bits } |
||
387 | f := f - xp^; { ELSE deduct codes from patterns } |
||
388 | Inc(j); |
||
389 | end; |
||
390 | end; |
||
391 | |||
392 | if ((w + j > el) and (w < el)) then |
||
393 | j := el - w; { make EOB code END at table } |
||
394 | |||
395 | z := 1 shl j; { table entries FOR j-bit table } |
||
396 | lx[h] := j; { set table size in stack } |
||
397 | |||
398 | { allocate AND link in new table } |
||
399 | GetMem(q, (z + 1) * SizeOf(Thuft)); |
||
400 | if q = nil then |
||
401 | begin |
||
402 | if (h > 0) then |
||
403 | huft_free(u[0]); |
||
404 | Result := 3; |
||
405 | Exit; |
||
406 | end; |
||
407 | |||
408 | Inc(hufts, z + 1); { track memory usage } |
||
409 | r.Next := HF; |
||
410 | q^.Next := HF; |
||
411 | Inc(q); |
||
412 | HF := q; |
||
413 | u[h] := q; |
||
414 | |||
415 | // first block link |
||
416 | if t = nil then |
||
417 | t := q; |
||
418 | |||
419 | { connect TO last table, IF there is one } |
||
420 | if h > 0 then |
||
421 | begin |
||
422 | x[h] := i; { save pattern FOR backing up } |
||
423 | |||
424 | r.b := lx[h - 1]; { bits TO dump before this table } |
||
425 | r.e := (16 + j); { bits in this table } |
||
426 | r.Next := q; { pointer TO this table } |
||
427 | j := (i and ((1 shl w) - 1)) shr (w - lx[h - 1]); |
||
428 | |||
429 | { connect TO last table } |
||
430 | { **************************************************************** |
||
431 | Use the following line in the debugger TO verify the allocated |
||
432 | memory boundries with data being inserted. |
||
433 | * u[h - 1][j] = q; * |
||
434 | *-> (LONGINT(u[h-1])+(j*sizeof(Thuft))) - LONGINT(u[h-1]) <-* |
||
435 | **************************************************************** } |
||
436 | Move(r, pointer(Cardinal(u[h - 1]) + (j * SizeOf(Thuft)))^, SizeOf(r)); |
||
437 | end; |
||
438 | end; |
||
439 | |||
440 | { set up table entry in r } |
||
441 | r.b := ShortInt(k - w); |
||
442 | |||
443 | { IF (LONGINT(addr(p^)) >= LONGINT(addr(v[n]))) } |
||
444 | if (LONGINT(p) >= LONGINT(@v[n])) then |
||
445 | r.e := 99 { out OF values--invalid code } |
||
446 | else if (p^ < s) then |
||
447 | begin |
||
448 | if p^ < 256 then { 256 is END-OF-block code } |
||
449 | r.e := 16 |
||
450 | else |
||
451 | r.e := 15; |
||
452 | |||
453 | r.n := p^; { simple code is just the value } |
||
454 | Inc(p); |
||
455 | end |
||
456 | else |
||
457 | begin |
||
458 | r.e := e[p^ - s]; { non-simple--look up in lists } |
||
459 | r.n := d[p^ - s]; |
||
460 | Inc(p); |
||
461 | end; |
||
462 | |||
463 | { fill code-like entries with r } |
||
464 | f := 1 shl (k - w); |
||
465 | j := i shr w; |
||
466 | while (j < z) do |
||
467 | begin |
||
468 | { **************************************************************** |
||
469 | Use the following line in the debugger TO verify the allocated |
||
470 | memory boundries with data being inserted. |
||
471 | * q[j] = r; * |
||
472 | *-> (LONGINT(q)+(j*sizeof(Thuft))) - LONGINT(q) <-* |
||
473 | **************************************************************** } |
||
474 | Move(r, pointer(Cardinal(q) + (j * SizeOf(Thuft)))^, SizeOf(r)); |
||
475 | |||
476 | Inc(j, f); |
||
477 | end; |
||
478 | |||
479 | { backwards increment the k-bit code i } |
||
480 | j := 1 shl (k - 1); |
||
481 | while (i and j) <> 0 do { added... <> 0 } |
||
482 | begin |
||
483 | i := i xor j; { bitwise exclusive or } |
||
484 | j := j shr 1; |
||
485 | end; |
||
486 | |||
487 | i := i xor j; { bitwise exclusive or } |
||
488 | |||
489 | { backup over finished tables } |
||
490 | while ((i and ((1 shl w) - 1)) <> x[h]) do |
||
491 | begin |
||
492 | Dec(h); |
||
493 | Dec(w, lx[h]); { don't need TO update q } |
||
494 | end; |
||
495 | end; |
||
496 | end; |
||
497 | |||
498 | { return actual size OF base table } |
||
499 | m := Integer(lx[0]); |
||
500 | |||
501 | if (y <> 0) then |
||
502 | y := 1 |
||
503 | else |
||
504 | y := 0; |
||
505 | |||
506 | if (g <> 1) then |
||
507 | g := 1 |
||
508 | else |
||
509 | g := 0; |
||
510 | Result := (y and g); |
||
511 | |||
512 | { Return true (1) IF we were given an incomplete table } |
||
513 | { result := (y <> 0) AND (g <> 1); } |
||
514 | end; |
||
515 | (* -------------------------------------------------------------------------- *) |
||
516 | |||
517 | function inflate_codes(var tl, td: PT; bl, bd: Integer): Integer; |
||
518 | (* tl,td: literal/length AND distance decoder tables *) |
||
519 | (* bl,bd: number OF bits decoded by tl[] AND td[] *) |
||
520 | |||
521 | (* inflate (decompress) the codes in a deflated (compressed) block. |
||
522 | Return an error code or zero IF it all goes ok. *) |
||
523 | var |
||
524 | e: WORD; { table entry flag/number OF extra bits } |
||
525 | n, d: WORD; { length AND index FOR copy } |
||
526 | w: WORD; { current window position } |
||
527 | t: PT; { Thuft } { pointer TO table entry } |
||
528 | ml, md: WORD; { masks FOR bl AND bd bits } |
||
529 | b: LONGINT; { bit buffer } |
||
530 | k: WORD; { number OF bits in bit buffer } |
||
531 | begin |
||
532 | |||
533 | { make local copies OF globals } |
||
534 | b := bb; { initialize bit buffer } |
||
535 | k := bk; |
||
536 | w := WP; { initialize window position } |
||
537 | |||
538 | { inflate the coded data } |
||
539 | ml := maskr[bl]; { precompute masks FOR speed } |
||
540 | md := maskr[bd]; |
||
541 | repeat |
||
542 | NEEDBITS(bl, b, k); |
||
543 | t := pointer(LONGINT(tl) + ((WORD(b) and ml) * SizeOf(Thuft))); |
||
544 | { t :=ptr(seg(tl^), ofs(tl^)+ ((WORD(b) AND ml) * sizeof(Thuft))); } |
||
545 | |||
546 | (* Inflate_Fixed & Inflate_Dynamic *) |
||
547 | { with CentralZipHeader DO |
||
548 | IF CalcProgress(False, PMode, Percent, UnpackedSize - Bytes_To_Go, UnpackedSize) THEN |
||
549 | DoProgress(Percent); } |
||
550 | |||
551 | e := t^.e; |
||
552 | if (e > 16) then |
||
553 | while (e > 16) do |
||
554 | begin |
||
555 | if (e = 99) then |
||
556 | begin |
||
557 | Result := 1; |
||
558 | Exit; |
||
559 | end; |
||
560 | DUMPBITS(t^.b, b, k); |
||
561 | Dec(e, 16); |
||
562 | NEEDBITS(e, b, k); |
||
563 | |||
564 | t := pointer(LONGINT(t^.Next) + ((b and maskr[e]) * SizeOf(Thuft))); |
||
565 | e := t^.e; |
||
566 | end; |
||
567 | |||
568 | DUMPBITS(t^.b, b, k); |
||
569 | if (e = 16) then { THEN it's a literal } |
||
570 | begin |
||
571 | Slide^[w] := t^.n; |
||
572 | Inc(w); |
||
573 | // Dec(Bytes_To_Go); |
||
574 | |||
575 | if (w = WORD(WSIZE)) then |
||
576 | begin |
||
577 | // Inc(ExtCount); |
||
578 | CheckFWrite(VH_OutFile, Slide^, w, VStr_OutFile); |
||
579 | |||
580 | crc32_buf(PByte(Slide), w, VDW_CRC32Val); |
||
581 | w := 0; |
||
582 | end; |
||
583 | end |
||
584 | else |
||
585 | begin { it's an EOB or a length } |
||
586 | { exit IF END OF block } |
||
587 | if (e = 15) then |
||
588 | Break; |
||
589 | |||
590 | { get length OF block TO copy } |
||
591 | NEEDBITS(e, b, k); |
||
592 | n := t^.n + (WORD(b) and maskr[e]); |
||
593 | { n := t^.n + (b AND maskr[e]); } |
||
594 | DUMPBITS(e, b, k); |
||
595 | |||
596 | { decode distance OF block TO copy } |
||
597 | NEEDBITS(WORD(bd), b, k); |
||
598 | { NEEDBITS(bd,b,k); } |
||
599 | |||
600 | t := pointer(LONGINT(td) + ((b and md) * SizeOf(Thuft))); |
||
601 | |||
602 | e := t^.e; |
||
603 | if e > 16 then |
||
604 | repeat |
||
605 | if (e = 99) then |
||
606 | begin |
||
607 | Result := 1; |
||
608 | Exit; |
||
609 | end; |
||
610 | DUMPBITS(t^.b, b, k); |
||
611 | Dec(e, 16); |
||
612 | NEEDBITS(e, b, k); |
||
613 | t := pointer(LONGINT(t^.Next) + ((WORD(b) and maskr[e]) * SizeOf |
||
614 | (Thuft))); |
||
615 | { t := pointer(LONGINT(t^.next) + ((b AND maskr[e]) * sizeof(Thuft))); } |
||
616 | e := t^.e; |
||
617 | until (e <= 16); |
||
618 | |||
619 | DUMPBITS(t^.b, b, k); |
||
620 | NEEDBITS(e, b, k); |
||
621 | |||
622 | d := WORD(w - t^.n - (b and maskr[e])); |
||
623 | |||
624 | DUMPBITS(e, b, k); |
||
625 | |||
626 | { DO the copy } |
||
627 | repeat |
||
628 | d := (d and (WSIZE - 1)); |
||
629 | |||
630 | if (d > w) then |
||
631 | e := WSIZE - d |
||
632 | else |
||
633 | e := WSIZE - w; |
||
634 | |||
635 | if (e > n) then |
||
636 | e := n; |
||
637 | |||
638 | Dec(n, e); |
||
639 | |||
640 | (* incrementing w by e bytes below... DO same with bytes_to_go |
||
641 | prior TO value e changing *) |
||
642 | // Dec(Bytes_To_Go, e); |
||
643 | |||
644 | if ((w - d) >= e) then { this test assumes unsigned comparison } |
||
645 | begin |
||
646 | Move(Slide^[d], Slide^[w], e); |
||
647 | Inc(w, e); |
||
648 | Inc(d, e); |
||
649 | end |
||
650 | else |
||
651 | begin { DO it slow TO avoid memcpy() overlap } |
||
652 | repeat |
||
653 | Slide^[w] := Slide^[d]; |
||
654 | Inc(w); |
||
655 | Inc(d); |
||
656 | Dec(e); |
||
657 | until (e <= 0); |
||
658 | end; |
||
659 | |||
660 | if (w = WORD(WSIZE)) then |
||
661 | begin |
||
662 | CheckFWrite(VH_OutFile, Slide^, w, VStr_OutFile); |
||
663 | |||
664 | crc32_buf(PByte(Slide), w, VDW_CRC32Val); |
||
665 | w := 0; |
||
666 | end; |
||
667 | until n = 0; |
||
668 | end; |
||
669 | |||
670 | until (1 <> 1); |
||
671 | |||
672 | { restore the globals from the locals } |
||
673 | WP := w; { restore global window pointer } |
||
674 | bb := b; { restore global bit buffer } |
||
675 | bk := k; |
||
676 | |||
677 | Result := 0; |
||
678 | end; |
||
679 | (* -------------------------------------------------------------------------- *) |
||
680 | |||
681 | (* |
||
682 | mofified nov 23, 2002 (changes contributed by James Turner) |
||
683 | procedure inflate_fixed; |
||
684 | { decompress an inflated type 1 (fixed Huffman codes) block. We should |
||
685 | either replace this with a custom decoder, or at least precompute the |
||
686 | Huffman tables. } |
||
687 | var |
||
688 | i: INTEGER; { temporary variable } |
||
689 | l: array[0..287] of WORD; { length list FOR huft_build } |
||
690 | fixed_bl, fixed_bd: INTEGER; |
||
691 | HFTD, HFTL: PT; |
||
692 | begin |
||
693 | |||
694 | { IF first time, set up tables FOR fixed blocks } |
||
695 | if (fixed_tl = nil) then |
||
696 | begin |
||
697 | { literal table } |
||
698 | for i := 0 to 287 do |
||
699 | begin |
||
700 | case i of |
||
701 | 0..143: l[i] := 8; |
||
702 | 144..255: l[i] := 9; |
||
703 | 256..279: l[i] := 7; |
||
704 | 280..287: l[i] := 8; { make a complete, but wrong code set } |
||
705 | end; |
||
706 | end; |
||
707 | |||
708 | fixed_bl := 7; |
||
709 | i := huft_build(l, 288, 257, cplens, cplext, fixed_tl, HFTL, fixed_bl); |
||
710 | if (i <> 0) then |
||
711 | begin |
||
712 | fixed_tl := nil; |
||
713 | |||
714 | { ********** REM'D RAISE ************ } |
||
715 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
716 | end; |
||
717 | |||
718 | { distance table } |
||
719 | for i := 0 to 29 do { make an incomplete code set } |
||
720 | l[i] := 5; |
||
721 | |||
722 | fixed_bd := 5; |
||
723 | |||
724 | i := huft_build(l, 30, 0, cpdist, cpdext, fixed_td, HFTD, fixed_bd); |
||
725 | if (i > 1) then |
||
726 | begin |
||
727 | {ErrCode := IncompleteCodeSet;} |
||
728 | huft_free(HFTL); |
||
729 | fixed_tl := nil; |
||
730 | |||
731 | { ********** REM'D RAISE ************ } |
||
732 | //raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
733 | end; |
||
734 | end; |
||
735 | |||
736 | { decompress UNTIL an END-OF-block code } |
||
737 | i := inflate_codes(fixed_tl, fixed_td, fixed_bl, fixed_bd); |
||
738 | |||
739 | if i <> 0 then |
||
740 | |||
741 | { ********** REM'D RAISE ************ } |
||
742 | //raise E_RAISE.Create(LoadStr(E_BADBLOCK)); |
||
743 | ; |
||
744 | |||
745 | end; *) |
||
746 | |||
747 | procedure inflate_fixed; |
||
748 | begin |
||
749 | { decompress until an end-of-block code } |
||
750 | inflate_codes(fixed_tl, fixed_td, 7, 5); |
||
751 | end; |
||
752 | (* -------------------------------------------------------------------------- *) |
||
753 | var |
||
754 | HFTD, HFTL: PT; |
||
755 | |||
756 | procedure InitFixedTables; |
||
757 | var |
||
758 | i: Integer; |
||
759 | L: array [0 .. 287] of WORD; { length list FOR huft_build } |
||
760 | fixed_bl, fixed_bd: Integer; |
||
761 | // HFTD, HFTL: PT; |
||
762 | begin |
||
763 | HFTL := nil; |
||
764 | HFTD := nil; |
||
765 | |||
766 | { create literal table } |
||
767 | for i := 0 to 287 do |
||
768 | case i of |
||
769 | |||
770 | L[i] := 8; |
||
771 | 144 .. 255: |
||
772 | L[i] := 9; |
||
773 | 256 .. 279: |
||
774 | L[i] := 7; |
||
775 | 280 .. 287: |
||
776 | L[i] := 8; { make a complete, but wrong code set } |
||
777 | end; { case / for } |
||
778 | |||
779 | fixed_bl := 7; |
||
780 | |||
781 | huft_build(L, 288, 257, cplens, cplext, fixed_tl, HFTL, fixed_bl); |
||
782 | |||
783 | { distance table } |
||
784 | for i := 0 to 29 do |
||
785 | L[i] := 5; { make an incomplete code set } |
||
786 | |||
787 | fixed_bd := 5; |
||
788 | |||
789 | huft_build(L, 30, 0, cpdist, cpdext, fixed_td, HFTD, fixed_bd); |
||
790 | end; |
||
791 | (* -------------------------------------------------------------------------- *) |
||
792 | |||
793 | procedure FreeFixedTables; |
||
794 | begin |
||
795 | huft_free(HFTD); |
||
796 | huft_free(HFTL); |
||
797 | // huft_free(fixed_tl); |
||
798 | // huft_free(fixed_td); |
||
799 | end; |
||
800 | (* -------------------------------------------------------------------------- *) |
||
801 | |||
802 | procedure inflate_dynamic; |
||
803 | var |
||
804 | i: Integer; { temporary variables } |
||
805 | j: WORD; { } |
||
806 | L: WORD; { last length } |
||
807 | m: WORD; { mask FOR bit lengths table } |
||
808 | n: WORD; { number OF lengths TO get } |
||
809 | tl: PT; { literal/length code table } |
||
810 | td: PT; { distance code table } |
||
811 | HFTL, HFTD: PT; |
||
812 | bl: Integer; { lookup bits FOR tl } |
||
813 | bd: Integer; { lookup bits FOR td } |
||
814 | nb: WORD; { number OF bit length codes } |
||
815 | nl: WORD; { number OF literal/length codes } |
||
816 | nd: WORD; { number OF distance codes } |
||
817 | {$IFDEF PKZIP_BUG_WORKAROUND} |
||
818 | ll: array [0 .. 288 + 32] of WORD; |
||
819 | {$ELSE} |
||
820 | ll: array [0 .. 286 + 30] of WORD; |
||
821 | {$ENDIF} |
||
822 | b: LONGINT; { bit buffer } |
||
823 | k: WORD; { number OF bits in bit buffer } |
||
824 | const |
||
825 | border: array [0 .. 18] of BYTE = { Order OF the bit length code lengths } |
||
826 | (16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15); |
||
827 | dummy1: array [0 .. 30] of WORD = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
828 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
||
829 | dummy2: array [0 .. 30] of BYTE = { Extra bits FOR literal codes 257..285 } |
||
830 | (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||
831 | 0, 0, 0, 0, 0, 0); { 99==invalid } |
||
832 | begin |
||
833 | { make local bit buffer } |
||
834 | b := bb; |
||
835 | k := bk; |
||
836 | |||
837 | { read in table lengths } |
||
838 | NEEDBITS(5, b, k); |
||
839 | nl := 257 + (WORD(b) and $1F); { number OF literal/length codes } |
||
840 | DUMPBITS(5, b, k); |
||
841 | NEEDBITS(5, b, k); |
||
842 | nd := 1 + (WORD(b) and $1F); { number OF distance codes } |
||
843 | DUMPBITS(5, b, k); |
||
844 | NEEDBITS(4, b, k); |
||
845 | nb := 4 + (WORD(b) and $F); { number OF bit length codes } |
||
846 | DUMPBITS(4, b, k); |
||
847 | {$IFDEF PKZIP_BUG_WORKAROUND} |
||
848 | if ((nl > 288) or (nd > 32)) then |
||
849 | {$ELSE} |
||
850 | if ((nl > 286) or (nd > 30)) then |
||
851 | {$ENDIF} |
||
852 | (* *********** REM'D RAISE ************* *) |
||
853 | // raise E_RAISE.Create(LoadStr(E_INVALIDLEN)); |
||
854 | ; |
||
855 | |||
856 | { read in bit-length-code lengths } |
||
857 | for j := 0 to nb - 1 do |
||
858 | begin |
||
859 | NEEDBITS(3, b, k); |
||
860 | ll[border[j]] := WORD(b) and 7; |
||
861 | DUMPBITS(3, b, k); |
||
862 | end; |
||
863 | |||
864 | for j := nb to 18 do |
||
865 | ll[border[j]] := 0; |
||
866 | |||
867 | { build decoding table FOR trees--single level, 7 bit lookup } |
||
868 | bl := 7; |
||
869 | HFTL := nil; |
||
870 | i := huft_build(ll, 19, 19, dummy1, dummy2, tl, HFTL, bl); |
||
871 | if (i <> 0) then |
||
872 | begin |
||
873 | if (i = 1) then |
||
874 | { huft_free(tl); } |
||
875 | huft_free(HFTL); |
||
876 | |||
877 | (* *********** REM'D RAISE ************* *) |
||
878 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
879 | |||
880 | end; |
||
881 | |||
882 | { read in literal AND distance code lengths } |
||
883 | n := nl + nd; |
||
884 | m := maskr[bl]; |
||
885 | i := 0; |
||
886 | L := 0; |
||
887 | while (WORD(i) < n) do |
||
888 | begin |
||
889 | NEEDBITS(WORD(bl), b, k); |
||
890 | |||
891 | td := pointer(LONGINT(tl) + ((b and m) * SizeOf(Thuft))); |
||
892 | |||
893 | j := td^.b; |
||
894 | DUMPBITS(j, b, k); |
||
895 | |||
896 | j := td^.n; |
||
897 | if (j < 16) then { length OF code in bits (0..15) } |
||
898 | begin |
||
899 | ll[i] := j; |
||
900 | L := j; { * save last length in l } |
||
901 | Inc(i); |
||
902 | end |
||
903 | else if (j = 16) then { REPEAT last length 3 TO 6 times } |
||
904 | begin |
||
905 | NEEDBITS(2, b, k); |
||
906 | j := 3 + (WORD(b) and 3); |
||
907 | DUMPBITS(2, b, k); |
||
908 | if (WORD(i) + j > n) then |
||
909 | |||
910 | (* *********** REM'D RAISE ************* *) |
||
911 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
912 | ; |
||
913 | |||
914 | while (j <> 0) do |
||
915 | begin |
||
916 | ll[i] := L; |
||
917 | Inc(i); |
||
918 | Dec(j); |
||
919 | end |
||
920 | end |
||
921 | else if (j = 17) then { 3 TO 10 zero length codes } |
||
922 | begin |
||
923 | NEEDBITS(3, b, k); |
||
924 | j := 3 + (WORD(b) and 7); |
||
925 | DUMPBITS(3, b, k); |
||
926 | if (WORD(i) + j > n) then |
||
927 | |||
928 | (* *********** REM'D RAISE ************* *) |
||
929 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
930 | ; |
||
931 | |||
932 | while (j <> 0) do |
||
933 | begin |
||
934 | ll[i] := 0; |
||
935 | Inc(i); |
||
936 | Dec(j); |
||
937 | end; |
||
938 | L := 0; |
||
939 | end |
||
940 | else |
||
941 | begin { j == 18: 11 TO 138 zero length codes } |
||
942 | NEEDBITS(7, b, k); |
||
943 | j := 11 + (WORD(b) and $7F); |
||
944 | DUMPBITS(7, b, k); |
||
945 | if (WORD(i) + j > n) then |
||
946 | |||
947 | (* *********** REM'D RAISE ************* *) |
||
948 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
949 | ; |
||
950 | |||
951 | while (j <> 0) do |
||
952 | begin |
||
953 | ll[i] := 0; |
||
954 | Inc(i); |
||
955 | Dec(j); |
||
956 | end; |
||
957 | L := 0; |
||
958 | end; |
||
959 | end; |
||
960 | |||
961 | { free decoding table FOR trees } |
||
962 | { huft_free(tl); } |
||
963 | huft_free(HFTL); |
||
964 | |||
965 | { restore the global bit buffer } |
||
966 | bb := b; |
||
967 | bk := k; |
||
968 | |||
969 | { build the decoding tables for literal/length AND distance codes } |
||
970 | bl := lbits; |
||
971 | HFTL := nil; |
||
972 | i := huft_build(ll, nl, 257, cplens, cplext, tl, HFTL, bl); |
||
973 | if (i <> 0) then |
||
974 | begin |
||
975 | if i = 1 then |
||
976 | huft_free(HFTL); |
||
977 | |||
978 | (* *********** REM'D RAISE ************* *) |
||
979 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
980 | |||
981 | end; |
||
982 | |||
983 | bd := dbits; |
||
984 | HFTD := nil; |
||
985 | i := huft_build(ll[nl], nd, 0, cpdist, cpdext, td, HFTD, bd); |
||
986 | if (i <> 0) then |
||
987 | begin |
||
988 | if i = 1 then |
||
989 | begin |
||
990 | |||
991 | (* *********** REM'D RAISE ************* *) |
||
992 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
993 | {$IFDEF PKZIP_BUG_WORKAROUND} |
||
994 | { i := 0; ********************** return as result?????? } |
||
995 | end; |
||
996 | {$ELSE} |
||
997 | huft_free(HFTD); |
||
998 | |||
999 | (* *********** REM'D RAISE ************* *) |
||
1000 | // raise E_RAISE.Create(E_CODESET); |
||
1001 | |||
1002 | end; |
||
1003 | { huft_free(tl); } |
||
1004 | huft_free(HFTL); |
||
1005 | { result := i; }{ incomplete code set } |
||
1006 | Result := IncompleteCodeSet; |
||
1007 | Exit; |
||
1008 | {$ENDIF} |
||
1009 | end; |
||
1010 | |||
1011 | { decompress UNTIL an END-OF-block code } |
||
1012 | if (inflate_codes(tl, td, bl, bd)) <> 0 then |
||
1013 | // raise E_RAISE.Create(LoadStr(E_CODESET)); |
||
1014 | ; |
||
1015 | |||
1016 | { free the decoding tables, return } |
||
1017 | huft_free(HFTL); { ******** IF inflate_codes fails above, } |
||
1018 | huft_free(HFTD); { ******** memory is not released!!! } |
||
1019 | |||
1020 | { result :=0; } |
||
1021 | { result := None; }{ 100% correct result???? } |
||
1022 | end; |
||
1023 | (* -------------------------------------------------------------------------- *) |
||
1024 | |||
1025 | { decompress an inflated block } |
||
1026 | |||
1027 | procedure inflate_block(var e: Integer); { e = last block flag } |
||
1028 | var |
||
1029 | t: WORD; { block type } |
||
1030 | k: WORD; { number OF bits in bit buffer } |
||
1031 | b: LONGINT; { bit buffer } |
||
1032 | begin |
||
1033 | { make local bit buffer } |
||
1034 | b := bb; |
||
1035 | k := bk; |
||
1036 | |||
1037 | { read in last block bit } |
||
1038 | NEEDBITS(1, b, k); |
||
1039 | e := Integer(b) and 1; |
||
1040 | DUMPBITS(1, b, k); |
||
1041 | |||
1042 | { read in block type */ } |
||
1043 | NEEDBITS(2, b, k); |
||
1044 | t := WORD(b) and 3; |
||
1045 | DUMPBITS(2, b, k); |
||
1046 | |||
1047 | { restore the global bit buffer } |
||
1048 | bb := b; |
||
1049 | bk := k; |
||
1050 | |||
1051 | { inflate that block type } |
||
1052 | case t of |
||
1053 | 0: |
||
1054 | inflate_stored; |
||
1055 | 1: |
||
1056 | inflate_fixed; |
||
1057 | 2: |
||
1058 | inflate_dynamic; |
||
1059 | else |
||
1060 | (* *********** REM'D RAISE ************* *) |
||
1061 | // raise E_RAISE.Create(LoadStr(E_BADBLOCK)); |
||
1062 | ; |
||
1063 | end; |
||
1064 | end; |
||
1065 | (* -------------------------------------------------------------------------- *) |
||
1066 | |||
1067 | { decompress an inflated entry } |
||
1068 | |||
1069 | procedure Inflate(mem: pointer; size: Integer); |
||
1070 | var |
||
1071 | e: Integer; { last block flag } |
||
1072 | h: WORD; { maximum struct huft's malloc'ed } |
||
1073 | begin |
||
1074 | InPTR := 0; |
||
1075 | ZipCount := 0; |
||
1076 | |||
1077 | { initialize window, bit buffer } |
||
1078 | WP := 0; |
||
1079 | bk := 0; |
||
1080 | bb := 0; |
||
1081 | |||
1082 | { decompress UNTIL the last block } |
||
1083 | h := 0; |
||
1084 | |||
1085 | // InBuf := nil; |
||
1086 | Slide := nil; |
||
1087 | // GetMem(InBuf, sizeof(InBuf^) + 1); |
||
1088 | GetMem(Slide, SizeOf(Slide^) + 1); |
||
1089 | if (mem = nil) or (size <= 0) then |
||
1090 | begin |
||
1091 | InBuf := nil; |
||
1092 | GetMem(InBuf, SizeOf(InBuf^) + 1); |
||
1093 | InfMem := False; |
||
1094 | end |
||
1095 | else |
||
1096 | begin |
||
1097 | InBuf := mem; |
||
1098 | ZipCount := Cardinal(size); |
||
1099 | InfMem := True; |
||
1100 | end; |
||
1101 | |||
1102 | try |
||
1103 | // fixed_tl := nil; //changes contributed by James Turner, done nov 23, 2002 |
||
1104 | // fixed_td := nil; //changes contributed by James Turner, done nov 23, 2002 |
||
1105 | try |
||
1106 | repeat |
||
1107 | hufts := 0; |
||
1108 | inflate_block(e); |
||
1109 | if (hufts > h) then |
||
1110 | h := hufts; |
||
1111 | until (e <> 0); |
||
1112 | |||
1113 | // with LocalZipHeader DO |
||
1114 | // IF CalcProgress(False, PMode, Percent, PackedSize - Bytes_To_Go, PackedSize) THEN |
||
1115 | // DoProgress(Percent); |
||
1116 | |||
1117 | if WP > 0 then |
||
1118 | begin |
||
1119 | CheckFWrite(VH_OutFile, Slide^, WP, VStr_OutFile); |
||
1120 | |||
1121 | crc32_buf(PByte(Slide), WP, VDW_CRC32Val); |
||
1122 | WP := 0; |
||
1123 | end; |
||
1124 | except |
||
1125 | // MessageBox(0, 'Error...', 'Error', mb_OK) |
||
1126 | end; |
||
1127 | |||
1128 | finally |
||
1129 | if not InfMem then |
||
1130 | FreeMem(InBuf); |
||
1131 | FreeMem(Slide); |
||
1132 | end; |
||
1133 | end; |
||
1134 | (* -------------------------------------------------------------------------- *) |
||
1135 | |||
1136 | initialization |
||
1137 | |||
1138 | InitFixedTables; |
||
1139 | |||
1140 | finalization |
||
1141 | |||
1142 | FreeFixedTables; |
||
1143 | |||
1144 | end. |