asphyrezlib.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:54k
源码类别:

2D图形编程

开发平台:

Delphi

  1. {*****************************************************************************
  2. *  ZLibEx.pas                                                                *
  3. *                                                                            *
  4. *  copyright (c) 2000-2006 base2 technologies                                *
  5. *  copyright (c) 1995-2002 Borland Software Corporation                      *
  6. *                                                                            *
  7. *  NOTICE:  This file includes minor modifications made by Yuriy Kotsarenko  *
  8. *  in order to make this unit compatible with Asphyre package. This file is  *
  9. *  distributed with the permission of Brent Sherwood, Base2 Technologies.    *
  10. *                                                                            *
  11. *  revision history                                                          *
  12. *    2006.10.07  fixed EZLibError constructor for c++ builder compatibility  *
  13. *    2006.08.10  added ZDecompressStrG (simple gzip format)                  *
  14. *    2006.06.02  added DateTimeToUnix for delphi 5-                          *
  15. *    2006.03.28  moved Z_DEFLATED to interface section                       *
  16. *                added custom compression levels zcLevel1 thru zcLevel9      *
  17. *    2006.03.27  added ZCompressStreamWeb                                    *
  18. *                added ZCompressStreamG (simple gzip format)                 *
  19. *    2006.03.24  added ZCompressStrG (simple gzip format)                    *
  20. *                added ZAdler32 and ZCrc32                                   *
  21. *    2005.11.29  changed FStreamPos to Int64 for delphi 6+                   *
  22. *    2005.07.25  updated to zlib version 1.2.3                               *
  23. *    2005.03.04  modified ZInternalCompressStream loops                      *
  24. *                modified ZInternalDecompressStream loops                    *
  25. *    2005.02.07  fixed ZInternalCompressStream loop conditions               *
  26. *                fixed ZInternalDecompressStream loop conditions             *
  27. *    2005.01.11  updated to zlib version 1.2.2                               *
  28. *                added ZCompressStrWeb                                       *
  29. *    2004.01.06  updated to zlib version 1.2.1                               *
  30. *    2003.04.14  added ZCompress2 and ZDecompress2                           *
  31. *                added ZCompressStr2 and ZDecompressStr2                     *
  32. *                added ZCompressStream2 and ZDecompressStream2               *
  33. *                added overloaded T*Stream constructors to support           *
  34. *                  InflateInit2 and DeflateInit2                             *
  35. *                fixed ZDecompressStream to use ZDecompressCheck instead of  *
  36. *                  ZCompressCheck                                            *
  37. *    2002.03.15  updated to zlib version 1.1.4                               *
  38. *    2001.11.27  enhanced TZDecompressionStream.Read to adjust source        *
  39. *                  stream position upon end of compression data              *
  40. *                fixed endless loop in TZDecompressionStream.Read when       *
  41. *                  destination count was greater than uncompressed data      *
  42. *    2001.10.26  renamed unit to integrate "nicely" with delphi 6            *
  43. *    2000.11.24  added soFromEnd condition to TZDecompressionStream.Seek     *
  44. *                added ZCompressStream and ZDecompressStream                 *
  45. *    2000.06.13  optimized, fixed, rewrote, and enhanced the zlib.pas unit   *
  46. *                  included on the delphi cd (zlib version 1.1.3)            *
  47. *                                                                            *
  48. *  acknowledgements                                                          *
  49. *    2001.10.26  erik turner                                                 *
  50. *      Z*Stream routines                                                     *
  51. *                                                                            *
  52. *    2001.11.27  david bennion                                               *
  53. *      finding the nastly little endless loop quirk with the                 *
  54. *        TZDecompressionStream.Read method                                   *
  55. *                                                                            *
  56. *    2002.03.15  burak kalayci                                               *
  57. *      informing me about the zlib 1.1.4 update and the 1.2.1 update         *
  58. *                                                                            *
  59. *    2005.01.11  vicente s醤chez-alarcos                                     *
  60. *      informing me about the zlib 1.2.2 update                              *
  61. *                                                                            *
  62. *    2005.02.07  luigi sandon                                                *
  63. *      pointing out the missing loop condition (Z_STREAM_END) in             *
  64. *        ZInternalCompressStream and ZInternalDecompressStream               *
  65. *                                                                            *
  66. *    2005.03.04  ferry van genderen                                          *
  67. *      assiting me fine tune and beta test ZInternalCompressStream and       *
  68. *        ZInternalDecompressStream                                           *
  69. *                                                                            *
  70. *    2005.07.25  mathijs van veluw                                           *
  71. *      informing me about the zlib 1.2.3 update                              *
  72. *                                                                            *
  73. *    2005.11.28  j. rathlev                                                  *
  74. *      pointing out the FStreamPos and TStream.Position type inconsitency    *
  75. *                                                                            *
  76. *    2006.03.24  ralf wenske                                                 *
  77. *      prototyping and assisting with ZCompressStrG and ZCompressStreamG     *
  78. *                                                                            *
  79. *    2006.06.02  roman krupicka                                              *
  80. *      pointing out the DateUtils unit and the DateTimeToUnix function       *
  81. *        wasn't available prior to Delphi 6                                  *
  82. *                                                                            *
  83. *    2006.10.07  anders johansen                                             *
  84. *      pointing out the ELibError constructor incompatibility with c++       *
  85. *        builder                                                             *
  86. *****************************************************************************}
  87. unit AsphyreZLib;
  88. interface
  89. {$I asphyrezlib.inc}
  90. uses
  91.   Sysutils, Classes {$IFDEF Version6Plus}, DateUtils {$ENDIF};
  92. const
  93.   {** version ids ***********************************************************}
  94.   ZLIB_VERSION   = '1.2.3';
  95.   ZLIB_VERNUM    = $1230;
  96.   {** compression methods ***************************************************}
  97.   Z_DEFLATED = 8;
  98. type
  99.   TZAlloc = function (opaque: Pointer; items, size: Integer): Pointer;
  100.   TZFree  = procedure (opaque, block: Pointer);
  101.   TZCompressionLevel = (
  102.     zcNone,
  103.     zcFastest,
  104.     zcDefault,
  105.     zcMax,
  106.     zcLevel1,
  107.     zcLevel2,
  108.     zcLevel3,
  109.     zcLevel4,
  110.     zcLevel5,
  111.     zcLevel6,
  112.     zcLevel7,
  113.     zcLevel8,
  114.     zcLevel9
  115.   );
  116.   TZStrategy = (
  117.     zsDefault,
  118.     zsFiltered,
  119.     zsHuffman,
  120.     zsRLE,
  121.     zsFixed
  122.   );
  123.   {** TZStreamRec ***********************************************************}
  124.   TZStreamRec = packed record
  125.     next_in  : PChar;     // next input byte
  126.     avail_in : Longint;   // number of bytes available at next_in
  127.     total_in : Longint;   // total nb of input bytes read so far
  128.     next_out : PChar;     // next output byte should be put here
  129.     avail_out: Longint;   // remaining free space at next_out
  130.     total_out: Longint;   // total nb of bytes output so far
  131.     msg      : PChar;     // last error message, NULL if no error
  132.     state    : Pointer;   // not visible by applications
  133.     zalloc   : TZAlloc;   // used to allocate the internal state
  134.     zfree    : TZFree;    // used to free the internal state
  135.     opaque   : Pointer;   // private data object passed to zalloc and zfree
  136.     data_type: Integer;   // best guess about the data type: ascii or binary
  137.     adler    : Longint;   // adler32 value of the uncompressed data
  138.     reserved : Longint;   // reserved for future use
  139.   end;
  140.   {** TCustomZStream ********************************************************}
  141.   TCustomZStream = class(TStream)
  142.   private
  143.     FStream    : TStream;
  144.     FStreamPos : {$ifdef Version6Plus} Int64 {$else} Longint {$endif};
  145.     FOnProgress: TNotifyEvent;
  146.     FZStream   : TZStreamRec;
  147.     FBuffer    : Array [Word] of Char;
  148.   protected
  149.     constructor Create(stream: TStream);
  150.     procedure DoProgress; dynamic;
  151.     property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
  152.   end;
  153.   {** TZCompressionStream ***************************************************}
  154.   TZCompressionStream = class(TCustomZStream)
  155.   private
  156.     function GetCompressionRate: Single;
  157.   public
  158.     constructor Create(dest: TStream;
  159.       compressionLevel: TZCompressionLevel = zcDefault); overload;
  160.     constructor Create(dest: TStream; compressionLevel: TZCompressionLevel;
  161.       windowBits, memLevel: Integer; strategy: TZStrategy); overload;
  162.     destructor  Destroy; override;
  163.     function  Read(var buffer; count: Longint): Longint; override;
  164.     function  Write(const buffer; count: Longint): Longint; override;
  165.     function  Seek(offset: Longint; origin: Word): Longint; override;
  166.     property CompressionRate: Single read GetCompressionRate;
  167.     property OnProgress;
  168.   end;
  169.   {** TZDecompressionStream *************************************************}
  170.   TZDecompressionStream = class(TCustomZStream)
  171.   public
  172.     constructor Create(source: TStream); overload;
  173.     constructor Create(source: TStream; windowBits: Integer); overload;
  174.     destructor  Destroy; override;
  175.     function  Read(var buffer; count: Longint): Longint; override;
  176.     function  Write(const buffer; count: Longint): Longint; override;
  177.     function  Seek(offset: Longint; origin: Word): Longint; override;
  178.     property OnProgress;
  179.   end;
  180. {** zlib public routines ****************************************************}
  181. {*****************************************************************************
  182. *  ZCompress                                                                 *
  183. *                                                                            *
  184. *  pre-conditions                                                            *
  185. *    inBuffer  = pointer to uncompressed data                                *
  186. *    inSize    = size of inBuffer (bytes)                                    *
  187. *    outBuffer = pointer (unallocated)                                       *
  188. *    level     = compression level                                           *
  189. *                                                                            *
  190. *  post-conditions                                                           *
  191. *    outBuffer = pointer to compressed data (allocated)                      *
  192. *    outSize   = size of outBuffer (bytes)                                   *
  193. *****************************************************************************}
  194. procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
  195.   out outBuffer: Pointer; out outSize: Integer;
  196.   level: TZCompressionLevel = zcDefault);
  197. {*****************************************************************************
  198. *  ZCompress2                                                                *
  199. *                                                                            *
  200. *  pre-conditions                                                            *
  201. *    inBuffer   = pointer to uncompressed data                               *
  202. *    inSize     = size of inBuffer (bytes)                                   *
  203. *    outBuffer  = pointer (unallocated)                                      *
  204. *    level      = compression level                                          *
  205. *    method     = compression method                                         *
  206. *    windowBits = window bits                                                *
  207. *    memLevel   = memory level                                               *
  208. *    strategy   = compression strategy                                       *
  209. *                                                                            *
  210. *  post-conditions                                                           *
  211. *    outBuffer = pointer to compressed data (allocated)                      *
  212. *    outSize   = size of outBuffer (bytes)                                   *
  213. *****************************************************************************}
  214. procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
  215.   out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;
  216.   windowBits, memLevel: Integer; strategy: TZStrategy);
  217. {*****************************************************************************
  218. *  ZDecompress                                                               *
  219. *                                                                            *
  220. *  pre-conditions                                                            *
  221. *    inBuffer    = pointer to compressed data                                *
  222. *    inSize      = size of inBuffer (bytes)                                  *
  223. *    outBuffer   = pointer (unallocated)                                     *
  224. *    outEstimate = estimated size of uncompressed data (bytes)               *
  225. *                                                                            *
  226. *  post-conditions                                                           *
  227. *    outBuffer = pointer to decompressed data (allocated)                    *
  228. *    outSize   = size of outBuffer (bytes)                                   *
  229. *****************************************************************************}
  230. procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
  231.  out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer = 0);
  232. {*****************************************************************************
  233. *  ZDecompress2                                                              *
  234. *                                                                            *
  235. *  pre-conditions                                                            *
  236. *    inBuffer    = pointer to compressed data                                *
  237. *    inSize      = size of inBuffer (bytes)                                  *
  238. *    outBuffer   = pointer (unallocated)                                     *
  239. *    windowBits  = window bits                                               *
  240. *    outEstimate = estimated size of uncompressed data (bytes)               *
  241. *                                                                            *
  242. *  post-conditions                                                           *
  243. *    outBuffer = pointer to decompressed data (allocated)                    *
  244. *    outSize   = size of outBuffer (bytes)                                   *
  245. *****************************************************************************}
  246. procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
  247.  out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
  248.  outEstimate: Integer = 0);
  249. {** string routines *********************************************************}
  250. {*****************************************************************************
  251. *  ZCompressStr                                                              *
  252. *                                                                            *
  253. *  pre-conditions                                                            *
  254. *    s     = uncompressed data string                                        *
  255. *    level = compression level                                               *
  256. *                                                                            *
  257. *  return                                                                    *
  258. *    compressed data string                                                  *
  259. *****************************************************************************}
  260. function ZCompressStr(const s: String;
  261.   level: TZCompressionLevel = zcDefault): String;
  262. {*****************************************************************************
  263. *  ZCompressStrEx                                                            *
  264. *                                                                            *
  265. *  pre-conditions                                                            *
  266. *    s     = uncompressed data string                                        *
  267. *    level = compression level                                               *
  268. *                                                                            *
  269. *  return                                                                    *
  270. *    compressed data string with 4 byte (integer) header indicating          *
  271. *    original uncompressed data length                                       *
  272. *****************************************************************************}
  273. function ZCompressStrEx(const s: String;
  274.   level: TZCompressionLevel = zcDefault): String;
  275. {*****************************************************************************
  276. *  ZCompressStr2                                                             *
  277. *                                                                            *
  278. *  pre-conditions                                                            *
  279. *    s          = uncompressed data string                                   *
  280. *    level      = compression level                                          *
  281. *    windowBits = window bits                                                *
  282. *    memLevel   = memory level                                               *
  283. *    strategy   = compression strategy                                       *
  284. *                                                                            *
  285. *  return                                                                    *
  286. *    compressed data string                                                  *
  287. *****************************************************************************}
  288. function ZCompressStr2(const s: String; level: TZCompressionLevel;
  289.   windowBits, memLevel: Integer; strategy: TZStrategy): String;
  290. function ZCompressStrWeb(const s: String): String;
  291. {*****************************************************************************
  292. *  ZCompressStrG                                                             *
  293. *                                                                            *
  294. *  pre-conditions                                                            *
  295. *    s          = uncompressed data string                                   *
  296. *    fileName   = filename                                                   *
  297. *    comment    = comment                                                    *
  298. *    dateTime   = date/time                                                  *
  299. *                                                                            *
  300. *  return                                                                    *
  301. *    compressed data string in gzip format                                   *
  302. *****************************************************************************}
  303. function ZCompressStrG(const s: String; const fileName, comment: String;
  304.   dateTime: TDateTime): String;
  305. {*****************************************************************************
  306. *  ZDecompressStr                                                            *
  307. *                                                                            *
  308. *  pre-conditions                                                            *
  309. *    s = compressed data string                                              *
  310. *                                                                            *
  311. *  return                                                                    *
  312. *    uncompressed data string                                                *
  313. *****************************************************************************}
  314. function ZDecompressStr(const s: String): String;
  315. {*****************************************************************************
  316. *  ZDecompressStrEx                                                          *
  317. *                                                                            *
  318. *  pre-conditions                                                            *
  319. *    s = compressed data string with 4 byte (integer) header indicating      *
  320. *        original uncompressed data length                                   *
  321. *                                                                            *
  322. *  return                                                                    *
  323. *    uncompressed data string                                                *
  324. *****************************************************************************}
  325. function ZDecompressStrEx(const s: String): String;
  326. {*****************************************************************************
  327. *  ZDecompressStr2                                                           *
  328. *                                                                            *
  329. *  pre-conditions                                                            *
  330. *    s          = compressed data string                                     *
  331. *    windowBits = window bits                                                *
  332. *                                                                            *
  333. *  return                                                                    *
  334. *    uncompressed data string                                                *
  335. *****************************************************************************}
  336. function ZDecompressStr2(const s: String; windowBits: Integer): String;
  337. {*****************************************************************************
  338. *  ZDecompressStrG                                                           *
  339. *                                                                            *
  340. *  pre-conditions                                                            *
  341. *    s = compressed data string in gzip format                               *
  342. *                                                                            *
  343. *  post-conditions                                                           *
  344. *    fileName   = filename                                                   *
  345. *    comment    = comment                                                    *
  346. *    dateTime   = date/time                                                  *
  347. *                                                                            *
  348. *  return                                                                    *
  349. *    uncompressed data string                                                *
  350. *****************************************************************************}
  351. function ZDecompressStrG(const s: String; var fileName, comment: String;
  352.   var dateTime: TDateTime): String; overload;
  353. function ZDecompressStrG(const s: String): String; overload;
  354. {** stream routines *********************************************************}
  355. procedure ZCompressStream(inStream, outStream: TStream;
  356.   level: TZCompressionLevel = zcDefault);
  357. procedure ZCompressStream2(inStream, outStream: TStream;
  358.   level: TZCompressionLevel; windowBits, memLevel: Integer;
  359.   strategy: TZStrategy);
  360. procedure ZCompressStreamWeb(inStream, outStream: TStream);
  361. procedure ZCompressStreamG(inStream, outStream: TStream; const fileName,
  362.   comment: String; dateTime: TDateTime);
  363. procedure ZDecompressStream(inStream, outStream: TStream);
  364. procedure ZDecompressStream2(inStream, outStream: TStream;
  365.   windowBits: Integer);
  366. {** checksum routines *******************************************************}
  367. function ZAdler32(adler: Longint; const buffer; size: Integer): Longint;
  368. function ZCrc32(crc: Longint; const buffer; size: Integer): Longint;
  369. {****************************************************************************}
  370. type
  371.   EZLibErrorClass = class of EZlibError;
  372.   EZLibError = class(Exception)
  373.   private
  374.     FErrorCode: Integer;
  375.   public
  376.     constructor Create(code: Integer; const dummy: String = ''); overload;
  377.     property ErrorCode: Integer read FErrorCode write FErrorCode;
  378.   end;
  379.   EZCompressionError = class(EZLibError);
  380.   EZDecompressionError = class(EZLibError);
  381. {****************************************************************************}
  382. { Changes by Lifepower (lifepower@mail333.com):
  383.   The following functions have been moved to public section to be used by
  384.   third party packages that need them, e.g. TPNGImage.                       }
  385. {****************************************************************************}
  386. function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
  387.   recsize: Integer): Integer;
  388.   external;
  389. function deflate(var strm: TZStreamRec; flush: Integer): Integer;
  390.   external;
  391. function deflateEnd(var strm: TZStreamRec): Integer;
  392.   external;
  393. function inflateInit_(var strm: TZStreamRec; version: PChar;
  394.   recsize: Integer): Integer;
  395.   external;
  396. function inflate(var strm: TZStreamRec; flush: Integer): Integer;
  397.   external;
  398. function inflateEnd(var strm: TZStreamRec): Integer;
  399.   external;
  400. implementation
  401. {** link zlib code **********************************************************}
  402. {$L objdeflate.obj}
  403. {$L objinflate.obj}
  404. {$L objinftrees.obj}
  405. {$L objinfback.obj}
  406. {$L objinffast.obj}
  407. {$L objtrees.obj}
  408. {$L objcompress.obj}
  409. {$L objadler32.obj}
  410. {$L objcrc32.obj}
  411. {*****************************************************************************
  412. *  note: do not reorder the above -- doing so will result in external        *
  413. *  functions being undefined                                                 *
  414. *****************************************************************************}
  415. {** gzip ********************************************************************}
  416. type
  417.   PGZHeader = ^TGZHeader;
  418.   TGZHeader = packed record
  419.     Id1       : Byte;
  420.     Id2       : Byte;
  421.     Method    : Byte;
  422.     Flags     : Byte;
  423.     Time      : Cardinal;
  424.     ExtraFlags: Byte;
  425.     OS        : Byte;
  426.   end;
  427.   PGZTrailer = ^TGZTrailer;
  428.   TGZTrailer = packed record
  429.     Crc : Cardinal;
  430.     Size: Cardinal;
  431.   end;
  432. const
  433.   GZ_ASCII_TEXT  = $01;
  434.   GZ_HEADER_CRC  = $02;
  435.   GZ_EXTRA_FIELD = $04;
  436.   GZ_FILENAME    = $08;
  437.   GZ_COMMENT     = $10;
  438.   GZ_RESERVED    = $E0;
  439.   GZ_EXTRA_DEFAULT = 0;
  440.   GZ_EXTRA_MAX     = 2;
  441.   GZ_EXTRA_FASTEST = 4;
  442. const
  443.   {** flush constants *******************************************************}
  444.   Z_NO_FLUSH      = 0;
  445.   Z_PARTIAL_FLUSH = 1;
  446.   Z_SYNC_FLUSH    = 2;
  447.   Z_FULL_FLUSH    = 3;
  448.   Z_FINISH        = 4;
  449.   Z_BLOCK         = 5;
  450.   {** return codes **********************************************************}
  451.   Z_OK            = 0;
  452.   Z_STREAM_END    = 1;
  453.   Z_NEED_DICT     = 2;
  454.   Z_ERRNO         = (-1);
  455.   Z_STREAM_ERROR  = (-2);
  456.   Z_DATA_ERROR    = (-3);
  457.   Z_MEM_ERROR     = (-4);
  458.   Z_BUF_ERROR     = (-5);
  459.   Z_VERSION_ERROR = (-6);
  460.   {** compression levels ****************************************************}
  461.   Z_NO_COMPRESSION       =   0;
  462.   Z_BEST_SPEED           =   1;
  463.   Z_BEST_COMPRESSION     =   9;
  464.   Z_DEFAULT_COMPRESSION  = (-1);
  465.   {** compression strategies ************************************************}
  466.   Z_FILTERED            = 1;
  467.   Z_HUFFMAN_ONLY        = 2;
  468.   Z_RLE                 = 3;
  469.   Z_FIXED               = 4;
  470.   Z_DEFAULT_STRATEGY    = 0;
  471.   {** data types ************************************************************}
  472.   Z_BINARY   = 0;
  473.   Z_ASCII    = 1;
  474.   Z_TEXT     = Z_ASCII;
  475.   Z_UNKNOWN  = 2;
  476.   {** return code messages **************************************************}
  477.   _z_errmsg: array[0..9] of PChar = (
  478.     'need dictionary',      // Z_NEED_DICT      (2)
  479.     'stream end',           // Z_STREAM_END     (1)
  480.     'ok',                   // Z_OK             (0)
  481.     'file error',           // Z_ERRNO          (-1)
  482.     'stream error',         // Z_STREAM_ERROR   (-2)
  483.     'data error',           // Z_DATA_ERROR     (-3)
  484.     'insufficient memory',  // Z_MEM_ERROR      (-4)
  485.     'buffer error',         // Z_BUF_ERROR      (-5)
  486.     'incompatible version', // Z_VERSION_ERROR  (-6)
  487.     ''
  488.   );
  489.   ZLevels: Array [TZCompressionLevel] of Shortint = (
  490.     Z_NO_COMPRESSION,       // zcNone
  491.     Z_BEST_SPEED,           // zcFastest
  492.     Z_DEFAULT_COMPRESSION,  // zcDefault
  493.     Z_BEST_COMPRESSION,     // zcMax
  494.     1,                      // zcLevel1
  495.     2,                      // zcLevel2
  496.     3,                      // zcLevel3
  497.     4,                      // zcLevel4
  498.     5,                      // zcLevel5
  499.     6,                      // zcLevel6
  500.     7,                      // zcLevel7
  501.     8,                      // zcLevel8
  502.     9                       // zcLevel9
  503.   );
  504.   ZStrategies: Array [TZStrategy] of Shortint = (
  505.     Z_DEFAULT_STRATEGY,     // zsDefault
  506.     Z_FILTERED,             // zsFiltered
  507.     Z_HUFFMAN_ONLY,         // zsHuffman
  508.     Z_RLE,                  // zsRLE
  509.     Z_FIXED                 // zsFixed
  510.   );
  511.   SZInvalid = 'Invalid ZStream operation!';
  512. {** deflate routines ********************************************************}
  513. { Changes by Lifepower (lifepower@mail333.com):
  514.   Some functions have been commented and moved to public section to be used
  515.   by third party packages that need them, e.g. TPNGImage.                    }
  516. {function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
  517.   recsize: Integer): Integer;
  518.   external;}
  519. function deflateInit2_(var strm: TZStreamRec; level, method, windowBits,
  520.   memLevel, strategy: Integer; version: PChar; recsize: Integer): Integer;
  521.   external;
  522. {function deflate(var strm: TZStreamRec; flush: Integer): Integer;
  523.   external;}
  524. {function deflateEnd(var strm: TZStreamRec): Integer;
  525.   external;}
  526. {** inflate routines ********************************************************}
  527. {function inflateInit_(var strm: TZStreamRec; version: PChar;
  528.   recsize: Integer): Integer;
  529.   external;}
  530. function inflateInit2_(var strm: TZStreamRec; windowBits: Integer;
  531.   version: PChar; recsize: Integer): Integer;
  532.   external;
  533. {function inflate(var strm: TZStreamRec; flush: Integer): Integer;
  534.   external;}
  535. {function inflateEnd(var strm: TZStreamRec): Integer;
  536.   external;}
  537. function inflateReset(var strm: TZStreamRec): Integer;
  538.   external;
  539. {** checksum routines *******************************************************}
  540. function adler32(adler: Longint; const buf; len: Integer): Longint;
  541.   external;
  542. function crc32(crc: Longint; const buf; len: Integer): Longint;
  543.   external;
  544. {** zlib function implementations *******************************************}
  545. function zcalloc(opaque: Pointer; items, size: Integer): Pointer;
  546. begin
  547.   GetMem(result,items * size);
  548. end;
  549. procedure zcfree(opaque, block: Pointer);
  550. begin
  551.   FreeMem(block);
  552. end;
  553. {** c function implementations **********************************************}
  554. procedure _memset(p: Pointer; b: Byte; count: Integer); cdecl;
  555. begin
  556.   FillChar(p^,count,b);
  557. end;
  558. procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
  559. begin
  560.   Move(source^,dest^,count);
  561. end;
  562. {** custom zlib routines ****************************************************}
  563. function DeflateInit(var stream: TZStreamRec; level: Integer): Integer;
  564. begin
  565.   result := deflateInit_(stream,level,ZLIB_VERSION,SizeOf(TZStreamRec));
  566. end;
  567. function DeflateInit2(var stream: TZStreamRec; level, method, windowBits,
  568.   memLevel, strategy: Integer): Integer;
  569. begin
  570.   result := deflateInit2_(stream,level,method,windowBits,memLevel,strategy,
  571.     ZLIB_VERSION,SizeOf(TZStreamRec));
  572. end;
  573. function InflateInit(var stream: TZStreamRec): Integer;
  574. begin
  575.   result := inflateInit_(stream,ZLIB_VERSION,SizeOf(TZStreamRec));
  576. end;
  577. function InflateInit2(var stream: TZStreamRec; windowBits: Integer): Integer;
  578. begin
  579.   result := inflateInit2_(stream,windowBits,ZLIB_VERSION,SizeOf(TZStreamRec));
  580. end;
  581. {** DateTimeToUnix **********************************************************}
  582. {$IFNDEF Version6Plus}
  583. { Days between TDateTime basis (12/31/1899) and Unix time_t basis (1/1/1970) }
  584. const
  585.   UnixDateDelta = 25569;
  586. function DateTimeToUnix(const AValue: TDateTime): Cardinal;
  587. begin
  588.   Result := Round((AValue - UnixDateDelta) * SecsPerDay);
  589. end;
  590. function UnixToDateTime(const AValue: Cardinal): TDateTime;
  591. begin
  592.   Result := AValue / SecsPerDay + UnixDateDelta;
  593. end;
  594. {$ENDIF}
  595. {****************************************************************************}
  596. function ZCompressCheck(code: Integer): Integer;
  597. begin
  598.   result := code;
  599.   if code < 0 then
  600.   begin
  601.     raise EZCompressionError.Create(code);
  602.   end;
  603. end;
  604. function ZDecompressCheck(code: Integer): Integer;
  605. begin
  606.   Result := code;
  607.   if code < 0 then
  608.   begin
  609.     raise EZDecompressionError.Create(code);
  610.   end;
  611. end;
  612. procedure ZInternalCompress(var zstream: TZStreamRec; const inBuffer: Pointer;
  613.   inSize: Integer; out outBuffer: Pointer; out outSize: Integer);
  614. const
  615.   delta = 256;
  616. begin
  617.   outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;
  618.   GetMem(outBuffer,outSize);
  619.   try
  620.     try
  621.       zstream.next_in := inBuffer;
  622.       zstream.avail_in := inSize;
  623.       zstream.next_out := outBuffer;
  624.       zstream.avail_out := outSize;
  625.       while ZCompressCheck(deflate(zstream,Z_FINISH)) <> Z_STREAM_END do
  626.       begin
  627.         Inc(outSize,delta);
  628.         ReallocMem(outBuffer,outSize);
  629.         zstream.next_out := PChar(Integer(outBuffer) + zstream.total_out);
  630.         zstream.avail_out := delta;
  631.       end;
  632.     finally
  633.       ZCompressCheck(deflateEnd(zstream));
  634.     end;
  635.     ReallocMem(outBuffer,zstream.total_out);
  636.     outSize := zstream.total_out;
  637.   except
  638.     FreeMem(outBuffer);
  639.     raise;
  640.   end;
  641. end;
  642. procedure ZInternalDecompress(zstream: TZStreamRec; const inBuffer: Pointer;
  643.   inSize: Integer; out outBuffer: Pointer; out outSize: Integer;
  644.   outEstimate: Integer);
  645. var
  646.   delta: Integer;
  647. begin
  648.   delta := (inSize + 255) and not 255;
  649.   if outEstimate = 0 then outSize := delta
  650.   else outSize := outEstimate;
  651.   GetMem(outBuffer,outSize);
  652.   try
  653.     try
  654.       zstream.next_in := inBuffer;
  655.       zstream.avail_in := inSize;
  656.       zstream.next_out := outBuffer;
  657.       zstream.avail_out := outSize;
  658.       while ZDecompressCheck(inflate(zstream,Z_NO_FLUSH)) <> Z_STREAM_END do
  659.       begin
  660.         Inc(outSize,delta);
  661.         ReallocMem(outBuffer,outSize);
  662.         zstream.next_out := PChar(Integer(outBuffer) + zstream.total_out);
  663.         zstream.avail_out := delta;
  664.       end;
  665.     finally
  666.       ZDecompressCheck(inflateEnd(zstream));
  667.     end;
  668.     ReallocMem(outBuffer,zstream.total_out);
  669.     outSize := zstream.total_out;
  670.   except
  671.     FreeMem(outBuffer);
  672.     raise;
  673.   end;
  674. end;
  675. procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
  676.   out outBuffer: Pointer; out outSize: Integer;
  677.   level: TZCompressionLevel);
  678. var
  679.   zstream: TZStreamRec;
  680. begin
  681.   FillChar(zstream,SizeOf(TZStreamRec),0);
  682.   ZCompressCheck(DeflateInit(zstream,ZLevels[level]));
  683.   ZInternalCompress(zstream,inBuffer,inSize,outBuffer,outSize);
  684. end;
  685. procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
  686.   out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;
  687.   windowBits, memLevel: Integer; strategy: TZStrategy);
  688. var
  689.   zstream: TZStreamRec;
  690. begin
  691.   FillChar(zstream,SizeOf(TZStreamRec),0);
  692.   ZCompressCheck(DeflateInit2(zstream,ZLevels[level],Z_DEFLATED,windowBits,
  693.     memLevel,ZStrategies[strategy]));
  694.   ZInternalCompress(zstream,inBuffer,inSize,outBuffer,outSize);
  695. end;
  696. procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
  697.   out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer);
  698. var
  699.   zstream: TZStreamRec;
  700. begin
  701.   FillChar(zstream,SizeOf(TZStreamRec),0);
  702.   ZDecompressCheck(InflateInit(zstream));
  703.   ZInternalDecompress(zstream,inBuffer,inSize,outBuffer,outSize,outEstimate);
  704. end;
  705. procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
  706.   out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
  707.   outEstimate: Integer);
  708. var
  709.   zstream: TZStreamRec;
  710. begin
  711.   FillChar(zstream,SizeOf(TZStreamRec),0);
  712.   ZDecompressCheck(InflateInit2(zstream,windowBits));
  713.   ZInternalDecompress(zstream,inBuffer,inSize,outBuffer,outSize,outEstimate);
  714. end;
  715. {** string routines *********************************************************}
  716. function ZCompressStr(const s: String; level: TZCompressionLevel): String;
  717. var
  718.   buffer: Pointer;
  719.   size  : Integer;
  720. begin
  721.   ZCompress(PChar(s),Length(s),buffer,size,level);
  722.   SetLength(result,size);
  723.   Move(buffer^,result[1],size);
  724.   FreeMem(buffer);
  725. end;
  726. function ZCompressStrEx(const s: String; level: TZCompressionLevel): String;
  727. var
  728.   buffer: Pointer;
  729.   size  : Integer;
  730. begin
  731.   ZCompress(PChar(s),Length(s),buffer,size,level);
  732.   SetLength(result,size + SizeOf(Integer));
  733.   Move(buffer^,result[5],size);
  734.   size := Length(s);
  735.   Move(size,result[1],SizeOf(Integer));
  736.   FreeMem(buffer);
  737. end;
  738. function ZCompressStr2(const s: String; level: TZCompressionLevel;
  739.   windowBits, memLevel: Integer; strategy: TZStrategy): String;
  740. var
  741.   buffer: Pointer;
  742.   size  : Integer;
  743. begin
  744.   ZCompress2(PChar(s),Length(s),buffer,size,level,windowBits,memLevel,
  745.     strategy);
  746.   SetLength(result,size);
  747.   Move(buffer^,result[1],size);
  748.   FreeMem(buffer);
  749. end;
  750. function ZCompressStrWeb(const s: String): String;
  751. begin
  752.   result := ZCompressStr2(s,zcFastest,-15,9,zsDefault);
  753. end;
  754. function ZCompressStrG(const s: String; const fileName, comment: String;
  755.   dateTime: TDateTime): String;
  756. var
  757.   header : PGZHeader;
  758.   trailer: PGZTrailer;
  759.   len    : Integer;
  760. begin
  761.   SetLength(result,SizeOf(TGZHeader));
  762.   header := PGZHeader(@result[1]);
  763.   FillChar(header^,SizeOf(TGZHeader),0);
  764.   header^.Id1 := $1F;
  765.   header^.Id2 := $8B;
  766.   header^.Method := Z_DEFLATED;
  767.   if dateTime <> 0 then header^.Time := DateTimeToUnix(dateTime);
  768.   header^.ExtraFlags := GZ_EXTRA_DEFAULT;
  769.   header^.OS := 0;
  770.   header^.Flags := 0;
  771.   if Length(fileName) > 0 then
  772.   begin
  773.     header^.Flags := header^.Flags or GZ_FILENAME;
  774.     result := result + fileName + #$00;
  775.   end;
  776.   if Length(comment) > 0 then
  777.   begin
  778.     header^.Flags := header^.Flags or GZ_COMMENT;
  779.     result := result + comment + #$00;
  780.   end;
  781.   result := result + ZCompressStr2(s,zcDefault,-15,9,zsDefault);
  782.   len := Length(result);
  783.   SetLength(result,len + SizeOf(TGZTrailer));
  784.   trailer := PGZTrailer(@result[len + 1]);
  785.   FillChar(trailer^,SizeOf(TGZTrailer),0);
  786.   trailer^.Crc := crc32(0,s[1],Length(s));
  787.   trailer^.Size := Length(s);
  788. end;
  789. function ZDecompressStr(const s: String): String;
  790. var
  791.   buffer: Pointer;
  792.   size  : Integer;
  793. begin
  794.   ZDecompress(PChar(s),Length(s),buffer,size);
  795.   SetLength(result,size);
  796.   Move(buffer^,result[1],size);
  797.   FreeMem(buffer);
  798. end;
  799. function ZDecompressStrEx(const s: String): String;
  800. var
  801.   buffer  : Pointer;
  802.   size    : Integer;
  803.   data    : String;
  804.   dataSize: Integer;
  805. begin
  806.   Move(s[1],size,SizeOf(Integer));
  807.   dataSize := Length(s) - SizeOf(Integer);
  808.   SetLength(data,dataSize);
  809.   Move(s[5],data[1],dataSize);
  810.   ZDecompress(PChar(data),dataSize,buffer,size,size);
  811.   SetLength(result,size);
  812.   Move(buffer^,result[1],size);
  813.   FreeMem(buffer);
  814. end;
  815. function ZDecompressStr2(const s: String; windowBits: Integer): String;
  816. var
  817.   buffer: Pointer;
  818.   size  : Integer;
  819. begin
  820.   ZDecompress2(PChar(s),Length(s),buffer,size,windowBits);
  821.   SetLength(result,size);
  822.   Move(buffer^,result[1],size);
  823.   FreeMem(buffer);
  824. end;
  825. function ZDecompressStrG(const s: String; var fileName, comment: String;
  826.   var dateTime: TDateTime): String;
  827. var
  828.   header  : PGZHeader;
  829.   trailer : PGZTrailer;
  830.   index   : Integer;
  831.   maxIndex: Integer;
  832.   endIndex: Integer;
  833.   size    : Integer;
  834. begin
  835.   result := '';
  836.   if Length(s) < SizeOf(TGZHeader) then
  837.   begin
  838.     raise EZDecompressionError.Create(Z_DATA_ERROR);
  839.   end;
  840.   header := PGZHeader(@s[1]);
  841.   if (header^.Id1 <> $1F)
  842.     or (header^.Id2 <> $8B)
  843.     or (header^.Method <> Z_DEFLATED)
  844.     or ((header^.Flags and GZ_RESERVED) <> 0) then
  845.   begin
  846.     raise EZDecompressionError.Create(Z_DATA_ERROR);
  847.   end;
  848.   if header^.Time <> 0 then dateTime := UnixToDateTime(header^.Time)
  849.   else dateTime := 0;
  850.   maxIndex := Length(s) - SizeOf(TGZTrailer);
  851.   index := SizeOf(TGZHeader) + 1;
  852.   if (header^.Flags and GZ_EXTRA_FIELD) <> 0 then
  853.   begin
  854.     if index <= (maxIndex - 1) then
  855.     begin
  856.       size := PWord(@s[index])^;
  857.       Inc(index,2);
  858.       if (size >= 0) and ((index + size) <= maxIndex) then Inc(index,size)
  859.       else index := maxIndex + 1;
  860.     end
  861.     else index := maxIndex + 1;
  862.   end;
  863.   if (header^.Flags and GZ_FILENAME) <> 0 then
  864.   begin
  865.     endIndex := index;
  866.     while (endIndex <= maxIndex) and (s[endIndex] <> #$00) do Inc(endIndex);
  867.     SetLength(fileName,endIndex - index);
  868.     Move(s[index],fileName[1],endIndex - index);
  869.     index := endIndex;
  870.     if index <= maxIndex then Inc(index);
  871.   end
  872.   else fileName := '';
  873.   if (header^.Flags and GZ_COMMENT) <> 0 then
  874.   begin
  875.     endIndex := index;
  876.     while (endIndex <= maxIndex) and (s[endIndex] <> #$00) do Inc(endIndex);
  877.     SetLength(comment,endIndex - index);
  878.     Move(s[index],comment[1],endIndex - index);
  879.     index := endIndex;
  880.     if index <= maxIndex then Inc(index);
  881.   end
  882.   else comment := '';
  883.   if (header^.Flags and GZ_HEADER_CRC) <> 0 then
  884.   begin
  885.     if index <= (maxIndex - 1) then
  886.     begin
  887.       // todo: validate header crc
  888.       Inc(index,2);
  889.     end
  890.     else index := maxIndex + 1; // force eof
  891.   end;
  892.   if index > maxIndex then
  893.   begin
  894.     raise EZDecompressionError.Create(Z_DATA_ERROR);
  895.   end;
  896.   size := maxIndex - index + 1;
  897.   result := ZDecompressStr2(Copy(s,index,size),-15);
  898.   Inc(index,size);
  899.   trailer := PGZTrailer(@s[index]);
  900.   if (trailer^.Crc <> Cardinal(crc32(0,result[1],Length(result))))
  901.     or (trailer^.Size <> Cardinal(Length(result))) then
  902.   begin
  903.     raise EZDecompressionError.Create(Z_DATA_ERROR);
  904.   end;
  905. end;
  906. function ZDecompressStrG(const s: String): String;
  907. var
  908.   fileName: String;
  909.   comment : String;
  910.   dateTime: TDateTime;
  911. begin
  912.   result := ZDecompressStrG(s,fileName,comment,dateTime);
  913. end;
  914. {** stream routines *********************************************************}
  915. procedure ZInternalCompressStream(zstream: TZStreamRec; inStream,
  916.   outStream: TStream);
  917. const
  918.   bufferSize = 32768;
  919. var
  920.   zresult  : Integer;
  921.   inBuffer : Array [0..bufferSize-1] of Char;
  922.   outBuffer: Array [0..bufferSize-1] of Char;
  923.   outSize  : Integer;
  924. begin
  925.   zresult := Z_STREAM_END;
  926.   zstream.avail_in := inStream.Read(inBuffer,bufferSize);
  927.   while zstream.avail_in > 0 do
  928.   begin
  929.     zstream.next_in := inBuffer;
  930.     repeat
  931.       zstream.next_out := outBuffer;
  932.       zstream.avail_out := bufferSize;
  933.       zresult := ZCompressCheck(deflate(zstream,Z_NO_FLUSH));
  934.       outSize := bufferSize - zstream.avail_out;
  935.       outStream.Write(outBuffer,outSize);
  936.     until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
  937.     zstream.avail_in := inStream.Read(inBuffer,bufferSize);
  938.   end;
  939.   while zresult <> Z_STREAM_END do
  940.   begin
  941.     zstream.next_out := outBuffer;
  942.     zstream.avail_out := bufferSize;
  943.     zresult := ZCompressCheck(deflate(zstream,Z_FINISH));
  944.     outSize := bufferSize - zstream.avail_out;
  945.     outStream.Write(outBuffer,outSize);
  946.   end;
  947.   ZCompressCheck(deflateEnd(zstream));
  948. end;
  949. procedure ZInternalDecompressStream(zstream: TZStreamRec; inStream,
  950.   outStream: TStream);
  951. const
  952.   bufferSize = 32768;
  953. var
  954.   zresult  : Integer;
  955.   inBuffer : Array [0..bufferSize-1] of Char;
  956.   outBuffer: Array [0..bufferSize-1] of Char;
  957.   outSize  : Integer;
  958. begin
  959.   zresult := Z_STREAM_END;
  960.   zstream.avail_in := inStream.Read(inBuffer,bufferSize);
  961.   while zstream.avail_in > 0 do
  962.   begin
  963.     zstream.next_in := inBuffer;
  964.     repeat
  965.       zstream.next_out := outBuffer;
  966.       zstream.avail_out := bufferSize;
  967.       zresult := ZDecompressCheck(inflate(zstream,Z_NO_FLUSH));
  968.       outSize := bufferSize - zstream.avail_out;
  969.       outStream.Write(outBuffer,outSize);
  970.     until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
  971.     if zresult <> Z_STREAM_END then
  972.     begin
  973.       zstream.avail_in := inStream.Read(inBuffer,bufferSize);
  974.     end
  975.     else if zstream.avail_in > 0 then
  976.     begin
  977.       inStream.Position := inStream.Position - zstream.avail_in;
  978.       zstream.avail_in := 0;
  979.     end;
  980.   end;
  981.   while zresult <> Z_STREAM_END do
  982.   begin
  983.     zstream.next_out := outBuffer;
  984.     zstream.avail_out := bufferSize;
  985.     zresult := ZDecompressCheck(inflate(zstream,Z_FINISH));
  986.     outSize := bufferSize - zstream.avail_out;
  987.     outStream.Write(outBuffer,outSize);
  988.   end;
  989.   ZDecompressCheck(inflateEnd(zstream));
  990. end;
  991. procedure ZCompressStream(inStream, outStream: TStream;
  992.   level: TZCompressionLevel);
  993. var
  994.   zstream: TZStreamRec;
  995. begin
  996.   FillChar(zstream,SizeOf(TZStreamRec),0);
  997.   ZCompressCheck(DeflateInit(zstream,ZLevels[level]));
  998.   ZInternalCompressStream(zstream,inStream,outStream);
  999. end;
  1000. procedure ZCompressStream2(inStream, outStream: TStream;
  1001.   level: TZCompressionLevel; windowBits, memLevel: Integer;
  1002.   strategy: TZStrategy);
  1003. var
  1004.   zstream: TZStreamRec;
  1005. begin
  1006.   FillChar(zstream,SizeOf(TZStreamRec),0);
  1007.   ZCompressCheck(DeflateInit2(zstream,ZLevels[level],Z_DEFLATED,windowBits,
  1008.     memLevel,ZStrategies[strategy]));
  1009.   ZInternalCompressStream(zstream,inStream,outStream);
  1010. end;
  1011. procedure ZCompressStreamWeb(inStream, outStream: TStream);
  1012. begin
  1013.   ZCompressStream2(inStream,outStream,zcFastest,-15,9,zsDefault);
  1014. end;
  1015. procedure ZCompressStreamG(inStream, outStream: TStream; const fileName,
  1016.   comment: String; dateTime: TDateTime);
  1017. const
  1018.   bufferSize = 32768;
  1019. var
  1020.   header    : TGZHeader;
  1021.   trailer   : TGZTrailer;
  1022.   buffer    : Array [0..bufferSize-1] of Char;
  1023.   count     : Integer;
  1024.   position  : {$ifdef Version6Plus} Int64 {$else} Longint {$endif};
  1025.   nullString: String;
  1026. begin
  1027.   FillChar(header,SizeOf(TGZHeader),0);
  1028.   header.Id1 := $1F;
  1029.   header.Id2 := $8B;
  1030.   header.Method := Z_DEFLATED;
  1031.   if dateTime <> 0 then header.Time := DateTimeToUnix(dateTime);
  1032.   header.ExtraFlags := GZ_EXTRA_DEFAULT;
  1033.   header.OS := 0;
  1034.   header.Flags := 0;
  1035.   if Length(fileName) > 0 then header.Flags := header.Flags or GZ_FILENAME;
  1036.   if Length(comment) > 0 then header.Flags := header.Flags or GZ_COMMENT;
  1037.   FillChar(trailer,SizeOf(TGZTrailer),0);
  1038.   trailer.Crc := 0;
  1039.   position := inStream.Position;
  1040.   while inStream.Position < inStream.Size do
  1041.   begin
  1042.     count := inStream.Read(buffer[0],bufferSize);
  1043.     trailer.Crc := crc32(trailer.Crc,buffer[0],count);
  1044.   end;
  1045.   inStream.Position := position;
  1046.   trailer.Size := inStream.Size - inStream.Position;
  1047.   outStream.Write(header,SizeOf(TGZHeader));
  1048.   if Length(filename) > 0 then
  1049.   begin
  1050.     nullString := fileName + #$00;
  1051.     outStream.Write(nullString[1],Length(nullString));
  1052.   end;
  1053.   if Length(comment) > 0 then
  1054.   begin
  1055.     nullString := comment + #$00;
  1056.     outStream.Write(nullString[1],Length(nullString));
  1057.   end;
  1058.   ZCompressStream2(inStream,outStream,zcDefault,-15,9,zsDefault);
  1059.   outStream.Write(trailer,SizeOf(TGZTrailer));
  1060. end;
  1061. procedure ZDecompressStream(inStream, outStream: TStream);
  1062. var
  1063.   zstream: TZStreamRec;
  1064. begin
  1065.   FillChar(zstream,SizeOf(TZStreamRec),0);
  1066.   ZDecompressCheck(InflateInit(zstream));
  1067.   ZInternalDecompressStream(zstream,inStream,outStream);
  1068. end;
  1069. procedure ZDecompressStream2(inStream, outStream: TStream;
  1070.   windowBits: Integer);
  1071. var
  1072.   zstream: TZStreamRec;
  1073. begin
  1074.   FillChar(zstream,SizeOf(TZStreamRec),0);
  1075.   ZDecompressCheck(InflateInit2(zstream,windowBits));
  1076.   ZInternalDecompressStream(zstream,inStream,outStream);
  1077. end;
  1078. {** checksum routines *******************************************************}
  1079. function ZAdler32(adler: Longint; const buffer; size: Integer): Longint;
  1080. begin
  1081.   result := adler32(adler,buffer,size);
  1082. end;
  1083. function ZCrc32(crc: Longint; const buffer; size: Integer): Longint;
  1084. begin
  1085.   result := crc32(crc,buffer,size);
  1086. end;
  1087. {** TCustomZStream **********************************************************}
  1088. constructor TCustomZStream.Create(stream: TStream);
  1089. begin
  1090.   inherited Create;
  1091.   FStream := stream;
  1092.   FStreamPos := stream.Position;
  1093. end;
  1094. procedure TCustomZStream.DoProgress;
  1095. begin
  1096.   if Assigned(FOnProgress) then FOnProgress(Self);
  1097. end;
  1098. {** TZCompressionStream *****************************************************}
  1099. constructor TZCompressionStream.Create(dest: TStream;
  1100.   compressionLevel: TZCompressionLevel);
  1101. begin
  1102.   inherited Create(dest);
  1103.   FZStream.next_out := FBuffer;
  1104.   FZStream.avail_out := SizeOf(FBuffer);
  1105.   ZCompressCheck(DeflateInit(FZStream,ZLevels[compressionLevel]));
  1106. end;
  1107. constructor TZCompressionStream.Create(dest: TStream;
  1108.   compressionLevel: TZCompressionLevel; windowBits, memLevel: Integer;
  1109.   strategy: TZStrategy);
  1110. begin
  1111.   inherited Create(dest);
  1112.   FZStream.next_out := FBuffer;
  1113.   FZStream.avail_out := SizeOf(FBuffer);
  1114.   ZCompressCheck(DeflateInit2(FZStream,ZLevels[compressionLevel],Z_DEFLATED,
  1115.     windowBits,memLevel,ZStrategies[strategy]));
  1116. end;
  1117. destructor TZCompressionStream.Destroy;
  1118. begin
  1119.   FZStream.next_in := Nil;
  1120.   FZStream.avail_in := 0;
  1121.   try
  1122.     if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
  1123.     while ZCompressCheck(deflate(FZStream,Z_FINISH)) <> Z_STREAM_END do
  1124.     begin
  1125.       FStream.WriteBuffer(FBuffer,SizeOf(FBuffer) - FZStream.avail_out);
  1126.       FZStream.next_out := FBuffer;
  1127.       FZStream.avail_out := SizeOf(FBuffer);
  1128.     end;
  1129.     if FZStream.avail_out < SizeOf(FBuffer) then
  1130.     begin
  1131.       FStream.WriteBuffer(FBuffer,SizeOf(FBuffer) - FZStream.avail_out);
  1132.     end;
  1133.   finally
  1134.     deflateEnd(FZStream);
  1135.   end;
  1136.   inherited Destroy;
  1137. end;
  1138. function TZCompressionStream.Read(var buffer; count: Longint): Longint;
  1139. begin
  1140.   raise EZCompressionError.Create(SZInvalid);
  1141. end;
  1142. function TZCompressionStream.Write(const buffer; count: Longint): Longint;
  1143. begin
  1144.   FZStream.next_in := @buffer;
  1145.   FZStream.avail_in := count;
  1146.   if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
  1147.   while FZStream.avail_in > 0 do
  1148.   begin
  1149.     ZCompressCheck(deflate(FZStream,Z_NO_FLUSH));
  1150.     if FZStream.avail_out = 0 then
  1151.     begin
  1152.       FStream.WriteBuffer(FBuffer,SizeOf(FBuffer));
  1153.       FZStream.next_out := FBuffer;
  1154.       FZStream.avail_out := SizeOf(FBuffer);
  1155.       FStreamPos := FStream.Position;
  1156.       DoProgress;
  1157.     end;
  1158.   end;
  1159.   result := Count;
  1160. end;
  1161. function TZCompressionStream.Seek(offset: Longint; origin: Word): Longint;
  1162. begin
  1163.   if (offset = 0) and (origin = soFromCurrent) then
  1164.   begin
  1165.     result := FZStream.total_in;
  1166.   end
  1167.   else raise EZCompressionError.Create(SZInvalid);
  1168. end;
  1169. function TZCompressionStream.GetCompressionRate: Single;
  1170. begin
  1171.   if FZStream.total_in = 0 then result := 0
  1172.   else result := (1.0 - (FZStream.total_out / FZStream.total_in)) * 100.0;
  1173. end;
  1174. {** TZDecompressionStream ***************************************************}
  1175. constructor TZDecompressionStream.Create(source: TStream);
  1176. begin
  1177.   inherited Create(source);
  1178.   FZStream.next_in := FBuffer;
  1179.   FZStream.avail_in := 0;
  1180.   ZDecompressCheck(InflateInit(FZStream));
  1181. end;
  1182. constructor TZDecompressionStream.Create(source: TStream;
  1183.   windowBits: Integer);
  1184. begin
  1185.   inherited Create(source);
  1186.   FZStream.next_in := FBuffer;
  1187.   FZStream.avail_in := 0;
  1188.   ZDecompressCheck(InflateInit2(FZStream,windowBits));
  1189. end;
  1190. destructor TZDecompressionStream.Destroy;
  1191. begin
  1192.   inflateEnd(FZStream);
  1193.   inherited Destroy;
  1194. end;
  1195. function TZDecompressionStream.Read(var buffer; count: Longint): Longint;
  1196. var
  1197.   zresult: Integer;
  1198. begin
  1199.   FZStream.next_out := @buffer;
  1200.   FZStream.avail_out := count;
  1201.   if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
  1202.   zresult := Z_OK;
  1203.   while (FZStream.avail_out > 0) and (zresult <> Z_STREAM_END) do
  1204.   begin
  1205.     if FZStream.avail_in = 0 then
  1206.     begin
  1207.       FZStream.avail_in := FStream.Read(FBuffer,SizeOf(FBuffer));
  1208.       if FZStream.avail_in = 0 then
  1209.       begin
  1210.         result := count - FZStream.avail_out;
  1211.         Exit;
  1212.       end;
  1213.       FZStream.next_in := FBuffer;
  1214.       FStreamPos := FStream.Position;
  1215.       DoProgress;
  1216.     end;
  1217.     zresult := ZDecompressCheck(inflate(FZStream,Z_NO_FLUSH));
  1218.   end;
  1219.   if (zresult = Z_STREAM_END) and (FZStream.avail_in > 0) then
  1220.   begin
  1221.     FStream.Position := FStream.Position - FZStream.avail_in;
  1222.     FStreamPos := FStream.Position;
  1223.     FZStream.avail_in := 0;
  1224.   end;
  1225.   result := count - FZStream.avail_out;
  1226. end;
  1227. function TZDecompressionStream.Write(const Buffer; Count: Longint): Longint;
  1228. begin
  1229.   raise EZDecompressionError.Create(SZInvalid);
  1230. end;
  1231. function TZDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
  1232. var
  1233.   buf: Array [0..8191] of Char;
  1234.   i  : Integer;
  1235. begin
  1236.   if (offset = 0) and (origin = soFromBeginning) then
  1237.   begin
  1238.     ZDecompressCheck(inflateReset(FZStream));
  1239.     FZStream.next_in := FBuffer;
  1240.     FZStream.avail_in := 0;
  1241.     FStream.Position := 0;
  1242.     FStreamPos := 0;
  1243.   end
  1244.   else if ((offset >= 0) and (origin = soFromCurrent)) or
  1245.           (((offset - FZStream.total_out) > 0) and (origin = soFromBeginning)) then
  1246.   begin
  1247.     if origin = soFromBeginning then Dec(offset,FZStream.total_out);
  1248.     if offset > 0 then
  1249.     begin
  1250.       for i := 1 to offset div SizeOf(buf) do ReadBuffer(buf,SizeOf(buf));
  1251.       ReadBuffer(buf,offset mod SizeOf(buf));
  1252.     end;
  1253.   end
  1254.   else if (offset = 0) and (origin = soFromEnd) then
  1255.   begin
  1256.     while Read(buf,SizeOf(buf)) > 0 do ;
  1257.   end
  1258.   else raise EZDecompressionError.Create(SZInvalid);
  1259.   result := FZStream.total_out;
  1260. end;
  1261. {** EZLibError **************************************************************}
  1262. constructor EZLibError.Create(code: Integer; const dummy: String);
  1263. begin
  1264.   inherited Create(_z_errmsg[2 - code]);
  1265.   FErrorCode := code;
  1266. end;
  1267. end.