📄 ztvinflate.pas
字号:
If (n <> 0) And (R = Z_BUF_ERROR) Then
R := Z_OK;
Dec(z.avail_out, n);
inc(z.total_out, n);
If Assigned(s.CheckFn) Then
Begin
s.Check := s.CheckFn(s.Check, q, n);
z.adler := s.Check;
End;
{ copy as far as end of window }
CopyMem(@q^, @p^, n);
inc(p, n);
inc(q, n);
{ see if more to copy at beginning of window }
If (q = s.zend) Then
Begin
{ wrap pointers }
q := s.window;
If (s.Write = s.zend) Then
s.Write := s.window;
{ compute bytes to copy }
n := _uInt(ptr2int(s.Write) - ptr2int(q));
If (n > z.avail_out) Then
n := z.avail_out;
If (n <> 0) And (R = Z_BUF_ERROR) Then
R := Z_OK;
Dec(z.avail_out, n);
inc(z.total_out, n);
If Assigned(s.CheckFn) Then
Begin
s.Check := s.CheckFn(s.Check, q, n);
z.adler := s.Check;
End;
CopyMem(@q^, @p^, n);
inc(p, n);
inc(q, n);
End;
z.next_out := p;
s.Read := q;
Result := R;
End;
//-------------------------------------------------------------
Function huft_build(
Var b: Array Of {u_long; //}uIntf; //v6.1 { code lengths in bits (all assumed <= BMAX) }
n: _uInt; { number of codes (assumed <= N_MAX) }
s: _uInt; { number of simple-valued codes (0..s-1) }
Const d: Array Of {u_long; //}uIntf; //v6.1 { list of base values for non-simple codes }
Const e: Array Of {u_long; //}uIntf; //v6.1 { list of extra bits for non-simple codes (array of word )}
t: pphuft; { result: starting table (array of byte) }
Var m: {u_long; //}uIntf; //v6.1 { maximum lookup bits, returns actual }
Var hp: Array Of huft; { space for trees }
Var hn: _uInt; { hufts used in space }
Var v: Array Of {u_long //}uIntf { working area: values in order of bit length }
): _int;
Const
//{$ifndef LocalDef64}
AdditionalBitsInTable = 0;
InvalidCode = 128 + 64;
EobCode = 32 + 64;
ValidCode = 0;
NonSimpleLookup = 16 + 64;
//{$else}
// AdditionalBitsInTable = 32;
// InvalidCode = 99;
// EobCode = 31;
// ValidCode = 32;
// NonSimpleLookup = 0;
//{$endif}
Var
a: _uInt; { counter for codes of length k }
C: Array[0..BMAX] Of _uInt; { bit length count table }
f: _uInt; { i repeats in table every f entries }
g: _int; { maximum code length }
H: _int; { table level }
i: _uInt; {register} { counter, current code }
j: _uInt; {register} { counter }
k: _int; {register} { number of bits in current code }
l: uintf; //_int; { bits per table (returned in m) }
Mask: _uInt; { (1 shl w) - 1, to avoid cc -O bug on HP }
p: ^uIntf; {register} { pointer into c[], b[], or v[] }
q: phuft; { points to current table }
R: huft; { table entry for structure assignment }
u: Array[0..BMAX - 1] Of phuft; { table stack }
w: _int; {register} { bits before this table = (l*h) }
x: Array[0..BMAX] Of _uInt; { bit offsets, then code stack }
{$IFDEF USE_PTR}
xp: puIntf; { pointer into x }
{$ELSE}
xp: _uInt;
{$ENDIF}
y: _int; { number of dummy codes added }
z: _uInt; { number of entries in current table }
Begin
FillChar(C, SizeOf(C), 0); { clear c[] }
For i := 0 To n - 1 Do
inc(C[b[i]]); { assume all entries <= BMAX }
If (C[0] = n) Then { null input--all zero length codes }
Begin
t^ := phuft(Nil);
m := 0;
Result := Z_OK;
Exit;
End;
{ Find minimum and maximum length, bound [m] by those }
l := m;
For j := 1 To BMAX Do
If (C[j] <> 0) Then
break;
k := j; { minimum code length }
If (_uInt(l) < j) Then
l := j;
For i := BMAX Downto 1 Do
If (C[i] <> 0) Then
break;
g := i; { maximum code length }
If (_uInt(l) > i) Then
l := i;
m := l;
{ Adjust last length count to fill out codes, if needed }
y := 1 Shl j;
While (j < i) Do
Begin
Dec(y, C[j]);
If (y < 0) Then
Begin
Result := Z_DATA_ERROR; { bad input: more codes than bits }
Exit;
End;
inc(j);
y := y Shl 1
End;
Dec(y, C[i]);
If (y < 0) Then
Begin
Result := Z_DATA_ERROR; { bad input: more codes than bits }
Exit;
End;
inc(C[i], y);
{ Generate starting offsets into the value table for each length }
{$IFDEF USE_PTR}
x[1] := 0;
j := 0;
p := @C[1];
xp := @x[2];
Dec(i); { note that i = g from above }
While (i > 0) Do
Begin
inc(j, p^);
xp^ := j;
inc(p);
inc(xp);
Dec(i);
End;
{$ELSE}
x[1] := 0;
j := 0;
For i := 1 To g Do
Begin
x[i] := j;
inc(j, C[i]);
End;
{$ENDIF}
{ Make a table of values in order of bit lengths }
For i := 0 To n - 1 Do
Begin
j := b[i];
If (j <> 0) Then
Begin
v[x[j]] := i;
inc(x[j]);
End;
End;
n := x[g]; { set n to length of v }
{ Generate the Huffman codes and for each, make the table entries }
i := 0;
x[0] := 0; { first Huffman code is zero }
p := Addr(v); { grab values in bit order }
H := -1; { no tables yet--level -1 }
w := -l; { bits decoded = (l*h) }
u[0] := phuft(Nil); { just to keep compilers happy }
q := phuft(Nil); { ditto }
z := 0; { ditto }
{ go through the bit lengths (k already is bits in shortest code) }
While (k <= g) Do
Begin
a := C[k];
While (a <> 0) Do
Begin
Dec(a);
{ here i is the Huffman code of length k bits for value p^ }
{ make tables up to required level }
While (k > w + l) Do
Begin
inc(H);
inc(w, l); { add bits already decoded }
{ previous table always l bits }
{ compute minimum size table less than or equal to l bits }
{ table size upper limit }
z := g - w;
If (z > _uInt(l)) Then
z := l;
{ try a k-w bit table }
j := k - w;
f := 1 Shl j;
If (f > a + 1) Then { too few codes for k-w bit table }
Begin
Dec(f, a + 1); { deduct codes from patterns left }
{$IFDEF USE_PTR}
xp := Addr(C[k]);
If (j < z) Then
Begin
inc(j);
While (j < z) Do
Begin { try smaller tables up to z bits }
f := f Shl 1;
inc(xp);
If (f <= xp^) Then
break; { enough codes to use up j bits }
Dec(f, xp^); { else deduct codes from patterns }
inc(j);
End;
End;
{$ELSE}
xp := k;
If (j < z) Then
Begin
inc(j);
While (j < z) Do
Begin { try smaller tables up to z bits }
f := f * 2;
inc(xp);
If (f <= C[xp]) Then
break; { enough codes to use up j bits }
Dec(f, C[xp]); { else deduct codes from patterns }
inc(j);
End;
End;
{$ENDIF}
End;
z := 1 Shl j; { table entries for j-bit table }
{ allocate new table }
If (hn + z > MANY) Then { (note: doesn't matter for fixed) }
Begin
Result := Z_MEM_ERROR; { not enough memory }
Exit;
End;
q := @hp[hn];
u[H] := q;
inc(hn, z);
{ connect to last table, if there is one }
If (H <> 0) Then
Begin
x[H] := i; { save pattern for backing up }
R.b := Byte(l); { bits to dump before this table }
R.e := Byte(AdditionalBitsInTable+j); { bits in this table }
{.$ifdef LocalDef64}
// ==========
//R.Pad := 101; // next table
// ==========
{.$endif}
j := i Shr (w - l);
{r.v_n := _uInt( q - u[h-1] -j);}{ offset to this table }
R.v_n := (ptr2int(q) - ptr2int(u[H - 1])) Div SizeOf(q^) - j;
huft_ptr(u[H - 1])^[j] := R; { connect to last table }
End
Else
t^ := q; { first table is returned result }
End;
{ set up table entry in r }
R.b := Byte(k - w);
If ptr2int(p) >= ptr2int(@(v[n])) Then { also works under DPMI ?? }
Begin
R.e := InvalidCode; { out of values--invalid code }
{.$ifdef LocalDef64} // ============
//R.pad := 99; // Invalid Code
{.$endif} // ============
End Else
If (p^ < s) Then
Begin
If (p^ < 256) Then { 256 is end-of-block code }
Begin
R.e := ValidCode;
{.$ifdef LocalDef64} // =======
//R.pad := 102; // literal
{.$endif} // =======
End Else Begin
R.e := EobCode;
{.$ifdef LocalDef64} // =======================
//R.pad := 103; // EOB - end of block code
{.$endif} // =======================
End;
R.v_n := p^; { simple code is just the value }
inc(p);
End Else Begin
R.e := Byte(e[p^ - s] + NonSimpleLookup); { non-simple--look up in lists }
R.v_n := d[p^ - s];
{.$ifdef LocalDef64} // ======
//R.pad := 105; // length
{.$endif} // ======
inc(p);
End;
{ fill code-like entries with r }
f := 1 Shl (k - w);
j := i Shr w;
While (j < z) Do
Begin
huft_ptr(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 Xor j; { bitwise exclusive or }
j := j Shr 1
End;
i := i Xor j;
{ backup over finished tables }
Mask := (1 Shl w) - 1; { needed on HP, cc -O bug }
While ((i And Mask) <> x[H]) Do
Begin
Dec(H); { don't need to update q }
Dec(w, l);
Mask := (1 Shl w) - 1;
End;
End;
inc(k);
End;
If (y <> 0) And (g <> 1) Then
Result := Z_BUF_ERROR
Else
Result := Z_OK;
End;
//-------------------------------------------------------------
Function inflate_trees_fixed(
Var bl: {u_long; //}_uInt; //v6.1 { literal desired/actual bit depth }
Var bd: {u_long; //}_uInt; //v6.1 { distance desired/actual bit depth }
Var tl: phuft; { literal/length tree result }
Var td: phuft; { distance tree result }
Var z: ztv_stream { for memory allocation }
): _int;
Type
pFixed_table = ^fixed_table;
fixed_table = Array[0..288 - 1] Of {u_long; //}uIntf; //v6.1
Var
k: _int; { temporary variable }
C: pFixed_table; { length list for huft_build }
v: PuIntArray; { work area for huft_build }
f: _uInt; { number of hufts used in fixed_mem }
Begin
{ build fixed tables if not already (multiple overlapped executions ok) }
If Not fixed_built Then
Begin
f := 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -