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

📄 ztvinflate64.pas

📁 ziptv为delphi控件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
            If f > a + 1 Then
            Begin
               dec(f, a + 1);
               xp := @c[k];
               Inc(j);
               TryAgain := True;
               While (j < z) And TryAgain Do
               Begin
                  f := f Shl 1;
                  Inc(Longint(xp), SizeOf(Word));
                  If f <= xp^ Then
                     TryAgain := False
                  Else
                  Begin
                     dec(f, xp^);
                     Inc(j);
                  End;
               End;
            End;

            If (w + j > el) And (w < el) Then
               j := el - w;             {make eob code end at table}

            If w = 0 Then
            Begin
               j := m;                  {fix: main table always m bits}
            End;

            z := 1 Shl j;
            l[h] := j;

            {allocate and link new table}
            GetMem(q, (z + 1) * SizeOf(huft));
            If q = Nil Then
            Begin
               If h <> 0 Then
                  huft_free(Pointer(u[0]));
               Result := huft_outofmem;
               exit
            End;

            FillChar(q^, (z + 1) * SizeOf(huft), #0);
            q^[0].v_n := z;             {size of table, needed in freemem ***}

            t^ := @q^[1];               {first item starts at 1}
            t := pphuft(@q^[0].v_t);
            t^ := Nil;
            q := phuftlist(@q^[1]); {pointer(longint(q)+sizeof(huft));} {???}
            u[h] := q;

            {connect to last table, if there is one}
            If h <> 0 Then
            Begin
               x[h] := i;
               r.b := l[h - 1];
               r.e := AdditionalBitsInTable + j;
               r.v_t := q;
               j := (i And ((1 Shl w) - 1)) Shr (w - l[h - 1]);

               {test against bad input!}
               pt := phuft(Longint(u[h - 1]) - SizeOf(huft));
               If j > pt^.v_n Then
               Begin
                  huft_free(Pointer(u[0]));
                  Result := huft_error;
                  exit
               End;

               pt := @u[h - 1]^[j];
               pt^ := r;
            End;
         End;

         {set up table entry in r}
         r.b := Word(k - w);
         r.v_t := Nil; 						 {unused}

         If Longint(p) >= Longint(@v[n]) Then
            r.e := InvalidCode
         Else
            If p^ < s Then
            Begin
            	If AdditionalBitsInTable = 16 Then
               Begin
                  If p^ < 256 Then
                     r.e := 16
                  Else
                     r.e := 15;
               End Else
                  If p^ < 256 Then
                     r.e := ValidCode
                  Else
                     r.e := EndOfBlock;

               r.v_n := p^;
               Inc(Longint(p), SizeOf(Word));
            End
            Else
            Begin
               If (d = Nil) Or (e = Nil) Then
               Begin
                  huft_free(Pointer(u[0]));
                  Result := huft_error;
                  exit
               End;
               r.e := Word(e^[p^ - s] + NonSimpleLookup);
               r.e := e^[p^ - s];
               r.v_n := d^[p^ - s];
               Inc(Longint(p), SizeOf(Word));
            End;

         {fill code like entries with r}
         f := 1 Shl (k - w);
         j := i Shr w;
         While j < z Do
         Begin
            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^j;}
            i := i Xor j;
            j := j Shr 1;
         End;
         i := i Xor j;

         {backup over finished tables}
         While ((i And ((1 Shl w) - 1)) <> x[h]) Do
         Begin
            dec(h);
            dec(w, l[h]);               {size of previous table!}
         End;
      End;
   End;

   m := Integer(l[0]);

   If (y <> 0) And (g <> 1) Then
      Result := huft_incomplete
   Else
      Result := huft_complete;
End;
//-------------------------------------------------------------

(* "Decompress" an inflated type 0 ( stored ) block. *)

Function inflate_stored: Integer;
Var
   n: Word;                             {number of bytes in block}
Begin
   {go to byte boundary}
   n := k And 7;
   DumpBits(n);
   {get the length and its complement}
   NeedBits(16);
   n := b And $FFFF;
   DumpBits(16);
   NeedBits(16);
   If (n <> (Not b) And $FFFF) Then
   Begin
      inflate_stored := unzip_ZipFileErr;
      exit
   End;
   DumpBits(16);
   While (n > 0) And Not (pCancel^ Or zipEOF) Do
   Begin                                {read and output the compressed data}
      dec(n);
      NeedBits(8);
      Slide[w] := Char(b);
      Inc(w);
      If w = WSIZE Then
      Begin
         If Not Flush(w) Then
         Begin
            Result := unzip_WriteErr;
            exit
         End;
         w := 0;
      End;
      DumpBits(8);
   End;

   If pCancel^ Then
      Result := unzip_UserAbort
   Else
      If zipEOF Then
         Result := unzip_ReadErr
      Else
         Result := unzip_Ok;
End;
//-------------------------------------------------------------

Function inflate_codes(tl, td: phuftlist; bl, bd: Integer): Integer;
Var
   n, d: Cardinal;
   e1,                                  //length and index for copy
   ml, md: Word;                        //masks for bl and bd bits
   t: phuft;                            //pointer to table entry
   e: Byte;                             //table entry flag/number of extra bits
Begin

   // inflate the coded data
   ml := mask_bits[bl];                 //precompute masks for speed
   md := mask_bits[bd];

   While Not (pCancel^ Or zipEOF) Do
   Begin
      NeedBits(bl);
      t := @tl^[b And ml];
      e := t^.e;

      If e > ValidCode Then
         Repeat                         // it's a literal
            If e = InvalidCode Then
            Begin
               Result := unzip_ZipFileErr;
               exit
            End;
            DumpBits(t^.b);
            dec(e, ValidCode);
            NeedBits(e);
            t := @t^.v_t^[b And mask_bits[e]];
            e := t^.e;
         Until e <= ValidCode;

      DumpBits(t^.b);
      If e = ValidCode Then
      Begin
         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
         End;
      End
      Else
      Begin                             //it's an EOB or a length
         If e = EndOfBlock Then
         Begin                          //exit if end of block
            Result := unzip_Ok;
            exit;
         End;

         NeedBits(e);                   //get length of block to copy
         n := t^.v_n + (b And mask_bits[e]);
         DumpBits(e);
         NeedBits(bd);                  //Decode distance of block to copy
         t := @td^[b And md];

         e := t^.e;
         If e > ValidCode Then
            Repeat
               If e = InvalidCode Then
               Begin
                  Result := unzip_ZipFileErr;
                  exit
               End;
               DumpBits(t^.b);

               dec(e, ValidCode);
               NeedBits(e);
               t := @t^.v_t^[b And mask_bits[e]];
               e := t^.e;
            Until e <= ValidCode;

         DumpBits(t^.b);
         NeedBits(e);
         d := w - t^.v_n - b And mask_bits[e];
         DumpBits(e);

         //do the copy
         Repeat
            If pCancel^ Then
               Break;
            d := d And (WSIZE - 1);
            If d > w Then
               e1 := WSIZE - d
            Else
               e1 := WSIZE - w;

            If e1 > n Then
               e1 := n;

            dec(n, e1);

            // v6.4.2 revised ==================================
            // changed for speed.  The "move" procedure does not
            // work due to overlap issues.  CopyMem works great
            // and much faster!
            // =================================================
            If (w - d >= e1) Then
            Begin
               Move(Slide[d], Slide[w], e1);
               Inc(w, e1);
               Inc(d, e1);
            End
            Else
            Begin
               Repeat
                  Slide[w] := Slide[d];
                  Inc(w);
                  Inc(d);
                  dec(e1);
               Until (e1 = 0);
            End;
            //CopyMem(@Slide[d], @Slide[w], e1);
            //Inc(w, e1);
            //Inc(d, e1);
            // v6.4.2 ==========================================

            If w = WSIZE Then
            Begin
               If (Not pCancel^) And (Not Flush(w)) Then
               Begin
                  Result := unzip_WriteErr;
                  exit;
               End;
               w := 0;
            End;

         Until n = 0;
      End;
   End;

   If pCancel^ Then
      inflate_codes := unzip_UserAbort
   Else
      inflate_codes := unzip_ReadErr;
End;
//-------------------------------------------------------------

Function inflate_fixed: Integer;
Var
   i: Integer;                          { temporary variable }
   tl,                                  { literal/length code table }
   td: phuftlist;                       { distance code table }
   bl, bd: Integer;                     { lookup bits for tl/bd }
   l: Array[0..287] Of Word;            { length list for huft_build }
Begin
   {set up literal table}
   For i := 0 To 143 Do
      l[i] := 8;
   For i := 144 To 255 Do
      l[i] := 9;
   For i := 256 To 279 Do
      l[i] := 7;
   For i := 280 To 287 Do
      l[i] := 8;                        {make a complete, but wrong code set}

   bl := 7;
   If Is64Bit Then
      i := huft_build(pWord(@l), 288, 257, PushList(@cplens64), PushList(@cplext64),
         pphuft(@tl), bl)
   Else
      i := huft_build(pWord(@l), 288, 257, PushList(@cplens), PushList(@cplext),
         pphuft(@tl), bl);

   If i <> huft_complete Then
   Begin
      Result := i;
      exit
   End;

   For i := 0 To 29 Do
      l[i] := 5;                        {make an incomplete code set}

   bd := 5;
   If Is64Bit Then
      i := huft_build(pWord(@l), 30, 0, PushList(@cpdist64), PushList(@cpdext64),
         pphuft(@td), bd)
   Else
      i := huft_build(pWord(@l), 30, 0, PushList(@cpdist), PushList(@cpdext),
         pphuft(@td), bd);

   If i > huft_incomplete Then
   Begin
      huft_free(tl);
      Result := unzip_ZipFileErr;
      exit
   End;

   Result := inflate_codes(tl, td, bl, bd);
   huft_free(tl);
   huft_free(td);
End;
//-------------------------------------------------------------

(* Decompress an inflated type 2 ( dynamic Huffman codes ) block. *)

Function inflate_dynamic: Integer;
Var
   i: Integer;                          { temporary variables }
   j,
      l,                                { last length }
   m,                                   { mask for bit length table }
   n: Word;                             { number of lengths to get }
   tl,                                  { literal/length code table }
   td: phuftlist;                       { distance code table }
   bl, bd: Integer;                     { lookup bits for tl/bd }
   nb, nl, nd: Word; 						 { number of bit length/literal length/distance codes }
   ll: Array[0..288 + 32 - 1] Of Word;  { literal/length and distance code lengths }

Begin
   //read in table lengths
   NeedBits(5);
   nl := 257 + Word(b) And $1F;
   DumpBits(5);
   NeedBits(5);
   nd := 1 + Word(b) And $1F;
   DumpBits(5);
   NeedBits(4);
   nb := 4 + Word(b) And $F;
   DumpBits(4);

   If (nl > 288) Or (nd > 32) Then
   Begin
      Result := 1;
      exit
   End;

   FillChar(ll, SizeOf(ll), #0);

   {read in bit-length-code lengths}
   For j := 0 To nb - 1 Do
   Begin
      NeedBits(3);
      ll[Border[j]] := b And 7;
      DumpBits(3);
   End;

   For j := nb To 18 Do
      ll[Border[j]] := 0;

   {build Decoding table for trees--single level, 7 bit lookup}
   bl := 7;
   If Is64Bit Then
      i := huft_build(pWord(@ll), 19, 19, Nil, Nil, pphuft(@tl), bl)
   Else
      i := huft_build(pWord(@ll), 19, 19, Nil, Nil, pphuft(@tl), bl);

   If i <> huft_complete Then
   Begin
      If i = huft_incomplete Then
         huft_free(tl);                 {other errors: already freed}
      Result := unzip_ZipFileErr;
      exit;
   End;

   {read in literal and distance code lengths}
   n := nl + nd;
   m := mask_bits[bl];
   l := 0;

   i := 0;
   While Word(i) < n Do
   Begin
      NeedBits(bl);
      td := phuftlist(@tl^[b And m]);
      j := phuft(td)^.b;
      DumpBits(j);
      j := phuft(td)^.v_n;
      If j < 16 Then
      Begin                             {length of code in bits (0..15)}
         l := j;                        {save last length in l}
         ll[i] := l;
         Inc(i)
      End
      Else
         If j = 16 Then
         Begin                          {repeat last length 3 to 6 times}
            NeedBits(2);
            j := 3 + b And 3;
            DumpBits(2);

            If i + j > n Then
            Begin
               inflate_dynamic := 1;
               exit
            End;

            While j > 0 Do
            Begin
               ll[i] := l;
               dec(j);
               Inc(i);
            End;
         End
         Else
            If j = 17 Then
            Begin                       {3 to 10 zero length codes}
               NeedBits(3);
               j := 3 + b And 7;
               DumpBits(3);

               If i + j > n Then
               Begin
                  inflate_dynamic := 1;
                  exit
               End;

               While j > 0 Do
               Begin
                  ll[i] := 0;
                  Inc(i);
                  dec(j);
               End;
               l := 0;
            End
            Else
            Begin                       {j == 18: 11 to 138 zero length codes}
               NeedBits(7);
               j := 11 + b And $7F;
               DumpBits(7);

               If i + j > n Then
               Begin
                  Result := unzip_ZipFileErr;

⌨️ 快捷键说明

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