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

📄 idcompressorzlibex.pas

📁 photo.163.com 相册下载器 多线程下载
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      end;
      // Get the data from the input stream and save it off
      LSendCount := AStream.Read(LSendBuf^, AStream.Size);
      LCompressRec.next_in := LSendBuf;
      LCompressRec.avail_in := LSendCount;
      LCompressRec.avail_out := 0;

      if Assigned(AOutStream) then
      begin
        AOutStream.Size := 0;
      end
      else
      begin
        // reset and clear the input stream in preparation for compression
        AStream.Size := 0;
      end;
      // As long as data is being outputted, keep compressing
      while LCompressRec.avail_out = 0 do
      begin
        LCompressRec.next_out := Buffer;
        LCompressRec.avail_out := SizeOf(Buffer);
        case deflate(LCompressRec, Z_SYNC_FLUSH) of
          Z_STREAM_ERROR,
          Z_DATA_ERROR,
          Z_MEM_ERROR: raise EIdCompressionError.Create(RSZLCompressionError);
        end;

        if Assigned(AOutStream) then
        begin
          AOutStream.Write(Buffer, SizeOf(Buffer) - LCompressRec.avail_out);
        end
        else
        begin
          // Place the compressed data back into the input stream
          AStream.Write(Buffer, SizeOf(Buffer) - LCompressRec.avail_out);
        end;
      end;
    //finalization cleanup
    finally
      deflateEnd(LCompressRec);
      FillChar(LCompressRec, SizeOf(LCompressRec), 0);
      if LSendBuf<>nil then
      begin
        FreeMem(LSendBuf);
      end;
    end;
  end;
end;

procedure TIdCompressorZLibEx.DecompressStream(AStream : TStream; const AWindowBits : Integer; const AOutStream : TStream=nil);
var
  Buffer: array[0..2047] of Char;
  nChars, C: Integer;
  StreamEnd: Boolean;
  LDecompressRec: TZStreamRec;
  LRecvCount, LRecvSize: Int64;
  LRecvBuf: Pointer;
begin
    LRecvCount := 0;
    LRecvSize := 0;
    LRecvBuf := nil;
    //initialization section
    LDecompressRec.zalloc := zcalloc;
    LDecompressRec.zfree := zcfree;
    if inflateInit2_(LDecompressRec, AWindowBits, zlib_Version, SizeOf(LDecompressRec)) <> Z_OK then
    begin
      raise EIdDecompressorInitFailure.Create(RSZLDecompressorInitializeFailure);
    end;
    try
      //decompression
      StreamEnd := False;
      repeat
        nChars := AStream.Read(Buffer, SizeOf(Buffer));
        if nChars = 0 then
        begin
          Break;
        end;
        LDecompressRec.next_in := Buffer;
        LDecompressRec.avail_in := nChars;
        LDecompressRec.total_in := 0;
        while LDecompressRec.avail_in > 0 do
        begin
          if LRecvCount = LRecvSize then
          begin
            if LRecvSize = 0 then
            begin
              LRecvSize := 2048;
            end
            else
            begin
              Inc(LRecvSize, 1024);
            end;
            ReallocMem(LRecvBuf, LRecvSize);
          end;
          LDecompressRec.next_out := PChar(LRecvBuf) + LRecvCount;
          C := LRecvSize - LRecvCount;
          LDecompressRec.avail_out := C;
          LDecompressRec.total_out := 0;
          case inflate(LDecompressRec, Z_NO_FLUSH) of
            Z_STREAM_END:
              StreamEnd := True;
            Z_STREAM_ERROR,
            Z_DATA_ERROR,
            Z_MEM_ERROR:
              raise EIdDecompressionError.Create(RSZLDecompressionError);
          end;
          Inc(LRecvCount, C - LDecompressRec.avail_out);
        end;
      until StreamEnd;
      if Assigned(AOutStream) then
      begin
        AOutStream.Size := 0;
        AOutStream.Write(LRecvBuf^, LRecvCount);
      end
      else
      begin
        AStream.Size := 0;
        AStream.Write(LRecvBuf^, LRecvCount);
      end;
    finally
      //deinitialization
      inflateEnd(LDecompressRec);
      FillChar(LDecompressRec, SizeOf(LDecompressRec), 0);
      if LRecvBuf<>nil then
      begin
        FreeMem(LRecvBuf);
      end;
    end;
end;

procedure TIdCompressorZLibEx.DeflateStream(AStream : TStream; const ALevel : TIdCompressionLevel=0; const AOutStream : TStream=nil);

var 
    LCompressRec: TZStreamRec;
var
  Buffer: array[0..1023] of Char;
   LSendBuf: Pointer;
   LSendCount, LSendSize: Int64;
begin
  if ALevel in [1..9] then
  begin
    LSendSize := 0;
    LSendBuf := nil;
    //initialization
    LCompressRec.zalloc := zcalloc;
    LCompressRec.zfree := zcfree;
    if deflateInit_(LCompressRec, ALevel, ZLIB_VERSION,  SizeOf(LCompressRec)) <> Z_OK then
    begin
      raise EIdCompressorInitFailure.Create(RSZLCompressorInitializeFailure);
    end;
    try
      // Make sure the Send buffer is large enough to hold the input stream data
      if AStream.Size > LSendSize then
      begin
        if AStream.Size > 2048 then
        begin
          LSendSize := AStream.Size + (AStream.Size + 1023) mod 1024
        end
        else
        begin
          LSendSize := 2048;
        end;
        ReallocMem(LSendBuf, LSendSize);
      end;
      // Get the data from the input stream and save it off
      LSendCount := AStream.Read(LSendBuf^, AStream.Size);
      LCompressRec.next_in := LSendBuf;
      LCompressRec.avail_in := LSendCount;
      LCompressRec.avail_out := 0;
      if Assigned(AOutStream) then
      begin
        AOutStream.Size := 0;
      end
      else
      begin
        // reset and clear the input stream in preparation for compression
        AStream.Size := 0;
      end;
      // As long as data is being outputted, keep compressing
      while LCompressRec.avail_out = 0 do
      begin
        LCompressRec.next_out := Buffer;
        LCompressRec.avail_out := SizeOf(Buffer);
        
        case deflate(LCompressRec, Z_SYNC_FLUSH) of
          Z_STREAM_ERROR,
          Z_DATA_ERROR,
          Z_MEM_ERROR: raise EIdCompressionError.Create(RSZLCompressionError);
        end;
        if Assigned(AOutStream) then
        begin
          AOutStream.Write(Buffer, SizeOf(Buffer) - LCompressRec.avail_out);
        end
        else
        begin
          // Place the compressed data back into the input stream
          AStream.Write(Buffer, SizeOf(Buffer) - LCompressRec.avail_out);
        end;
      end;
    //finalization cleanup
    finally
      deflateEnd(LCompressRec);

      FillChar(LCompressRec, SizeOf(LCompressRec), 0);
      if LSendBuf<>nil then
      begin
        FreeMem(LSendBuf);
      end;
    end;
  end;
end;

procedure TIdCompressorZLibEx.InflateStream(AStream : TStream; const AOutStream : TStream=nil);
var
  Buffer: array[0..2047] of Char;
  nChars, C: Integer;
  StreamEnd: Boolean;
  LDecompressRec: TZStreamRec;
  LRecvCount, LRecvSize: Int64;
  LRecvBuf: Pointer;
begin
    LRecvCount := 0;
    LRecvSize := 0;
    LRecvBuf := nil;
    LDecompressRec.adler := 0;
    //initialization section
    LDecompressRec.zalloc := zcalloc;
    LDecompressRec.zfree := zcfree;
    if inflateInit_(LDecompressRec, zlib_Version, SizeOf(LDecompressRec)) <> Z_OK then
    begin
      raise EIdDecompressorInitFailure.Create(RSZLDecompressorInitializeFailure);
    end;
    try
      //decompression
      StreamEnd := False;
      repeat
        nChars := AStream.Read(Buffer, SizeOf(Buffer));
        if nChars = 0 then
        begin
          Break;
        end;
        LDecompressRec.next_in := Buffer;
        LDecompressRec.avail_in := nChars;
        LDecompressRec.total_in := 0;

        while LDecompressRec.avail_in > 0 do
        begin
          if LRecvCount = LRecvSize then
          begin
            if LRecvSize = 0 then
            begin
              LRecvSize := 2048;
            end
            else
            begin
              Inc(LRecvSize, 1024);
            end;
            ReallocMem(LRecvBuf, LRecvSize);
          end;
          LDecompressRec.next_out := PChar(LRecvBuf) + LRecvCount;
          C := LRecvSize - LRecvCount;
          LDecompressRec.avail_out := C;
          LDecompressRec.total_out := 0;
          case inflate(LDecompressRec, Z_NO_FLUSH) of
            Z_STREAM_END:
              StreamEnd := True;
            Z_STREAM_ERROR,
            Z_DATA_ERROR,
            Z_MEM_ERROR:
              raise EIdDecompressionError.Create(RSZLDecompressionError);
          end;

          Inc(LRecvCount, C - LDecompressRec.avail_out);
        end;
      until StreamEnd;
      if Assigned(AOutStream) then
      begin
        AOutStream.Size := 0;
        AOutStream.Write(LRecvBuf^, LRecvCount);
      end
      else
      begin
        AStream.Size := 0;
        AStream.Write(LRecvBuf^, LRecvCount);
      end;
    finally
      //deinitialization
      inflateEnd(LDecompressRec);

      FillChar(LDecompressRec, SizeOf(LDecompressRec), 0);
      if LRecvBuf<>nil then
      begin
        FreeMem(LRecvBuf);
      end;
    end;
end;

end.

⌨️ 快捷键说明

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