📄 ztvinflate.pas
字号:
End;
Until False;
break;
End;
If (e And 64 = 0) Then
Begin
inc(t, t^.v_n + (_uInt(b) And inflate_mask[e]));
e := t^.e;
If (e = 0) Then
Begin
DUMPBITS(t^.b);
q^ := Byte(t^.v_n);
inc(q);
Dec(m);
break;
End;
End Else
If (e And 32 <> 0) Then
Begin
UNGRAB();
UPDATE();
Result := Z_STREAM_END;
Exit;
End Else Begin
//invalid literal/length code
UNGRAB();
UPDATE();
Result := Z_DATA_ERROR;
Exit;
End;
Until False;
Until (m < 258) Or (n < 10);
{ not enough input or output--restore pointers and return }
UNGRAB();
UPDATE();
Result := Z_OK;
End;
{$ENDIF SLOW}
//-------------------------------------------------------------
Function inflate_codes(Var s: inflate_blocks_state;
Var z: ztv_stream;
R: _int): _int;
Var
j: _uInt; { temporary storage }
t: phuft; { temporary pointer }
e: _uInt; { extra bits or operation }
b: u_long; { bit buffer }
k: _uInt; { bits in bit buffer }
p: _pBytef; { input data pointer }
n: _uInt; { bytes available there }
q: _pBytef; { output window write pointer }
m: _uInt; { bytes to end of window or read pointer }
f: _pBytef; { pointer to copy strings from }
C: pInflate_codes_state;
Begin
C := s.sub.decode.CODES;
p := z.next_in;
n := z.avail_in;
b := s.bitb;
k := s.bitk;
q := s.Write;
If ptr2int(q) < ptr2int(s.Read) Then
m := _uInt(ptr2int(s.Read) - ptr2int(q) - 1)
Else
m := _uInt(ptr2int(s.zend) - ptr2int(q));
While True Do
Case (C^.mode) Of
START:
Begin
{$IFNDEF SLOW}
If (m >= 258) And (n >= 10) Then
Begin
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
R := inflate_fast(C^.lbits, C^.dbits, C^.ltree, C^.dtree, s, z);
{LOAD}
p := z.next_in;
n := z.avail_in;
b := s.bitb;
k := s.bitk;
q := s.Write;
If ptr2int(q) < ptr2int(s.Read) Then
m := _uInt(ptr2int(s.Read) - ptr2int(q) - 1)
Else
m := _uInt(ptr2int(s.zend) - ptr2int(q));
If (R <> Z_OK) Then
Begin
If (R = Z_STREAM_END) Then
C^.mode := WASH
Else
C^.mode := BADCODE;
Continue;
End;
End;
{$ENDIF}
C^.sub.code.need := C^.lbits;
C^.sub.code.tree := C^.ltree;
C^.mode := Len;
End;
Len: { i: get length/literal/eob next }
Begin
j := C^.sub.code.need;
//NeedBits(j); + read
While (k < j) Do
Begin
If (n <> 0) Then
R := Z_OK
Else
Begin
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
Result := inflate_flush(s, z, R);
Exit;
End;
Dec(n);
b := b Or (u_long(p^) Shl k);
inc(p);
inc(k, 8);
End;
t := C^.sub.code.tree;
inc(t, _uInt(b) And inflate_mask[j]);
b := b Shr t^.b;
Dec(k, t^.b);
e := _uInt(t^.e);
{.$ifndef LocalDef64}
If (e = 0) Then
{.$else}
// If (e = 32) Then
{.$endif}
Begin
// =======
// t^.pad = 102 // literal
// =======
C^.sub.lit := t^.v_n;
C^.mode := lit;
Continue;
End;
{.$ifndef LocalDef64}
If (e And 16 <> 0) Then
{.$else}
//If (e And 32 <> 0) Then
{.$endif}
Begin
// ======
// t^.pad = 105 // length
// ======
{.$ifndef LocalDef64}
C^.sub.Copy.get := e And 15;
{.$else}
//C^.sub.Copy.get := e And 31;
{.$endif}
C^.Len := t^.v_n;
C^.mode := LENEXT;
Continue;
End;
If (e And 64 = 0) Then
Begin
// ==========
// t^.pad = 101 // next table
// ==========
C^.sub.code.need := e;
C^.sub.code.tree := @huft_ptr(t)^[t^.v_n];
Continue;
End;
If (e And 32 <> 0) Then
Begin
// ==================
// t^.pad := 103 // EOB - end of block
// ==================
C^.mode := WASH;
Continue;
End;
// ===========================
// invalid literal/length code
// ===========================
C^.mode := BADCODE;
R := Z_DATA_ERROR;
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
Result := inflate_flush(s, z, R);
Exit;
End;
LENEXT: { i: getting length extra (have base) }
Begin
j := C^.sub.Copy.get;
While (k < j) Do
Begin
If (n <> 0) Then
R := Z_OK
Else
Begin
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
Result := inflate_flush(s, z, R);
Exit;
End;
Dec(n);
b := b Or (u_long(p^) Shl k);
inc(p);
inc(k, 8);
End;
inc(C^.Len, _uInt(b And inflate_mask[j]));
b := b Shr j;
Dec(k, j);
C^.sub.code.need := C^.dbits;
C^.sub.code.tree := C^.dtree;
C^.mode := dist;
End;
dist: { i: get distance next }
Begin
j := C^.sub.code.need;
While (k < j) Do
Begin
If (n <> 0) Then
R := Z_OK
Else
Begin
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
Result := inflate_flush(s, z, R);
Exit;
End;
Dec(n);
b := b Or (u_long(p^) Shl k);
inc(p);
inc(k, 8);
End;
t := @huft_ptr(C^.sub.code.tree)^[_uInt(b) And inflate_mask[j]];
b := b Shr t^.b;
Dec(k, t^.b);
e := _uInt(t^.e);
If (e And 16 <> 0) Then { distance }
Begin
C^.sub.Copy.get := e And 15;
C^.sub.Copy.dist := t^.v_n;
C^.mode := DISTEXT;
Continue; { break C-switch statement }
End;
If (e And 64 = 0) Then { next table }
Begin
C^.sub.code.need := e;
C^.sub.code.tree := @huft_ptr(t)^[t^.v_n];
Continue; { break C-switch statement }
End;
C^.mode := BADCODE; { invalid code }
//invalid distance code
R := Z_DATA_ERROR;
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
Result := inflate_flush(s, z, R);
Exit;
End;
DISTEXT: { i: getting distance extra }
Begin
j := C^.sub.Copy.get;
While (k < j) Do
Begin
If (n <> 0) Then
R := Z_OK
Else
Begin
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
Result := inflate_flush(s, z, R);
Exit;
End;
Dec(n);
b := b Or (u_long(p^) Shl k);
inc(p);
inc(k, 8);
End;
inc(C^.sub.Copy.dist, _uInt(b) And inflate_mask[j]);
b := b Shr j;
Dec(k, j);
C^.mode := zCOPY;
End;
zCOPY: { o: copying bytes in window, waiting for space }
Begin
f := q;
Dec(f, C^.sub.Copy.dist);
If (_uInt(ptr2int(q) - ptr2int(s.window)) < C^.sub.Copy.dist) Then
Begin
f := s.zend;
Dec(f, C^.sub.Copy.dist - _uInt(ptr2int(q) - ptr2int(s.window)));
End;
While (C^.Len <> 0) Do
Begin
If (m = 0) Then
Begin
If (q = s.zend) And (s.Read <> s.window) Then
Begin
q := s.window;
If ptr2int(q) < ptr2int(s.Read) Then
m := _uInt(ptr2int(s.Read) - ptr2int(q) - 1)
Else
m := _uInt(ptr2int(s.zend) - ptr2int(q));
End;
If (m = 0) Then
Begin
{FLUSH}
s.Write := q;
R := inflate_flush(s, z, R);
q := s.Write;
If ptr2int(q) < ptr2int(s.Read) Then
m := _uInt(ptr2int(s.Read) - ptr2int(q) - 1)
Else
m := _uInt(ptr2int(s.zend) - ptr2int(q));
If (q = s.zend) And (s.Read <> s.window) Then
Begin
q := s.window;
If ptr2int(q) < ptr2int(s.Read) Then
m := _uInt(ptr2int(s.Read) - ptr2int(q) - 1)
Else
m := _uInt(ptr2int(s.zend) - ptr2int(q));
End;
If (m = 0) Then
Begin
s.bitb := b;
s.bitk := k;
z.avail_in := n;
inc(z.total_in, ptr2int(p) - ptr2int(z.next_in));
z.next_in := p;
s.Write := q;
Result := inflate_flush(s, z, R);
Exit;
End;
End;
End;
R := Z_OK;
q^ := f^;
inc(q);
inc(f);
Dec(m);
If (f = s.zend) Then
f := s.window;
Dec(C^.Len);
End;
C^.mode := START;
End;
lit: { o: got literal, waiting for output space }
Begin
If (m = 0) Then
Begin
If (q = s.zend) And (s.Read <> s.window) Then
Begin
q := s.window;
If ptr2int(q) < ptr2int(s.Read) Then
m := _uInt(ptr2int(s.Read) - ptr2int(q) - 1)
Else
m := _uInt(ptr2int(s.zend) - ptr2int(q));
End;
If (m = 0) Then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -