📄 frxzlib.pas
字号:
result:= code;
if code < 0 then
begin
raise EZCompressionError.Create(_z_errmsg[2-code]);
end;
end;
function ZDecompressCheck(code:Integer):Integer;
begin
Result:= code;
if code < 0 then
begin
raise EZDecompressionError.Create(_z_errmsg[2-code]);
end;
end;
procedure ZCompress(const inBuffer:Pointer; inSize:Integer;
out outBuffer:Pointer; out outSize:Integer;
level:TZCompressionLevel);
const
delta = 256;
var
zstream:TZStreamRec;
begin
FillChar(zstream, SizeOf(TZStreamRec), 0);
outSize:= ((inSize+(inSize div 10)+12)+255) and not 255;
GetMem(outBuffer, outSize);
try
zstream.next_in:= inBuffer;
zstream.avail_in:= inSize;
zstream.next_out:= outBuffer;
zstream.avail_out:= outSize;
ZCompressCheck(DeflateInit(zstream, ZLevels[level]));
try
while ZCompressCheck(deflate(zstream, Z_FINISH))<>Z_STREAM_END do
begin
Inc(outSize, delta);
ReallocMem(outBuffer, outSize);
zstream.next_out:= PChar(Integer(outBuffer)+zstream.total_out);
zstream.avail_out:= delta;
end;
finally
ZCompressCheck(deflateEnd(zstream));
end;
ReallocMem(outBuffer, zstream.total_out);
outSize:= zstream.total_out;
except
FreeMem(outBuffer);
raise;
end;
end;
procedure ZDecompress(const inBuffer:Pointer; inSize:Integer;
out outBuffer:Pointer; out outSize:Integer; outEstimate:Integer);
var
zstream:TZStreamRec;
delta:Integer;
begin
FillChar(zstream, SizeOf(TZStreamRec), 0);
delta:= (inSize+255) and not 255;
if outEstimate = 0 then outSize:= delta
else outSize:= outEstimate;
GetMem(outBuffer, outSize);
try
zstream.next_in:= inBuffer;
zstream.avail_in:= inSize;
zstream.next_out:= outBuffer;
zstream.avail_out:= outSize;
ZDecompressCheck(InflateInit(zstream));
try
while ZDecompressCheck(inflate(zstream, Z_NO_FLUSH))<>Z_STREAM_END do
begin
Inc(outSize, delta);
ReallocMem(outBuffer, outSize);
zstream.next_out:= PChar(Integer(outBuffer)+zstream.total_out);
zstream.avail_out:= delta;
end;
finally
ZDecompressCheck(inflateEnd(zstream));
end;
ReallocMem(outBuffer, zstream.total_out);
outSize:= zstream.total_out;
except
FreeMem(outBuffer);
raise;
end;
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;
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;
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;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -