📄 ztvinflate64.pas
字号:
If f > a + 1 Then
Begin
dec(f, a + 1);
xp := @c[k];
Inc(j);
TryAgain := True;
While (j < z) And TryAgain Do
Begin
f := f Shl 1;
Inc(Longint(xp), SizeOf(Word));
If f <= xp^ Then
TryAgain := False
Else
Begin
dec(f, xp^);
Inc(j);
End;
End;
End;
If (w + j > el) And (w < el) Then
j := el - w; {make eob code end at table}
If w = 0 Then
Begin
j := m; {fix: main table always m bits}
End;
z := 1 Shl j;
l[h] := j;
{allocate and link new table}
GetMem(q, (z + 1) * SizeOf(huft));
If q = Nil Then
Begin
If h <> 0 Then
huft_free(Pointer(u[0]));
Result := huft_outofmem;
exit
End;
FillChar(q^, (z + 1) * SizeOf(huft), #0);
q^[0].v_n := z; {size of table, needed in freemem ***}
t^ := @q^[1]; {first item starts at 1}
t := pphuft(@q^[0].v_t);
t^ := Nil;
q := phuftlist(@q^[1]); {pointer(longint(q)+sizeof(huft));} {???}
u[h] := q;
{connect to last table, if there is one}
If h <> 0 Then
Begin
x[h] := i;
r.b := l[h - 1];
r.e := AdditionalBitsInTable + j;
r.v_t := q;
j := (i And ((1 Shl w) - 1)) Shr (w - l[h - 1]);
{test against bad input!}
pt := phuft(Longint(u[h - 1]) - SizeOf(huft));
If j > pt^.v_n Then
Begin
huft_free(Pointer(u[0]));
Result := huft_error;
exit
End;
pt := @u[h - 1]^[j];
pt^ := r;
End;
End;
{set up table entry in r}
r.b := Word(k - w);
r.v_t := Nil; {unused}
If Longint(p) >= Longint(@v[n]) Then
r.e := InvalidCode
Else
If p^ < s Then
Begin
If AdditionalBitsInTable = 16 Then
Begin
If p^ < 256 Then
r.e := 16
Else
r.e := 15;
End Else
If p^ < 256 Then
r.e := ValidCode
Else
r.e := EndOfBlock;
r.v_n := p^;
Inc(Longint(p), SizeOf(Word));
End
Else
Begin
If (d = Nil) Or (e = Nil) Then
Begin
huft_free(Pointer(u[0]));
Result := huft_error;
exit
End;
r.e := Word(e^[p^ - s] + NonSimpleLookup);
r.e := e^[p^ - s];
r.v_n := d^[p^ - s];
Inc(Longint(p), SizeOf(Word));
End;
{fill code like entries with r}
f := 1 Shl (k - w);
j := i Shr w;
While j < z Do
Begin
q^[j] := r;
Inc(j, f);
End;
{backwards increment the k-bit code i}
j := 1 Shl (k - 1);
While (i And j) <> 0 Do
Begin
{i:=i^j;}
i := i Xor j;
j := j Shr 1;
End;
i := i Xor j;
{backup over finished tables}
While ((i And ((1 Shl w) - 1)) <> x[h]) Do
Begin
dec(h);
dec(w, l[h]); {size of previous table!}
End;
End;
End;
m := Integer(l[0]);
If (y <> 0) And (g <> 1) Then
Result := huft_incomplete
Else
Result := huft_complete;
End;
//-------------------------------------------------------------
(* "Decompress" an inflated type 0 ( stored ) block. *)
Function inflate_stored: Integer;
Var
n: Word; {number of bytes in block}
Begin
{go to byte boundary}
n := k And 7;
DumpBits(n);
{get the length and its complement}
NeedBits(16);
n := b And $FFFF;
DumpBits(16);
NeedBits(16);
If (n <> (Not b) And $FFFF) Then
Begin
inflate_stored := unzip_ZipFileErr;
exit
End;
DumpBits(16);
While (n > 0) And Not (pCancel^ Or zipEOF) Do
Begin {read and output the compressed data}
dec(n);
NeedBits(8);
Slide[w] := Char(b);
Inc(w);
If w = WSIZE Then
Begin
If Not Flush(w) Then
Begin
Result := unzip_WriteErr;
exit
End;
w := 0;
End;
DumpBits(8);
End;
If pCancel^ Then
Result := unzip_UserAbort
Else
If zipEOF Then
Result := unzip_ReadErr
Else
Result := unzip_Ok;
End;
//-------------------------------------------------------------
Function inflate_codes(tl, td: phuftlist; bl, bd: Integer): Integer;
Var
n, d: Cardinal;
e1, //length and index for copy
ml, md: Word; //masks for bl and bd bits
t: phuft; //pointer to table entry
e: Byte; //table entry flag/number of extra bits
Begin
// inflate the coded data
ml := mask_bits[bl]; //precompute masks for speed
md := mask_bits[bd];
While Not (pCancel^ Or zipEOF) Do
Begin
NeedBits(bl);
t := @tl^[b And ml];
e := t^.e;
If e > ValidCode Then
Repeat // it's a literal
If e = InvalidCode Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, ValidCode);
NeedBits(e);
t := @t^.v_t^[b And mask_bits[e]];
e := t^.e;
Until e <= ValidCode;
DumpBits(t^.b);
If e = ValidCode Then
Begin
Slide[w] := Char(t^.v_n);
Inc(w);
If w = WSIZE Then
Begin
If Not Flush(w) Then
Begin
Result := unzip_WriteErr;
exit;
End;
w := 0
End;
End
Else
Begin //it's an EOB or a length
If e = EndOfBlock Then
Begin //exit if end of block
Result := unzip_Ok;
exit;
End;
NeedBits(e); //get length of block to copy
n := t^.v_n + (b And mask_bits[e]);
DumpBits(e);
NeedBits(bd); //Decode distance of block to copy
t := @td^[b And md];
e := t^.e;
If e > ValidCode Then
Repeat
If e = InvalidCode Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, ValidCode);
NeedBits(e);
t := @t^.v_t^[b And mask_bits[e]];
e := t^.e;
Until e <= ValidCode;
DumpBits(t^.b);
NeedBits(e);
d := w - t^.v_n - b And mask_bits[e];
DumpBits(e);
//do the copy
Repeat
If pCancel^ Then
Break;
d := d And (WSIZE - 1);
If d > w Then
e1 := WSIZE - d
Else
e1 := WSIZE - w;
If e1 > n Then
e1 := n;
dec(n, e1);
// v6.4.2 revised ==================================
// changed for speed. The "move" procedure does not
// work due to overlap issues. CopyMem works great
// and much faster!
// =================================================
If (w - d >= e1) Then
Begin
Move(Slide[d], Slide[w], e1);
Inc(w, e1);
Inc(d, e1);
End
Else
Begin
Repeat
Slide[w] := Slide[d];
Inc(w);
Inc(d);
dec(e1);
Until (e1 = 0);
End;
//CopyMem(@Slide[d], @Slide[w], e1);
//Inc(w, e1);
//Inc(d, e1);
// v6.4.2 ==========================================
If w = WSIZE Then
Begin
If (Not pCancel^) And (Not Flush(w)) Then
Begin
Result := unzip_WriteErr;
exit;
End;
w := 0;
End;
Until n = 0;
End;
End;
If pCancel^ Then
inflate_codes := unzip_UserAbort
Else
inflate_codes := unzip_ReadErr;
End;
//-------------------------------------------------------------
Function inflate_fixed: Integer;
Var
i: Integer; { temporary variable }
tl, { literal/length code table }
td: phuftlist; { distance code table }
bl, bd: Integer; { lookup bits for tl/bd }
l: Array[0..287] Of Word; { length list for huft_build }
Begin
{set up literal table}
For i := 0 To 143 Do
l[i] := 8;
For i := 144 To 255 Do
l[i] := 9;
For i := 256 To 279 Do
l[i] := 7;
For i := 280 To 287 Do
l[i] := 8; {make a complete, but wrong code set}
bl := 7;
If Is64Bit Then
i := huft_build(pWord(@l), 288, 257, PushList(@cplens64), PushList(@cplext64),
pphuft(@tl), bl)
Else
i := huft_build(pWord(@l), 288, 257, PushList(@cplens), PushList(@cplext),
pphuft(@tl), bl);
If i <> huft_complete Then
Begin
Result := i;
exit
End;
For i := 0 To 29 Do
l[i] := 5; {make an incomplete code set}
bd := 5;
If Is64Bit Then
i := huft_build(pWord(@l), 30, 0, PushList(@cpdist64), PushList(@cpdext64),
pphuft(@td), bd)
Else
i := huft_build(pWord(@l), 30, 0, PushList(@cpdist), PushList(@cpdext),
pphuft(@td), bd);
If i > huft_incomplete Then
Begin
huft_free(tl);
Result := unzip_ZipFileErr;
exit
End;
Result := inflate_codes(tl, td, bl, bd);
huft_free(tl);
huft_free(td);
End;
//-------------------------------------------------------------
(* Decompress an inflated type 2 ( dynamic Huffman codes ) block. *)
Function inflate_dynamic: Integer;
Var
i: Integer; { temporary variables }
j,
l, { last length }
m, { mask for bit length table }
n: Word; { number of lengths to get }
tl, { literal/length code table }
td: phuftlist; { distance code table }
bl, bd: Integer; { lookup bits for tl/bd }
nb, nl, nd: Word; { number of bit length/literal length/distance codes }
ll: Array[0..288 + 32 - 1] Of Word; { literal/length and distance code lengths }
Begin
//read in table lengths
NeedBits(5);
nl := 257 + Word(b) And $1F;
DumpBits(5);
NeedBits(5);
nd := 1 + Word(b) And $1F;
DumpBits(5);
NeedBits(4);
nb := 4 + Word(b) And $F;
DumpBits(4);
If (nl > 288) Or (nd > 32) Then
Begin
Result := 1;
exit
End;
FillChar(ll, SizeOf(ll), #0);
{read in bit-length-code lengths}
For j := 0 To nb - 1 Do
Begin
NeedBits(3);
ll[Border[j]] := b And 7;
DumpBits(3);
End;
For j := nb To 18 Do
ll[Border[j]] := 0;
{build Decoding table for trees--single level, 7 bit lookup}
bl := 7;
If Is64Bit Then
i := huft_build(pWord(@ll), 19, 19, Nil, Nil, pphuft(@tl), bl)
Else
i := huft_build(pWord(@ll), 19, 19, Nil, Nil, pphuft(@tl), bl);
If i <> huft_complete Then
Begin
If i = huft_incomplete Then
huft_free(tl); {other errors: already freed}
Result := unzip_ZipFileErr;
exit;
End;
{read in literal and distance code lengths}
n := nl + nd;
m := mask_bits[bl];
l := 0;
i := 0;
While Word(i) < n Do
Begin
NeedBits(bl);
td := phuftlist(@tl^[b And m]);
j := phuft(td)^.b;
DumpBits(j);
j := phuft(td)^.v_n;
If j < 16 Then
Begin {length of code in bits (0..15)}
l := j; {save last length in l}
ll[i] := l;
Inc(i)
End
Else
If j = 16 Then
Begin {repeat last length 3 to 6 times}
NeedBits(2);
j := 3 + b And 3;
DumpBits(2);
If i + j > n Then
Begin
inflate_dynamic := 1;
exit
End;
While j > 0 Do
Begin
ll[i] := l;
dec(j);
Inc(i);
End;
End
Else
If j = 17 Then
Begin {3 to 10 zero length codes}
NeedBits(3);
j := 3 + b And 7;
DumpBits(3);
If i + j > n Then
Begin
inflate_dynamic := 1;
exit
End;
While j > 0 Do
Begin
ll[i] := 0;
Inc(i);
dec(j);
End;
l := 0;
End
Else
Begin {j == 18: 11 to 138 zero length codes}
NeedBits(7);
j := 11 + b And $7F;
DumpBits(7);
If i + j > n Then
Begin
Result := unzip_ZipFileErr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -