⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ztvinflate.pas

📁 ziptv为delphi控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
// decompress
(**********************************************************************

  Copyright 1998-2003,  Microchip Data Systems / Carl Bunton

  Under license agreement, this source module may be used only on a
  single computer.

  No portion of this module may be reproduced, copied, revised, edited,
  distributed or transmitted via electronic means except in compiled
  application format.

  Web-site:  http://www.ziptv.com
  Email:     custsupt@ziptv.com

  Notes:
  	v6.5.1:
   	Proc: inflate_blocks_reset
      	rem'd "Or (s.mode = dtree)", see note above this line.  Unable
         to locate a memory allocation for this attempt at freeing mem.

**********************************************************************)
Unit ztvInflate;

Interface

Uses
   Classes,
   SysUtils,
   ztvRegister,
   ztvBase,
   ztvStreams,
   ztvGbls,
   ztvConsts;

{$I ZipTV.inc}
{.$Define Patch112}
{$Define USE_PTR}
{.$define SLOW}
{.$define LocalDef64}

{$J+}    { Writeable Typed Constants }     // v4.0 added
{$Q-}    { Overflow Checking }  // v4.5.3 added

Function inflateInit_(z: ztv_streamp; DEF_WBITS: smallint; stream_size: _int): _int;
Function inflateEnd(Var z: ztv_stream): _int;
Function inflateReset(Var z: ztv_stream): _int;
Function _inflate(Var z: ztv_stream; f: _int): _int;
//Function inflateSetDictionary(Var z: ztv_stream; dictionary: _pBytef;
//	dictLength: uInt): _int;
Function ztvDecompress_String_Method1(s: String): String;
Function ztvDecompress_String_Method2(s: String; StrLength: Integer): String;
Function ztvDecompress_BufToBuf(Const inbuf: Pointer; InBytes: _int;
   Var outbuf: Pointer; Var outBytes: _int; OutEstimate: _int): u_long;
Function ztvDecompress_StreamToFile(Stream: TStream32; FileName: String): u_long;
Function ztvDecompress_StreamFromClipboard(Stream: TStream32): u_long;
Function ztvDecompress_StreamToStream(InStream, OutStream: TStream32;
	InBytes: _int): u_long;


Implementation

Uses
   ztvCrypt;

Const
   PRESET_DICT = $20;                   { preset dictionary flag in header }
   MANY = 1440;
   BMAX = {15} 16;                      { maximum bit length of any code }

Const
   inflate_mask: Array[0..16] Of _uInt = ($0000,
      $0001, $0003, $0007, $000F, $001F, $003F, $007F, $00FF,
      $01FF, $03FF, $07FF, $0FFF, $1FFF, $3FFF, $7FFF, $FFFF);

   invalid_code = {112; //} 99;  // v6.1 v4.8.5 revised
   border: Array[0..18] Of Word   { Order of the bit length code lengths }
   	= (16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);

	// Tables for deflate from PKZIP's appnote.txt.
	cplens64: Array[0..30] Of {u_long = //}_uInt = //v6.1
     (3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
      35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3, 0, 0);
   { the code 285 is defined differently }
   cplens32: Array[0..30] Of {u_long = //}_uInt = //v6.1    { Copy lengths for literal codes 257..285 }
     (3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
      35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);
   { actually lengths - 2; also see note #13 above about 258 }


	// Extra bits for literal codes 257..285
   cplext64: Array[0..30] Of {u_long = //}_uInt = //v6.1
     (0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
   	3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 16, invalid_code, invalid_code);
   cplext32: Array[0..30] Of {u_long = //}_uInt = //v6.1
     (0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
      3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 , invalid_code, invalid_code);

   cpdist64: Array[0..31] Of {u_long = //}_uInt = //v6.1      { Copy offsets for distance codes 0..31 }
     (1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
      257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
      8193, 12289, 16385, 24577, 32769, 49153);
{$IFDEF PKZIP_BUG_WORKAROUND}
   cpdist32: Array[0..31] Of {u_long = //}_uInt = //v6.1      { Copy offsets for distance codes 0..31 }
     (1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
      257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
      8193, 12289, 16385, 24577, 32769, 49153);
{$ELSE}
   cpdist32: Array[0..29] Of {u_long = //}_uInt = //v6.1       { Copy offsets for distance codes 0..29 }
     (1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
      257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
      8193, 12289, 16385, 24577);
{$ENDIF PKZIP_BUG_WORKAROUND}

   cpdext64: Array[0..31] Of {u_long = //}_uInt = //v6.1      { Extra bits for distance codes }
     (0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
      7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
      14, 14);
{$IFDEF PKZIP_BUG_WORKAROUND}
   cpdext32: Array[0..31] Of {u_long = //}_uInt = //v6.1      { Extra bits for distance codes }
     (0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
      7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
      INVALID_CODE, INVALID_CODE);
{$ELSE}
   cpdext32: Array[0..29] Of {u_long = //}_uInt = //v6.1      { Extra bits for distance codes }
     (0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
      7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
      12, 12, 13, 13);
{$ENDIF PKZIP_BUG_WORKAROUND}


Const
   FIXEDH = 544;                        { number of hufts used by fixed tables }
   fixed_built: Boolean = False;        //v4.0 rem'd... changed to a global var

Var
   MaxDists: Byte;
   fixed_mem: Array[0..FIXEDH - 1] Of huft;
   fixed_bl: {u_long; //}_uInt; //v6.1
   fixed_bd: {u_long; //}_uInt; //v6.1
   fixed_tl: phuft;
   fixed_td: phuft;


//-------------------------------------------------------------

Function ZALLOC(Var strm: ztv_stream; Items: _uInt; size: _uInt): voidpf;
Begin
   ZALLOC := strm.ZALLOC(strm.opaque, Items, size);
End;
//-------------------------------------------------------------

Procedure ZFREE(Var strm: ztv_stream; ptr: voidpf);
Begin
   strm.ZFREE(strm.opaque, ptr);
End;
//-------------------------------------------------------------

Procedure inflate_codes_free(C: pInflate_codes_state; Var z: ztv_stream);
Begin
   ZFREE(z, C);
End;
//-------------------------------------------------------------

Procedure inflate_blocks_reset(Var s: inflate_blocks_state;
   Var z: ztv_stream;
   C: puLong);                          { check value on output }
Begin
   If (C <> Z_NULL) Then
      C^ := s.Check;

   // v6.5.1 rem'd "Or (s.mode = dtree)".  Using TZipKey with \3\zip\Encrypt_Xxxxx.zip,
   // password of "MhWEa" causes an unknown exception.  Attempts to release
   // memory that wasn't (at least in this review, couldn't find the allocation)
   // first allocated.
   If (s.mode = BTREE) {Or (s.mode = dtree)} Then
      ZFREE(z, s.sub.trees.blens);

   If (s.mode = CODES) Then
      inflate_codes_free(s.sub.decode.CODES, z);

   s.mode := ZTYPE;
   s.bitk := 0;
   s.bitb := 0;

   s.Write := s.window;
   s.Read := s.window;
   If Assigned(s.CheckFn) Then
   Begin
      s.Check := s.CheckFn(u_long(0), _pBytef(Nil), 0);
      z.adler := s.Check;
   End;
End;
//-------------------------------------------------------------

Function inflateReset(Var z: ztv_stream): _int;
Begin
   If (z.state = Z_NULL) Then
   Begin
      Result := Z_STREAM_ERROR;
      Exit;
   End;

   z.total_out := 0;
   z.total_in := 0;

   If z.state^.nowrap Then
      z.state^.mode := BLOCKS
   Else
      z.state^.mode := method;

   inflate_blocks_reset(z.state^.BLOCKS^, z, Z_NULL);
   Result := Z_OK;
End;
//-------------------------------------------------------------

Function inflate_blocks_free(s: pInflate_blocks_state; Var z: ztv_stream): _int;
Begin
   inflate_blocks_reset(s^, z, Z_NULL);
   ZFREE(z, s^.window);
   ZFREE(z, s^.hufts);
   ZFREE(z, s);
   Result := Z_OK;
End;
//-------------------------------------------------------------

Function inflateEnd(Var z: ztv_stream): _int;
Begin
   If (z.state = Z_NULL) Or Not Assigned(z.ZFREE) Then
   Begin
      Result := Z_STREAM_ERROR;
      Exit;
   End;
   If (z.state^.BLOCKS <> Z_NULL) Then
      inflate_blocks_free(z.state^.BLOCKS, z);

   ZFREE(z, z.state);
   z.state := Z_NULL;
   Result := Z_OK;
End;
//-------------------------------------------------------------

Function inflate_blocks_new(Var z: ztv_stream;
   C: _check_func;                      { check function }
   w: _uInt                              { window size }
   ): pInflate_blocks_state;
Var
   s: pInflate_blocks_state;
Begin
   s := pInflate_blocks_state(ZALLOC(z, 1, SizeOf(inflate_blocks_state)));
   If (s = Z_NULL) Then
   Begin
      Result := s;
      Exit;
   End;

   s^.hufts := huft_ptr(ZALLOC(z, SizeOf(huft), MANY));

   If (s^.hufts = Z_NULL) Then
   Begin
      ZFREE(z, s);
      Result := Z_NULL;
      Exit;
   End;

   s^.window := _pBytef(ZALLOC(z, 1, w));

   If (s^.window = Z_NULL) Then
   Begin
      ZFREE(z, s^.hufts);
      ZFREE(z, s);
      Result := Z_NULL;
      Exit;
   End;

   s^.zend := s^.window;
   inc(s^.zend, w);

   s^.CheckFn := C;
   s^.mode := ZTYPE;
   inflate_blocks_reset(s^, z, Z_NULL);
   Result := s;
End;
//-------------------------------------------------------------

Function inflateInit2_(Var z: ztv_stream;
   w: _int;
   stream_size: _int): _int;
Var
	BitMask: Byte;
Begin
	If is64Bit Then
   	MAXDISTS := 32
   Else
      {$IFDEF PKZIP_BUG_WORKAROUND}
      MAXDISTS := 32;
      {$ELSE}
      MAXDISTS := 30;
      {$ENDIF PKZIP_BUG_WORKAROUND}

   If (stream_size <> SizeOf(ztv_stream)) Then
   Begin
      Result := Z_VERSION_ERROR;
      Exit;
   End;

   { SetLength(strm.msg, 255); }
   If Not Assigned(z.ZALLOC) Then
   Begin
      z.ZALLOC := @ztvAllocMem;
      z.opaque := voidpf(0);
   End;

   If Not Assigned(z.ZFREE) Then
      z.ZFREE := @ztvFreeMem;

   z.state := pInternal_state(ZALLOC(z, 1, SizeOf(internal_state)));
   If (z.state = Z_NULL) Then
   Begin
      Result := Z_MEM_ERROR;
      Exit;
   End;

   z.state^.BLOCKS := Z_NULL;

   { handle undocumented nowrap option (no zlib header or check) }
   z.state^.nowrap := False;
   If (w < 0) Then
   Begin
      w := -w;
      z.state^.nowrap := True;
   End;

   BitMask := -MAX_WBITS;
   If is64Bit Then
   Begin
   	Inc(w);
      Inc(BitMask);
   End;
   
   { set window size }
   If (w < 8) Or (w > BitMask) Then
   Begin
      inflateEnd(z);
      Result := Z_STREAM_ERROR;
      Exit;
   End;
   z.state^.wbits := _uInt(w);

   { create inflate_blocks state }
   If z.state^.nowrap Then
      z.state^.BLOCKS := inflate_blocks_new(z, Nil, _uInt(1) Shl w)
   Else
      z.state^.BLOCKS := inflate_blocks_new(z, @_adler, _uInt(1) Shl w);

   If (z.state^.BLOCKS = Z_NULL) Then
   Begin
      inflateEnd(z);
      Result := Z_MEM_ERROR;
      Exit;
   End;

   inflateReset(z);
   Result := Z_OK;
End;
//-------------------------------------------------------------

{Function inflateInit2( Var z: ztv_stream; windowBits: SmallInt ): _int;
Begin
   Result := inflateInit2_( z, windowBits, SizeOf( ztv_stream ) );
End;}
//-------------------------------------------------------------

{Function inflateInit( Var z: ztv_stream; DEF_WBITS: SmallInt ): _int;
Begin
   Result := inflateInit2_( z, DEF_WBITS, SizeOf( ztv_stream ) );
End;}
//-------------------------------------------------------------

Function inflateInit_(z: ztv_streamp; DEF_WBITS: smallint; stream_size: _int): _int;
Begin
   If (z = Z_NULL) Then
      Result := Z_STREAM_ERROR
   Else
      Result := inflateInit2_(z^, DEF_WBITS, stream_size);
End;
//-------------------------------------------------------------

Function inflate_flush(Var s: inflate_blocks_state; Var z: ztv_stream;
   R: _int): _int;
Var
   n: _uInt;
   p, q: _pBytef;
Begin
   p := z.next_out;
   q := s.Read;

   { compute number of bytes to copy as far as end of window }
   If ptr2int(q) <= ptr2int(s.Write) Then
      n := _uInt(ptr2int(s.Write) - ptr2int(q))
   Else
      n := _uInt(ptr2int(s.zend) - ptr2int(q));

   If (n > z.avail_out) Then
      n := z.avail_out;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -