2
// This unit is part of the GLScene Engine https://github.com/glscene
6
07/05/10 - Yar - Fixed for Linux x64
7
06/05/10 - Yar - Added to GLScene (contributed by oleg matrozov)
10
{*****************************************************************************
12
* copyright (c) 2000-2010 base2 technologies *
13
* copyright (c) 1995-2002 Borland Software Corporation *
16
* 2010.05.02 added ZDelfateEx and ZInflateEx *
17
* 2010.04.20 added TZ*Buffer classes *
18
* 2010.04.15 moved core zlib routines to separate unit (ZLibExApi.pas) *
19
* added ZDeflate* and ZInflate* *
20
* 2010.04.14 fixed ZInternalCompress loops *
21
* fixed ZInternalDecompress loops *
22
* updated ZInternalCompressStream loops *
23
* updated ZInternalDecompressStream loops *
24
* 2010.01.27 updated for delphi 2010 *
25
* 2009.04.14 added overloaded string routines for AnsiString and *
27
* 2009.01.28 updated for delphi 2009 String (UnicodeString) *
28
* 2008.05.15 added TStreamPos type for Stream.Position variants *
29
* added TCustomZStream.Stream* methods *
30
* 2007.08.17 modified TZCompressionStream.Write to use Write instead of *
32
* 2007.03.15 moved gzip routines to separate unit (ZLibExGZ.pas) *
33
* 2006.10.07 fixed EZLibError constructor for c++ builder compatibility *
34
* 2006.03.28 moved Z_DEFLATED to interface section *
35
* added custom compression levels zcLevel1 thru zcLevel9 *
36
* 2006.03.27 added ZCompressStreamWeb *
37
* 2006.03.24 added ZAdler32 and ZCrc32 *
38
* 2005.11.29 changed FStreamPos to Int64 for delphi 6+ *
39
* 2005.03.04 modified ZInternalCompressStream loops *
40
* modified ZInternalDecompressStream loops *
41
* 2005.02.07 fixed ZInternalCompressStream loop conditions *
42
* fixed ZInternalDecompressStream loop conditions *
43
* 2005.01.11 added ZCompressStrWeb *
44
* 2003.04.14 added ZCompress2 and ZDecompress2 *
45
* added ZCompressStr2 and ZDecompressStr2 *
46
* added ZCompressStream2 and ZDecompressStream2 *
47
* added overloaded T*Stream constructors to support *
48
* InflateInit2 and DeflateInit2 *
49
* fixed ZDecompressStream to use ZDecompressCheck instead of *
51
* 2001.11.27 enhanced TZDecompressionStream.Read to adjust source *
52
* stream position upon end of compression data *
53
* fixed endless loop in TZDecompressionStream.Read when *
54
* destination count was greater than uncompressed data *
55
* 2001.10.26 renamed unit to integrate "nicely" with delphi 6 *
56
* 2000.11.24 added soFromEnd condition to TZDecompressionStream.Seek *
57
* added ZCompressStream and ZDecompressStream *
58
* 2000.06.13 optimized, fixed, rewrote, and enhanced the zlib.pas unit *
59
* included on the delphi cd (zlib version 1.1.3) *
63
* 2001.10.26 Z*Stream routines *
66
* 2001.11.27 finding the nasty little endless loop quirk with the *
67
* TZDecompressionStream.Read method *
70
* 2005.02.07 pointing out the missing loop condition (Z_STREAM_END) *
71
* in ZInternalCompressStream and *
72
* ZInternalDecompressStream *
75
* 2005.03.04 assisting me fine tune and beta test *
76
* ZInternalCompressStream and ZInternalDecompressStream *
79
* 2005.11.28 pointing out the FStreamPos and TStream.Position type *
83
* 2006.10.07 pointing out the ELibError constructor incompatibility *
87
* 2009.01.28 beta testing the delphi 2009 changes *
90
* 2009.04.14 assisting me design and further improve support for *
94
* 2010.04.14 pointing out the missing loop condition (avail_in > 0) *
95
* in ZInternalCompress and ZInternalDecompress *
96
* 2010.04.20 prototyping and assisting with the TZ*Buffer classes *
97
*****************************************************************************}
107
SysUtils, Classes, GLCrossPlatform, GLSZLibExApi;
113
RawByteString = AnsiString;
115
UnicodeString = WideString;
116
UnicodeChar = WideChar;
118
{$else ifdef Version2010Plus}
120
UnicodeChar = WideChar;
124
TStreamPos = {$ifdef Version6Plus} Int64 {$else} Longint {$endif};
126
TZCompressionLevel = (
170
ZLevels: Array [TZCompressionLevel] of Integer = (
171
Z_NO_COMPRESSION, // zcNone
172
Z_BEST_SPEED, // zcFastest
173
Z_DEFAULT_COMPRESSION, // zcDefault
174
Z_BEST_COMPRESSION, // zcMax
186
ZStrategies: Array [TZStrategy] of Integer = (
187
Z_DEFAULT_STRATEGY, // zsDefault
188
Z_FILTERED, // zsFiltered
189
Z_HUFFMAN_ONLY, // zsHuffman
194
ZErrors: Array [TZError] of Integer = (
196
Z_STREAM_ERROR, // zeStreamError
197
Z_DATA_ERROR, // zeDataError
198
Z_MEM_ERROR, // zeMemoryError
199
Z_BUF_ERROR, // zeBufferError
200
Z_VERSION_ERROR // zeVersionError
203
ZFlushes: Array [TZFlush] of Integer = (
204
Z_NO_FLUSH, // zfNoFlush
205
Z_PARTIAL_FLUSH, // zfPartialFlush
206
Z_SYNC_FLUSH, // zfSyncFlush
207
Z_FULL_FLUSH, // zfFullFlush
208
Z_FINISH, // zfFinish
214
{** TZ*Function ***********************************************************}
216
TZReadFunction = function (param: Pointer; var buffer;
217
size: Integer): Integer;
219
TZWriteFunction = function (param: Pointer; const buffer;
220
size: Integer): Integer;
222
{** TZInformation *********************************************************}
224
TZInformation = packed record
225
CompressedFlags : Longint;
226
CompressedSize : TStreamPos;
227
CompressedCrc : Longint;
228
CompressedAdler : Longint;
230
UncompressedFlags: Longint;
231
UncompressedSize : TStreamPos;
232
UncompressedCrc : Longint;
233
UncompressedAdler: Longint;
236
{** TCustomZStream ********************************************************}
238
TCustomZStream = class(TStream)
241
FStreamPos : TStreamPos;
242
FOnProgress: TNotifyEvent;
244
FZStream : TZStreamRec;
245
FBuffer : Array [Word] of Byte;
247
function GetStreamPosition: TStreamPos;
248
procedure SetStreamPosition(value: TStreamPos);
250
function StreamRead(var buffer; count: Longint): Longint;
251
function StreamWrite(const buffer; count: Longint): Longint;
252
function StreamSeek(offset: Longint; origin: Word): Longint;
254
procedure StreamReadBuffer(var buffer; count: Longint);
255
procedure StreamWriteBuffer(const buffer; count: Longint);
257
procedure DoProgress; dynamic;
259
property StreamPosition: TStreamPos read GetStreamPosition write SetStreamPosition;
261
property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
263
constructor Create(stream: TStream);
266
{** TZCompressionStream ***************************************************}
268
TZCompressionStream = class(TCustomZStream)
270
function GetCompressionRate: Single;
272
constructor Create(dest: TStream;
273
compressionLevel: TZCompressionLevel = zcDefault); overload;
275
constructor Create(dest: TStream; compressionLevel: TZCompressionLevel;
276
windowBits, memLevel: Integer; strategy: TZStrategy); overload;
278
destructor Destroy; override;
280
function Read(var buffer; count: Longint): Longint; override;
281
function Write(const buffer; count: Longint): Longint; override;
282
function Seek(offset: Longint; origin: Word): Longint; override;
284
property CompressionRate: Single read GetCompressionRate;
288
{** TZDecompressionStream *************************************************}
290
TZDecompressionStream = class(TCustomZStream)
292
constructor Create(source: TStream); overload;
293
constructor Create(source: TStream; windowBits: Integer); overload;
295
destructor Destroy; override;
297
function Read(var buffer; count: Longint): Longint; override;
298
function Write(const buffer; count: Longint): Longint; override;
299
function Seek(offset: Longint; origin: Word): Longint; override;
304
{** TZCustomBuffer ********************************************************}
306
TZCustomBuffer = class(TObject)
309
FBufferCapacity: Integer;
310
FBufferSize : Integer;
312
FZStream: TZStreamRec;
314
procedure BufferWrite(const buffer: Pointer; size: Integer);
315
procedure BufferRead(var buffer: Pointer; size: Integer);
317
procedure BufferCapacity(capacity: Integer);
319
property BufferSize: Integer read FBufferSize;
322
destructor Destroy; override;
324
procedure Clear; virtual;
326
procedure Flush(flush: TZFlush); virtual;
328
function Write(const buffer: Pointer; size: Integer): Integer; overload;
331
function Write(const s: AnsiString): Integer; overload;
333
function Read(var buffer: Pointer; size: Integer): Integer; overload;
334
function Read(var s: AnsiString): Integer; overload;
337
{** TZCompressionBuffer ***************************************************}
339
TZCompressionBuffer = class(TZCustomBuffer)
341
constructor Create(level: TZCompressionLevel = zcDefault); overload;
342
constructor Create(level: TZCompressionLevel;
343
windowBits, memLevel: Integer; strategy: TZStrategy); overload;
345
destructor Destroy; override;
347
procedure Clear; override;
349
procedure Flush(flush: TZFlush); override;
351
function Write(const buffer: Pointer; size: Integer): Integer;
355
{** TZDecompressionBuffer *************************************************}
357
TZDecompressionBuffer = class(TZCustomBuffer)
359
constructor Create; overload;
360
constructor Create(windowBits: Integer); overload;
362
destructor Destroy; override;
364
procedure Clear; override;
366
function Write(const buffer: Pointer; size: Integer): Integer; override;
369
{** zlib deflate routines ***************************************************}
371
function ZDeflateInit(var stream: TZStreamRec;
372
level: TZCompressionLevel): Integer;
373
{$ifdef GLS_INLINE} inline; {$endif}
375
function ZDeflateInit2(var stream: TZStreamRec;
376
level: TZCompressionLevel; windowBits, memLevel: Integer;
377
strategy: TZStrategy): Integer;
378
{$ifdef GLS_INLINE} inline; {$endif}
380
function ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;
381
{$ifdef GLS_INLINE} inline; {$endif}
383
function ZDeflateEnd(var stream: TZStreamRec): Integer;
384
{$ifdef GLS_INLINE} inline; {$endif}
386
function ZDeflateReset(var stream: TZStreamRec): Integer;
387
{$ifdef GLS_INLINE} inline; {$endif}
389
{** zlib inflate routines ***************************************************}
391
function ZInflateInit(var stream: TZStreamRec): Integer;
392
{$ifdef GLS_INLINE} inline; {$endif}
394
function ZInflateInit2(var stream: TZStreamRec;
395
windowBits: Integer): Integer;
396
{$ifdef GLS_INLINE} inline; {$endif}
398
function ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;
399
{$ifdef GLS_INLINE} inline; {$endif}
401
function ZInflateEnd(var stream: TZStreamRec): Integer;
402
{$ifdef GLS_INLINE} inline; {$endif}
404
function ZInflateReset(var stream: TZStreamRec): Integer;
405
{$ifdef GLS_INLINE} inline; {$endif}
407
{** zlib checksum routines **************************************************}
409
function ZAdler32(adler: Longint; const buffer; size: Integer): Longint;
410
{$ifdef GLS_INLINE} inline; {$endif}
412
function ZCrc32(crc: Longint; const buffer; size: Integer): Longint;
413
{$ifdef GLS_INLINE} inline; {$endif}
415
{** zlib custom routines ****************************************************}
417
procedure ZDeflateEx(var stream: TZStreamRec; param: Pointer;
418
read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
420
procedure ZInflateEx(var stream: TZStreamRec; param: Pointer;
421
read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
423
{*****************************************************************************
427
* inBuffer = pointer to uncompressed data *
428
* inSize = size of inBuffer (bytes) *
429
* outBuffer = pointer (unallocated) *
430
* level = compression level *
433
* outBuffer = pointer to compressed data (allocated) *
434
* outSize = size of outBuffer (bytes) *
435
*****************************************************************************}
437
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
438
out outBuffer: Pointer; out outSize: Integer;
439
level: TZCompressionLevel = zcDefault);
441
{*****************************************************************************
445
* inBuffer = pointer to uncompressed data *
446
* inSize = size of inBuffer (bytes) *
447
* outBuffer = pointer (unallocated) *
448
* level = compression level *
449
* method = compression method *
450
* windowBits = window bits *
451
* memLevel = memory level *
452
* strategy = compression strategy *
455
* outBuffer = pointer to compressed data (allocated) *
456
* outSize = size of outBuffer (bytes) *
457
*****************************************************************************}
459
procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
460
out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;
461
windowBits, memLevel: Integer; strategy: TZStrategy);
463
{*****************************************************************************
467
* inBuffer = pointer to compressed data *
468
* inSize = size of inBuffer (bytes) *
469
* outBuffer = pointer (unallocated) *
470
* outEstimate = estimated size of uncompressed data (bytes) *
473
* outBuffer = pointer to decompressed data (allocated) *
474
* outSize = size of outBuffer (bytes) *
475
*****************************************************************************}
477
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
478
out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer = 0);
480
{*****************************************************************************
484
* inBuffer = pointer to compressed data *
485
* inSize = size of inBuffer (bytes) *
486
* outBuffer = pointer (unallocated) *
487
* windowBits = window bits *
488
* outEstimate = estimated size of uncompressed data (bytes) *
491
* outBuffer = pointer to decompressed data (allocated) *
492
* outSize = size of outBuffer (bytes) *
493
*****************************************************************************}
495
procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
496
out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
497
outEstimate: Integer = 0);
499
{** string routines *********************************************************}
501
{*****************************************************************************
505
* s = uncompressed data string *
506
* level = compression level *
509
* compressed data string *
510
*****************************************************************************}
512
function ZCompressStr(const s: AnsiString;
513
level: TZCompressionLevel = zcDefault): RawByteString;
515
procedure ZCompressString(var result: RawByteString; const s: AnsiString;
516
level: TZCompressionLevel = zcDefault); overload;
518
procedure ZCompressString(var result: RawByteString; const s: UnicodeString;
519
level: TZCompressionLevel = zcDefault); overload;
521
{*****************************************************************************
525
* s = uncompressed data string *
526
* level = compression level *
529
* compressed data string with 4 byte (integer) header indicating *
530
* original uncompressed data length *
531
*****************************************************************************}
533
function ZCompressStrEx(const s: AnsiString;
534
level: TZCompressionLevel = zcDefault): RawByteString;
536
procedure ZCompressStringEx(var result: RawByteString; const s: AnsiString;
537
level: TZCompressionLevel = zcDefault); overload;
539
procedure ZCompressStringEx(var result: RawByteString; const s: UnicodeString;
540
level: TZCompressionLevel = zcDefault); overload;
542
{*****************************************************************************
546
* s = uncompressed data string *
547
* level = compression level *
548
* windowBits = window bits *
549
* memLevel = memory level *
550
* strategy = compression strategy *
553
* compressed data string *
554
*****************************************************************************}
556
function ZCompressStr2(const s: AnsiString; level: TZCompressionLevel;
557
windowBits, memLevel: Integer; strategy: TZStrategy): RawByteString;
559
procedure ZCompressString2(var result: RawByteString; const s: AnsiString;
560
level: TZCompressionLevel; windowBits, memLevel: Integer;
561
strategy: TZStrategy); overload;
563
procedure ZCompressString2(var result: RawByteString; const s: UnicodeString;
564
level: TZCompressionLevel; windowBits, memLevel: Integer;
565
strategy: TZStrategy); overload;
567
{*****************************************************************************
571
* s = uncompressed data string *
574
* compressed data string *
575
*****************************************************************************}
577
function ZCompressStrWeb(const s: AnsiString): RawByteString;
579
procedure ZCompressStringWeb(var result: RawByteString; const s: AnsiString);
582
procedure ZCompressStringWeb(var result: RawByteString;
583
const s: UnicodeString); overload;
585
{*****************************************************************************
589
* s = compressed data string *
592
* uncompressed data string *
593
*****************************************************************************}
595
function ZDecompressStr(const s: RawByteString): AnsiString;
597
procedure ZDecompressString(var result: AnsiString; const s: RawByteString);
600
procedure ZDecompressString(var result: UnicodeString;
601
const s: RawByteString); overload;
603
{*****************************************************************************
607
* s = compressed data string with 4 byte (integer) header indicating *
608
* original uncompressed data length *
611
* uncompressed data string *
612
*****************************************************************************}
614
function ZDecompressStrEx(const s: RawByteString): AnsiString;
616
procedure ZDecompressStringEx(var result: AnsiString; const s: RawByteString);
619
procedure ZDecompressStringEx(var result: UnicodeString;
620
const s: RawByteString); overload;
622
{*****************************************************************************
626
* s = compressed data string *
627
* windowBits = window bits *
630
* uncompressed data string *
631
*****************************************************************************}
633
function ZDecompressStr2(const s: RawByteString;
634
windowBits: Integer): AnsiString;
636
procedure ZDecompressString2(var result: AnsiString; const s: RawByteString;
637
windowBits: Integer); overload;
639
procedure ZDecompressString2(var result: UnicodeString;
640
const s: RawByteString; windowBits: Integer); overload;
642
{** stream routines *********************************************************}
644
procedure ZCompressStream(inStream, outStream: TStream;
645
level: TZCompressionLevel = zcDefault);
647
procedure ZCompressStream2(inStream, outStream: TStream;
648
level: TZCompressionLevel; windowBits, memLevel: Integer;
649
strategy: TZStrategy);
651
procedure ZCompressStreamWeb(inStream, outStream: TStream);
653
procedure ZDecompressStream(inStream, outStream: TStream);
655
procedure ZDecompressStream2(inStream, outStream: TStream;
656
windowBits: Integer);
658
{****************************************************************************}
661
EZLibErrorClass = class of EZlibError;
663
EZLibError = class(Exception)
667
constructor Create(code: Integer; const dummy: String = ''); overload;
668
constructor Create(error: TZError; const dummy: String = ''); overload;
670
property ErrorCode: Integer read FErrorCode write FErrorCode;
673
EZCompressionError = class(EZLibError);
674
EZDecompressionError = class(EZLibError);
679
SZInvalid = 'Invalid ZStream operation!';
681
{****************************************************************************}
683
function ZCompressCheck(code: Integer): Integer;
689
raise EZCompressionError.Create(code);
693
function ZDecompressCheck(code: Integer; raiseBufferError: Boolean = True): Integer;
699
if (code <> Z_BUF_ERROR) or raiseBufferError then
701
raise EZDecompressionError.Create(code);
706
{** zlib deflate routines ***************************************************}
708
function ZDeflateInit(var stream: TZStreamRec;
709
level: TZCompressionLevel): Integer;
711
result := deflateInit_(stream, ZLevels[level], ZLIB_VERSION,
712
SizeOf(TZStreamRec));
715
function ZDeflateInit2(var stream: TZStreamRec;
716
level: TZCompressionLevel; windowBits, memLevel: Integer;
717
strategy: TZStrategy): Integer;
719
result := deflateInit2_(stream, ZLevels[level], Z_DEFLATED, windowBits,
720
memLevel, ZStrategies[strategy], ZLIB_VERSION, SizeOf(TZStreamRec));
723
function ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;
725
result := deflate(stream, ZFlushes[flush]);
728
function ZDeflateEnd(var stream: TZStreamRec): Integer;
730
result := deflateEnd(stream);
733
function ZDeflateReset(var stream: TZStreamRec): Integer;
735
result := deflateReset(stream);
738
{** zlib inflate routines ***************************************************}
740
function ZInflateInit(var stream: TZStreamRec): Integer;
742
result := inflateInit_(stream, ZLIB_VERSION, SizeOf(TZStreamRec));
745
function ZInflateInit2(var stream: TZStreamRec;
746
windowBits: Integer): Integer;
748
result := inflateInit2_(stream, windowBits, ZLIB_VERSION,
749
SizeOf(TZStreamRec));
752
function ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;
754
result := inflate(stream, ZFlushes[flush]);
757
function ZInflateEnd(var stream: TZStreamRec): Integer;
759
result := inflateEnd(stream);
762
function ZInflateReset(var stream: TZStreamRec): Integer;
764
result := inflateReset(stream);
767
{** zlib checksum routines **************************************************}
769
function ZAdler32(adler: Longint; const buffer; size: Integer): Longint;
771
result := adler32(adler,buffer,size);
774
function ZCrc32(crc: Longint; const buffer; size: Integer): Longint;
776
result := crc32(crc,buffer,size);
779
{** zlib extended routines **************************************************}
781
procedure ZDeflateEx(var stream: TZStreamRec; param: Pointer;
782
read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
787
readBuffer : Array [0..bufferSize - 1] of Byte;
788
writeBuffer: Array [0..bufferSize - 1] of Byte;
792
if Assigned(read) then
794
stream.avail_in := read(param, readBuffer, bufferSize);
796
else stream.avail_in := 0;
799
stream.next_in := @readBuffer;
802
stream.avail_out := bufferSize;
803
stream.next_out := @writeBuffer;
807
if (flushEx = zfFinish) and (stream.avail_in = bufferSize) then
809
flushEx := zfNoFlush;
812
zresult := ZCompressCheck(ZDeflate(stream, flushEx));
814
writeSize := bufferSize - stream.avail_out;
816
write(param, writeBuffer, writeSize);
817
until stream.avail_out > 0;
819
//assert: stream.avail_in = 0
821
if (zresult <> Z_STREAM_END) and Assigned(read) then
823
stream.avail_in := read(param, readBuffer, bufferSize);
825
until (stream.avail_in = 0) and (flush = flushEx);
828
procedure ZInflateEx(var stream: TZStreamRec; param: Pointer;
829
read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
834
readBuffer : Array [0..bufferSize - 1] of Byte;
835
writeBuffer: Array [0..bufferSize - 1] of Byte;
838
if Assigned(read) then
840
stream.avail_in := read(param, readBuffer, bufferSize);
842
else stream.avail_in := 0;
846
while (zresult <> Z_STREAM_END) and (stream.avail_in > 0) do
848
stream.next_in := @readBuffer;
851
stream.avail_out := bufferSize;
852
stream.next_out := @writeBuffer;
854
zresult := ZDecompressCheck(ZInflate(stream, flush), False);
856
writeSize := bufferSize - stream.avail_out;
858
write(param, writeBuffer, writeSize);
859
until stream.avail_out > 0;
861
if (zresult <> Z_STREAM_END) and Assigned(read) then
863
stream.avail_in := read(param, readBuffer, bufferSize);
868
{** private buffer routines *************************************************}
871
PZBufferParam = ^TZBufferParam;
872
TZBufferParam = packed record
874
InPosition : Integer;
877
OutPosition: Integer;
881
function ZBufferRead(p: Pointer; var buffer; size: Integer): Integer;
883
param: PZBufferParam;
885
param := PZBufferParam(p);
887
result := param^.InSize - param^.InPosition;
888
if result > size then result := size;
890
Move(Pointer(PtrUInt(param^.InBuffer) + PtrUInt(param^.InPosition))^, buffer, result);
892
Inc(param^.InPosition, result);
895
function ZBufferWrite(p: Pointer; const buffer; size: Integer): Integer;
897
param: PZBufferParam;
899
param := PZBufferParam(p);
901
if param^.OutPosition + size > param^.OutSize then
903
param^.OutSize := param^.OutPosition + size;
905
ReallocMem(Pointer(param^.OutBuffer), param^.OutSize);
908
Move(buffer, Pointer(PtrUInt(param^.OutBuffer) + PtrUInt(param^.OutPosition))^, size);
910
Inc(param^.OutPosition, size);
915
procedure ZInternalCompressEx(var zstream: TZStreamRec; const inBuffer: Pointer;
916
inSize: Integer; out outBuffer: Pointer; out outSize: Integer);
918
param: TZBufferParam;
920
FillChar(param, SizeOf(TZBufferParam), 0);
925
param.InBuffer := inBuffer;
926
param.InSize := inSize;
929
ZDeflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfFinish);
931
ZCompressCheck(ZDeflateEnd(zstream));
933
outBuffer := param.OutBuffer;
934
outSize := param.OutSize;
936
FreeMem(param.OutBuffer);
942
procedure ZInternalDecompressEx(zstream: TZStreamRec; const inBuffer: Pointer;
943
inSize: Integer; out outBuffer: Pointer; out outSize: Integer;
944
outEstimate: Integer);
946
param: TZBufferParam;
948
FillChar(param, SizeOf(TZBufferParam), 0);
953
param.InBuffer := inBuffer;
954
param.InSize := inSize;
956
if outEstimate > 0 then
958
GetMem(param.OutBuffer, outEstimate);
960
param.OutSize := outEstimate;
964
ZInflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfNoFlush);
966
ZDecompressCheck(ZInflateEnd(zstream));
968
outBuffer := param.OutBuffer;
969
outSize := param.OutSize;
971
FreeMem(param.OutBuffer);
977
procedure ZInternalCompress(var zstream: TZStreamRec; const inBuffer: Pointer;
978
inSize: Integer; out outBuffer: Pointer; out outSize: Integer);
984
outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;
990
zstream.next_in := inBuffer;
991
zstream.avail_in := inSize;
994
ReallocMem(outBuffer, outSize);
996
zstream.next_out := Pointer(PtrUInt(outBuffer) + PtrUInt(zstream.total_out));
997
zstream.avail_out := outSize - zstream.total_out;
999
zresult := ZCompressCheck(ZDeflate(zstream, zfNoFlush));
1001
Inc(outSize, delta);
1002
until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
1004
while zresult <> Z_STREAM_END do
1006
ReallocMem(outBuffer, outSize);
1008
zstream.next_out := Pointer(PtrUInt(outBuffer) + PtrUInt(zstream.total_out));
1009
zstream.avail_out := outSize - zstream.total_out;
1011
zresult := ZCompressCheck(ZDeflate(zstream, zfFinish));
1013
Inc(outSize, delta);
1016
ZCompressCheck(ZDeflateEnd(zstream));
1019
ReallocMem(outBuffer, zstream.total_out);
1021
outSize := zstream.total_out;
1028
procedure ZInternalDecompress(zstream: TZStreamRec; const inBuffer: Pointer;
1029
inSize: Integer; out outBuffer: Pointer; out outSize: Integer;
1030
outEstimate: Integer);
1035
delta := (inSize + 255) and not 255;
1037
if outEstimate = 0 then outSize := delta
1038
else outSize := outEstimate;
1046
zstream.avail_in := inSize;
1047
zstream.next_in := inBuffer;
1049
while (zresult <> Z_STREAM_END) and (zstream.avail_in > 0) do
1052
ReallocMem(outBuffer, outSize);
1054
zstream.next_out := Pointer(PtrUInt(outBuffer) + PtrUInt(zstream.total_out));
1055
zstream.avail_out := outSize - zstream.total_out;
1057
zresult := ZDecompressCheck(ZInflate(zstream, zfNoFlush), False);
1059
Inc(outSize, delta);
1060
until (zresult = Z_STREAM_END) or (zstream.avail_out > 0);
1063
ZDecompressCheck(ZInflateEnd(zstream));
1066
ReallocMem(outBuffer, zstream.total_out);
1068
outSize := zstream.total_out;
1070
if Assigned(outBuffer) then FreeMem(outBuffer);
1076
{** buffer routines *********************************************************}
1078
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
1079
out outBuffer: Pointer; out outSize: Integer;
1080
level: TZCompressionLevel);
1082
zstream: TZStreamRec;
1084
FillChar(zstream, SizeOf(TZStreamRec), 0);
1086
ZCompressCheck(ZDeflateInit(zstream, level));
1088
ZInternalCompress(zstream, inBuffer, inSize, outBuffer, outSize);
1091
procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
1092
out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;
1093
windowBits, memLevel: Integer; strategy: TZStrategy);
1095
zstream: TZStreamRec;
1097
FillChar(zstream, SizeOf(TZStreamRec), 0);
1099
ZCompressCheck(ZDeflateInit2(zstream, level, windowBits, memLevel,
1102
ZInternalCompress(zstream, inBuffer, inSize, outBuffer, outSize);
1105
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
1106
out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer);
1108
zstream: TZStreamRec;
1110
FillChar(zstream, SizeOf(TZStreamRec), 0);
1112
ZDecompressCheck(ZInflateInit(zstream));
1114
ZInternalDecompress(zstream, inBuffer, inSize, outBuffer, outSize,
1118
procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
1119
out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
1120
outEstimate: Integer);
1122
zstream: TZStreamRec;
1124
FillChar(zstream, SizeOf(TZStreamRec), 0);
1126
ZDecompressCheck(ZInflateInit2(zstream, windowBits));
1128
ZInternalDecompress(zstream, inBuffer, inSize, outBuffer, outSize,
1132
{** string routines *********************************************************}
1134
function ZCompressStr(const s: AnsiString;
1135
level: TZCompressionLevel): RawByteString;
1137
ZCompressString(result, s, level);
1140
procedure ZCompressString(var result: RawByteString; const s: AnsiString;
1141
level: TZCompressionLevel);
1146
ZCompress(Pointer(s), Length(s), buffer, size, level);
1148
SetLength(result, size);
1150
Move(buffer^, result[1], size);
1155
procedure ZCompressString(var result: RawByteString; const s: UnicodeString;
1156
level: TZCompressionLevel);
1161
ZCompress(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size, level);
1163
SetLength(result, size);
1165
Move(buffer^, result[1], size);
1170
function ZCompressStrEx(const s: AnsiString;
1171
level: TZCompressionLevel): RawByteString;
1173
ZCompressStringEx(result, s, level);
1176
procedure ZCompressStringEx(var result: RawByteString; const s: AnsiString;
1177
level: TZCompressionLevel);
1182
ZCompress(Pointer(s), Length(s), buffer, size, level);
1184
SetLength(result, size + SizeOf(Integer));
1186
Move(buffer^, result[5], size);
1190
Move(size, result[1], SizeOf(Integer));
1195
procedure ZCompressStringEx(var result: RawByteString; const s: UnicodeString;
1196
level: TZCompressionLevel);
1201
ZCompress(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size, level);
1203
SetLength(result, size + SizeOf(Integer));
1205
Move(buffer^, result[5], size);
1207
size := Length(s) * SizeOf(UnicodeChar);
1209
Move(size, result[1], SizeOf(Integer));
1214
function ZCompressStr2(const s: AnsiString; level: TZCompressionLevel;
1215
windowBits, memLevel: Integer; strategy: TZStrategy): RawByteString;
1217
ZCompressString2(result, s, level, windowBits, memLevel, strategy);
1220
procedure ZCompressString2(var result: RawByteString; const s: AnsiString;
1221
level: TZCompressionLevel; windowBits, memLevel: Integer;
1222
strategy: TZStrategy);
1227
ZCompress2(Pointer(s), Length(s), buffer, size, level, windowBits,
1228
memLevel, strategy);
1230
SetLength(result, size);
1232
Move(buffer^, result[1], size);
1237
procedure ZCompressString2(var result: RawByteString; const s: UnicodeString;
1238
level: TZCompressionLevel; windowBits, memLevel: Integer;
1239
strategy: TZStrategy);
1244
ZCompress2(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size,
1245
level, windowBits, memLevel, strategy);
1247
SetLength(result, size);
1249
Move(buffer^, result[1], size);
1254
function ZCompressStrWeb(const s: AnsiString): RawByteString;
1256
ZCompressStringWeb(result, s);
1259
procedure ZCompressStringWeb(var result: RawByteString; const s: AnsiString);
1261
ZCompressString2(result, s, zcFastest, -15, 9, zsDefault);
1264
procedure ZCompressStringWeb(var result: RawBytestring;
1265
const s: UnicodeString);
1267
ZCompressString2(result, s, zcFastest, -15, 9, zsDefault);
1270
function ZDecompressStr(const s: RawByteString): AnsiString;
1272
ZDecompressString(result, s);
1275
procedure ZDecompressString(var result: AnsiString;
1276
const s: RawByteString);
1281
ZDecompress(Pointer(s), Length(s), buffer, size);
1283
SetLength(result, size);
1285
Move(buffer^, result[1], size);
1290
procedure ZDecompressString(var result: UnicodeString;
1291
const s: RawByteString);
1296
ZDecompress(Pointer(s), Length(s), buffer, size);
1298
SetLength(result, size div SizeOf(UnicodeChar));
1300
Move(buffer^, result[1], size);
1305
function ZDecompressStrEx(const s: RawByteString): AnsiString;
1307
ZDecompressStringEx(result, s);
1310
procedure ZDecompressStringEx(var result: AnsiString; const s: RawByteString);
1317
Move(s[1], size, SizeOf(Integer));
1319
dataSize := Length(s) - SizeOf(Integer);
1321
SetLength(data, dataSize);
1323
Move(s[5], data[1], dataSize);
1325
ZDecompress(Pointer(data), dataSize, buffer, size, size);
1327
SetLength(result, size);
1329
Move(buffer^, result[1], size);
1334
procedure ZDecompressStringEx(var result: UnicodeString;
1335
const s: RawByteString);
1342
Move(s[1], size, SizeOf(Integer));
1344
dataSize := Length(s) - SizeOf(Integer);
1346
SetLength(data, dataSize);
1348
Move(s[5], data[1], dataSize);
1350
ZDecompress(Pointer(data), dataSize, buffer, size, size);
1352
SetLength(result, size div SizeOf(UnicodeChar));
1354
Move(buffer^, result[1], size);
1359
function ZDecompressStr2(const s: RawByteString;
1360
windowBits: Integer): AnsiString;
1362
ZDecompressString2(result, s, windowBits);
1365
procedure ZDecompressString2(var result: AnsiString; const s: RawByteString;
1366
windowBits: Integer);
1371
ZDecompress2(Pointer(s), Length(s), buffer, size, windowBits);
1373
SetLength(result, size);
1375
Move(buffer^, result[1], size);
1380
procedure ZDecompressString2(var result: UnicodeString;
1381
const s: RawByteString; windowBits: Integer);
1386
ZDecompress2(Pointer(s), Length(s), buffer, size, windowBits);
1388
SetLength(result, size div SizeOf(UnicodeChar));
1390
Move(buffer^, result[1], size);
1395
{** private stream routines *************************************************}
1398
PZStreamParam = ^TZStreamParam;
1399
TZStreamParam = packed record
1401
OutStream : TStream;
1404
function ZStreamRead(p: Pointer; var buffer; size: Integer): Integer;
1406
param: PZStreamParam;
1408
param := PZStreamParam(p);
1410
result := param^.InStream.Read(buffer, size);
1413
function ZStreamWrite(p: Pointer; const buffer; size: Integer): Integer;
1415
param: PZStreamParam;
1417
param := PZStreamParam(p);
1419
result := param^.OutStream.Write(buffer, size);
1422
procedure ZInternalCompressStreamEx(zstream: TZStreamRec; inStream,
1423
outStream: TStream);
1425
param: TZStreamParam;
1427
FillChar(param, SizeOf(TZStreamParam), 0);
1429
param.InStream := inStream;
1430
param.OutStream := outStream;
1432
ZDeflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfFinish);
1434
ZCompressCheck(ZDeflateEnd(zstream));
1437
procedure ZInternalDecompressStreamEx(zstream: TZStreamRec; inStream,
1438
outStream: TStream);
1440
param: TZStreamParam;
1442
FillChar(param, SizeOf(TZStreamParam), 0);
1444
param.InStream := inStream;
1445
param.OutStream := outStream;
1447
ZInflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfNoFlush);
1449
ZDecompressCheck(ZInflateEnd(zstream));
1452
procedure ZInternalCompressStream(zstream: TZStreamRec; inStream,
1453
outStream: TStream);
1458
inBuffer : Array [0..bufferSize-1] of Byte;
1459
outBuffer: Array [0..bufferSize-1] of Byte;
1462
zresult := Z_STREAM_END;
1464
zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1466
while zstream.avail_in > 0 do
1468
zstream.next_in := @inBuffer;
1471
zstream.next_out := @outBuffer;
1472
zstream.avail_out := bufferSize;
1474
zresult := ZCompressCheck(ZDeflate(zstream, zfNoFlush));
1476
outSize := bufferSize - zstream.avail_out;
1478
outStream.Write(outBuffer, outSize);
1479
until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
1481
zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1484
while zresult <> Z_STREAM_END do
1486
zstream.next_out := @outBuffer;
1487
zstream.avail_out := bufferSize;
1489
zresult := ZCompressCheck(ZDeflate(zstream, zfFinish));
1491
outSize := bufferSize - zstream.avail_out;
1493
outStream.Write(outBuffer, outSize);
1496
ZCompressCheck(ZDeflateEnd(zstream));
1499
procedure ZInternalDecompressStream(zstream: TZStreamRec; inStream,
1500
outStream: TStream);
1505
inBuffer : Array [0..bufferSize-1] of Byte;
1506
outBuffer: Array [0..bufferSize-1] of Byte;
1512
zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1514
while (zresult <> Z_STREAM_END) and (zstream.avail_in > 0) do
1516
zstream.next_in := @inBuffer;
1519
zstream.next_out := @outBuffer;
1520
zstream.avail_out := bufferSize;
1522
zresult := ZDecompressCheck(ZInflate(zstream, zfNoFlush), False);
1524
outSize := bufferSize - zstream.avail_out;
1526
outStream.Write(outBuffer, outSize);
1527
until (zresult = Z_STREAM_END) or (zstream.avail_out > 0);
1529
if zstream.avail_in > 0 then
1531
inStream.Position := inStream.Position - zstream.avail_in;
1534
if zresult <> Z_STREAM_END then
1536
zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1540
ZDecompressCheck(ZInflateEnd(zstream));
1544
{** stream routines *********************************************************}
1546
procedure ZCompressStream(inStream, outStream: TStream;
1547
level: TZCompressionLevel);
1549
zstream: TZStreamRec;
1551
FillChar(zstream, SizeOf(TZStreamRec), 0);
1553
ZCompressCheck(ZDeflateInit(zstream, level));
1555
ZInternalCompressStream(zstream, inStream, outStream);
1558
procedure ZCompressStream2(inStream, outStream: TStream;
1559
level: TZCompressionLevel; windowBits, memLevel: Integer;
1560
strategy: TZStrategy);
1562
zstream: TZStreamRec;
1564
FillChar(zstream, SizeOf(TZStreamRec), 0);
1566
ZCompressCheck(ZDeflateInit2(zstream, level, windowBits, memLevel,
1569
ZInternalCompressStream(zstream,inStream,outStream);
1572
procedure ZCompressStreamWeb(inStream, outStream: TStream);
1574
ZCompressStream2(inStream, outStream, zcFastest, -15, 9, zsDefault);
1577
procedure ZDecompressStream(inStream, outStream: TStream);
1579
zstream: TZStreamRec;
1581
FillChar(zstream, SizeOf(TZStreamRec), 0);
1583
ZDecompressCheck(ZInflateInit(zstream));
1585
ZInternalDecompressStream(zstream, inStream, outStream);
1588
procedure ZDecompressStream2(inStream, outStream: TStream;
1589
windowBits: Integer);
1591
zstream: TZStreamRec;
1593
FillChar(zstream, SizeOf(TZStreamRec), 0);
1595
ZDecompressCheck(ZInflateInit2(zstream, windowBits));
1597
ZInternalDecompressStream(zstream, inStream, outStream);
1600
{** TCustomZStream **********************************************************}
1602
constructor TCustomZStream.Create(stream: TStream);
1607
FStreamPos := stream.Position;
1610
function TCustomZStream.StreamRead(var buffer; count: Longint): Longint;
1612
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1614
result := FStream.Read(buffer,count);
1616
FStreamPos := FStreamPos + result;
1619
function TCustomZStream.StreamWrite(const buffer; count: Longint): Longint;
1621
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1623
result := FStream.Write(buffer,count);
1625
FStreamPos := FStreamPos + result;
1628
function TCustomZStream.StreamSeek(offset: Longint; origin: Word): Longint;
1630
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1632
result := FStream.Seek(offset,origin);
1634
FStreamPos := FStream.Position;
1637
procedure TCustomZStream.StreamReadBuffer(var buffer; count: Longint);
1639
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1641
FStream.ReadBuffer(buffer,count);
1643
FStreamPos := FStreamPos + count;
1646
procedure TCustomZStream.StreamWriteBuffer(const buffer; count: Longint);
1648
if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1650
FStream.WriteBuffer(buffer,count);
1652
FStreamPos := FStreamPos + count;
1655
procedure TCustomZStream.DoProgress;
1657
if Assigned(FOnProgress) then FOnProgress(Self);
1660
function TCustomZStream.GetStreamPosition: TStreamPos;
1662
result := FStream.Position;
1665
procedure TCustomZStream.SetStreamPosition(value: TStreamPos);
1667
FStream.Position := value;
1668
FStreamPos := FStream.Position;
1671
{** TZCompressionStream *****************************************************}
1673
constructor TZCompressionStream.Create(dest: TStream;
1674
compressionLevel: TZCompressionLevel);
1676
inherited Create(dest);
1678
FZStream.next_out := @FBuffer;
1679
FZStream.avail_out := SizeOf(FBuffer);
1681
ZCompressCheck(ZDeflateInit(FZStream, compressionLevel));
1684
constructor TZCompressionStream.Create(dest: TStream;
1685
compressionLevel: TZCompressionLevel; windowBits, memLevel: Integer;
1686
strategy: TZStrategy);
1688
inherited Create(dest);
1690
FZStream.next_out := @FBuffer;
1691
FZStream.avail_out := SizeOf(FBuffer);
1693
ZCompressCheck(ZDeflateInit2(FZStream, compressionLevel, windowBits,
1694
memLevel, strategy));
1697
destructor TZCompressionStream.Destroy;
1699
FZStream.next_in := Nil;
1700
FZStream.avail_in := 0;
1703
while ZCompressCheck(ZDeflate(FZStream, zfFinish)) <> Z_STREAM_END do
1705
StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);
1707
FZStream.next_out := @FBuffer;
1708
FZStream.avail_out := SizeOf(FBuffer);
1711
if FZStream.avail_out < SizeOf(FBuffer) then
1713
StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);
1716
ZDeflateEnd(FZStream);
1722
function TZCompressionStream.Read(var buffer; count: Longint): Longint;
1725
raise EZCompressionError.Create(SZInvalid);
1728
function TZCompressionStream.Write(const buffer; count: Longint): Longint;
1730
writeCount: Longint;
1734
FZStream.next_in := @buffer;
1735
FZStream.avail_in := count;
1737
while FZStream.avail_in > 0 do
1739
ZCompressCheck(ZDeflate(FZStream, zfNoFlush));
1741
if FZStream.avail_out = 0 then
1743
writeCount := StreamWrite(FBuffer,SizeOf(FBuffer));
1745
if writeCount = SizeOf(FBuffer) then
1747
FZStream.next_out := @FBuffer;
1748
FZStream.avail_out := SizeOf(FBuffer);
1754
StreamPosition := StreamPosition - writeCount;
1756
result := count - FZStream.avail_in;
1758
FZStream.avail_in := 0;
1764
function TZCompressionStream.Seek(offset: Longint; origin: Word): Longint;
1766
if (offset = 0) and (origin = soFromCurrent) then
1768
result := FZStream.total_in;
1770
else raise EZCompressionError.Create(SZInvalid);
1773
function TZCompressionStream.GetCompressionRate: Single;
1775
if FZStream.total_in = 0 then result := 0
1776
else result := (1.0 - (FZStream.total_out / FZStream.total_in)) * 100.0;
1779
{** TZDecompressionStream ***************************************************}
1781
constructor TZDecompressionStream.Create(source: TStream);
1783
inherited Create(source);
1785
FZStream.next_in := @FBuffer;
1786
FZStream.avail_in := 0;
1788
ZDecompressCheck(ZInflateInit(FZStream));
1791
constructor TZDecompressionStream.Create(source: TStream;
1792
windowBits: Integer);
1794
inherited Create(source);
1796
FZStream.next_in := @FBuffer;
1797
FZStream.avail_in := 0;
1799
ZDecompressCheck(ZInflateInit2(FZStream, windowBits));
1802
destructor TZDecompressionStream.Destroy;
1804
ZInflateEnd(FZStream);
1809
function TZDecompressionStream.Read(var buffer; count: Longint): Longint;
1813
FZStream.next_out := @buffer;
1814
FZStream.avail_out := count;
1818
while (FZStream.avail_out > 0) and (zresult <> Z_STREAM_END) do
1820
if FZStream.avail_in = 0 then
1822
FZStream.avail_in := StreamRead(FBuffer,SizeOf(FBuffer));
1824
if FZStream.avail_in = 0 then
1826
result := count - FZStream.avail_out;
1831
FZStream.next_in := @FBuffer;
1836
zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush));
1839
if (zresult = Z_STREAM_END) and (FZStream.avail_in > 0) then
1841
StreamPosition := StreamPosition - FZStream.avail_in;
1843
FZStream.avail_in := 0;
1846
result := count - FZStream.avail_out;
1849
function TZDecompressionStream.Write(const Buffer; Count: Longint): Longint;
1852
raise EZDecompressionError.Create(SZInvalid);
1855
function TZDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
1857
buf: Array [0..8191] of Byte;
1860
if (offset = 0) and (origin = soFromBeginning) then
1862
ZDecompressCheck(ZInflateReset(FZStream));
1864
FZStream.next_in := @FBuffer;
1865
FZStream.avail_in := 0;
1867
StreamPosition := 0;
1869
else if ((offset >= 0) and (origin = soFromCurrent)) or
1870
(((offset - FZStream.total_out) > 0) and (origin = soFromBeginning)) then
1872
if origin = soFromBeginning then Dec(offset, FZStream.total_out);
1876
for i := 1 to offset div SizeOf(buf) do ReadBuffer(buf, SizeOf(buf));
1877
ReadBuffer(buf, offset mod SizeOf(buf));
1880
else if (offset = 0) and (origin = soFromEnd) then
1882
while Read(buf, SizeOf(buf)) > 0 do ;
1884
else raise EZDecompressionError.Create(SZInvalid);
1886
result := FZStream.total_out;
1889
{** TZCustomBuffer **********************************************************}
1891
constructor TZCustomBuffer.Create;
1895
FillChar(FZStream, SizeOf(TZStreamRec), 0);
1898
FBufferCapacity := 0;
1903
destructor TZCustomBuffer.Destroy;
1910
procedure TZCustomBuffer.Clear;
1917
procedure TZCustomBuffer.Flush(flush: TZFlush);
1919
// to be implemented by descendents as needed
1922
function TZCustomBuffer.Write(const s: AnsiString): Integer;
1924
result := Write(Pointer(s), Length(s));
1927
function TZCustomBuffer.Read(var buffer: Pointer; size: Integer): Integer;
1929
result := BufferSize;
1930
if size < result then result := size;
1932
BufferRead(buffer, result);
1935
function TZCustomBuffer.Read(var s: AnsiString): Integer;
1937
SetLength(s, BufferSize);
1939
result := Read(Pointer(s), Length(s));
1942
procedure TZCustomBuffer.BufferWrite(const buffer: Pointer; size: Integer);
1946
BufferCapacity(FBufferSize + size);
1948
Move(buffer^, Pointer(PtrUInt(FBuffer) + PtrUInt(FBufferSize))^, size);
1950
Inc(FBufferSize, size);
1954
procedure TZCustomBuffer.BufferRead(var buffer: Pointer; size: Integer);
1958
Move(FBuffer^, buffer^, size);
1960
Move(Pointer(PtrUInt(FBuffer) + PtrUInt(size))^, FBuffer^, FBufferSize - size);
1962
Dec(FBufferSize, size);
1966
procedure TZCustomBuffer.BufferCapacity(capacity: Integer);
1968
delta = 8192; // must be a power of 2
1970
if capacity > 0 then
1972
capacity := (capacity + (delta - 1)) and not (delta - 1);
1975
if FBufferCapacity <> capacity then
1977
if capacity = 0 then FreeMem(FBuffer)
1978
else if FBufferCapacity = 0 then GetMem(FBuffer, capacity)
1979
else ReallocMem(FBuffer, capacity);
1981
FBufferCapacity := capacity;
1985
{** TZCompressionBuffer *****************************************************}
1987
constructor TZCompressionBuffer.Create(level: TZCompressionLevel);
1991
ZCompressCheck(ZDeflateInit(FZStream, level));
1994
constructor TZCompressionBuffer.Create(level: TZCompressionLevel;
1995
windowBits, memLevel: Integer; strategy: TZStrategy);
1999
ZCompressCheck(ZDeflateInit2(FZStream, level, windowBits, memLevel,
2003
destructor TZCompressionBuffer.Destroy;
2005
ZCompressCheck(ZDeflateEnd(FZStream));
2010
procedure TZCompressionBuffer.Clear;
2014
ZCompressCheck(ZDeflateReset(FZStream));
2017
procedure TZCompressionBuffer.Flush(flush: TZFlush);
2022
outBuffer: Array [0..outSize - 1] of Byte;
2025
FZStream.next_in := Nil;
2026
FZStream.avail_in := 0;
2029
FZStream.next_out := @outBuffer;
2030
FZStream.avail_out := outSize;
2032
zresult := ZCompressCheck(ZDeflate(FZStream, flush));
2034
outCount := outSize - FZStream.avail_out;
2036
BufferWrite(@outBuffer, outCount);
2037
until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);
2040
function TZCompressionBuffer.Write(const buffer: Pointer;
2041
size: Integer): Integer;
2046
outBuffer: Array [0..outSize - 1] of Byte;
2051
FZStream.next_in := buffer;
2052
FZStream.avail_in := size;
2054
while (zresult <> Z_STREAM_END) and (FZStream.avail_in > 0) do
2057
FZStream.next_out := @outBuffer;
2058
FZStream.avail_out := outSize;
2060
zresult := ZCompressCheck(ZDeflate(FZStream, zfNoFlush));
2062
outCount := outSize - FZStream.avail_out;
2064
BufferWrite(@outBuffer, outCount);
2065
until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);
2068
result := size - FZStream.avail_in;
2071
{** TZDecompressionBuffer ***************************************************}
2073
constructor TZDecompressionBuffer.Create;
2077
ZDecompressCheck(ZInflateInit(FZStream));
2080
constructor TZDecompressionBuffer.Create(windowBits: Integer);
2084
ZDecompressCheck(ZInflateInit2(FZStream, windowBits));
2087
destructor TZDecompressionBuffer.Destroy;
2089
ZDecompressCheck(ZInflateEnd(FZStream));
2094
procedure TZDecompressionBuffer.Clear;
2098
ZDecompressCheck(ZInflateReset(FZStream));
2101
function TZDecompressionBuffer.Write(const buffer: Pointer;
2102
size: Integer): Integer;
2107
outBuffer: Array [0..outSize - 1] of Byte;
2112
FZStream.next_in := buffer;
2113
FZStream.avail_in := size;
2115
while (zresult <> Z_STREAM_END) and (FZStream.avail_in > 0) do
2118
FZStream.next_out := @outBuffer;
2119
FZStream.avail_out := outSize;
2121
zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush), False);
2123
outCount := outSize - FZStream.avail_out;
2125
BufferWrite(@outBuffer, outCount);
2126
until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);
2129
result := size - FZStream.avail_in;
2132
{** EZLibError **************************************************************}
2134
constructor EZLibError.Create(code: Integer; const dummy: String);
2136
inherited Create(_z_errmsg[2 - code]);
2141
constructor EZLibError.Create(error: TZError; const dummy: String);
2143
Create(ZErrors[error], dummy);