📄 iezlib.pas
字号:
(*
Copyright (c) 1998-2007 by HiComponents. All rights reserved.
This software comes without express or implied warranty.
In no case shall the author be liable for any damage or unwanted behavior of any
computer hardware and/or software.
HiComponents grants you the right to include the compiled component
in your application, whether COMMERCIAL, SHAREWARE, or FREEWARE,
BUT YOU MAY NOT DISTRIBUTE THIS SOURCE CODE OR ITS COMPILED .DCU IN ANY FORM.
ImageEn, IEvolution and ImageEn ActiveX may not be included in any commercial,
shareware or freeware libraries or components.
email: support@hicomponents.com
http://www.hicomponents.com
*)
unit iezlib;
{$R-}
{$Q-}
{$I ie.inc}
{$IFDEF IEINCLUDEZLIB}
interface
uses Windows, Graphics, classes, sysutils, ImageEnProc, ImageEnIO, hyiedefs, hyieutils;
type
// portions of ZLib
TZAlloc = function(opaque: Pointer; items, size: Integer): Pointer;
TZFree = procedure(opaque, block: Pointer);
TZCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
TZStreamRec = packed record
next_in: PChar; // next input byte
avail_in: Longint; // number of bytes available at next_in
total_in: Longint; // total nb of input bytes read so far
next_out: PChar; // next output byte should be put here
avail_out: Longint; // remaining free space at next_out
total_out: Longint; // total nb of bytes output so far
msg: PChar; // last error message, NULL if no error
state: Pointer; // not visible by applications
zalloc: TZAlloc; // used to allocate the internal state
zfree: TZFree; // used to free the internal state
opaque: Pointer; // private data object passed to zalloc and zfree
data_type: Integer; // best guess about the data type: ascii or binary
adler: Longint; // adler32 value of the uncompressed data
reserved: Longint; // reserved for future use
end;
TCustomZStream = class(TStream)
private
FStream: TStream;
FStreamPos: Int64;
FOnProgress: TNotifyEvent;
FZStream: TZStreamRec;
FBuffer: array[Word] of Char;
protected
constructor Create(stream: TStream);
procedure DoProgress; dynamic;
property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
end;
TZCompressionStream = class(TCustomZStream)
private
function GetCompressionRate: Single;
public
constructor Create(dest: TStream; compressionLevel: TZCompressionLevel); // compressionLevel: TZCompressionLevel = zcDefault
destructor Destroy; override;
function Read(var buffer; count: Longint): Longint; override;
function Write(const buffer; count: Longint): Longint; override;
function Seek(offset: Longint; origin: Word): Longint; override;
property CompressionRate: Single read GetCompressionRate;
property OnProgress;
end;
TZDecompressionStream = class(TCustomZStream)
public
constructor Create(source: TStream);
destructor Destroy; override;
function Read(var buffer; count: Longint): Longint; override;
function Write(const buffer; count: Longint): Longint; override;
function Seek(offset: Longint; origin: Word): Longint; override;
property OnProgress;
end;
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer;
level: TZCompressionLevel); // level: TZCompressionLevel = zcDefault
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer); // outEstimate: Integer = 0
function ZCompressStr(const s: string; level: TZCompressionLevel): string; // level: TZCompressionLevel = zcDefault
function ZDecompressStr(const s: string): string;
procedure ZCompressStream(inStream, outStream: TStream;
level: TZCompressionLevel); // level: TZCompressionLevel = zcDefault
procedure ZDecompressStream(inStream, outStream: TStream);
type
EZLibError = class(Exception);
EZCompressionError = class(EZLibError);
EZDecompressionError = class(EZLibError);
const
ZLIB_VERSION = '1.2.3';
procedure _abort; cdecl; forward;
function _memcmp(buf1, buf2: pbyte; count: integer): integer; cdecl; forward;
procedure memset(P: Pointer; B: Byte; count: Integer); cdecl; forward;
procedure memcpy(dest, source: Pointer; count: Integer); cdecl; forward;
function _malloc(size: Integer): Pointer; cdecl; forward;
procedure _free(P: Pointer); cdecl; forward;
function _fabs(v: double): double; cdecl; forward;
function _pow(Base, Exponent: double): double; cdecl; forward;
function __ftol: Integer; cdecl; forward;
function _strlen(s: pchar): cardinal; cdecl; forward;
function _strtod(s: pchar; var vp: pchar): double; cdecl;
procedure crc32; cdecl; external;
function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar; recsize: Integer): Integer; cdecl; external;
function deflate(var strm: TZStreamRec; flush: Integer): Integer; cdecl; external;
function deflateEnd(var strm: TZStreamRec): Integer; cdecl; external;
function inflateInit_(var strm: TZStreamRec; version: PChar; recsize: Integer): Integer; cdecl; external;
function inflate(var strm: TZStreamRec; flush: Integer): Integer; cdecl; external;
function inflateEnd(var strm: TZStreamRec): Integer; cdecl; external;
function inflateReset(var strm: TZStreamRec): Integer; cdecl; external;
procedure deflateInit2_; cdecl; external;
procedure deflateReset; cdecl; external;
implementation
{$R-}
const
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)
''
);
ZLevels: array[TZCompressionLevel] of Shortint = (
Z_NO_COMPRESSION,
Z_BEST_SPEED,
Z_DEFAULT_COMPRESSION,
Z_BEST_COMPRESSION
);
SZInvalid = 'Invalid ZStream operation!';
(*
{$L deflate.obj}
{$L inflate.obj}
{$L infblock.obj}
{$L inftrees.obj}
{$L infcodes.obj}
{$L infutil.obj}
{$L inffast.obj}
{$L trees.obj}
{$L adler32.obj}
{$L crc32.obj}
*)
{$L deflate.obj}
{$L inflate.obj}
{$L inftrees.obj}
{$L infback.obj}
{$L inffast.obj}
{$L trees.obj}
{$L adler32.obj}
{$L crc32.obj}
{$L compress.obj}
function zcalloc(opaque: Pointer; items, size: Integer): Pointer; cdecl;
begin
GetMem(result, items * size);
end;
procedure zcfree(opaque, block: Pointer); cdecl;
begin
FreeMem(block);
end;
function DeflateInit(var stream: TZStreamRec; level: Integer): Integer; cdecl;
begin
result := DeflateInit_(stream, level, ZLIB_VERSION, SizeOf(TZStreamRec));
end;
function InflateInit(var stream: TZStreamRec): Integer; cdecl;
begin
result := InflateInit_(stream, ZLIB_VERSION, SizeOf(TZStreamRec));
end;
procedure memset(P: Pointer; B: Byte; count: Integer); cdecl;
begin
FillChar(P^, count, B);
end;
function _memcmp(buf1, buf2: pbyte; count: integer): integer; cdecl;
begin
if count = 0 then
result := 0
else
begin
while true do
begin
dec(count);
if (count=0) or (buf1^<>buf2^) then
break;
inc(buf1);
inc(buf2);
end;
result := buf1^ - buf2^;
end;
end;
(*
function _strtod(s:pchar; vp:pinteger):double; cdecl;
begin
vp^:=0;
//result:=strtofloat(s);
result:=IEStrToFloatDef(s,0);
end;
*)
function _strtod(s: pchar; var vp: pchar): double; cdecl;
begin
vp := @s[strlen(s) - 1]; // !!
result := IEStrToFloatDef(s, 0);
end;
procedure _abort; cdecl;
begin
end;
procedure memcpy(dest, source: Pointer; count: Integer); cdecl;
begin
Move(source^, dest^, count);
end;
function _malloc(size: Integer): Pointer; cdecl;
begin
GetMem(Result, size);
end;
procedure _free(P: Pointer); cdecl;
begin
FreeMem(P);
end;
function _fabs(v: double): double; cdecl;
begin
result := abs(v);
end;
function IntPower(Base: Extended; Exponent: Integer): Extended; cdecl;
asm
mov ecx, eax
cdq
fld1 { Result := 1 }
xor eax, edx
sub eax, edx { eax := Abs(Exponent) }
jz @@3
fld Base
jmp @@2
@@1: fmul ST, ST { X := Base * Base }
@@2: shr eax,1
jnc @@1
fmul ST(1),ST { Result := Result * X }
jnz @@1
fstp st { pop X from FPU stack }
cmp ecx, 0
jge @@3
fld1
fdivrp { Result := 1 / Result }
@@3:
fwait
end;
function _pow(Base, Exponent: double): double; cdecl;
begin
if Exponent = 0.0 then
Result := 1.0 { n**0 = 1 }
else if (Base = 0.0) and (Exponent > 0.0) then
Result := 0.0 { 0**n = 0, n > 0 }
else if (Frac(Exponent) = 0.0) and (Abs(Exponent) <= MaxInt) then
Result := IntPower(Base, Trunc(Exponent))
else
Result := Exp(Exponent * Ln(Base))
end;
function __ftol: Integer; cdecl;
var
f: double;
begin
asm
lea eax, f // BC++ passes floats on the FPU stack
fstp qword ptr [eax] // Delphi passes floats on the CPU stack
end;
Result := Trunc(f);
end;
function _strlen(s: pchar): cardinal; cdecl;
begin
result := strlen(s);
end;
var
__turboFloat: LongBool = False;
function ZCompressCheck(code: Integer): Integer;
begin
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -