git-svn-id: https://svn.code.sf.net/p/kolmck/code@69 91bb2d04-0c0c-4d2d-88a5-bbb6f4c1fa07
This commit is contained in:
@ -1,576 +0,0 @@
|
||||
{*******************************************************}
|
||||
{ }
|
||||
{ Delphi Supplemental Components }
|
||||
{ ZLIB Data Compression Interface Unit }
|
||||
{ }
|
||||
{ Copyright (c) 1997 Borland International }
|
||||
{ }
|
||||
{*******************************************************}
|
||||
|
||||
{ Modified for zlib 1.1.3 by Davide Moretti <dave@rimini.com> }
|
||||
{ Modified for KOL by Alexey Shuvalov <alekc_s@mail.ru> }
|
||||
{ Updated to zlib 1.1.4 by Dimaxx <dimaxx@atnet.ru>}
|
||||
|
||||
// Important! As this unit does not use Kol_Err.pas and SysUtils.pas, there is no
|
||||
// exceptions raised. Therefore check for errors by comparing the values returned by
|
||||
// functions such as Read/Write/Seek with value ZLIB_ERROR.
|
||||
|
||||
|
||||
//Uncomment this to enable CompressBuf & DecompressBuf procedures.
|
||||
//!!! This procedures converted but UNTESTED and MAY BE UNSTABLE !!!
|
||||
//{$DEFINE BUFFERPROCS}
|
||||
|
||||
unit KolZLib;
|
||||
|
||||
{$I KOLDEF.INC}
|
||||
|
||||
interface
|
||||
|
||||
uses Windows, Kol;
|
||||
|
||||
const
|
||||
ZLIB_ERROR = TStrmSize (-1);
|
||||
|
||||
type
|
||||
TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer;
|
||||
TFree = procedure (AppData, Block: Pointer);
|
||||
|
||||
// Internal structure. Ignore.
|
||||
TZStreamRec = packed record
|
||||
next_in: PChar; // next input byte
|
||||
avail_in: Integer; // number of bytes available at next_in
|
||||
total_in: Integer; // total nb of input bytes read so far
|
||||
|
||||
next_out: PChar; // next output byte should be put here
|
||||
avail_out: Integer; // remaining free space at next_out
|
||||
total_out: Integer; // total nb of bytes output so far
|
||||
|
||||
msg: PChar; // last error message, NULL if no error
|
||||
internal: Pointer; // not visible by applications
|
||||
|
||||
zalloc: TAlloc; // used to allocate the internal state
|
||||
zfree: TFree; // used to free the internal state
|
||||
AppData: Pointer; // private data object passed to zalloc and zfree
|
||||
|
||||
data_type: Integer; // best guess about the data type: ascii or binary
|
||||
adler: Integer; // adler32 value of the uncompressed data
|
||||
reserved: Integer; // reserved for future use
|
||||
end;
|
||||
|
||||
TZLibEvent = procedure (Sender: PStream) of Object;
|
||||
|
||||
PZLibData = ^TZLibData;
|
||||
TZLibData = record
|
||||
FStrm: PStream;
|
||||
FStrmPos: Cardinal;
|
||||
FOnProgress: TZLibEvent;
|
||||
FZRec: TZStreamRec;
|
||||
FBuffer: array [Word] of Char;
|
||||
end;
|
||||
|
||||
{ TCompressionStream compresses data on the fly as data is written to it, and
|
||||
stores the compressed data to another stream.
|
||||
|
||||
TCompressionStream is write-only and strictly sequential. Reading from the
|
||||
stream will raise an exception. Using Seek to move the stream pointer
|
||||
will raise an exception.
|
||||
|
||||
Output data is cached internally, written to the output stream only when
|
||||
the internal output buffer is full. All pending output data is flushed
|
||||
when the stream is destroyed.
|
||||
|
||||
The Position property returns the number of uncompressed bytes of
|
||||
data that have been written to the stream so far.
|
||||
|
||||
CompressionRate returns the on-the-fly percentage by which the original
|
||||
data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100
|
||||
If raw data size = 100 and compressed data size = 25, the CompressionRate
|
||||
is 75%
|
||||
|
||||
The OnProgress event is called each time the output buffer is filled and
|
||||
written to the output stream. This is useful for updating a progress
|
||||
indicator when you are writing a large chunk of data to the compression
|
||||
stream in a single call.}
|
||||
|
||||
TCompressionLevel = (clNone, clFastest, clDefault, clMax);
|
||||
|
||||
//******************* NewCompressionStream *************************
|
||||
// Creates new ZLib decompression stream. If ZLib initialization failed returns Nil;
|
||||
// On Read/Write errors Read/Write functions return ZLIB_ERROR value (also for Seek).
|
||||
|
||||
function NewCompressionStream (CompressionLevel: TCompressionLevel; Destination: PStream; OnProgress: TZLibEvent): PStream;
|
||||
|
||||
{ TDecompressionStream decompresses data on the fly as data is read from it.
|
||||
|
||||
Compressed data comes from a separate source stream. TDecompressionStream
|
||||
is read-only and unidirectional; you can seek forward in the stream, but not
|
||||
backwards. The special case of setting the stream position to zero is
|
||||
allowed. Seeking forward decompresses data until the requested position in
|
||||
the uncompressed data has been reached. Seeking backwards, seeking relative
|
||||
to the end of the stream, requesting the size of the stream, and writing to
|
||||
the stream will return ZLIB_ERROR as a Result.
|
||||
|
||||
The Position property returns the number of bytes of uncompressed data that
|
||||
have been read from the stream so far.
|
||||
|
||||
The OnProgress event is called each time the internal input buffer of
|
||||
compressed data is exhausted and the next block is read from the input stream.
|
||||
This is useful for updating a progress indicator when you are reading a
|
||||
large chunk of data from the decompression stream in a single call.}
|
||||
|
||||
|
||||
//******************* NewDecompressionStream *************************
|
||||
// Creates new ZLib decompression stream. If ZLib initialization failed returns Nil;
|
||||
// On Read/Write errors Read/Write functions return ZLIB_ERROR value (also for Seek).
|
||||
|
||||
function NewDecompressionStream (Source: PStream; OnProgress: TZLibEvent): PStream;
|
||||
|
||||
|
||||
//******************* NewZLibXStream *************************
|
||||
//Calls New[De]CompressionStream and returns True if Result<>Nil; Stream = Result.
|
||||
// !!! Don't use Overload on this functions - it may cause compilation error
|
||||
// when called with OnProgress=Nil !!!
|
||||
|
||||
function NewZLibDStream (var Stream: PStream; Source: PStream; OnProgress: TZLibEvent): Boolean;
|
||||
function NewZLibCStream (var Stream: PStream; CompressionLevel: TCompressionLevel; Destination: PStream; OnProgress: TZLibEvent): Boolean;
|
||||
|
||||
|
||||
{$IFDEF BUFFERPROCS}
|
||||
{ CompressBuf compresses data, buffer to buffer, in one call.
|
||||
In: InBuf = ptr to compressed data
|
||||
InBytes = number of bytes in InBuf
|
||||
Out: OutBuf = ptr to newly allocated buffer containing decompressed data
|
||||
OutBytes = number of bytes in OutBuf }
|
||||
|
||||
function CompressBuf(const InBuf: Pointer; InBytes: Integer; out OutBuf: Pointer; out OutBytes: Integer): Boolean;
|
||||
|
||||
{ DecompressBuf decompresses data, buffer to buffer, in one call.
|
||||
In: InBuf = ptr to compressed data
|
||||
InBytes = number of bytes in InBuf
|
||||
OutEstimate = zero, or est. size of the decompressed data
|
||||
Out: OutBuf = ptr to newly allocated buffer containing decompressed data
|
||||
OutBytes = number of bytes in OutBuf }
|
||||
|
||||
function DecompressBuf(const InBuf: Pointer; InBytes: Integer; OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer): Boolean;
|
||||
{$ENDIF BUFFERPROCS}
|
||||
|
||||
const
|
||||
ZLib_Version = '1.1.4';
|
||||
Z_NO_FLUSH = 0;
|
||||
Z_PARTIAL_FLUSH = 1;
|
||||
Z_SYNC_FLUSH = 2;
|
||||
Z_FULL_FLUSH = 3;
|
||||
Z_FINISH = 4;
|
||||
|
||||
Z_OK = 0;
|
||||
Z_STREAM_END = 1;
|
||||
Z_NEED_DICT = 2;
|
||||
Z_ERRNO = (-1);
|
||||
Z_STREAM_ERROR = (-2);
|
||||
Z_DATA_ERROR = (-3);
|
||||
Z_MEM_ERROR = (-4);
|
||||
Z_BUF_ERROR = (-5);
|
||||
Z_VERSION_ERROR = (-6);
|
||||
|
||||
Z_NO_COMPRESSION = 0;
|
||||
Z_BEST_SPEED = 1;
|
||||
Z_BEST_COMPRESSION = 9;
|
||||
Z_DEFAULT_COMPRESSION = (-1);
|
||||
|
||||
Z_FILTERED = 1;
|
||||
Z_HUFFMAN_ONLY = 2;
|
||||
Z_DEFAULT_STRATEGY = 0;
|
||||
|
||||
Z_BINARY = 0;
|
||||
Z_ASCII = 1;
|
||||
Z_UNKNOWN = 2;
|
||||
|
||||
Z_DEFLATED = 8;
|
||||
|
||||
_z_errmsg: array[0..9] of PChar = (
|
||||
'need dictionary', // Z_NEED_DICT (2)
|
||||
'stream end', // Z_STREAM_END (1)
|
||||
'', // Z_OK (0)
|
||||
'file error', // Z_ERRNO (-1)
|
||||
'stream error', // Z_STREAM_ERROR (-2)
|
||||
'data error', // Z_DATA_ERROR (-3)
|
||||
'insufficient memory', // Z_MEM_ERROR (-4)
|
||||
'buffer error', // Z_BUF_ERROR (-5)
|
||||
'incompatible version', // Z_VERSION_ERROR (-6)
|
||||
'' );
|
||||
|
||||
function adler32(adler: Integer; buf: PChar; len: Integer): Integer;
|
||||
|
||||
{$L Obj\deflate.obj}
|
||||
{$L Obj\trees.obj}
|
||||
{$L Obj\inflate.obj}
|
||||
{$L Obj\inftrees.obj}
|
||||
{$L Obj\adler32.obj}
|
||||
{$L Obj\infblock.obj}
|
||||
{$L Obj\infcodes.obj}
|
||||
{$L Obj\infutil.obj}
|
||||
{$L Obj\inffast.obj}
|
||||
|
||||
procedure _tr_init; external;
|
||||
procedure _tr_tally; external;
|
||||
procedure _tr_flush_block; external;
|
||||
procedure _tr_align; external;
|
||||
procedure _tr_stored_block; external;
|
||||
function adler32; external;
|
||||
procedure inflate_blocks_new; external;
|
||||
procedure inflate_blocks; external;
|
||||
procedure inflate_blocks_reset; external;
|
||||
procedure inflate_blocks_free; external;
|
||||
procedure inflate_set_dictionary; external;
|
||||
procedure inflate_trees_bits; external;
|
||||
procedure inflate_trees_dynamic; external;
|
||||
procedure inflate_trees_fixed; external;
|
||||
procedure inflate_codes_new; external;
|
||||
procedure inflate_codes; external;
|
||||
procedure inflate_codes_free; external;
|
||||
procedure _inflate_mask; external;
|
||||
procedure inflate_flush; external;
|
||||
procedure inflate_fast; external;
|
||||
|
||||
// deflate compresses data
|
||||
function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar; recsize: Integer): Integer; external;
|
||||
function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
|
||||
function deflateEnd(var strm: TZStreamRec): Integer; external;
|
||||
|
||||
// inflate decompresses data
|
||||
function inflateInit_(var strm: TZStreamRec; 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;
|
||||
|
||||
implementation
|
||||
|
||||
procedure _memset(P: Pointer; B: Byte; count: Integer);cdecl;
|
||||
begin
|
||||
FillChar(P^, count, Char( B ));
|
||||
end;
|
||||
|
||||
procedure _memcpy(dest, source: Pointer; count: Integer);cdecl;
|
||||
begin
|
||||
Move(source^, dest^, count);
|
||||
end;
|
||||
|
||||
function zcalloc(AppData: Pointer; Items, Size: Integer): Pointer;
|
||||
begin
|
||||
GetMem(Result, Items*Size);
|
||||
end;
|
||||
|
||||
procedure zcfree(AppData, Block: Pointer);
|
||||
begin
|
||||
FreeMem(Block);
|
||||
end;
|
||||
|
||||
function ZCheck(Code: Integer; var Clear: Boolean): Integer;
|
||||
begin
|
||||
Result:=Code;
|
||||
Clear:=Code>=0;
|
||||
end;
|
||||
|
||||
{$IFDEF BUFFERPROCS}
|
||||
function CompressBuf(const InBuf: Pointer; InBytes: Integer;
|
||||
out OutBuf: Pointer; out OutBytes: Integer): Boolean;
|
||||
var
|
||||
strm: TZStreamRec;
|
||||
P: Pointer;
|
||||
begin
|
||||
Result:=True;
|
||||
FillChar(strm, SizeOf(strm), 0);
|
||||
OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
|
||||
GetMem(OutBuf, OutBytes);
|
||||
try
|
||||
strm.next_in := InBuf;
|
||||
strm.avail_in := InBytes;
|
||||
strm.next_out := OutBuf;
|
||||
strm.avail_out := OutBytes;
|
||||
ZCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)), Result);
|
||||
If not Result then Exit;
|
||||
while (ZCheck(deflate(strm, Z_FINISH), Result)<>Z_STREAM_END) and Result do
|
||||
begin
|
||||
P := OutBuf;
|
||||
Inc(OutBytes, 256);
|
||||
ReallocMem(OutBuf, OutBytes);
|
||||
strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
|
||||
strm.avail_out := 256;
|
||||
end;
|
||||
If Result then ZCheck(deflateEnd(strm), Result)
|
||||
else deflateEnd(strm);
|
||||
If not Result then Exit;
|
||||
ReallocMem(OutBuf, strm.total_out);
|
||||
OutBytes := strm.total_out;
|
||||
finally
|
||||
If not Result then begin
|
||||
FreeMem(OutBuf);
|
||||
OutBuf:=nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function DecompressBuf(const InBuf: Pointer; InBytes: Integer;
|
||||
OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer): Boolean;
|
||||
var
|
||||
strm: TZStreamRec;
|
||||
P: Pointer;
|
||||
BufInc: Integer;
|
||||
begin
|
||||
Result:=True;
|
||||
FillChar(strm, sizeof(strm), 0);
|
||||
BufInc := (InBytes + 255) and not 255;
|
||||
if OutEstimate = 0 then
|
||||
OutBytes := BufInc
|
||||
else
|
||||
OutBytes := OutEstimate;
|
||||
GetMem(OutBuf, OutBytes);
|
||||
try
|
||||
strm.next_in := InBuf;
|
||||
strm.avail_in := InBytes;
|
||||
strm.next_out := OutBuf;
|
||||
strm.avail_out := OutBytes;
|
||||
ZCheck(InflateInit_(strm, zlib_version, sizeof(strm)), Result);
|
||||
If not Result then Exit;
|
||||
while (ZCheck(Inflate(strm, Z_FINISH), Result) <> Z_STREAM_END) and Result do
|
||||
begin
|
||||
P := OutBuf;
|
||||
Inc(OutBytes, BufInc);
|
||||
ReallocMem(OutBuf, OutBytes);
|
||||
strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
|
||||
strm.avail_out := BufInc;
|
||||
end;
|
||||
If Result then ZCheck(inflateEnd(strm), Result)
|
||||
else InflateEnd(strm);
|
||||
If not Result Then Exit;
|
||||
ReallocMem(OutBuf, strm.total_out);
|
||||
OutBytes := strm.total_out;
|
||||
finally
|
||||
If not Result then begin
|
||||
FreeMem(OutBuf);
|
||||
OutBuf:=nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{$ENDIF BUFFERPROCS}
|
||||
|
||||
// Dummy methods
|
||||
procedure DummySetSize(Strm: PStream; {$IFNDEF STREAM_COMPAT} const {$ENDIF} Value: TStrmSize);
|
||||
asm
|
||||
end;
|
||||
|
||||
function DummyReadWrite (Strm: PStream; var Buffer; {$IFNDEF STREAM_COMPAT} const {$ENDIF} Count: TStrmSize): TStrmSize;
|
||||
begin
|
||||
Result:=ZLIB_ERROR;
|
||||
end;
|
||||
|
||||
function DummyGetSize(Strm: PStream): TStrmSize;
|
||||
begin
|
||||
Result:=ZLIB_ERROR;
|
||||
end;
|
||||
|
||||
// CompressStream methods
|
||||
function CZLibWriteStream(Strm: PStream; var Buffer; {$IFNDEF STREAM_COMPAT} const {$ENDIF} Count: TStrmSize): TStrmSize;
|
||||
var
|
||||
Check: Boolean;
|
||||
begin
|
||||
Result:=ZLIB_ERROR;
|
||||
With PZlibData (Strm.Methods.fCustom)^ do begin
|
||||
FZRec.next_in := @Buffer;
|
||||
FZRec.avail_in := Count;
|
||||
If FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
|
||||
While (FZRec.avail_in > 0) do begin
|
||||
ZCheck(deflate(FZRec, 0), Check);
|
||||
If not Check then Exit;
|
||||
If FZRec.avail_out = 0 then begin
|
||||
If FStrm.Write (FBuffer, SizeOf(FBuffer))<>SizeOf(FBuffer) then Exit;
|
||||
FZRec.next_out := FBuffer;
|
||||
FZRec.avail_out := SizeOf(FBuffer);
|
||||
FStrmPos := FStrm.Position;
|
||||
If Assigned (fOnProgress) then
|
||||
fOnProgress (Strm);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Result := Count;
|
||||
end;
|
||||
|
||||
function CZLibSeekStream(Strm: PStream; {$IFNDEF STREAM_COMPAT} const {$ENDIF} Offset: TStrmMove; Origin: TMoveMethod): TStrmSize;
|
||||
begin
|
||||
If (Offset = 0) and (Origin=spCurrent) then Result:=PZlibData (Strm.Methods.fCustom).FZRec.total_in
|
||||
else Result:=ZLIB_ERROR;
|
||||
end;
|
||||
|
||||
procedure CZLibCloseStream(Strm: PStream);
|
||||
var
|
||||
Check: Boolean;
|
||||
begin
|
||||
With PZlibData (Strm.Methods.fCustom)^ do begin
|
||||
FZRec.next_in := nil;
|
||||
FZRec.avail_in := 0;
|
||||
try
|
||||
If FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
|
||||
while (ZCheck(deflate(FZRec, Z_FINISH), Check) <> Z_STREAM_END) and (FZRec.avail_out = 0) do begin
|
||||
If not Check then Exit;
|
||||
If FStrm.Write (FBuffer, SizeOf(FBuffer))<>SizeOf(FBuffer) then Exit;
|
||||
FZRec.next_out := FBuffer;
|
||||
FZRec.avail_out := sizeof(FBuffer);
|
||||
end;
|
||||
If FZRec.avail_out < SizeOf(FBuffer) then
|
||||
FStrm.Write (FBuffer, SizeOf(FBuffer) - FZRec.avail_out)
|
||||
finally
|
||||
deflateEnd(FZRec);
|
||||
Dispose (PZLibData (Strm.Methods.fCustom));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// DecompressStream methods
|
||||
procedure DZLibCloseStream(Strm: PStream);
|
||||
begin
|
||||
InflateEnd(PZLibData (Strm.Methods.fCustom).FZRec);
|
||||
Dispose (PZLibData (Strm.Methods.fCustom));
|
||||
end;
|
||||
|
||||
function DZLibSeekStream(Strm: PStream; {$IFNDEF STREAM_COMPAT} const {$ENDIF} Offset: TStrmMove; Origin: TMoveMethod): TStrmSize;
|
||||
var
|
||||
I: Integer;
|
||||
Buf: array [0..4095] of Char;
|
||||
Check: Boolean;
|
||||
Off: TStrmMove;
|
||||
begin
|
||||
Result:=ZLIB_ERROR;
|
||||
Off := Offset;
|
||||
With PZlibData (Strm.Methods.fCustom)^ do begin
|
||||
If (Off=0) and (Origin=spBegin) then begin
|
||||
ZCheck(InflateReset(FZRec), Check);
|
||||
If not Check then Exit;
|
||||
FZRec.next_in := FBuffer;
|
||||
FZRec.avail_in := 0;
|
||||
FStrm.Position := 0;
|
||||
FStrmPos := 0;
|
||||
end
|
||||
else If ((Off>=0) and (Origin=spCurrent)) or (((Off-FZRec.total_out)>0) and (Origin=spBegin)) then begin
|
||||
If Origin=spBegin then Dec(Off, FZRec.total_out);
|
||||
If Off>0 then begin
|
||||
for I:=1 to Off div SizeOf(Buf) do
|
||||
If Strm.Read(Buf, SizeOf(Buf))=ZLIB_ERROR then Exit;
|
||||
If Strm.Read(Buf, Off mod SizeOf(Buf))=ZLIB_ERROR then Exit;
|
||||
end;
|
||||
end else Exit;
|
||||
Result:=FZRec.total_out;
|
||||
end;
|
||||
end;
|
||||
|
||||
function DZLibReadStream (Strm: PStream; var Buffer; {$IFNDEF STREAM_COMPAT} const {$ENDIF} Count: TStrmSize): TStrmSize;
|
||||
var
|
||||
Check: Boolean;
|
||||
D: PZLibData;
|
||||
begin
|
||||
Result:=ZLIB_ERROR;
|
||||
D := PZlibData (Strm.Methods.fCustom);
|
||||
D.FZRec.next_out := @Buffer;
|
||||
D.FZRec.avail_out := Count;
|
||||
If D.FStrm.Position <> D.FStrmPos then
|
||||
D.FStrm.Position := D.FStrmPos;
|
||||
While (D.FZRec.avail_out > 0) do begin
|
||||
If D.FZRec.avail_in = 0 then begin
|
||||
D.FZRec.avail_in := D.FStrm.Read(D.FBuffer, SizeOf(D.FBuffer));
|
||||
If D.FZRec.avail_in = 0 then begin
|
||||
Result := Count - DWord(D.FZRec.avail_out);
|
||||
Exit;
|
||||
end;
|
||||
D.FZRec.next_in := D.FBuffer;
|
||||
D.FStrmPos := D.FStrm.Position;
|
||||
If Assigned (D.fOnProgress) then
|
||||
D.fOnProgress (Strm);
|
||||
end;
|
||||
ZCheck(Inflate(D.FZRec, 0), Check);
|
||||
If not Check then Exit;
|
||||
end;
|
||||
Result:=Count;
|
||||
end;
|
||||
|
||||
const
|
||||
BaseCZlibMethods: TStreamMethods = (
|
||||
fSeek: CZLibSeekStream;
|
||||
fGetSiz: DummyGetSize;
|
||||
fSetSiz: DummySetSize;
|
||||
fRead: DummyReadWrite;
|
||||
fWrite: CZLibWriteStream;
|
||||
fClose: CZLibCloseStream;
|
||||
fCustom: nil; );
|
||||
|
||||
BaseDZlibMethods: TStreamMethods = (
|
||||
fSeek: DZLibSeekStream;
|
||||
fGetSiz: DummyGetSize;
|
||||
fSetSiz: DummySetSize;
|
||||
fRead: DZLibReadStream;
|
||||
fWrite: DummyReadWrite;
|
||||
fClose: DZLibCloseStream;
|
||||
fCustom: nil; );
|
||||
|
||||
function NewDecompressionStream (Source: PStream; OnProgress: TZLibEvent): PStream;
|
||||
var
|
||||
Inited: Boolean;
|
||||
ZLibData: PZLibData;
|
||||
begin
|
||||
New (ZLibData);
|
||||
With ZLibData^ do begin
|
||||
FillChar(FZRec, SizeOf(FZRec), #0);
|
||||
FOnProgress:=OnProgress;
|
||||
FStrm:=Source;
|
||||
FStrmPos:=Source.Position;
|
||||
FZRec.next_in := FBuffer;
|
||||
FZRec.avail_in := 0;
|
||||
ZCheck(InflateInit_(FZRec, ZLib_Version, SizeOf(FZRec)), Inited);
|
||||
end;
|
||||
If Inited then begin
|
||||
Result:=_NewStream (BaseDZlibMethods);
|
||||
Result.Methods.fCustom:=ZLibData;
|
||||
end else begin
|
||||
Dispose (ZLibData);
|
||||
Result:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
function NewCompressionStream (CompressionLevel: TCompressionLevel; Destination: PStream; OnProgress: TZLibEvent): PStream;
|
||||
const
|
||||
Levels: array [TCompressionLevel] of ShortInt = (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
|
||||
var
|
||||
Inited: Boolean;
|
||||
ZLibData: PZLibData;
|
||||
begin
|
||||
New (ZLibData);
|
||||
With ZLibData^ do begin
|
||||
FillChar(FZRec, SizeOf(FZRec), #0);
|
||||
FOnProgress:=OnProgress;
|
||||
FStrm:=Destination;
|
||||
FStrmPos:=Destination.Position;
|
||||
FZRec.next_out := FBuffer;
|
||||
FZRec.avail_out := SizeOf(FBuffer);
|
||||
ZCheck(deflateInit_(FZRec, Levels[CompressionLevel], ZLib_Version, SizeOf(FZRec)), Inited);
|
||||
end;
|
||||
If Inited then begin
|
||||
Result:=_NewStream (BaseCZlibMethods);
|
||||
Result.Methods.fCustom:=ZLibData;
|
||||
end else begin
|
||||
Dispose (ZLibData);
|
||||
Result:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
function NewZLibDStream (var Stream: PStream; Source: PStream; OnProgress: TZLibEvent): boolean;
|
||||
begin
|
||||
Stream:=NewDecompressionStream (Source, OnProgress);
|
||||
Result:=Assigned (Stream);
|
||||
end;
|
||||
|
||||
function NewZLibCStream (var Stream: PStream; CompressionLevel: TCompressionLevel; Destination: PStream; OnProgress: TZLibEvent): boolean;
|
||||
begin
|
||||
Stream:=NewCompressionStream (CompressionLevel, Destination, OnProgress);
|
||||
Result:=Assigned (Stream);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
1017
Addons/bis.pas
1017
Addons/bis.pas
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user