📄 idcompressorzlibex.pas
字号:
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 + -