Spzlib.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:12k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {*******************************************************************}
  2. {                                                                   }
  3. {       Almediadev Visual Component Library                         }
  4. {       DynamicSkinForm                                             }
  5. {       Version 4.98                                                }
  6. {                                                                   }
  7. {       Copyright (c) 2000-2002 Almediadev                          }
  8. {       ALL RIGHTS RESERVED                                         }
  9. {                                                                   }
  10. {       Home:  http://www.almdev.com                                }
  11. {       Support: support@almdev.com                                 }
  12. {                                                                   }
  13. {*******************************************************************}
  14. unit spzlib;
  15. interface
  16. uses Sysutils, Classes;
  17. type
  18.   TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer;
  19.   TFree = procedure (AppData, Block: Pointer);
  20.   TZStreamRec = packed record
  21.     next_in: PChar;
  22.     avail_in: Integer;
  23.     total_in: Integer;
  24.     next_out: PChar;
  25.     avail_out: Integer;
  26.     total_out: Integer;
  27.     msg: PChar;
  28.     internal: Pointer;
  29.     zalloc: TAlloc;
  30.     zfree: TFree;
  31.     AppData: Pointer;
  32.     data_type: Integer;
  33.     adler: Integer;
  34.     reserved: Integer;
  35.   end;
  36.   TCustomZlibStream = class(TStream)
  37.   private
  38.     FStrm: TStream;
  39.     FStrmPos: Integer;
  40.     FOnProgress: TNotifyEvent;
  41.     FZRec: TZStreamRec;
  42.     FBuffer: array [Word] of Char;
  43.   protected
  44.     procedure Progress(Sender: TObject); dynamic;
  45.     property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
  46.     constructor Create(Strm: TStream);
  47.   end;
  48.   TCompressionLevel = (clNone, clFastest, clDefault, clMax);
  49.   TCompressionStream = class(TCustomZlibStream)
  50.   private
  51.     function GetCompressionRate: Single;
  52.   public
  53.     constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
  54.     destructor Destroy; override;
  55.     function Read(var Buffer; Count: Longint): Longint; override;
  56.     function Write(const Buffer; Count: Longint): Longint; override;
  57.     function Seek(Offset: Longint; Origin: Word): Longint; override;
  58.     property CompressionRate: Single read GetCompressionRate;
  59.     property OnProgress;
  60.   end;
  61.   TDecompressionStream = class(TCustomZlibStream)
  62.   public
  63.     constructor Create(Source: TStream);
  64.     destructor Destroy; override;
  65.     function Read(var Buffer; Count: Longint): Longint; override;
  66.     function Write(const Buffer; Count: Longint): Longint; override;
  67.     function Seek(Offset: Longint; Origin: Word): Longint; override;
  68.     property OnProgress;
  69.   end;
  70. const
  71.   zlib_version = '1.1.4';
  72. type
  73.   EZlibError = class(Exception);
  74.   ECompressionError = class(EZlibError);
  75.   EDecompressionError = class(EZlibError);
  76. function adler32(adler: Integer; buf: PChar; len: Integer): Integer;
  77. procedure CompressStream(Stream, SaveStream: TStream);
  78. procedure DeCompressStream(Stream, CompressedStream: TStream);
  79. implementation
  80. const
  81.   Z_NO_FLUSH      = 0;
  82.   Z_PARTIAL_FLUSH = 1;
  83.   Z_SYNC_FLUSH    = 2;
  84.   Z_FULL_FLUSH    = 3;
  85.   Z_FINISH        = 4;
  86.   Z_OK            = 0;
  87.   Z_STREAM_END    = 1;
  88.   Z_NEED_DICT     = 2;
  89.   Z_ERRNO         = (-1);
  90.   Z_STREAM_ERROR  = (-2);
  91.   Z_DATA_ERROR    = (-3);
  92.   Z_MEM_ERROR     = (-4);
  93.   Z_BUF_ERROR     = (-5);
  94.   Z_VERSION_ERROR = (-6);
  95.   Z_NO_COMPRESSION       =   0;
  96.   Z_BEST_SPEED           =   1;
  97.   Z_BEST_COMPRESSION     =   9;
  98.   Z_DEFAULT_COMPRESSION  = (-1);
  99.   Z_FILTERED            = 1;
  100.   Z_HUFFMAN_ONLY        = 2;
  101.   Z_DEFAULT_STRATEGY    = 0;
  102.   Z_BINARY   = 0;
  103.   Z_ASCII    = 1;
  104.   Z_UNKNOWN  = 2;
  105.   Z_DEFLATED = 8;
  106.   _z_errmsg: array[0..9] of PChar = (
  107.     'need dictionary',      // Z_NEED_DICT      (2)
  108.     'stream end',           // Z_STREAM_END     (1)
  109.     '',                     // Z_OK             (0)
  110.     'file error',           // Z_ERRNO          (-1)
  111.     'stream error',         // Z_STREAM_ERROR   (-2)
  112.     'data error',           // Z_DATA_ERROR     (-3)
  113.     'insufficient memory',  // Z_MEM_ERROR      (-4)
  114.     'buffer error',         // Z_BUF_ERROR      (-5)
  115.     'incompatible version', // Z_VERSION_ERROR  (-6)
  116.     ''
  117.   );
  118. {$L deflate.obj}
  119. {$L inflate.obj}
  120. {$L inftrees.obj}
  121. {$L trees.obj}
  122. {$L adler32.obj}
  123. {$L infblock.obj}
  124. {$L infcodes.obj}
  125. {$L infutil.obj}
  126. {$L inffast.obj}
  127. procedure _tr_init; external;
  128. procedure _tr_tally; external;
  129. procedure _tr_flush_block; external;
  130. procedure _tr_align; external;
  131. procedure _tr_stored_block; external;
  132. function adler32; external;
  133. procedure inflate_blocks_new; external;
  134. procedure inflate_blocks; external;
  135. procedure inflate_blocks_reset; external;
  136. procedure inflate_blocks_free; external;
  137. procedure inflate_set_dictionary; external;
  138. procedure inflate_trees_bits; external;
  139. procedure inflate_trees_dynamic; external;
  140. procedure inflate_trees_fixed; external;
  141. procedure inflate_codes_new; external;
  142. procedure inflate_codes; external;
  143. procedure inflate_codes_free; external;
  144. procedure _inflate_mask; external;
  145. procedure inflate_flush; external;
  146. procedure inflate_fast; external;
  147. procedure _memset(P: Pointer; B: Byte; count: Integer);cdecl;
  148. begin
  149.   FillChar(P^, count, B);
  150. end;
  151. procedure _memcpy(dest, source: Pointer; count: Integer);cdecl;
  152. begin
  153.   Move(source^, dest^, count);
  154. end;
  155. // deflate compresses data
  156. function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
  157.   recsize: Integer): Integer; external;
  158. function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
  159. function deflateEnd(var strm: TZStreamRec): Integer; external;
  160. // inflate decompresses data
  161. function inflateInit_(var strm: TZStreamRec; version: PChar;
  162.   recsize: Integer): Integer; external;
  163. function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
  164. function inflateEnd(var strm: TZStreamRec): Integer; external;
  165. function inflateReset(var strm: TZStreamRec): Integer; external;
  166. function zcalloc(AppData: Pointer; Items, Size: Integer): Pointer;
  167. begin
  168.   GetMem(Result, Items*Size);
  169. end;
  170. procedure zcfree(AppData, Block: Pointer);
  171. begin
  172.   FreeMem(Block);
  173. end;
  174. function CCheck(code: Integer): Integer;
  175. begin
  176.   Result := code;
  177.   if code < 0 then
  178.     raise ECompressionError.Create('compression error');
  179. end;
  180. function DCheck(code: Integer): Integer;
  181. begin
  182.   Result := code;
  183.   if code < 0 then
  184.     raise EDecompressionError.Create('compression error');
  185. end;
  186. constructor TCustomZLibStream.Create(Strm: TStream);
  187. begin
  188.   inherited Create;
  189.   FStrm := Strm;
  190.   FStrmPos := Strm.Position;
  191. end;
  192. procedure TCustomZLibStream.Progress(Sender: TObject);
  193. begin
  194.   if Assigned(FOnProgress) then FOnProgress(Sender);
  195. end;
  196. constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
  197.   Dest: TStream);
  198. const
  199.   Levels: array [TCompressionLevel] of ShortInt =
  200.     (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
  201. begin
  202.   inherited Create(Dest);
  203.   FZRec.next_out := FBuffer;
  204.   FZRec.avail_out := sizeof(FBuffer);
  205.   CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
  206. end;
  207. destructor TCompressionStream.Destroy;
  208. begin
  209.   FZRec.next_in := nil;
  210.   FZRec.avail_in := 0;
  211.   try
  212.     if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
  213.     while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
  214.       and (FZRec.avail_out = 0) do
  215.     begin
  216.       FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
  217.       FZRec.next_out := FBuffer;
  218.       FZRec.avail_out := sizeof(FBuffer);
  219.     end;
  220.     if FZRec.avail_out < sizeof(FBuffer) then
  221.       FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
  222.   finally
  223.     deflateEnd(FZRec);
  224.   end;
  225.   inherited Destroy;
  226. end;
  227. function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
  228. begin
  229.   raise ECompressionError.Create('Invalid stream operation');
  230. end;
  231. function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
  232. begin
  233.   FZRec.next_in := @Buffer;
  234.   FZRec.avail_in := Count;
  235.   if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
  236.   while (FZRec.avail_in > 0) do
  237.   begin
  238.     CCheck(deflate(FZRec, 0));
  239.     if FZRec.avail_out = 0 then
  240.     begin
  241.       FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
  242.       FZRec.next_out := FBuffer;
  243.       FZRec.avail_out := sizeof(FBuffer);
  244.       FStrmPos := FStrm.Position;
  245.       Progress(Self);
  246.     end;
  247.   end;
  248.   Result := Count;
  249. end;
  250. function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
  251. begin
  252.   if (Offset = 0) and (Origin = soFromCurrent) then
  253.     Result := FZRec.total_in
  254.   else
  255.     raise ECompressionError.Create('Invalid stream operation');
  256. end;
  257. function TCompressionStream.GetCompressionRate: Single;
  258. begin
  259.   if FZRec.total_in = 0 then
  260.     Result := 0
  261.   else
  262.     Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
  263. end;
  264. constructor TDecompressionStream.Create(Source: TStream);
  265. begin
  266.   inherited Create(Source);
  267.   FZRec.next_in := FBuffer;
  268.   FZRec.avail_in := 0;
  269.   DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
  270. end;
  271. destructor TDecompressionStream.Destroy;
  272. begin
  273.   inflateEnd(FZRec);
  274.   inherited Destroy;
  275. end;
  276. function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
  277. begin
  278.   FZRec.next_out := @Buffer;
  279.   FZRec.avail_out := Count;
  280.   if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
  281.   while (FZRec.avail_out > 0) do
  282.   begin
  283.     if FZRec.avail_in = 0 then
  284.     begin
  285.       FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
  286.       if FZRec.avail_in = 0 then
  287.         begin
  288.           Result := Count - FZRec.avail_out;
  289.           Exit;
  290.         end;
  291.       FZRec.next_in := FBuffer;
  292.       FStrmPos := FStrm.Position;
  293.       Progress(Self);
  294.     end;
  295.     DCheck(inflate(FZRec, 0));
  296.   end;
  297.   Result := Count;
  298. end;
  299. function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
  300. begin
  301.   raise EDecompressionError.Create('Invalid stream operation');
  302. end;
  303. function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
  304. var
  305.   I: Integer;
  306.   Buf: array [0..4095] of Char;
  307. begin
  308.   if (Offset = 0) and (Origin = soFromBeginning) then
  309.   begin
  310.     DCheck(inflateReset(FZRec));
  311.     FZRec.next_in := FBuffer;
  312.     FZRec.avail_in := 0;
  313.     FStrm.Position := 0;
  314.     FStrmPos := 0;
  315.   end
  316.   else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
  317.           ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
  318.   begin
  319.     if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
  320.     if Offset > 0 then
  321.     begin
  322.       for I := 1 to Offset div sizeof(Buf) do
  323.         ReadBuffer(Buf, sizeof(Buf));
  324.       ReadBuffer(Buf, Offset mod sizeof(Buf));
  325.     end;
  326.   end
  327.   else
  328.     raise EDecompressionError.Create('Invalid stream operation');
  329.   Result := FZRec.total_out;
  330. end;
  331. procedure CompressStream(Stream, SaveStream: TStream);
  332. var
  333.   CompStrm: TCompressionStream;
  334. begin
  335.   CompStrm := TCompressionStream.Create(clMax, SaveStream);
  336.   try
  337.     Stream.Seek(0, 0);
  338.     CompStrm.CopyFrom(Stream, 0);
  339.   finally
  340.     CompStrm.Free;
  341.   end;
  342. end;
  343. procedure DeCompressStream(Stream, CompressedStream: TStream);
  344. const
  345.   BufSize = 4096;
  346. var
  347.   Size: LongInt;
  348.   DecompStrm: TDecompressionStream;
  349.   Buf: array[0..BufSize - 1] of Byte;
  350. begin
  351.   CompressedStream.Seek(0, 0);
  352.   DeCompStrm := TDecompressionStream.Create(CompressedStream);
  353.   try
  354.     while True do
  355.     begin
  356.       Size := DecompStrm.Read(Buf, BufSize);
  357.       if Size <> 0 then Stream.WriteBuffer(Buf, Size) else Break;
  358.     end;
  359.   finally
  360.     DecompStrm.Free;
  361.   end;
  362. end;
  363. end.