📄 zlibex.pas
字号:
zresult := ZCompressCheck(deflate(zstream,Z_NO_FLUSH));
outSize := bufferSize - zstream.avail_out;
outStream.Write(outBuffer,outSize);
until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
zstream.avail_in := inStream.Read(inBuffer,bufferSize);
end;
while zresult <> Z_STREAM_END do
begin
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize;
zresult := ZCompressCheck(deflate(zstream,Z_FINISH));
outSize := bufferSize - zstream.avail_out;
outStream.Write(outBuffer,outSize);
end;
ZCompressCheck(deflateEnd(zstream));
end;
procedure ZInternalDecompressStream(zstream: TZStreamRec; inStream,
outStream: TStream);
const
//bufferSize = 32768;
bufferSize = 393216;
var
zresult : Integer;
inBuffer : Array [0..bufferSize-1] of Char;
outBuffer: Array [0..bufferSize-1] of Char;
outSize : Integer;
begin
zresult := Z_STREAM_END;
zstream.avail_in := inStream.Read(inBuffer,bufferSize);
while zstream.avail_in > 0 do
begin
zstream.next_in := inBuffer;
repeat
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize;
zresult := ZDecompressCheck(inflate(zstream,Z_NO_FLUSH));
outSize := bufferSize - zstream.avail_out;
outStream.Write(outBuffer,outSize);
until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
if zresult <> Z_STREAM_END then
begin
zstream.avail_in := inStream.Read(inBuffer,bufferSize);
end
else if zstream.avail_in > 0 then
begin
inStream.Position := inStream.Position - zstream.avail_in;
zstream.avail_in := 0;
end;
end;
while zresult <> Z_STREAM_END do
begin
zstream.next_out := outBuffer;
zstream.avail_out := bufferSize;
zresult := ZDecompressCheck(inflate(zstream,Z_FINISH));
outSize := bufferSize - zstream.avail_out;
outStream.Write(outBuffer,outSize);
end;
ZDecompressCheck(inflateEnd(zstream));
end;
procedure ZCompressStream(inStream, outStream: TStream;
level: TZCompressionLevel);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZCompressCheck(DeflateInit(zstream,ZLevels[level]));
ZInternalCompressStream(zstream,inStream,outStream);
end;
procedure ZCompressStream2(inStream, outStream: TStream;
level: TZCompressionLevel; windowBits, memLevel: Integer;
strategy: TZStrategy);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZCompressCheck(DeflateInit2(zstream,ZLevels[level],Z_DEFLATED,windowBits,
memLevel,ZStrategies[strategy]));
ZInternalCompressStream(zstream,inStream,outStream);
end;
procedure ZDecompressStream(inStream, outStream: TStream);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZDecompressCheck(InflateInit(zstream));
ZInternalDecompressStream(zstream,inStream,outStream);
end;
procedure ZDecompressStream2(inStream, outStream: TStream;
windowBits: Integer);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZDecompressCheck(InflateInit2(zstream,windowBits));
ZInternalDecompressStream(zstream,inStream,outStream);
end;
{** TCustomZStream **********************************************************}
constructor TCustomZStream.Create(stream: TStream);
begin
inherited Create;
FStream := stream;
FStreamPos := stream.Position;
end;
procedure TCustomZStream.DoProgress;
begin
if Assigned(FOnProgress) then FOnProgress(Self);
end;
{** TZCompressionStream *****************************************************}
constructor TZCompressionStream.Create(dest: TStream;
compressionLevel: TZCompressionLevel);
begin
inherited Create(dest);
FZStream.next_out := FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
ZCompressCheck(DeflateInit(FZStream,ZLevels[compressionLevel]));
end;
constructor TZCompressionStream.Create(dest: TStream;
compressionLevel: TZCompressionLevel; windowBits, memLevel: Integer;
strategy: TZStrategy);
begin
inherited Create(dest);
FZStream.next_out := FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
ZCompressCheck(DeflateInit2(FZStream,ZLevels[compressionLevel],Z_DEFLATED,
windowBits,memLevel,ZStrategies[strategy]));
end;
destructor TZCompressionStream.Destroy;
begin
FZStream.next_in := Nil;
FZStream.avail_in := 0;
try
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
while ZCompressCheck(deflate(FZStream,Z_FINISH)) <> Z_STREAM_END do
begin
FStream.WriteBuffer(FBuffer,SizeOf(FBuffer) - FZStream.avail_out);
FZStream.next_out := FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
end;
if FZStream.avail_out < SizeOf(FBuffer) then
begin
FStream.WriteBuffer(FBuffer,SizeOf(FBuffer) - FZStream.avail_out);
end;
finally
deflateEnd(FZStream);
end;
inherited Destroy;
end;
function TZCompressionStream.Read(var buffer; count: Longint): Longint;
begin
raise EZCompressionError.Create(SZInvalid);
end;
function TZCompressionStream.Write(const buffer; count: Longint): Longint;
begin
FZStream.next_in := @buffer;
FZStream.avail_in := count;
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
while FZStream.avail_in > 0 do
begin
ZCompressCheck(deflate(FZStream,Z_NO_FLUSH));
if FZStream.avail_out = 0 then
begin
FStream.WriteBuffer(FBuffer,SizeOf(FBuffer));
FZStream.next_out := FBuffer;
FZStream.avail_out := SizeOf(FBuffer);
FStreamPos := FStream.Position;
DoProgress;
end;
end;
result := Count;
end;
function TZCompressionStream.Seek(offset: Longint; origin: Word): Longint;
begin
if (offset = 0) and (origin = soFromCurrent) then
begin
result := FZStream.total_in;
end
else raise EZCompressionError.Create(SZInvalid);
end;
function TZCompressionStream.GetCompressionRate: Single;
begin
if FZStream.total_in = 0 then result := 0
else result := (1.0 - (FZStream.total_out / FZStream.total_in)) * 100.0;
end;
{** TZDecompressionStream ***************************************************}
constructor TZDecompressionStream.Create(source: TStream);
begin
inherited Create(source);
FZStream.next_in := FBuffer;
FZStream.avail_in := 0;
ZDecompressCheck(InflateInit(FZStream));
end;
constructor TZDecompressionStream.Create(source: TStream;
windowBits: Integer);
begin
inherited Create(source);
FZStream.next_in := FBuffer;
FZStream.avail_in := 0;
ZDecompressCheck(InflateInit2(FZStream,windowBits));
end;
destructor TZDecompressionStream.Destroy;
begin
inflateEnd(FZStream);
inherited Destroy;
end;
function TZDecompressionStream.Read(var buffer; count: Longint): Longint;
var
zresult: Integer;
begin
FZStream.next_out := @buffer;
FZStream.avail_out := count;
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
zresult := Z_OK;
while (FZStream.avail_out > 0) and (zresult <> Z_STREAM_END) do
begin
if FZStream.avail_in = 0 then
begin
FZStream.avail_in := FStream.Read(FBuffer,SizeOf(FBuffer));
if FZStream.avail_in = 0 then
begin
result := count - FZStream.avail_out;
Exit;
end;
FZStream.next_in := FBuffer;
FStreamPos := FStream.Position;
DoProgress;
end;
zresult := ZDecompressCheck(inflate(FZStream,Z_NO_FLUSH));
end;
if (zresult = Z_STREAM_END) and (FZStream.avail_in > 0) then
begin
FStream.Position := FStream.Position - FZStream.avail_in;
FStreamPos := FStream.Position;
FZStream.avail_in := 0;
end;
result := count - FZStream.avail_out;
end;
function TZDecompressionStream.Write(const Buffer; Count: Longint): Longint;
begin
raise EZDecompressionError.Create(SZInvalid);
end;
function TZDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
var
buf: Array [0..8191] of Char;
i : Integer;
begin
if (offset = 0) and (origin = soFromBeginning) then
begin
ZDecompressCheck(inflateReset(FZStream));
FZStream.next_in := FBuffer;
FZStream.avail_in := 0;
FStream.Position := 0;
FStreamPos := 0;
end
else if ((offset >= 0) and (origin = soFromCurrent)) or
(((offset - FZStream.total_out) > 0) and (origin = soFromBeginning)) then
begin
if origin = soFromBeginning then Dec(offset,FZStream.total_out);
if offset > 0 then
begin
for i := 1 to offset div SizeOf(buf) do ReadBuffer(buf,SizeOf(buf));
ReadBuffer(buf,offset mod SizeOf(buf));
end;
end
else if (offset = 0) and (origin = soFromEnd) then
begin
while Read(buf,SizeOf(buf)) > 0 do ;
end
else raise EZDecompressionError.Create(SZInvalid);
result := FZStream.total_out;
end;
{** EZLibError **************************************************************}
constructor EZLibError.Create(code: Integer);
begin
inherited Create(_z_errmsg[2 - code]);
FErrorCode := code;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -