📄 ztvinflate64.pas
字号:
exit
End;
While j > 0 Do
Begin
ll[i] := 0;
dec(j);
Inc(i);
End;
l := 0;
End;
End;
huft_free(tl); {free Decoding table for trees}
{build the Decoding tables for literal/length and distance codes}
bl := lbits;
If Is64Bit Then
i := huft_build(pWord(@ll), nl, 257, PushList(@cplens64), PushList(@cplext64),
pphuft(@tl), bl)
Else
i := huft_build(pWord(@ll), nl, 257, PushList(@cplens), PushList(@cplext),
pphuft(@tl), bl);
If i <> huft_complete Then
Begin
If i = huft_incomplete Then
huft_free(tl);
Result := unzip_ZipFileErr;
exit
End;
bd := dbits;
If Is64Bit Then
i := huft_build(pWord(@ll[nl]), nd, 0, PushList(@cpdist64), PushList(@cpdext64),
pphuft(@td), bd)
Else
i := huft_build(pWord(@ll[nl]), nd, 0, PushList(@cpdist), PushList(@cpdext),
pphuft(@td), bd);
If i > huft_incomplete Then
Begin {pkzip bug workaround}
If i = huft_incomplete Then
huft_free(td);
huft_free(tl);
Result := unzip_ZipFileErr;
exit
End;
{Decompress until an end-of-block code}
Result := inflate_codes(tl, td, bl, bd);
huft_free(tl);
huft_free(td);
End;
//-------------------------------------------------------------
Function inflate_block(Var e: Integer): Integer;
Var
t: Word; {block type}
Begin
NeedBits(1);
e := b And 1;
DumpBits(1);
NeedBits(2);
t := b And 3;
DumpBits(2);
Case t Of
0: Result := inflate_stored;
1: Result := inflate_fixed;
2: Result := inflate_dynamic;
Else
Result := unzip_ZipFileErr; {bad block type}
End;
End;
//-------------------------------------------------------------
(* The file position is set prior to entering this unit. *)
Function Inflate(Inf: TStream32; Var Outf: TStream32; IR: TInflateRec;
ABIT: Byte; InflateProc: TInflateProc): Boolean;
Function _Inflate: Integer;
Var
e, {last block flag}
r: Integer; {result code}
Begin
Inpos := 0; {Input buffer position}
ReadPos := -1; {Nothing read}
ReachedSize := 0;
zipEOF := False;
{initialize window, bit buffer}
w := 0;
k := 0;
b := 0;
{Decompress until the last block}
Repeat
r := inflate_block(e);
If pCancel^ Then
Break;
If r <> 0 Then
Begin
Result := r;
exit
End;
Until e <> 0;
{flush out slide}
If Not Flush(w) Then
Result := unzip_WriteErr
Else
Result := unzip_Ok;
End;
Begin
//WindowPtr^.zWindow := @Inbuf[0];
//WindowPtr^.zEnd := Pointer(Ptr2Int(WindowPtr^.zWindow) + SizeOf(Inbuf));
//Result := True;
Infile := Inf;
Outfile := Outf;
InflateRec := IR;
AdditionalBitsInTable := ABIT;
ReadProc := InflateProc.RB;
WriteProc := InflateProc.WB;
ProgressProc := InflateProc.PP;
pProgressPos := InflateProc.pProgressPos;
pCancel := InflateProc.pCancel;
Bytes_To_Go := InflateRec.UnpackedSize;
If Is64Bit Then
WSIZE := 65536
Else
WSIZE := 32768;
GetMem(Slide, WSIZE);
Try
Result := _Inflate() = unzip_Ok;
Finally
FreeMem(Slide, WSIZE);
End;
End;
//-------------------------------------------------------------
//-------------------------------------------------------------
//
// Explode() ...start
//
//-------------------------------------------------------------
//-------------------------------------------------------------
Const
cplen2: Array[0..63] Of word16 =
(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65);
cplen3: Array[0..63] Of word16 =
(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66);
extra: Array[0..63] Of word16 =
(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, 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, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 8);
cpdist4: Array[0..63] Of word16 =
(1, 65, 129, 193, 257, 321, 385, 449, 513, 577, 641,
705, 769, 833, 897, 961, 1025, 1089, 1153, 1217, 1281, 1345,
1409, 1473, 1537, 1601, 1665, 1729, 1793, 1857, 1921, 1985, 2049,
2113, 2177, 2241, 2305, 2369, 2433, 2497, 2561, 2625, 2689, 2753,
2817, 2881, 2945, 3009, 3073, 3137, 3201, 3265, 3329, 3393, 3457,
3521, 3585, 3649, 3713, 3777, 3841, 3905, 3969, 4033);
cpdist8: Array[0..63] Of word16 =
(1, 129, 257, 385, 513, 641, 769, 897, 1025, 1153, 1281,
1409, 1537, 1665, 1793, 1921, 2049, 2177, 2305, 2433, 2561, 2689,
2817, 2945, 3073, 3201, 3329, 3457, 3585, 3713, 3841, 3969, 4097,
4225, 4353, 4481, 4609, 4737, 4865, 4993, 5121, 5249, 5377, 5505,
5633, 5761, 5889, 6017, 6145, 6273, 6401, 6529, 6657, 6785, 6913,
7041, 7169, 7297, 7425, 7553, 7681, 7809, 7937, 8065);
//-------------------------------------------------------------
Procedure ReadByte(Var bt: Byte);
Begin
If Inpos > ReadPos Then
ReadBuf();
bt := Inbuf[Inpos];
Inc(Inpos);
End;
//-------------------------------------------------------------
Function GetTree(l: pWord; n: Word): Integer;
Var
i, k, j, b: Word;
bytebuf: Byte;
Begin
ReadByte(bytebuf);
i := bytebuf;
Inc(i);
k := 0;
Repeat
ReadByte(bytebuf);
j := bytebuf;
b := (j And $F) + 1;
j := ((j And $F0) Shr 4) + 1;
If (k + j) > n Then
Begin
Result := 4;
exit
End;
Repeat
l^ := b;
Inc(Longint(l), SizeOf(word16));
Inc(k);
dec(j);
Until j = 0;
dec(i);
Until i = 0;
If k <> n Then
Result := 4
Else
Result := 0;
End;
//-------------------------------------------------------------
Function explode_lit8(tb, tl, td: phuftlist; bb, bl, bd: Integer): Integer;
Var
s: Longint;
e: Word;
n, d: Word;
w: Word;
t: phuft;
mb, ml, md: Word;
u: Word;
Begin
b := 0;
k := 0;
w := 0;
u := 1;
mb := mask_bits[bb];
ml := mask_bits[bl];
md := mask_bits[bd];
s := InflateRec.UnpackedSize;
While (s > 0) And Not (pCancel^ Or zipEOF) Do
Begin
NeedBits(1);
If (b And 1) <> 0 Then
Begin {Literal}
DumpBits(1);
dec(s);
NeedBits(bb);
t := @tb^[(Not b) And mb];
e := t^.e;
If e > 16 Then
Repeat
If e = 99 Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, 16);
NeedBits(e);
t := @t^.v_t^[(Not b) And mask_bits[e]];
e := t^.e;
Until e <= 16;
DumpBits(t^.b);
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; u := 0;
End;
End
Else
Begin
DumpBits(1);
NeedBits(7);
d := b And $7F;
DumpBits(7);
NeedBits(bd);
t := @td^[(Not b) And md];
e := t^.e;
If e > 16 Then
Repeat
If e = 99 Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, 16);
NeedBits(e);
t := @t^.v_t^[(Not b) And mask_bits[e]];
e := t^.e;
Until e <= 16;
DumpBits(t^.b);
d := w - d - t^.v_n;
NeedBits(bl);
t := @tl^[(Not b) And ml];
e := t^.e;
If e > 16 Then
Repeat
If e = 99 Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, 16);
NeedBits(e);
t := @t^.v_t^[(Not b) And mask_bits[e]];
e := t^.e;
Until e <= 16;
DumpBits(t^.b);
n := t^.v_n;
If e <> 0 Then
Begin
NeedBits(8);
Inc(n, Byte(b) And $FF);
DumpBits(8);
End;
dec(s, n);
Repeat
d := d And pred(WSIZE);
If d > w Then
e := WSIZE - d
Else
e := WSIZE - w;
If e > n Then
e := n;
dec(n, e);
If (u <> 0) And (w <= d) Then
Begin
FillChar(Slide[w], e, #0);
Inc(w, e);
Inc(d, e);
End
Else
If (w - d >= e) Then
Begin
Move(Slide[d], Slide[w], e);
Inc(w, e);
Inc(d, e);
End
Else
Repeat
Slide[w] := Slide[d];
Inc(w);
Inc(d);
dec(e);
Until e = 0;
If w = WSIZE Then
Begin
If Not Flush(w) Then
Begin
Result := unzip_WriteErr;
exit
End;
w := 0; u := 0;
End;
Until n = 0;
End;
End;
If pCancel^ Then
Result := unzip_UserAbort
Else
If Not Flush(w) Then
Result := unzip_WriteErr
Else
If zipEOF Then
Result := unzip_ReadErr
Else
Result := unzip_Ok;
End;
//-------------------------------------------------------------
Function explode_lit4(tb, tl, td: phuftlist; bb, bl, bd: Integer): Integer;
Var
s: Longint;
e: Word;
n, d: Word;
w: Word;
t: phuft;
mb, ml, md: Word;
u: Word;
Begin
b := 0; k := 0; w := 0;
u := 1;
mb := mask_bits[bb];
ml := mask_bits[bl];
md := mask_bits[bd];
s := InflateRec.UnpackedSize;
While (s > 0) And Not (pCancel^ Or zipEOF) Do
Begin
NeedBits(1);
If (b And 1) <> 0 Then
Begin {Literal}
DumpBits(1);
dec(s);
NeedBits(bb);
t := @tb^[(Not b) And mb];
e := t^.e;
If e > 16 Then
Repeat
If e = 99 Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, 16);
NeedBits(e);
t := @t^.v_t^[(Not b) And mask_bits[e]];
e := t^.e;
Until e <= 16;
DumpBits(t^.b);
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; u := 0;
End;
End
Else
Begin
DumpBits(1);
NeedBits(6);
d := b And $3F;
DumpBits(6);
NeedBits(bd);
t := @td^[(Not b) And md];
e := t^.e;
If e > 16 Then
Repeat
If e = 99 Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, 16);
NeedBits(e);
t := @t^.v_t^[(Not b) And mask_bits[e]];
e := t^.e;
Until e <= 16;
DumpBits(t^.b);
d := w - d - t^.v_n;
NeedBits(bl);
t := @tl^[(Not b) And ml];
e := t^.e;
If e > 16 Then
Repeat
If e = 99 Then
Begin
Result := unzip_ZipFileErr;
exit
End;
DumpBits(t^.b);
dec(e, 16);
NeedBits(e);
t := @t^.v_t^[(Not b) And mask_bits[e]];
e := t^.e;
Until e <= 16;
DumpBits(t^.b);
n := t^.v_n;
If e <> 0 Then
Begin
NeedBits(8);
Inc(n, b And $FF);
DumpBits(8);
End;
dec(s, n);
Repeat
d := d And Pred(WSIZE);
If d > w Then
e := WSIZE - d
Else
e := WSIZE - w;
If e > n Then
e := n;
dec(n, e);
If (u <> 0) And (w <= d) Then
Begin
FillChar(Slide[w], e, #0);
Inc(w, e);
Inc(d, e);
End
Else
If (w - d >= e) Then
Begin
Move(Slide[d], Slide[w], e);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -