📄 zlibex.pas
字号:
);
ZStrategies: Array [TZStrategy] of Shortint = (
Z_DEFAULT_STRATEGY,
Z_FILTERED,
Z_HUFFMAN_ONLY,
Z_RLE,
Z_FIXED
);
SZInvalid = 'Invalid ZStream operation!';
{** deflate routines ********************************************************}
function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
recsize: Integer): Integer;
external;
function deflateInit2_(var strm: TZStreamRec; level, method, windowBits,
memLevel, strategy: Integer; version: PChar; recsize: Integer): Integer;
external;
function deflate(var strm: TZStreamRec; flush: Integer): Integer;
external;
function deflateEnd(var strm: TZStreamRec): Integer;
external;
{** inflate routines ********************************************************}
function inflateInit_(var strm: TZStreamRec; version: PChar;
recsize: Integer): Integer;
external;
function inflateInit2_(var strm: TZStreamRec; windowBits: Integer;
version: PChar; recsize: Integer): Integer;
external;
function inflate(var strm: TZStreamRec; flush: Integer): Integer;
external;
function inflateEnd(var strm: TZStreamRec): Integer;
external;
function inflateReset(var strm: TZStreamRec): Integer;
external;
{** zlib function implementations *******************************************}
function zcalloc(opaque: Pointer; items, size: Integer): Pointer;
begin
GetMem(result,items * size);
end;
procedure zcfree(opaque, block: Pointer);
begin
FreeMem(block);
end;
{** c function implementations **********************************************}
procedure _memset(p: Pointer; b: Byte; count: Integer); cdecl;
begin
FillChar(p^,count,b);
end;
procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
begin
Move(source^,dest^,count);
end;
{** custom zlib routines ****************************************************}
function DeflateInit(var stream: TZStreamRec; level: Integer): Integer;
begin
result := deflateInit_(stream,level,ZLIB_VERSION,SizeOf(TZStreamRec));
end;
function DeflateInit2(var stream: TZStreamRec; level, method, windowBits,
memLevel, strategy: Integer): Integer;
begin
result := deflateInit2_(stream,level,method,windowBits,memLevel,strategy,
ZLIB_VERSION,SizeOf(TZStreamRec));
end;
function InflateInit(var stream: TZStreamRec): Integer;
begin
result := inflateInit_(stream,ZLIB_VERSION,SizeOf(TZStreamRec));
end;
function InflateInit2(var stream: TZStreamRec; windowBits: Integer): Integer;
begin
result := inflateInit2_(stream,windowBits,ZLIB_VERSION,SizeOf(TZStreamRec));
end;
{****************************************************************************}
function ZCompressCheck(code: Integer): Integer;
begin
result := code;
if code < 0 then
begin
raise EZCompressionError.Create(code);
end;
end;
function ZDecompressCheck(code: Integer): Integer;
begin
Result := code;
if code < 0 then
begin
raise EZDecompressionError.Create(code);
end;
end;
procedure ZInternalCompress(var zstream: TZStreamRec; const inBuffer: Pointer;
inSize: Integer; out outBuffer: Pointer; out outSize: Integer);
const
delta = 256;
begin
outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;
GetMem(outBuffer,outSize);
try
try
zstream.next_in := inBuffer;
zstream.avail_in := inSize;
zstream.next_out := outBuffer;
zstream.avail_out := outSize;
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 ZInternalDecompress(zstream: TZStreamRec; const inBuffer: Pointer;
inSize: Integer; out outBuffer: Pointer; out outSize: Integer;
outEstimate: Integer);
var
delta: Integer;
begin
delta := (inSize + 255) and not 255;
if outEstimate = 0 then outSize := delta
else outSize := outEstimate;
GetMem(outBuffer,outSize);
try
try
zstream.next_in := inBuffer;
zstream.avail_in := inSize;
zstream.next_out := outBuffer;
zstream.avail_out := outSize;
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;
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer;
level: TZCompressionLevel);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZCompressCheck(DeflateInit(zstream,ZLevels[level]));
ZInternalCompress(zstream,inBuffer,inSize,outBuffer,outSize);
end;
procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; 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]));
ZInternalCompress(zstream,inBuffer,inSize,outBuffer,outSize);
end;
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZDecompressCheck(InflateInit(zstream));
ZInternalDecompress(zstream,inBuffer,inSize,outBuffer,outSize,outEstimate);
end;
procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
outEstimate: Integer);
var
zstream: TZStreamRec;
begin
FillChar(zstream,SizeOf(TZStreamRec),0);
ZDecompressCheck(InflateInit2(zstream,windowBits));
ZInternalDecompress(zstream,inBuffer,inSize,outBuffer,outSize,outEstimate);
end;
{** string routines *********************************************************}
function ZCompressStr(const s: String; level: TZCompressionLevel): String;
var
buffer: Pointer;
size : Integer;
begin
ZCompress(PChar(s),Length(s),buffer,size,level);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZCompressStrEx(const s: String; level: TZCompressionLevel): String;
var
buffer: Pointer;
size : Integer;
begin
ZCompress(PChar(s),Length(s),buffer,size,level);
SetLength(result,size + SizeOf(Integer));
Move(buffer^,result[5],size);
size := Length(s);
Move(size,result[1],SizeOf(Integer));
FreeMem(buffer);
end;
function ZCompressStr2(const s: String; level: TZCompressionLevel;
windowBits, memLevel: Integer; strategy: TZStrategy): String;
var
buffer: Pointer;
size : Integer;
begin
ZCompress2(PChar(s),Length(s),buffer,size,level,windowBits,memLevel,
strategy);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZCompressStrWeb(const s: String): String;
begin
result := ZCompressStr2(s,zcFastest,-15,9,zsDefault);
end;
function ZDecompressStr(const s: String): String;
var
buffer: Pointer;
size : Integer;
begin
ZDecompress(PChar(s),Length(s),buffer,size);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZDecompressStrEx(const s: String): String;
var
buffer : Pointer;
size : Integer;
data : String;
dataSize: Integer;
begin
Move(s[1],size,SizeOf(Integer));
dataSize := Length(s) - SizeOf(Integer);
SetLength(data,dataSize);
Move(s[5],data[1],dataSize);
ZDecompress(PChar(data),dataSize,buffer,size,size);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
function ZDecompressStr2(const s: String; windowBits: Integer): String;
var
buffer: Pointer;
size : Integer;
begin
ZDecompress2(PChar(s),Length(s),buffer,size,windowBits);
SetLength(result,size);
Move(buffer^,result[1],size);
FreeMem(buffer);
end;
{** stream routines *********************************************************}
procedure ZInternalCompressStream(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -