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

📄 ztvdeflate.pas

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

   If (Flush <> Z_FINISH) Then
   Begin
      Result := Z_OK;
      Exit;
   End;

   If (s^.noheader <> 0) Then
   Begin
      Result := Z_STREAM_END;
      Exit;
   End;

   { Write the lib trailer (adler32) }
   putShortMSB(s^, word(strm.adler Shr 16));
   putShortMSB(s^, word(strm.adler And $FFFF));
   flush_pending(strm);

   s^.noheader := -1;
   If (s^.pending <> 0) Then
      Result := Z_OK
   Else
      Result := Z_STREAM_END;
End;
//-------------------------------------------------------------

Function deflateCopy(dest, source: ztv_streamp): _int;
{$IFNDEF MAXSEG_64K}
Var
   ds: deflate_state_ptr;
   ss: deflate_state_ptr;
   overlay: pushfArray;
{$ENDIF}
Begin
{$IFDEF MAXSEG_64K}
   Result := Z_STREAM_ERROR;
   Exit;
{$ELSE}

   If (source = Z_NULL) Or (dest = Z_NULL) Or (source^.state = Z_NULL) Then
   Begin
      Result := Z_STREAM_ERROR;
      Exit;
   End;
   ss := deflate_state_ptr(source^.state);
   dest^ := source^;

   ds := deflate_state_ptr(ZALLOC(dest^, 1, SizeOf(deflate_state)));
   If (ds = Z_NULL) Then
   Begin
      Result := Z_MEM_ERROR;
      Exit;
   End;
   dest^.state := pInternal_state(ds);
   ds^ := ss^;
   ds^.strm := dest;

   ds^.window := pzByteArray(ZALLOC(dest^, ds^.w_size, 2 * SizeOf(Byte)));
   ds^.prev := pzPosfArray(ZALLOC(dest^, ds^.w_size, SizeOf(_Pos)));
   ds^.head := pzPosfArray(ZALLOC(dest^, ds^.hash_size, SizeOf(_Pos)));
   overlay := pushfArray(ZALLOC(dest^, ds^.lit_bufsize, SizeOf(ush) + 2));
   ds^.pending_buf := pzByteArray(overlay);

   If (ds^.window = Z_NULL) Or (ds^.prev = Z_NULL) Or (ds^.head = Z_NULL)
      Or (ds^.pending_buf = Z_NULL) Then
   Begin
      _deflateEnd(dest^);
      Result := Z_MEM_ERROR;
      Exit;
   End;

   CopyMem(@ss^.window^, @ds^.window^, ds^.w_size * 2 * SizeOf(Byte));
   CopyMem(@ss^.prev^, @ds^.prev^, ds^.w_size * SizeOf(_Pos));
   CopyMem(@ss^.head^, @ds^.head^, ds^.hash_size * SizeOf(_Pos));
   CopyMem(@ss^.pending_buf^, @ds^.pending_buf^, word(ds^.pending_buf_size));

   ds^.pending_out := @ds^.pending_buf^[ptr2int(ss^.pending_out) - ptr2int(ss^.pending_buf)];
   ds^.d_buf := pushfArray(@overlay^[ds^.lit_bufsize Div SizeOf(ush)]);
   ds^.l_buf := puchfArray(@ds^.pending_buf^[(1 + SizeOf(ush)) * ds^.lit_bufsize]);

   ds^.l_desc.dyn_tree := tree_ptr(@ds^.dyn_ltree);
   ds^.d_desc.dyn_tree := tree_ptr(@ds^.dyn_dtree);
   ds^.bl_desc.dyn_tree := tree_ptr(@ds^.bl_tree);

   Result := Z_OK;
{$ENDIF}
End;
//-------------------------------------------------------------

Function read_buf(strm: ztv_streamp; Buf: _pBytef; size: _unsigned): _int;
Var
   Len: _unsigned;
Begin
   Len := strm^.avail_in;

   If (Len > size) Then
      Len := size;

   If (Len = 0) Then
   Begin
      Result := 0;
      Exit;
   End;

   Dec(strm^.avail_in, Len);

   If deflate_state_ptr(strm^.state)^.noheader = 0 Then
      strm^.adler := _adler(strm^.adler, strm^.next_in, Len);

   //CopyMem(@strm^.next_in^, @Buf^, Len);
   Move(strm^.next_in^, Buf^, Len);

   If (Not strm^.cb.Protect) Then
   	Crc32_buf(@Buf^, Len, strm^.cb.CRC);

   inc(strm^.next_in, Len);
   strm^.total_in := strm^.total_in + Len;

   Result := _int(Len);
End;
//-------------------------------------------------------------

Procedure lm_init(Var s: deflate_state);
Begin
   s.window_size := longint(u_long(2) * u_long(s.w_size));
   s.head^[s.hash_size - 1] := ZNIL;
   zmemzero(_pBytef(s.head), _unsigned(s.hash_size - 1) * SizeOf(s.head^[0]));

   { Set the default configuration parameters: }
   s.max_lazy_match := configuration_table[s.level].max_lazy;
   s.good_match := configuration_table[s.level].good_length;
   s.nice_match := configuration_table[s.level].nice_length;
   s.max_chain_length := configuration_table[s.level].max_chain;

   s.strstart := 0;
   s.block_start := longint(0);
   s.lookahead := 0;
   s.prev_length := MIN_MATCH - 1;
   s.match_length := MIN_MATCH - 1;
   s.match_available := False;
   s.ins_h := 0;
End;
//-------------------------------------------------------------

{.$IFNDEF ASMV}
{$IFNDEF FASTEST}

Function longest_match(Var s: deflate_state;
   cur_match: IPos                      { current match }
   ): word;
Label
   nextstep;
Var
   chain_length: _unsigned;             { max hash chain length }
   {register} Scan: _pBytef;            { current string }
   {register} match: _pBytef;           { matched string }
   {register} Len: _int;                { length of current match }
   best_len: _int;                      { best match length so far }
   nice_match: _int;                    { stop if match LongInt enough }
   limit: IPos;

   prev: pzPosfArray;
   wmask: word;
{$IFDEF UNALIGNED_OK}
   {register} strend: _pBytef;
   {register} scan_start: ush;
   {register} scan_end: ush;
{$ELSE}
   {register} strend: _pBytef;
   {register} scan_end1: Byte;
   {register} scan_end: Byte;
{$ENDIF}
Var
   MAX_DIST: word;
Begin
   chain_length := s.max_chain_length;  { max hash chain length }
   Scan := @(s.window^[s.strstart]);
   best_len := s.prev_length;           { best match length so far }
   nice_match := s.nice_match;          { stop if match LongInt enough }

{$IFDEF DEFLATE64}
   MAX_DIST := s.w_size - MIN_LOOKAHEAD_DEF64;
{$ELSE}
   MAX_DIST := s.w_size - MIN_LOOKAHEAD;
{$ENDIF}

   {In order to simplify the code, particularly on 16 bit machines, match
   distances are limited to MAX_DIST instead of WSIZE. }

   If s.strstart > IPos(MAX_DIST) Then
      limit := s.strstart - IPos(MAX_DIST)
   Else
      limit := ZNIL;
   { Stop when cur_match becomes <= limit. To simplify the code,
     we prevent matches with the string of window index 0. }

   prev := s.prev;
   wmask := s.w_mask;

{$IFDEF UNALIGNED_OK}
   { Compare two bytes at a time. Note: this is not always beneficial.
     Try with and without -DUNALIGNED_OK to check. }

   strend := _pBytef(@(s.window^[s.strstart + MAX_MATCH - 1]));
   scan_start := pushf(Scan)^;
   scan_end := pushfArray(Scan)^[best_len - 1]; { fix }
{$ELSE}
   strend := _pBytef(@(s.window^[s.strstart + MAX_MATCH]));
{$IFOPT R+}{$R-}{$DEFINE NoRangeCheck}{$ENDIF}
   scan_end1 := pzByteArray(Scan)^[best_len - 1];
{$IFDEF NoRangeCheck}{$R+}{$UNDEF NoRangeCheck}{$ENDIF}
   scan_end := pzByteArray(Scan)^[best_len];
{$ENDIF}

   If (s.prev_length >= s.good_match) Then
      chain_length := chain_length Shr 2;

   If (word(nice_match) > s.lookahead) Then
      nice_match := s.lookahead;

   Repeat
      match := @(s.window^[cur_match]);

{$UNDEF DO_UNALIGNED_OK}
{$IFDEF UNALIGNED_OK}
{$IFDEF MAX_MATCH_IS_258}
{$DEFINE DO_UNALIGNED_OK}
{$ENDIF}
{$ENDIF}

{$IFDEF DO_UNALIGNED_OK}
      { This code assumes sizeof(_unsigned short) = 2. Do not use
        UNALIGNED_OK if your compiler uses a different size. }
{$IFOPT R+}{$R-}{$DEFINE NoRangeCheck}{$ENDIF}
      If (pushfArray(match)^[best_len - 1] <> scan_end) Or
         (pushf(match)^ <> scan_start) Then
         Goto nextstep;                 {continue;}
{$IFDEF NoRangeCheck}{$R+}{$UNDEF NoRangeCheck}{$ENDIF}

      inc(Scan);
      inc(match);

      Repeat
         inc(Scan, 2);
         inc(match, 2);
         If (pushf(Scan)^ <> pushf(match)^) Then break;
         inc(Scan, 2);
         inc(match, 2);
         If (pushf(Scan)^ <> pushf(match)^) Then break;
         inc(Scan, 2);
         inc(match, 2);
         If (pushf(Scan)^ <> pushf(match)^) Then break;
         inc(Scan, 2);
         inc(match, 2);
         If (pushf(Scan)^ <> pushf(match)^) Then break;
      Until (ptr2int(Scan) >= ptr2int(strend));
      //The "do while" generates better code on most compilers }

      //While (ptr2int(Scan) < ptr2int(strend)) Do
      //Begin
      //   inc(Scan, 2);
      //   inc(match, 2);
      //   If (pushf(Scan)^ <> pushf(match)^) Then break;
      //End;

      If (Scan^ = match^) Then
         inc(Scan);

      Len := (MAX_MATCH - 1) - _int(ptr2int(strend)) + _int(ptr2int(Scan));
      Scan := strend;
      Dec(Scan, (MAX_MATCH - 1));

{$ELSE}                                 { UNALIGNED_OK }

{$IFOPT R+}{$R-}{$DEFINE NoRangeCheck}{$ENDIF}
      If (pzByteArray(match)^[best_len] <> scan_end) Or
         (pzByteArray(match)^[best_len - 1] <> scan_end1) Or
         (match^ <> Scan^) Then
         Goto nextstep;                 {continue;}

{$IFDEF NoRangeCheck}{$R+}{$UNDEF NoRangeCheck}{$ENDIF}
      inc(match);

      If (match^ <> pzByteArray(Scan)^[1]) Then
         Goto nextstep;                 {continue;}

      inc(Scan, 2);
      inc(match);

      Repeat
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
      Until (ptr2int(Scan) >= ptr2int(strend));

      {While (ptr2int(Scan) < ptr2int(strend)) Do
      Begin
         inc(Scan);
         inc(match);
         If (Scan^ <> match^) Then break;
      End;}

      Len := MAX_MATCH - _int(ptr2int(strend) - ptr2int(Scan));
      Scan := strend;
      Dec(Scan, MAX_MATCH);

{$ENDIF}                                { UNALIGNED_OK }

      If (Len > best_len) Then
      Begin
         s.match_start := cur_match;
         best_len := Len;
         If (Len >= nice_match) Then
            break;
{$IFOPT R+}{$R-}{$DEFINE NoRangeCheck}{$ENDIF}
{$IFDEF UNALIGNED_OK}
         scan_end := pzByteArray(Scan)^[best_len - 1];
{$ELSE}
         scan_end1 := pzByteArray(Scan)^[best_len - 1];
         scan_end := pzByteArray(Scan)^[best_len];
{$ENDIF}
{$IFDEF NoRangeCheck}{$R+}{$UNDEF NoRangeCheck}{$ENDIF}
      End;
      nextstep:
      cur_match := prev^[cur_match And wmask];
      Dec(chain_length);
   Until (cur_match <= limit) Or (chain_length = 0);

   If (word(best_len) <= s.lookahead) Then
      longest_match := word(best_len)
   Else
      longest_match := s.lookahead;
End;
{.$ENDIF}{ ASMV }
//-------------------------------------------------------------

{$ELSE}                                 { FASTEST }

Function longest_match(Var s

⌨️ 快捷键说明

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