diff options
author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-10-08 18:43:29 +0000 |
---|---|---|
committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-10-08 18:43:29 +0000 |
commit | 864081102a5f252415f41950b3039a896b4ae9c5 (patch) | |
tree | c6b764651e9dd1f8f53b98eab05f16ba4a492a79 /plugins/Libs/KolZLibBzip.pas | |
parent | db5149b48346c417e18add5702a9dfe7f6e28dd0 (diff) |
Awkwars's plugins - welcome to our trunk
git-svn-id: http://svn.miranda-ng.org/main/trunk@1822 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/Libs/KolZLibBzip.pas')
-rw-r--r-- | plugins/Libs/KolZLibBzip.pas | 1940 |
1 files changed, 1940 insertions, 0 deletions
diff --git a/plugins/Libs/KolZLibBzip.pas b/plugins/Libs/KolZLibBzip.pas new file mode 100644 index 0000000000..f6b91a4d48 --- /dev/null +++ b/plugins/Libs/KolZLibBzip.pas @@ -0,0 +1,1940 @@ +//{$DEFINE USE_EXCEPTIONS}
+{*****************************************************************************
+* unit based on *
+* ZLibEx.pas (zlib 1.2.1) *
+* Edition 2003.12.18 *
+* *
+* copyright (c) 2002-2003 Roberto Della Pasqua (www.dellapasqua.com) *
+* copyright (c) 2000-2002 base2 technologies (www.base2ti.com) *
+* copyright (c) 1997 Borland International (www.borland.com) *
+* *
+* and *
+* *
+* BZip2 unit by Edison Mera (www.geocities.com/efmera/) *
+* Version 1.02 *
+* Edition 21-11-2002 *
+* *
+* Changes made by GMax: *
+* *
+* units joined. gzip support functions added. *
+* compression/decompression streams classes excluded, *
+* compression/decompression stream2stream functions added *
+* *
+* procedures converted to functions to add "no exceptions" functionality *
+* return values actual ONLY in this case (no exceptions) *
+* error occured while value<0 *
+* *
+* function names for Z(De)Compress changed to Z(De)CompressBuf *
+* *
+* (C) GMax 2004. email: gmax@loving.ru *
+*****************************************************************************}
+
+unit KolZLibBzip;
+
+interface
+
+uses
+ KOL{$IFDEF USE_EXCEPTIONS}, ERR{$ENDIF};
+
+const
+ ZLIB_VERSION = '1.2.1';
+ BZIP_VERSION = '1.0.2';
+
+type
+ TAlloc = function(opaque: Pointer; Items, Size: Integer): Pointer; cdecl;
+ TFree = procedure(opaque, Block: Pointer); cdecl;
+
+ TZCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
+ TZCompressionStrategy = (zcsDefault, zcsFiltered, zcsHuffmanOnly);
+ {** TZStreamRec ***********************************************************}
+
+ 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: TAlloc; // used to allocate the internal state
+ zfree: TFree; // 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;
+
+ {** zlib public routines ****************************************************}
+
+ {*****************************************************************************
+ * ZCompressBuf *
+ * *
+ * pre-conditions *
+ * inBuffer = pointer to uncompressed data *
+ * inSize = size of inBuffer (bytes) *
+ * outBuffer = pointer (unallocated) *
+ * level = compression level *
+ * *
+ * post-conditions *
+ * outBuffer = pointer to compressed data (allocated) *
+ * outSize = size of outBuffer (bytes) *
+ *****************************************************************************}
+
+function ZCompressBuf(const inBuffer: Pointer; inSize: Integer;
+ out outBuffer: Pointer; out outSize: Integer;
+ level: TZCompressionLevel = zcDefault): Integer;
+
+{*****************************************************************************
+* ZDecompressBuf *
+* *
+* pre-conditions *
+* inBuffer = pointer to compressed data *
+* inSize = size of inBuffer (bytes) *
+* outBuffer = pointer (unallocated) *
+* outEstimate = estimated size of uncompressed data (bytes) *
+* *
+* post-conditions *
+* outBuffer = pointer to decompressed data (allocated) *
+* outSize = size of outBuffer (bytes) *
+*****************************************************************************}
+
+function ZDecompressBuf(const inBuffer: Pointer; inSize: Integer;
+ out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer = 0): Integer;
+
+{** string routines *********************************************************}
+
+function ZCompressStr(const s: string; level: TZCompressionLevel = zcDefault): string;
+
+function ZDecompressStr(const s: string): string;
+
+{** stream routines *********************************************************}
+
+function ZCompressStream(inStream, outStream: PStream;
+ level: TZCompressionLevel = zcDefault): Integer;
+
+function ZDecompressStream(inStream, outStream: PStream): Integer;
+
+{** utility routines ********************************************************}
+
+function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;
+function CRC32(CRC: Cardinal; const Data: PChar; cbData: Cardinal): Cardinal;
+function compressBound(sourceLen: LongInt): LongInt;
+
+{****************************************************************************}
+
+procedure MoveI32(const Source; var Dest; Count: Integer);
+procedure ZFastCompressString(var s: string; level: TZCompressionLevel);
+procedure ZFastDecompressString(var s: string);
+procedure ZSendToBrowser(var s: string);
+
+type
+ TgzipHeader = packed record
+ FileName: string;
+ Comment: string;
+ FileTime: TDateTime;
+ Extra: string;
+ end;
+
+function gZipCompressStream(inStream, outStream: PStream; var gzHdr: TgzipHeader; level: TZCompressionLevel = zcDefault; strategy: TZCompressionStrategy = zcsDefault): Integer; overload;
+function gZipCompressStream(inStream, outStream: PStream; level: TZCompressionLevel = zcDefault; strategy: TZCompressionStrategy = zcsDefault): Integer; overload;
+function gZipDecompressStreamHeader(inStream: PStream; var gzHdr: TgzipHeader): Integer;
+function gZipDecompressStreamBody(inStream, outStream: PStream): Integer;
+function gZipDecompressStream(inStream, outStream: PStream; var gzHdr: TgzipHeader): Integer;
+function gZipDecompressString(const S: String): String;
+
+{*******************************************************}
+{ }
+{ BZIP2 Data Compression Interface Unit }
+{ }
+{*******************************************************}
+type
+ // Internal structure.
+ TBZStreamRec = packed record
+ next_in: PChar; // next input byte
+ avail_in: Integer; // number of bytes available at next_in
+ total_in_lo32: Integer; // total nb of input bytes read so far
+ total_in_hi32: Integer;
+
+ next_out: PChar; // next output byte should be put here
+ avail_out: Integer; // remaining free space at next_out
+ total_out_lo32: Integer; // total nb of bytes output so far
+ total_out_hi32: Integer;
+
+ state: Pointer;
+
+ bzalloc: TAlloc; // used to allocate the internal state
+ bzfree: TFree; // used to free the internal state
+ opaque: Pointer;
+ end;
+ TBlockSize100k = 1..9;
+ { 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 BZCompressBuf(const InBuf: Pointer; InBytes: Integer;
+ out OutBuf: Pointer; out OutBytes: Integer): Integer;
+
+{ 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 BZDecompressBuf(const InBuf: Pointer; InBytes: Integer;
+ OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer): Integer;
+
+function BZCompressStream(inStream, outStream: PStream; BlockSize100k: TBlockSize100k = 5): Integer;
+function BZDecompressStream(inStream, outStream: PStream): Integer;
+
+
+{** deflate routines ********************************************************}
+
+function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
+ recsize: Integer): Integer; external;
+
+function DeflateInit2_(var strm: TZStreamRec; level: integer; method: integer; windowBits: integer;
+ memLevel: integer; 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;
+
+const
+ gzBufferSize = 16384;
+ gz_magic : array[0..1] of Byte = ($1F, $8B);
+ { gzip flag byte }
+
+ GZF_ASCII_FLAG = $01; { bit 0 set: file probably ascii text }
+ GZF_HEAD_CRC = $02; { bit 1 set: header CRC present }
+ GZF_EXTRA_FIELD = $04; { bit 2 set: extra field present }
+ GZF_ORIG_NAME = $08; { bit 3 set: original file name present }
+ GZF_COMMENT = $10; { bit 4 set: file comment present }
+ GZF_RESERVED = $E0; { bits 5..7: reserved }
+ Z_EOF = -1;
+
+const
+ { ** Maximum value for windowBits in deflateInit2 and inflateInit2 }
+ MAX_WBITS = 15;
+ { ** Maximum value for memLevel in deflateInit2 }
+const
+ MAX_MEM_LEVEL = 9;
+ DEF_MEM_LEVEL = 8;
+
+ {** link zlib 1.2.1 *********************************************************}
+ {** bcc32 flags: -c -6 -O2 -Ve -X- -pr -a8 -b -d -k- -vi -tWM -r -RT- }
+
+{$L zlib\adler32.obj}
+{$L zlib\compress.obj}
+ {.$L zlib\crc32.obj}
+{$L zlib\deflate.obj}
+{$L zlib\infback.obj}
+{$L zlib\inffast.obj}
+{$L zlib\inflate.obj}
+{$L zlib\inftrees.obj}
+{$L zlib\trees.obj}
+{$L zlib\uncompr.obj}
+
+ {*****************************************************************************
+ * note: do not reorder the above -- doing so will result in external *
+ * functions being undefined *
+ *****************************************************************************}
+
+const
+ {** flush constants *******************************************************}
+
+ Z_NO_FLUSH = 0;
+ Z_PARTIAL_FLUSH = 1;
+ Z_SYNC_FLUSH = 2;
+ Z_FULL_FLUSH = 3;
+ Z_FINISH = 4;
+
+ {** return codes **********************************************************}
+
+ 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_WRITE_ERROR = (-10);
+ Z_CRC_ERROR = (-11);
+ Z_SIZE_ERROR = (-12);
+
+ {** compression levels ****************************************************}
+
+ Z_NO_COMPRESSION = 0;
+ Z_BEST_SPEED = 1;
+ Z_BEST_COMPRESSION = 9;
+ Z_DEFAULT_COMPRESSION = (-1);
+
+ {** compression strategies ************************************************}
+
+ Z_FILTERED = 1;
+ Z_HUFFMAN_ONLY = 2;
+ Z_DEFAULT_STRATEGY = 0;
+
+ {** data types ************************************************************}
+
+ Z_BINARY = 0;
+ Z_ASCII = 1;
+ Z_UNKNOWN = 2;
+
+ {** compression methods ***************************************************}
+
+ Z_DEFLATED = 8;
+
+ Z_NULL = nil; { for initializing zalloc, zfree, opaque }
+
+ {** return code messages **************************************************}
+
+ _z_errmsg : array[0..14] 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)
+ '', '', '',
+ 'stream write error', // Z_WRITE_ERROR = (-10);
+ 'crc error', // Z_CRC_ERROR = (-11);
+ 'size mismarch' // Z_SIZE_ERROR = (-12);
+ );
+
+ ZLevels : array[TZCompressionLevel] of Shortint = (
+ Z_NO_COMPRESSION,
+ Z_BEST_SPEED,
+ Z_DEFAULT_COMPRESSION,
+ Z_BEST_COMPRESSION
+ );
+ ZStrategy : array[TZCompressionStrategy] of Shortint = (
+ Z_DEFAULT_STRATEGY,
+ Z_FILTERED,
+ Z_HUFFMAN_ONLY
+ );
+
+ {************** BZip constants **********************************************}
+{$L bz2\blocks~1.obj} //blocksort
+{$L bz2\huffman.obj}
+{$L bz2\compress.obj}
+{$L bz2\decomp~1.obj} //decompress
+{$L bz2\bzlib.obj}
+ { $L bz2\crctable.obj}
+ { $L bz2\randtable.obj}
+
+procedure _BZ2_hbMakeCodeLengths; external;
+procedure _BZ2_blockSort; external;
+procedure _BZ2_hbCreateDecodeTables; external;
+procedure _BZ2_hbAssignCodes; external;
+procedure _BZ2_compressBlock; external;
+procedure _BZ2_decompress; external;
+
+const
+ bzBufferSize = 32768;
+
+ BZ_RUN = 0;
+ BZ_FLUSH = 1;
+ BZ_FINISH = 2;
+ BZ_OK = 0;
+ BZ_RUN_OK = 1;
+ BZ_FLUSH_OK = 2;
+ BZ_FINISH_OK = 3;
+ BZ_STREAM_END = 4;
+ BZ_SEQUENCE_ERROR = (-1);
+ BZ_PARAM_ERROR = (-2);
+ BZ_MEM_ERROR = (-3);
+ BZ_DATA_ERROR = (-4);
+ BZ_DATA_ERROR_MAGIC = (-5);
+ BZ_IO_ERROR = (-6);
+ BZ_UNEXPECTED_EOF = (-7);
+ BZ_OUTBUFF_FULL = (-8);
+
+ BZ_Error_Msg : array[1..8] of PChar = (
+ 'BZ_SEQUENCE_ERROR',
+ 'BZ_PARAM_ERROR',
+ 'BZ_MEM_ERROR',
+ 'BZ_DATA_ERROR',
+ 'BZ_DATA_ERROR_MAGIC',
+ 'BZ_IO_ERROR',
+ 'BZ_UNEXPECTED_EOF',
+ 'BZ_OUTBUFF_FULL'
+ );
+
+ BZ_BLOCK_SIZE_100K = 9;
+
+ _BZ2_rNums : array[0..511] of Longint = (
+ 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
+ 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
+ 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
+ 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
+ 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
+ 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
+ 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
+ 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
+ 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
+ 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
+ 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
+ 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
+ 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
+ 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
+ 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
+ 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
+ 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
+ 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
+ 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
+ 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
+ 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
+ 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
+ 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
+ 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
+ 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
+ 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
+ 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
+ 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
+ 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
+ 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
+ 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
+ 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
+ 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
+ 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
+ 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
+ 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
+ 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
+ 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
+ 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
+ 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
+ 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
+ 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
+ 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
+ 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
+ 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
+ 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
+ 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
+ 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
+ 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
+ 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
+ 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
+ 936, 638
+ );
+
+ _BZ2_crc32Table : array[0..255] of Longint = (
+ $00000000, $04C11DB7, $09823B6E, $0D4326D9,
+ $130476DC, $17C56B6B, $1A864DB2, $1E475005,
+ $2608EDB8, $22C9F00F, $2F8AD6D6, $2B4BCB61,
+ $350C9B64, $31CD86D3, $3C8EA00A, $384FBDBD,
+ $4C11DB70, $48D0C6C7, $4593E01E, $4152FDA9,
+ $5F15ADAC, $5BD4B01B, $569796C2, $52568B75,
+ $6A1936C8, $6ED82B7F, $639B0DA6, $675A1011,
+ $791D4014, $7DDC5DA3, $709F7B7A, $745E66CD,
+ -$67DC4920, -$631D54A9, -$6E5E7272, -$6A9F6FC7,
+ -$74D83FC4, -$70192275, -$7D5A04AE, -$799B191B,
+ -$41D4A4A8, -$4515B911, -$48569FCA, -$4C97827F,
+ -$52D0D27C, -$5611CFCD, -$5B52E916, -$5F93F4A3,
+ -$2BCD9270, -$2F0C8FD9, -$224FA902, -$268EB4B7,
+ -$38C9E4B4, -$3C08F905, -$314BDFDE, -$358AC26B,
+ -$0DC57FD8, -$09046261, -$044744BA, -$0086590F,
+ -$1EC1090C, -$1A0014BD, -$17433266, -$13822FD3,
+ $34867077, $30476DC0, $3D044B19, $39C556AE,
+ $278206AB, $23431B1C, $2E003DC5, $2AC12072,
+ $128E9DCF, $164F8078, $1B0CA6A1, $1FCDBB16,
+ $018AEB13, $054BF6A4, $0808D07D, $0CC9CDCA,
+ $7897AB07, $7C56B6B0, $71159069, $75D48DDE,
+ $6B93DDDB, $6F52C06C, $6211E6B5, $66D0FB02,
+ $5E9F46BF, $5A5E5B08, $571D7DD1, $53DC6066,
+ $4D9B3063, $495A2DD4, $44190B0D, $40D816BA,
+ -$535A3969, -$579B24E0, -$5AD80207, -$5E191FB2,
+ -$405E4FB5, -$449F5204, -$49DC74DB, -$4D1D696E,
+ -$7552D4D1, -$7193C968, -$7CD0EFBF, -$7811F20A,
+ -$6656A20D, -$6297BFBC, -$6FD49963, -$6B1584D6,
+ -$1F4BE219, -$1B8AFFB0, -$16C9D977, -$1208C4C2,
+ -$0C4F94C5, -$088E8974, -$05CDAFAB, -$010CB21E,
+ -$39430FA1, -$3D821218, -$30C134CF, -$3400297A,
+ -$2A47797D, -$2E8664CC, -$23C54213, -$27045FA6,
+ $690CE0EE, $6DCDFD59, $608EDB80, $644FC637,
+ $7A089632, $7EC98B85, $738AAD5C, $774BB0EB,
+ $4F040D56, $4BC510E1, $46863638, $42472B8F,
+ $5C007B8A, $58C1663D, $558240E4, $51435D53,
+ $251D3B9E, $21DC2629, $2C9F00F0, $285E1D47,
+ $36194D42, $32D850F5, $3F9B762C, $3B5A6B9B,
+ $0315D626, $07D4CB91, $0A97ED48, $0E56F0FF,
+ $1011A0FA, $14D0BD4D, $19939B94, $1D528623,
+ -$0ED0A9F2, -$0A11B447, -$075292A0, -$03938F29,
+ -$1DD4DF2E, -$1915C29B, -$1456E444, -$1097F9F5,
+ -$28D8444A, -$2C1959FF, -$215A7F28, -$259B6291,
+ -$3BDC3296, -$3F1D2F23, -$325E09FC, -$369F144D,
+ -$42C17282, -$46006F37, -$4B4349F0, -$4F825459,
+ -$51C5045E, -$550419EB, -$58473F34, -$5C862285,
+ -$64C99F3A, -$6008828F, -$6D4BA458, -$698AB9E1,
+ -$77CDE9E6, -$730CF453, -$7E4FD28C, -$7A8ECF3D,
+ $5D8A9099, $594B8D2E, $5408ABF7, $50C9B640,
+ $4E8EE645, $4A4FFBF2, $470CDD2B, $43CDC09C,
+ $7B827D21, $7F436096, $7200464F, $76C15BF8,
+ $68860BFD, $6C47164A, $61043093, $65C52D24,
+ $119B4BE9, $155A565E, $18197087, $1CD86D30,
+ $029F3D35, $065E2082, $0B1D065B, $0FDC1BEC,
+ $3793A651, $3352BBE6, $3E119D3F, $3AD08088,
+ $2497D08D, $2056CD3A, $2D15EBE3, $29D4F654,
+ -$3A56D987, -$3E97C432, -$33D4E2E9, -$3715FF60,
+ -$2952AF5B, -$2D93B2EE, -$20D09435, -$24118984,
+ -$1C5E343F, -$189F298A, -$15DC0F51, -$111D12E8,
+ -$0F5A42E3, -$0B9B5F56, -$06D8798D, -$0219643C,
+ -$764702F7, -$72861F42, -$7FC53999, -$7B042430,
+ -$6543742B, -$6182699E, -$6CC14F45, -$680052F4,
+ -$504FEF4F, -$548EF2FA, -$59CDD421, -$5D0CC998,
+ -$434B9993, -$478A8426, -$4AC9A2FD, -$4E08BF4C
+ );
+
+// deflate compresses data
+
+function BZ2_bzCompressInit(var strm: TBZStreamRec; blockSize100k: Integer;
+ verbosity: Integer; workFactor: Integer): Integer; stdcall; external;
+
+function BZ2_bzCompress(var strm: TBZStreamRec; action: Integer): Integer; stdcall; external;
+
+function BZ2_bzCompressEnd(var strm: TBZStreamRec): Integer; stdcall; external;
+
+function BZ2_bzBuffToBuffCompress(dest: Pointer; var destLen: Integer; source: Pointer;
+ sourceLen, blockSize100k, verbosity, workFactor: Integer): Integer; stdcall; external;
+
+// inflate decompresses data
+
+function BZ2_bzDecompressInit(var strm: TBZStreamRec; verbosity: Integer;
+ small: Integer): Integer; stdcall; external;
+
+function BZ2_bzDecompress(var strm: TBZStreamRec): Integer; stdcall; external;
+
+function BZ2_bzDecompressEnd(var strm: TBZStreamRec): Integer; stdcall; external;
+
+function BZ2_bzBuffToBuffDecompress(dest: Pointer; var destLen: Integer; source: Pointer;
+ sourceLen, small, verbosity: Integer): Integer; stdcall; external;
+
+{** utility routines *******************************************************}
+
+function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt; external;
+function compressBound(sourceLen: LongInt): LongInt; external;
+
+//
+function InflateInit(var stream: TZStreamRec): Integer;
+
+implementation
+
+procedure _bz_internal_error(errcode: Integer); cdecl;
+begin
+{$IFDEF USE_EXCEPTIONS}
+ //raise EBZip2Error.CreateFmt('Compression Error %d', [errcode]);
+ raise Exception.CreateFMT(e_Convert, 'Compression Error %d', [errcode]);
+ // I don't know, what make in {$ELSE} :(
+{$ENDIF}
+end;
+
+function _malloc(size: Integer): Pointer; cdecl;
+begin
+ GetMem(Result, Size);
+end;
+
+procedure _free(block: Pointer); cdecl;
+begin
+ FreeMem(block);
+end;
+
+function bzip2AllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+begin
+ GetMem(Result, Items * Size);
+end;
+
+procedure bzip2FreeMem(AppData, Block: Pointer); cdecl;
+begin
+ FreeMem(Block);
+end;
+
+{*********************** Peter Morris not aligned move **********************}
+
+procedure MoveI32(const Source; var Dest; Count: Integer); register;
+asm
+ cmp ECX,0
+ Je @JustQuit
+ push ESI
+ push EDI
+ mov ESI, EAX
+ mov EDI, EDX
+ @Loop:
+ Mov AL, [ESI]
+ Inc ESI
+ mov [EDI], AL
+ Inc EDI
+ Dec ECX
+ Jnz @Loop
+ pop EDI
+ pop ESI
+ @JustQuit:
+end;
+{****************************************************************************}
+
+{** utility routines *******************************************************}
+
+//function crc32; external;
+function CRC32(CRC: Cardinal; const Data: PChar; cbData: Cardinal): Cardinal; assembler;
+asm
+ or edx, edx
+ je @@exi
+ jecxz @@exi
+ xor eax,0FFFFFFFFh
+ push ebx
+@@upd:
+ movzx ebx, al
+ xor bl, [ edx ]
+ shr eax, 8
+ and eax, 00FFFFFFh
+ xor eax, cs:[ebx*4 + offset @@c32tt ]//OFFSET @@C32TT ]
+ inc edx
+ loop @@upd
+ pop ebx
+ xor eax,0FFFFFFFFh
+@@exi:
+ ret
+
+@@C32TT:
+
+DD 000000000h, 077073096h, 0ee0e612ch, 0990951bah
+DD 0076dc419h, 0706af48fh, 0e963a535h, 09e6495a3h
+DD 00edb8832h, 079dcb8a4h, 0e0d5e91eh, 097d2d988h
+DD 009b64c2bh, 07eb17cbdh, 0e7b82d07h, 090bf1d91h
+DD 01db71064h, 06ab020f2h, 0f3b97148h, 084be41deh
+DD 01adad47dh, 06ddde4ebh, 0f4d4b551h, 083d385c7h
+DD 0136c9856h, 0646ba8c0h, 0fd62f97ah, 08a65c9ech
+DD 014015c4fh, 063066cd9h, 0fa0f3d63h, 08d080df5h
+DD 03b6e20c8h, 04c69105eh, 0d56041e4h, 0a2677172h
+DD 03c03e4d1h, 04b04d447h, 0d20d85fdh, 0a50ab56bh
+DD 035b5a8fah, 042b2986ch, 0dbbbc9d6h, 0acbcf940h
+DD 032d86ce3h, 045df5c75h, 0dcd60dcfh, 0abd13d59h
+DD 026d930ach, 051de003ah, 0c8d75180h, 0bfd06116h
+DD 021b4f4b5h, 056b3c423h, 0cfba9599h, 0b8bda50fh
+DD 02802b89eh, 05f058808h, 0c60cd9b2h, 0b10be924h
+DD 02f6f7c87h, 058684c11h, 0c1611dabh, 0b6662d3dh
+DD 076dc4190h, 001db7106h, 098d220bch, 0efd5102ah
+DD 071b18589h, 006b6b51fh, 09fbfe4a5h, 0e8b8d433h
+DD 07807c9a2h, 00f00f934h, 09609a88eh, 0e10e9818h
+DD 07f6a0dbbh, 0086d3d2dh, 091646c97h, 0e6635c01h
+DD 06b6b51f4h, 01c6c6162h, 0856530d8h, 0f262004eh
+DD 06c0695edh, 01b01a57bh, 08208f4c1h, 0f50fc457h
+DD 065b0d9c6h, 012b7e950h, 08bbeb8eah, 0fcb9887ch
+DD 062dd1ddfh, 015da2d49h, 08cd37cf3h, 0fbd44c65h
+DD 04db26158h, 03ab551ceh, 0a3bc0074h, 0d4bb30e2h
+DD 04adfa541h, 03dd895d7h, 0a4d1c46dh, 0d3d6f4fbh
+DD 04369e96ah, 0346ed9fch, 0ad678846h, 0da60b8d0h
+DD 044042d73h, 033031de5h, 0aa0a4c5fh, 0dd0d7cc9h
+DD 05005713ch, 0270241aah, 0be0b1010h, 0c90c2086h
+DD 05768b525h, 0206f85b3h, 0b966d409h, 0ce61e49fh
+DD 05edef90eh, 029d9c998h, 0b0d09822h, 0c7d7a8b4h
+DD 059b33d17h, 02eb40d81h, 0b7bd5c3bh, 0c0ba6cadh
+DD 0edb88320h, 09abfb3b6h, 003b6e20ch, 074b1d29ah
+DD 0ead54739h, 09dd277afh, 004db2615h, 073dc1683h
+DD 0e3630b12h, 094643b84h, 00d6d6a3eh, 07a6a5aa8h
+DD 0e40ecf0bh, 09309ff9dh, 00a00ae27h, 07d079eb1h
+DD 0f00f9344h, 08708a3d2h, 01e01f268h, 06906c2feh
+DD 0f762575dh, 0806567cbh, 0196c3671h, 06e6b06e7h
+DD 0fed41b76h, 089d32be0h, 010da7a5ah, 067dd4acch
+DD 0f9b9df6fh, 08ebeeff9h, 017b7be43h, 060b08ed5h
+DD 0d6d6a3e8h, 0a1d1937eh, 038d8c2c4h, 04fdff252h
+DD 0d1bb67f1h, 0a6bc5767h, 03fb506ddh, 048b2364bh
+DD 0d80d2bdah, 0af0a1b4ch, 036034af6h, 041047a60h
+DD 0df60efc3h, 0a867df55h, 0316e8eefh, 04669be79h
+DD 0cb61b38ch, 0bc66831ah, 0256fd2a0h, 05268e236h
+DD 0cc0c7795h, 0bb0b4703h, 0220216b9h, 05505262fh
+DD 0c5ba3bbeh, 0b2bd0b28h, 02bb45a92h, 05cb36a04h
+DD 0c2d7ffa7h, 0b5d0cf31h, 02cd99e8bh, 05bdeae1dh
+DD 09b64c2b0h, 0ec63f226h, 0756aa39ch, 0026d930ah
+DD 09c0906a9h, 0eb0e363fh, 072076785h, 005005713h
+DD 095bf4a82h, 0e2b87a14h, 07bb12baeh, 00cb61b38h
+DD 092d28e9bh, 0e5d5be0dh, 07cdcefb7h, 00bdbdf21h
+DD 086d3d2d4h, 0f1d4e242h, 068ddb3f8h, 01fda836eh
+DD 081be16cdh, 0f6b9265bh, 06fb077e1h, 018b74777h
+DD 088085ae6h, 0ff0f6a70h, 066063bcah, 011010b5ch
+DD 08f659effh, 0f862ae69h, 0616bffd3h, 0166ccf45h
+DD 0a00ae278h, 0d70dd2eeh, 04e048354h, 03903b3c2h
+DD 0a7672661h, 0d06016f7h, 04969474dh, 03e6e77dbh
+DD 0aed16a4ah, 0d9d65adch, 040df0b66h, 037d83bf0h
+DD 0a9bcae53h, 0debb9ec5h, 047b2cf7fh, 030b5ffe9h
+DD 0bdbdf21ch, 0cabac28ah, 053b39330h, 024b4a3a6h
+DD 0bad03605h, 0cdd70693h, 054de5729h, 023d967bfh
+DD 0b3667a2eh, 0c4614ab8h, 05d681b02h, 02a6f2b94h
+DD 0b40bbe37h, 0c30c8ea1h, 05a05df1bh, 02d02ef8dh
+
+end;
+
+{** 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;
+
+{****************************************************************************}
+{$IFDEF USE_EXCEPTIONS}
+
+function ZCompressCheck(code: Integer): Integer;
+begin
+ result := code;
+
+ if code < 0 then begin
+ raise Exception.CreateFMT(e_Convert, 'Compression Error %d - %s', [code, _z_errmsg[2 - code]]);
+ end;
+end;
+
+function ZDecompressCheck(code: Integer): Integer;
+begin
+ Result := code;
+
+ if code < 0 then begin
+ raise Exception.CreateFMT(e_Convert, 'Decompression Error %d - %s', [code, _z_errmsg[2 - code]]);
+ end;
+end;
+{$ENDIF}
+
+{****************************************************************************}
+{****************************************************************************}
+{****************************************************************************}
+{**** implementation itself *************************************************}
+{****************************************************************************}
+{****************************************************************************}
+{****************************************************************************}
+
+function ZCompressBuf(const inBuffer: Pointer; inSize: Integer; out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel): Integer;
+const
+ delta = 256;
+var
+ zstream : TZStreamRec;
+begin
+ FillChar(zstream, SizeOf(TZStreamRec), 0);
+ Result := Z_OK;
+ outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;
+ outBuffer := nil;
+ GetMem(outBuffer, outSize);
+ try
+ zstream.next_in := inBuffer;
+ zstream.avail_in := inSize;
+ zstream.next_out := outBuffer;
+ zstream.avail_out := outSize;
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(DeflateInit(zstream, ZLevels[level]));
+{$ELSE}
+ Result := DeflateInit(zstream, ZLevels[level]);
+ if Result < 0 then Exit;
+{$ENDIF}
+ try
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZCompressCheck(deflate(zstream, Z_FINISH));
+{$ELSE}
+ Result := deflate(zstream, Z_FINISH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ while Result <> Z_STREAM_END do begin
+ Inc(outSize, delta);
+ ReallocMem(outBuffer, outSize);
+
+ zstream.next_out := PChar(Integer(outBuffer) + zstream.total_out);
+ zstream.avail_out := delta;
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZCompressCheck(deflate(zstream, Z_FINISH));
+{$ELSE}
+ Result := deflate(zstream, Z_FINISH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ end; // while
+ finally
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(deflateEnd(zstream));
+{$ELSE}
+ deflateEnd(zstream);
+{$ENDIF}
+ end;
+
+ ReallocMem(outBuffer, zstream.total_out);
+ outSize := zstream.total_out;
+{$IFDEF USE_EXCEPTIONS}
+ except
+ FreeMem(outBuffer);
+ raise;
+{$ELSE}
+ finally
+ if Result < 0 then FreeMem(outBuffer);
+{$ENDIF}
+ end;
+end;
+
+function ZCompressBuf2(const inBuffer: Pointer; inSize: Integer; out outBuffer: Pointer; out outSize: Integer): Integer;
+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);
+ Result := Z_OK;
+ try
+ zstream.next_in := inBuffer;
+ zstream.avail_in := inSize;
+ zstream.next_out := outBuffer;
+ zstream.avail_out := outSize;
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(DeflateInit2(zstream, 1, 8, -15, 9, 0));
+{$ELSE}
+ Result := DeflateInit2(zstream, 1, 8, -15, 9, 0);
+ if Result < 0 then Exit;
+{$ENDIF}
+
+ try
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZCompressCheck(deflate(zstream, Z_FINISH));
+{$ELSE}
+ Result := deflate(zstream, Z_FINISH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ while Result <> Z_STREAM_END do begin
+ Inc(outSize, delta);
+ ReallocMem(outBuffer, outSize);
+
+ zstream.next_out := PChar(Integer(outBuffer) + zstream.total_out);
+ zstream.avail_out := delta;
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZCompressCheck(deflate(zstream, Z_FINISH));
+{$ELSE}
+ Result := deflate(zstream, Z_FINISH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ end; // while
+ finally
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(deflateEnd(zstream));
+{$ELSE}
+ deflateEnd(zstream);
+{$ENDIF}
+ end;
+
+ ReallocMem(outBuffer, zstream.total_out);
+ outSize := zstream.total_out;
+{$IFDEF USE_EXCEPTIONS}
+ except
+ FreeMem(outBuffer);
+ raise;
+{$ELSE}
+ finally
+ if Result < 0 then FreeMem(outBuffer);
+{$ENDIF}
+ end;
+end;
+
+function ZDecompressBuf(const inBuffer: Pointer; inSize: Integer; out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer): 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;
+ Result := Z_OK;
+ GetMem(outBuffer, outSize);
+ try
+ zstream.next_in := inBuffer;
+ zstream.avail_in := inSize;
+ zstream.next_out := outBuffer;
+ zstream.avail_out := outSize;
+
+{$IFDEF USE_EXCEPTIONS}
+ ZDecompressCheck(InflateInit(zstream));
+{$ELSE}
+ Result := InflateInit(zstream);
+ if Result < 0 then Exit;
+{$ENDIF}
+
+ try
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZDecompressCheck(inflate(zstream, Z_NO_FLUSH));
+{$ELSE}
+ Result := inflate(zstream, Z_NO_FLUSH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ while (Result <> Z_STREAM_END) do begin
+ Inc(outSize, delta);
+ ReallocMem(outBuffer, outSize);
+
+ zstream.next_out := PChar(Integer(outBuffer) + zstream.total_out);
+ zstream.avail_out := delta;
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZDecompressCheck(inflate(zstream, Z_NO_FLUSH));
+{$ELSE}
+ Result := inflate(zstream, Z_NO_FLUSH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ end;
+ finally
+{$IFDEF USE_EXCEPTIONS}
+ ZDecompressCheck(inflateEnd(zstream));
+{$ELSE}
+ inflateEnd(zstream);
+{$ENDIF}
+ end;
+
+ ReallocMem(outBuffer, zstream.total_out);
+ outSize := zstream.total_out;
+
+{$IFDEF USE_EXCEPTIONS}
+ except
+ FreeMem(outBuffer);
+ raise;
+{$ELSE}
+ finally
+ if Result < 0 then FreeMem(outBuffer);
+{$ENDIF}
+ end;
+end;
+
+{** string routines *********************************************************}
+
+function ZCompressStr(const s: string; level: TZCompressionLevel): string;
+var
+ buffer : Pointer;
+ size : Integer;
+begin
+ ZCompressBuf(PChar(s), Length(s), buffer, size, level);
+ SetLength(result, size);
+ Move(buffer^, pointer(result)^, size);
+ FreeMem(buffer);
+end;
+
+procedure ZFastCompressString(var s: string; level: TZCompressionLevel);
+var
+ outBuf : Pointer;
+ outBytes : Integer;
+begin
+ ZCompressBuf(pointer(s), length(s), outBuf, outBytes, level);
+ SetLength(s, outBytes);
+ MoveI32(pointer(outBuf)^, pointer(s)^, outBytes);
+ FreeMem(outBuf);
+end;
+
+procedure ZFastDecompressString(var s: string);
+var
+ outBuf : Pointer;
+ outBytes : Integer;
+begin
+ ZDecompressBuf(pointer(s), Length(s), outBuf, outBytes);
+ SetLength(s, outBytes);
+ MoveI32(pointer(outBuf)^, pointer(s)^, outBytes);
+ FreeMem(outBuf);
+end;
+
+procedure ZSendToBrowser(var s: string);
+var
+ outBuf : Pointer;
+ outBytes : Integer;
+begin
+ ZCompressBuf2(pointer(s), length(s), outBuf, outBytes);
+ SetLength(s, outBytes);
+ Move(pointer(outBuf)^, pointer(s)^, outBytes);
+ FreeMem(outBuf);
+end;
+
+function ZDecompressStr(const s: string): string;
+var
+ buffer : Pointer;
+ size : Integer;
+begin
+ ZDecompressBuf(PChar(s), Length(s), buffer, size);
+ SetLength(result, size);
+ Move(buffer^, pointer(result)^, size);
+ FreeMem(buffer);
+end;
+
+{** stream routines *********************************************************}
+
+function ZCompressStream(inStream, outStream: PStream; level: TZCompressionLevel): Integer;
+const
+ bufferSize = 32768;
+var
+ zstream : TZStreamRec;
+ inBuffer : array[0..bufferSize - 1] of Char;
+ outBuffer : array[0..bufferSize - 1] of Char;
+ inSize : Integer;
+ outSize : Integer;
+begin
+ FillChar(zstream, SizeOf(TZStreamRec), 0);
+{$IFDEF USE_EXCEPTIONS}
+ Result := Z_OK;
+ ZCompressCheck(DeflateInit(zstream, ZLevels[level]));
+{$ELSE}
+ Result := DeflateInit(zstream, ZLevels[level]);
+ if Result < 0 then Exit;
+{$ENDIF}
+ try
+ inSize := inStream.Read(inBuffer, bufferSize);
+
+ while inSize > 0 do begin
+ zstream.next_in := inBuffer;
+ zstream.avail_in := inSize;
+
+ repeat
+ zstream.next_out := outBuffer;
+ zstream.avail_out := bufferSize;
+
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(deflate(zstream, Z_NO_FLUSH));
+{$ELSE}
+ Result := deflate(zstream, Z_NO_FLUSH);
+ if Result < 0 then Exit;
+{$ENDIF}
+
+ // outSize := zstream.next_out - outBuffer;
+ outSize := bufferSize - zstream.avail_out;
+
+ outStream.Write(outBuffer, outSize);
+ until (zstream.avail_in = 0) and (zstream.avail_out > 0);
+
+ inSize := inStream.Read(inBuffer, bufferSize);
+ end;
+
+ repeat
+ zstream.next_out := outBuffer;
+ zstream.avail_out := bufferSize;
+
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZCompressCheck(deflate(zstream, Z_FINISH));
+{$ELSE}
+ Result := deflate(zstream, Z_FINISH);
+ if Result < 0 then Break;
+{$ENDIF}
+
+ // outSize := zstream.next_out - outBuffer;
+ outSize := bufferSize - zstream.avail_out;
+
+ outStream.Write(outBuffer, outSize);
+ until (Result = Z_STREAM_END) and (zstream.avail_out > 0);
+ finally
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(deflateEnd(zstream));
+{$ELSE}
+ deflateEnd(zstream);
+{$ENDIF}
+ end;
+end;
+
+function ZDecompressStream(inStream, outStream: PStream): Integer;
+const
+ bufferSize = 32768;
+var
+ zstream : TZStreamRec;
+ inBuffer : array[0..bufferSize - 1] of Char;
+ outBuffer : array[0..bufferSize - 1] of Char;
+ inSize : Integer;
+ outSize : Integer;
+begin
+ FillChar(zstream, SizeOf(TZStreamRec), 0);
+
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZCompressCheck(InflateInit(zstream));
+{$ELSE}
+ Result := InflateInit(zstream);
+ if Result < 0 then Exit;
+{$ENDIF}
+ try
+ inSize := inStream.Read(inBuffer, bufferSize);
+
+ while inSize > 0 do begin
+ zstream.next_in := inBuffer;
+ zstream.avail_in := inSize;
+
+ repeat
+ zstream.next_out := outBuffer;
+ zstream.avail_out := bufferSize;
+
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(inflate(zstream, Z_NO_FLUSH));
+{$ELSE}
+ Result := inflate(zstream, Z_NO_FLUSH);
+ if Result < 0 then Exit;
+{$ENDIF}
+
+ // outSize := zstream.next_out - outBuffer;
+ outSize := bufferSize - zstream.avail_out;
+
+ outStream.Write(outBuffer, outSize);
+ until (zstream.avail_in = 0) and (zstream.avail_out > 0);
+
+ inSize := inStream.Read(inBuffer, bufferSize);
+ end;
+
+ repeat
+ zstream.next_out := outBuffer;
+ zstream.avail_out := bufferSize;
+
+{$IFDEF USE_EXCEPTIONS}
+ Result := ZCompressCheck(inflate(zstream, Z_FINISH));
+{$ELSE}
+ Result := inflate(zstream, Z_FINISH);
+ if Result < 0 then Break;
+{$ENDIF}
+
+ // outSize := zstream.next_out - outBuffer;
+ outSize := bufferSize - zstream.avail_out;
+
+ outStream.Write(outBuffer, outSize);
+ until (Result = Z_STREAM_END) and (zstream.avail_out > 0);
+ finally
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(inflateEnd(zstream));
+{$ELSE}
+ inflateEnd(zstream);
+{$ENDIF}
+ end;
+end;
+
+{** gzip Stream routines ******************************************************}
+const
+ UnixDateDelta = 25569;
+
+function DateTimeToUnix(ConvDate: TDateTime): Longint;
+begin
+ //example: DateTimeToUnix(now);
+ Result := Round((ConvDate - UnixDateDelta) * 86400);
+end;
+
+function UnixToDateTime(USec: Longint): TDateTime;
+begin
+ //Example: UnixToDateTime(1003187418);
+ Result := (Usec / 86400) + UnixDateDelta;
+end;
+
+function gZipCompressStream(inStream, outStream: PStream; var gzHdr: TgzipHeader; level: TZCompressionLevel = zcDefault; strategy: TZCompressionStrategy = zcsDefault): Integer;
+var
+ rSize,
+ wSize,
+ zResult : LongInt;
+ done : Boolean;
+ iBuffer,
+ oBuffer : PChar; //Array [0..gzBufferSize-1] of Char;
+ fCrc : Cardinal;
+ zStream : TZStreamRec;
+ stamp : Integer;
+
+begin
+ iBuffer := nil;
+ oBuffer := nil;
+ Result := Z_MEM_ERROR;
+ try
+ GetMem(iBuffer, gzBufferSize);
+ GetMem(oBuffer, gzBufferSize);
+
+ fCrc := 0;
+ FillChar(zStream, SizeOf(zStream), 0);
+
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(DeflateInit2(zStream, ZLevels[level], Z_DEFLATED, -MAX_WBITS,
+ DEF_MEM_LEVEL, ZStrategy[strategy]));
+{$ELSE}
+ Result := DeflateInit2(zStream, ZLevels[level], Z_DEFLATED, -MAX_WBITS,
+ DEF_MEM_LEVEL, ZStrategy[strategy]);
+ if Result < 0 then Exit;
+{$ENDIF}
+ { windowBits is passed < 0 to suppress zlib header }
+ oBuffer[0] := Char(gz_magic[0]);
+ oBuffer[1] := Char(gz_magic[1]); // gz Magic
+ oBuffer[2] := #08; // gz Compression method
+ oBuffer[3] := #0;
+ // set mtime
+ {
+ Inc(gzHdr.TimeStamp,gzTimeStampCorrection);
+ oBuffer[4]:=Lo(gzHdr.TimeStamp and $FFFF); oBuffer[5]:=Hi(gzHdr.TimeStamp and $FFFF);
+ oBuffer[6]:=Lo(gzHdr.TimeStamp shr 16); oBuffer[7]:=Hi(gzHdr.TimeStamp shr 16);
+ Dec(gzHdr.TimeStamp,gzTimeStampCorrection);
+ }
+ stamp := DateTimeToUnix(gzHdr.FileTime);
+ oBuffer[4] := Char(Lo(stamp and $FFFF));
+ oBuffer[5] := Char(Hi(stamp and $FFFF));
+ oBuffer[6] := Char(Lo(stamp shr 16));
+ oBuffer[7] := Char(Hi(stamp shr 16));
+
+ // xfl, os code sets to 0
+ oBuffer[8] := #0;
+ oBuffer[9] := #0;
+
+ if gzHdr.FileName <> '' then begin
+ oBuffer[3] := Char(Byte(oBuffer[3]) or GZF_ORIG_NAME);
+ end;
+ if gzHdr.Comment <> '' then begin
+ oBuffer[3] := Char(Byte(oBuffer[3]) or GZF_COMMENT);
+ end;
+ if gzHdr.Extra <> '' then begin
+ oBuffer[3] := Char(Byte(oBuffer[3]) or GZF_EXTRA_FIELD);
+ end;
+ wSize := outStream.Write(oBuffer^, 10);
+{$IFDEF USE_EXCEPTIONS}
+ if wSize <> 10 then ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if wSize <> 10 then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+
+ // extra
+ if (byte(oBuffer[3]) and GZF_EXTRA_FIELD) <> 0 then begin
+ rSize := Length(gzHdr.Extra);
+ Move(gzHdr.Extra[1], iBuffer^, rSize);
+ iBuffer[rSize] := #0;
+ Inc(rSize);
+ wSize := outStream.Write(iBuffer^, rSize);
+{$IFDEF USE_EXCEPTIONS}
+ if wSize <> rSize then ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if wSize <> rSize then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+ end;
+ // filename
+ if (byte(oBuffer[3]) and GZF_ORIG_NAME) <> 0 then begin
+ rSize := Length(gzHdr.FileName);
+ Move(gzHdr.FileName[1], iBuffer^, rSize);
+ iBuffer[rSize] := #0;
+ Inc(rSize);
+ wSize := outStream.Write(iBuffer^, rSize);
+{$IFDEF USE_EXCEPTIONS}
+ if wSize <> rSize then ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if wSize <> rSize then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+ end;
+ // comment
+ if (byte(oBuffer[3]) and GZF_COMMENT) <> 0 then begin
+ rSize := Length(gzHdr.Comment);
+ Move(gzHdr.Comment[1], iBuffer^, rSize);
+ iBuffer[rSize] := #0;
+ Inc(rSize);
+ wSize := outStream.Write(iBuffer^, rSize);
+{$IFDEF USE_EXCEPTIONS}
+ if wSize <> rSize then ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if wSize <> rSize then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+ end;
+ // hcrc
+
+ rSize := inStream.Read(iBuffer^, gzBufferSize);
+ zStream.next_out := PChar(oBuffer);
+ zStream.avail_out := gzBufferSize;
+ repeat
+ //DoProgressEvent;
+ zStream.next_in := PChar(iBuffer);
+ zStream.avail_in := rSize;
+ while (zStream.avail_in <> 0) do begin
+ if (zStream.avail_out = 0) then begin
+ zStream.next_out := PChar(oBuffer);
+ wSize := outStream.Write(oBuffer^, gzBufferSize);
+ if (wSize <> gzBufferSize) then begin
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ Result := Z_WRITE_ERROR;
+ Exit;
+{$ENDIF}
+ end;
+ zStream.avail_out := gzBufferSize;
+ end;
+{$IFDEF USE_EXCEPTIONS}
+ ZCompressCheck(deflate(zStream, Z_NO_FLUSH));
+{$ELSE}
+ Result := deflate(zStream, Z_NO_FLUSH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ end; // while
+ fCrc := Crc32(fCrc, PChar(iBuffer), rSize);
+ rSize := inStream.Read(iBuffer^, gzBufferSize);
+ until rSize = 0;
+ { flush buffers }
+ zStream.avail_in := 0; { should be zero already anyway }
+ done := False;
+
+ repeat
+ rSize := gzBufferSize - zStream.avail_out;
+ if (rSize <> 0) then begin
+ wSize := outStream.Write(oBuffer^, rSize);
+{$IFDEF USE_EXCEPTIONS}
+ if (wSize <> rSize) then ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if (wSize <> rSize) then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+ zStream.next_out := PChar(oBuffer);
+ zStream.avail_out := gzBufferSize;
+ end;
+ if done then Break;
+ zResult := deflate(zStream, Z_FINISH);
+ if (rSize = 0) and (zResult = Z_BUF_ERROR) then
+{$IFDEF USE_EXCEPTIONS}
+ else ZCompressCheck(zResult);
+{$ELSE}
+ else begin
+ Result := zResult;
+ if Result < 0 then Exit;
+ end;
+{$ENDIF}
+ { deflate has finished flushing only when it hasn't used up
+ all the available space in the output buffer: }
+ done := (zStream.avail_out <> 0) or (zResult = Z_STREAM_END);
+ until False;
+ wSize := outStream.Write(fCrc, 4);
+{$IFDEF USE_EXCEPTIONS}
+ if wSize <> 4 then ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if wSize <> 4 then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+ rSize := inStream.Size;
+ wSize := outStream.Write(rSize, 4);
+{$IFDEF USE_EXCEPTIONS}
+ if wSize <> 4 then ZCompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if wSize <> 4 then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+ Result := Z_OK;
+ finally
+ deflateEnd(zStream);
+ if Assigned(iBuffer) then FreeMem(iBuffer);
+ if Assigned(oBuffer) then FreeMem(oBuffer);
+ end;
+end;
+
+function gZipCompressStream(inStream, outStream: PStream; level: TZCompressionLevel = zcDefault; strategy: TZCompressionStrategy = zcsDefault): Integer; overload;
+var
+ gzHdr : TgzipHeader;
+begin
+ FillChar(gzHdr, SizeOf(gzHdr), 0);
+ gzHdr.FileTime := Date;
+ Result := gZipCompressStream(inStream, outStream, gzHdr, level, strategy);
+end;
+
+function gZipDecompressStreamHeader(inStream: PStream; var gzHdr: TgzipHeader): Integer;
+var
+ i, c, flg : LongInt;
+ fEOF : Boolean;
+
+ function gz_getbyte: Integer;
+ var
+ b, c : Integer;
+ begin
+ b := 0;
+ c := inStream.Read(b, 1);
+ if c = 0 then begin
+ fEOF := True;
+ Result := Z_EOF;
+ end
+ else Result := b;
+ end;
+
+ function gz_getlong: Integer;
+ var
+ b, c : Integer;
+ begin
+ b := 0;
+ c := inStream.Read(b, 4);
+ if c < 4 then begin
+ fEOF := True;
+ Result := Z_EOF;
+ end
+ else Result := b;
+ end;
+begin
+ // fTransparent := False;
+ Result := Z_OK;
+ fEOF := False;
+ gzHdr.FileName := '';
+ gzHdr.Comment := '';
+ gzHdr.Extra := '';
+ try
+ for i := 0 to 1 do begin
+ flg := gz_getbyte;
+ if (flg <> gz_magic[i]) then begin
+ fEOF := True;
+ exit;
+ end;
+ end;
+ c := gz_getbyte; // method
+ flg := gz_getbyte; // flags
+ if (c <> Z_DEFLATED) or ((flg and GZF_RESERVED) <> 0) then begin
+ fEOF := True;
+ exit;
+ end;
+
+ gzHdr.FileTime := UnixToDateTime(gz_getLong);
+ gz_getbyte;
+ gz_getbyte; { skip xflags and OS code }
+
+ if (flg and GZF_EXTRA_FIELD) <> 0 then begin // skip extra fields
+ i := gz_getbyte + (gz_getbyte shl 8); // length of extra
+ SetLength(gzHdr.Extra, i);
+ c := inStream.Read(gzHdr.Extra, i);
+ if c <> i then begin
+ fEOF := True;
+ Exit;
+ end;
+ end;
+ if (flg and GZF_ORIG_NAME) <> 0 then begin // extract File Name
+ repeat
+ c := gz_getbyte;
+ if (c <> 0) and (c <> Z_EOF) then gzHdr.FileName := gzHdr.FileName + char(c);
+ until (c = 0) or (c = Z_EOF);
+ end;
+ if (flg and GZF_COMMENT) <> 0 then begin // extract Comment
+ repeat
+ c := gz_getbyte;
+ if (c <> 0) and (c <> Z_EOF) then gzHdr.Comment := gzHdr.Comment + char(c);
+ until (c = 0) or (c = Z_EOF);
+ end;
+ if (flg and GZF_HEAD_CRC) <> 0 then begin // skip head crc
+ gz_getbyte;
+ gz_getbyte;
+ end;
+ finally
+ if fEOF then Result := Z_DATA_ERROR
+ else Result := Z_OK;
+ end;
+end;
+
+function gZipDecompressStreamBody(inStream, outStream: PStream): Integer;
+var
+ iBuffer,
+ oBuffer : PChar; //Array [0..gzBufferSize-1] of Char;
+ fCrc : Cardinal;
+ zStream : TZStreamRec;
+ rSize,
+ wSize : LongInt;
+ startCRC : PChar;
+ fileCRC,
+ fileSize : Cardinal;
+ fEOF : Boolean;
+
+ function gz_getbyte: Integer;
+ begin
+ // if (eof) then result:=-1;
+ if (zStream.avail_in = 0) then begin
+ zStream.avail_in := inStream.Read(iBuffer^, gzBufferSize);
+ if (zStream.avail_in = 0) then begin
+ Result := Z_EOF;
+ fEOF := True;
+ exit;
+ end
+ else zStream.next_in := PChar(iBuffer);
+ end;
+ Dec(zStream.avail_in);
+ Result := Byte(zStream.next_in[0]);
+ Inc(zStream.next_in);
+ end;
+
+ function gz_getLong: Cardinal;
+ var
+ c : Integer;
+ begin
+ c := gz_getbyte;
+ c := c + gz_getbyte shl 8;
+ c := c + gz_getbyte shl 16;
+ c := c + gz_getbyte shl 24;
+ Result := Cardinal(c);
+ end;
+begin
+ iBuffer := nil;
+ oBuffer := nil;
+ Result := Z_MEM_ERROR;
+ try
+ GetMem(iBuffer, gzBufferSize);
+ GetMem(oBuffer, gzBufferSize);
+ fEOF := False;
+ {Check the gzip header of a gz_stream opened for reading.
+ Set the stream mode to transparent if the gzip magic header is not present.}
+
+ FillChar(zStream, SizeOf(zStream), 0);
+ zStream.next_in := pChar(iBuffer);
+ fCRC := 0;
+ { windowBits is passed < 0 to tell that there is no zlib header }
+{$IFDEF USE_EXCEPTIONS}
+ ZDecompressCheck(InflateInit2(zStream, -MAX_WBITS));
+{$ELSE}
+ Result := InflateInit2(zStream, -MAX_WBITS);
+ if Result < 0 then Exit;
+{$ENDIF}
+ while not fEOF do begin
+ // gzread()
+ // DoProgressEvent;
+ startCRC := PChar(oBuffer);
+ zStream.next_out := PChar(oBuffer);
+ zStream.avail_out := gzBufferSize;
+// rSize := 0;
+ Result := Z_OK;
+ while zStream.avail_out <> 0 do begin
+ // not transparent
+ if (zStream.avail_in = 0) and (not fEOF) then begin
+ zStream.avail_in := inStream.Read(iBuffer^, gzBufferSize);
+ if (zStream.avail_in = 0) then fEOF := True;
+ zStream.next_in := PChar(iBuffer);
+ end;
+ Result := inflate(zStream, Z_NO_FLUSH);
+ if (Result = Z_STREAM_END) then begin
+ { Check CRC and original size }
+ fCrc := crc32(fCrc, PChar(StartCRC), (zStream.next_out - startCRC));
+ startCRC := zStream.next_out;
+
+ fileCRC := gz_getLong;
+ fileSize := gz_getLong;
+ if (fCrc <> fileCRC) then
+{$IFDEF USE_EXCEPTIONS}
+ ZDecompressCheck(Z_CRC_ERROR)
+{$ELSE}
+ Result := Z_CRC_ERROR
+{$ENDIF}
+ else
+ if (Cardinal(zStream.total_out) <> fileSize) then
+{$IFDEF USE_EXCEPTIONS}
+ ZDecompressCheck(Z_SIZE_ERROR)
+{$ELSE}
+ Result := Z_SIZE_ERROR
+{$ENDIF}
+ else begin
+ if zStream.avail_in > 0 then inStream.Seek(-zStream.avail_in, spCurrent);
+ fEOF := True;
+ end;
+ end;
+ if (Result <> Z_OK) or (fEOF) then break;
+ end; // while zStream.avail_out<>0
+ // end of gzread()
+
+{$IFDEF USE_EXCEPTIONS}
+ ZDecompressCheck(Result);
+{$ELSE}
+ if Result < 0 then Exit;
+{$ENDIF}
+ fCrc := crc32(fCrc, PChar(oBuffer), (zStream.next_out - startCRC));
+ rSize := gzBufferSize - zStream.avail_out;
+
+{$IFDEF USE_EXCEPTIONS}
+ if rSize < 0 then ZDecompressCheck(rSize);
+{$ELSE}
+ if rSize <= 0 then break;
+{$ENDIF}
+ wSize := outStream.Write(oBuffer^, rSize);
+{$IFDEF USE_EXCEPTIONS}
+ if (rSize <> wSize) then ZDecompressCheck(Z_WRITE_ERROR);
+{$ELSE}
+ if (rSize <> wSize) then begin
+ Result := Z_WRITE_ERROR;
+ Exit;
+ end;
+{$ENDIF}
+ end;
+ if Result = Z_STREAM_END then Result := Z_OK;
+ finally
+ inflateEnd(zStream);
+ if Assigned(iBuffer) then FreeMem(iBuffer);
+ if Assigned(oBuffer) then FreeMem(oBuffer);
+ end;
+end;
+
+function gZipDecompressStream(inStream, outStream: PStream; var gzHdr: TgzipHeader): Integer;
+begin
+ Result := gZipDecompressStreamHeader(inStream, gzHdr);
+ if (Result >= 0) then
+ Result := gZipDecompressStreamBody(inStream, outStream);
+end;
+
+function gZipDecompressString(const S: String): String;
+var
+ Rslt: Integer;
+ gzHdr: TgzipHeader;
+ inStream: PStream;
+ outStream: PStream;
+begin
+ Result := '';
+ inStream := NewExMemoryStream(@S[1], Length(S));
+ Rslt := gZipDecompressStreamHeader(inStream, gzHdr);
+ if (Rslt >= 0) then begin
+ outStream := NewMemoryStream;
+ Rslt := gZipDecompressStreamBody(inStream, outStream);
+ if (Rslt >= 0) then begin
+ outStream.Position := 0;
+ Result := outStream.ReadStrLen(outStream.Size);
+ end;
+ outStream.Free;
+ end;
+ inStream.Free;
+end;
+
+{****************************************************************************}
+{** BZip implementation *****************************************************}
+{****************************************************************************}
+{$IFDEF USE_EXCEPTIONS}
+
+function CCheck(code: Integer): Integer;
+begin
+ Result := code;
+ if code < 0 then
+ raise Exception.CreateFMT(e_Convert, 'Compression Error %d - %s', [code, BZ_Error_Msg[-code]]);
+end;
+
+function DCheck(code: Integer): Integer;
+begin
+ Result := code;
+ if code < 0 then
+ raise Exception.CreateFMT(e_Convert, 'Decompression Error %d - %s', [code, BZ_Error_Msg[-code]]);
+end;
+{$ENDIF}
+
+function BZCompressBuf(const InBuf: Pointer; InBytes: Integer; out OutBuf: Pointer; out OutBytes: Integer): Integer;
+var
+ strm : TBZStreamRec;
+ P : Pointer;
+begin
+ FillChar(strm, sizeof(strm), 0);
+ strm.bzalloc := bzip2AllocMem;
+ strm.bzfree := bzip2FreeMem;
+ OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
+ GetMem(OutBuf, OutBytes);
+ Result := BZ_OK;
+ try
+ strm.next_in := InBuf;
+ strm.avail_in := InBytes;
+ strm.next_out := OutBuf;
+ strm.avail_out := OutBytes;
+{$IFDEF USE_EXCEPTIONS}
+ CCheck(BZ2_bzCompressInit(strm, 9, 0, 0));
+{$ELSE}
+ Result := BZ2_bzCompressInit(strm, 9, 0, 0);
+ if Result < 0 then Exit;
+{$ENDIF}
+ try
+{$IFDEF USE_EXCEPTIONS}
+ Result := CCheck(BZ2_bzCompress(strm, BZ_FINISH));
+{$ELSE}
+ Result := BZ2_bzCompress(strm, BZ_FINISH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ while Result <> BZ_STREAM_END 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;
+{$IFDEF USE_EXCEPTIONS}
+ Result := CCheck(BZ2_bzCompress(strm, BZ_FINISH));
+{$ELSE}
+ Result := BZ2_bzCompress(strm, BZ_FINISH);
+ if Result < 0 then Exit;
+{$ENDIF}
+ end;
+ finally
+{$IFDEF USE_EXCEPTIONS}
+ CCheck(BZ2_bzCompressEnd(strm));
+{$ELSE}
+ BZ2_bzCompressEnd(strm);
+{$ENDIF}
+ end;
+ ReallocMem(OutBuf, strm.total_out_lo32);
+ OutBytes := strm.total_out_lo32;
+{$IFDEF USE_EXCEPTIONS}
+ except
+ FreeMem(outBuf);
+ raise;
+{$ELSE}
+ finally
+ if Result < 0 then FreeMem(outBuf);
+{$ENDIF}
+ end;
+end;
+
+function BZDecompressBuf(const InBuf: Pointer; InBytes: Integer; OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer): Integer;
+var
+ strm : TBZStreamRec;
+ P : Pointer;
+ BufInc : Integer;
+begin
+ FillChar(strm, sizeof(strm), 0);
+ strm.bzalloc := bzip2AllocMem;
+ strm.bzfree := bzip2FreeMem;
+ BufInc := (InBytes + 255) and not 255;
+ Result := BZ_OK;
+ 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;
+{$IFDEF USE_EXCEPTIONS}
+ DCheck(BZ2_bzDecompressInit(strm, 0, 0));
+{$ELSE}
+ Result := BZ2_bzDecompressInit(strm, 0, 0);
+ if Result < 0 then Exit;
+{$ENDIF}
+ try
+{$IFDEF USE_EXCEPTIONS}
+ Result := DCheck(BZ2_bzDecompress(strm));
+{$ELSE}
+ Result := BZ2_bzDecompress(strm);
+ if Result < 0 then Exit;
+{$ENDIF}
+ while Result <> BZ_STREAM_END 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;
+{$IFDEF USE_EXCEPTIONS}
+ Result := DCheck(BZ2_bzDecompress(strm));
+{$ELSE}
+ Result := BZ2_bzDecompress(strm);
+ if Result < 0 then Exit;
+{$ENDIF}
+ end;
+ finally
+{$IFDEF USE_EXCEPTIONS}
+ DCheck(BZ2_bzDecompressEnd(strm));
+{$ELSE}
+ BZ2_bzDecompressEnd(strm);
+{$ENDIF}
+ end;
+ ReallocMem(OutBuf, strm.total_out_lo32);
+ OutBytes := strm.total_out_lo32;
+ except
+ FreeMem(OutBuf);
+ raise
+ end;
+end;
+
+function BZCompressStream(inStream, outStream: PStream; BlockSize100k: TBlockSize100k = 5): Integer;
+var
+ FBZRec : TBZStreamRec;
+ iBuffer,
+ oBuffer : PChar;
+ wSize,
+ rSize : Integer;
+begin
+ Result := BZ_MEM_ERROR;
+ iBuffer := nil;
+ oBuffer := nil;
+ FillChar(FBZRec, SizeOf(FBZRec), 0);
+ // FBZRec.bzalloc := bzip2AllocMem;
+ // FBZRec.bzfree := bzip2FreeMem;
+ try
+ GetMem(iBuffer, bzBufferSize);
+ GetMem(oBuffer, bzBufferSize);
+{$IFDEF USE_EXCEPTIONS}
+ CCheck(BZ2_bzCompressInit(FBZRec, BlockSize100k, 0, 0));
+{$ELSE}
+ Result := BZ2_bzCompressInit(FBZRec, BlockSize100k, 0, 0);
+ if Result < 0 then Exit;
+{$ENDIF}
+ FBZRec.next_out := PChar(oBuffer);
+ FBZRec.avail_out := bzBufferSize;
+ rSize := inStream.Read(iBuffer^, bzBufferSize);
+ repeat
+ //DoProgressEvent;
+ FBZRec.next_in := PChar(iBuffer);
+ FBZRec.avail_in := rSize;
+ while (FBZRec.avail_in > 0) do begin
+ if (FBZRec.avail_out = 0) then begin
+ wSize := outStream.Write(oBuffer^, bzBufferSize);
+ if (wSize <> bzBufferSize) then begin
+{$IFDEF USE_EXCEPTIONS}
+ CCheck(BZ_IO_ERROR);
+{$ELSE}
+ Result := BZ_IO_ERROR;
+ Exit;
+{$ENDIF}
+ end;
+ FBZRec.next_out := PChar(oBuffer);
+ FBZRec.avail_out := bzBufferSize;
+ end;
+{$IFDEF USE_EXCEPTIONS}
+ CCheck(BZ2_bzCompress(FBZRec, BZ_RUN));
+{$ELSE}
+ Result := BZ2_bzCompress(FBZRec, BZ_RUN);
+ if Result < 0 then Exit;
+{$ENDIF}
+ end; // while
+ rSize := inStream.Read(iBuffer^, bzBufferSize);
+ until rSize = 0;
+ { flush buffers }
+ FBZRec.avail_in := 0; { should be zero already anyway }
+ repeat
+{$IFDEF USE_EXCEPTIONS}
+ Result := CCheck(BZ2_bzCompress(FBZRec, BZ_FINISH));
+{$ELSE}
+ Result := BZ2_bzCompress(FBZRec, BZ_FINISH);
+ if Result < 0 then Break;
+{$ENDIF}
+ rSize := bzBufferSize - FBZRec.avail_out;
+ wSize := outStream.Write(oBuffer^, rSize);
+{$IFDEF USE_EXCEPTIONS}
+ if (wSize <> rSize) then CCheck(BZ_IO_ERROR);
+{$ELSE}
+ if (wSize <> rSize) then begin
+ Result := BZ_IO_ERROR;
+ break;
+ end;
+{$ENDIF}
+ FBZRec.next_out := PChar(oBuffer);
+ FBZRec.avail_out := bzBufferSize;
+ until Result = BZ_STREAM_END;
+ finally
+ if Result = BZ_STREAM_END then Result := BZ_OK;
+ BZ2_bzCompressEnd(FBZRec);
+ if Assigned(iBuffer) then FreeMem(iBuffer);
+ if Assigned(oBuffer) then FreeMem(oBuffer);
+ end;
+
+end;
+
+function BZDecompressStream(inStream, outStream: PStream): Integer;
+var
+ FBZRec : TBZStreamRec;
+ iBuffer,
+ oBuffer : PChar;
+ wSize,
+ rSize : Integer;
+begin
+ Result := BZ_MEM_ERROR;
+ iBuffer := nil;
+ oBuffer := nil;
+ FillChar(FBZRec, SizeOf(FBZRec), 0);
+ try
+ GetMem(iBuffer, bzBufferSize);
+ GetMem(oBuffer, bzBufferSize);
+{$IFDEF USE_EXCEPTIONS}
+ DCheck(BZ2_bzDecompressInit(FBZRec, 0, 0));
+{$ELSE}
+ Result := BZ2_bzDecompressInit(FBZRec, 0, 0);
+ if Result < 0 then Exit;
+{$ENDIF}
+ rSize := inStream.Read(iBuffer^, bzBufferSize);
+ FBZRec.next_in := PChar(iBuffer);
+ FBZRec.avail_in := rSize;
+ repeat
+ FBZRec.next_out := PChar(oBuffer);
+ FBZRec.avail_out := bzBufferSize;
+ Result := 0;
+ while (FBZRec.avail_out > 0) and (Result <> BZ_STREAM_END) do begin
+{$IFDEF USE_EXCEPTIONS}
+ Result := CCheck(BZ2_bzDecompress(FBZRec));
+{$ELSE}
+ Result := BZ2_bzDecompress(FBZRec);
+ if Result < 0 then Break;
+{$ENDIF}
+ if FBZRec.avail_in = 0 then begin
+ rSize := inStream.Read(iBuffer^, bzBufferSize);
+ FBZRec.next_in := PChar(iBuffer);
+ FBZRec.avail_in := rSize;
+ end;
+ end;
+ FBZRec.avail_out := bzBufferSize - FBZRec.avail_out;
+ wSize := outStream.Write(oBuffer^, FBZRec.avail_out);
+{$IFDEF USE_EXCEPTIONS}
+ if FBZRec.avail_out <> wSize then CCheck(BZ_IO_ERROR);
+{$ELSE}
+ if FBZRec.avail_out <> wSize then Result := BZ_IO_ERROR;
+{$ENDIF}
+ until (rSize = 0) or (Result < 0);
+ finally
+ if Result = BZ_STREAM_END then Result := BZ_OK;
+ BZ2_bzDecompressEnd(FBZRec);
+ if Assigned(iBuffer) then FreeMem(iBuffer);
+ if Assigned(oBuffer) then FreeMem(oBuffer);
+ end;
+end;
+
+end.
|