diff options
Diffstat (limited to '')
-rw-r--r-- | contrib/delphi/ZLib.pas (renamed from contrib/delphi2/zlib.pas) | 163 |
1 files changed, 93 insertions, 70 deletions
diff --git a/contrib/delphi2/zlib.pas b/contrib/delphi/ZLib.pas index 10ae4ca..ea9a17f 100644 --- a/contrib/delphi2/zlib.pas +++ b/contrib/delphi/ZLib.pas | |||
@@ -1,33 +1,33 @@ | |||
1 | {*******************************************************} | 1 | {*******************************************************} |
2 | { } | 2 | { } |
3 | { Delphi Supplemental Components } | 3 | { Borland Delphi Supplemental Components } |
4 | { ZLIB Data Compression Interface Unit } | 4 | { ZLIB Data Compression Interface Unit } |
5 | { } | 5 | { } |
6 | { Copyright (c) 1997 Borland International } | 6 | { Copyright (c) 1997,99 Borland Corporation } |
7 | { } | 7 | { } |
8 | {*******************************************************} | 8 | {*******************************************************} |
9 | 9 | ||
10 | { Modified for zlib 1.1.3 by Davide Moretti <dave@rimini.com } | 10 | { Updated for zlib 1.2.x by Cosmin Truta <cosmint@cs.ubbcluj.ro> } |
11 | 11 | ||
12 | unit zlib; | 12 | unit ZLib; |
13 | 13 | ||
14 | interface | 14 | interface |
15 | 15 | ||
16 | uses Sysutils, Classes; | 16 | uses SysUtils, Classes; |
17 | 17 | ||
18 | type | 18 | type |
19 | TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; | 19 | TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl; |
20 | TFree = procedure (AppData, Block: Pointer); | 20 | TFree = procedure (AppData, Block: Pointer); cdecl; |
21 | 21 | ||
22 | // Internal structure. Ignore. | 22 | // Internal structure. Ignore. |
23 | TZStreamRec = packed record | 23 | TZStreamRec = packed record |
24 | next_in: PChar; // next input byte | 24 | next_in: PChar; // next input byte |
25 | avail_in: Integer; // number of bytes available at next_in | 25 | avail_in: Integer; // number of bytes available at next_in |
26 | total_in: Integer; // total nb of input bytes read so far | 26 | total_in: Longint; // total nb of input bytes read so far |
27 | 27 | ||
28 | next_out: PChar; // next output byte should be put here | 28 | next_out: PChar; // next output byte should be put here |
29 | avail_out: Integer; // remaining free space at next_out | 29 | avail_out: Integer; // remaining free space at next_out |
30 | total_out: Integer; // total nb of bytes output so far | 30 | total_out: Longint; // total nb of bytes output so far |
31 | 31 | ||
32 | msg: PChar; // last error message, NULL if no error | 32 | msg: PChar; // last error message, NULL if no error |
33 | internal: Pointer; // not visible by applications | 33 | internal: Pointer; // not visible by applications |
@@ -36,9 +36,9 @@ type | |||
36 | zfree: TFree; // used to free the internal state | 36 | zfree: TFree; // used to free the internal state |
37 | AppData: Pointer; // private data object passed to zalloc and zfree | 37 | AppData: Pointer; // private data object passed to zalloc and zfree |
38 | 38 | ||
39 | data_type: Integer; // best guess about the data type: ascii or binary | 39 | data_type: Integer; // best guess about the data type: ascii or binary |
40 | adler: Integer; // adler32 value of the uncompressed data | 40 | adler: Longint; // adler32 value of the uncompressed data |
41 | reserved: Integer; // reserved for future use | 41 | reserved: Longint; // reserved for future use |
42 | end; | 42 | end; |
43 | 43 | ||
44 | // Abstract ancestor class | 44 | // Abstract ancestor class |
@@ -143,18 +143,26 @@ procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; | |||
143 | procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; | 143 | procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; |
144 | OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); | 144 | OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); |
145 | 145 | ||
146 | { DecompressToUserBuf decompresses data, buffer to buffer, in one call. | ||
147 | In: InBuf = ptr to compressed data | ||
148 | InBytes = number of bytes in InBuf | ||
149 | Out: OutBuf = ptr to user-allocated buffer to contain decompressed data | ||
150 | BufSize = number of bytes in OutBuf } | ||
151 | procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; | ||
152 | const OutBuf: Pointer; BufSize: Integer); | ||
153 | |||
146 | const | 154 | const |
147 | zlib_version = '1.1.3'; | 155 | zlib_version = '1.2.0'; |
148 | 156 | ||
149 | type | 157 | type |
150 | EZlibError = class(Exception); | 158 | EZlibError = class(Exception); |
151 | ECompressionError = class(EZlibError); | 159 | ECompressionError = class(EZlibError); |
152 | EDecompressionError = class(EZlibError); | 160 | EDecompressionError = class(EZlibError); |
153 | 161 | ||
154 | function adler32(adler: Integer; buf: PChar; len: Integer): Integer; | ||
155 | |||
156 | implementation | 162 | implementation |
157 | 163 | ||
164 | uses ZLibConst; | ||
165 | |||
158 | const | 166 | const |
159 | Z_NO_FLUSH = 0; | 167 | Z_NO_FLUSH = 0; |
160 | Z_PARTIAL_FLUSH = 1; | 168 | Z_PARTIAL_FLUSH = 1; |
@@ -179,6 +187,7 @@ const | |||
179 | 187 | ||
180 | Z_FILTERED = 1; | 188 | Z_FILTERED = 1; |
181 | Z_HUFFMAN_ONLY = 2; | 189 | Z_HUFFMAN_ONLY = 2; |
190 | Z_RLE = 3; | ||
182 | Z_DEFAULT_STRATEGY = 0; | 191 | Z_DEFAULT_STRATEGY = 0; |
183 | 192 | ||
184 | Z_BINARY = 0; | 193 | Z_BINARY = 0; |
@@ -187,56 +196,41 @@ const | |||
187 | 196 | ||
188 | Z_DEFLATED = 8; | 197 | Z_DEFLATED = 8; |
189 | 198 | ||
190 | _z_errmsg: array[0..9] of PChar = ( | ||
191 | 'need dictionary', // Z_NEED_DICT (2) | ||
192 | 'stream end', // Z_STREAM_END (1) | ||
193 | '', // Z_OK (0) | ||
194 | 'file error', // Z_ERRNO (-1) | ||
195 | 'stream error', // Z_STREAM_ERROR (-2) | ||
196 | 'data error', // Z_DATA_ERROR (-3) | ||
197 | 'insufficient memory', // Z_MEM_ERROR (-4) | ||
198 | 'buffer error', // Z_BUF_ERROR (-5) | ||
199 | 'incompatible version', // Z_VERSION_ERROR (-6) | ||
200 | '' | ||
201 | ); | ||
202 | 199 | ||
200 | {$L adler32.obj} | ||
201 | {$L compress.obj} | ||
202 | {$L crc32.obj} | ||
203 | {$L deflate.obj} | 203 | {$L deflate.obj} |
204 | {$L infback.obj} | ||
205 | {$L inffast.obj} | ||
204 | {$L inflate.obj} | 206 | {$L inflate.obj} |
205 | {$L inftrees.obj} | 207 | {$L inftrees.obj} |
206 | {$L trees.obj} | 208 | {$L trees.obj} |
207 | {$L adler32.obj} | 209 | {$L uncompr.obj} |
208 | {$L infblock.obj} | 210 | {$L zutil.obj} |
209 | {$L infcodes.obj} | 211 | |
210 | {$L infutil.obj} | 212 | procedure adler32; external; |
211 | {$L inffast.obj} | 213 | procedure compressBound; external; |
214 | procedure crc32; external; | ||
215 | procedure deflateInit2_; external; | ||
216 | procedure deflateParams; external; | ||
212 | 217 | ||
213 | procedure _tr_init; external; | 218 | function _malloc(Size: Integer): Pointer; cdecl; |
214 | procedure _tr_tally; external; | 219 | begin |
215 | procedure _tr_flush_block; external; | 220 | Result := AllocMem(Size); |
216 | procedure _tr_align; external; | 221 | end; |
217 | procedure _tr_stored_block; external; | 222 | |
218 | function adler32; external; | 223 | procedure _free(Block: Pointer); cdecl; |
219 | procedure inflate_blocks_new; external; | 224 | begin |
220 | procedure inflate_blocks; external; | 225 | FreeMem(Block); |
221 | procedure inflate_blocks_reset; external; | 226 | end; |
222 | procedure inflate_blocks_free; external; | 227 | |
223 | procedure inflate_set_dictionary; external; | 228 | procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; |
224 | procedure inflate_trees_bits; external; | ||
225 | procedure inflate_trees_dynamic; external; | ||
226 | procedure inflate_trees_fixed; external; | ||
227 | procedure inflate_codes_new; external; | ||
228 | procedure inflate_codes; external; | ||
229 | procedure inflate_codes_free; external; | ||
230 | procedure _inflate_mask; external; | ||
231 | procedure inflate_flush; external; | ||
232 | procedure inflate_fast; external; | ||
233 | |||
234 | procedure _memset(P: Pointer; B: Byte; count: Integer);cdecl; | ||
235 | begin | 229 | begin |
236 | FillChar(P^, count, B); | 230 | FillChar(P^, count, B); |
237 | end; | 231 | end; |
238 | 232 | ||
239 | procedure _memcpy(dest, source: Pointer; count: Integer);cdecl; | 233 | procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; |
240 | begin | 234 | begin |
241 | Move(source^, dest^, count); | 235 | Move(source^, dest^, count); |
242 | end; | 236 | end; |
@@ -257,22 +251,23 @@ function inflateEnd(var strm: TZStreamRec): Integer; external; | |||
257 | function inflateReset(var strm: TZStreamRec): Integer; external; | 251 | function inflateReset(var strm: TZStreamRec): Integer; external; |
258 | 252 | ||
259 | 253 | ||
260 | function zcalloc(AppData: Pointer; Items, Size: Integer): Pointer; | 254 | function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl; |
261 | begin | 255 | begin |
262 | GetMem(Result, Items*Size); | 256 | // GetMem(Result, Items*Size); |
257 | Result := AllocMem(Items * Size); | ||
263 | end; | 258 | end; |
264 | 259 | ||
265 | procedure zcfree(AppData, Block: Pointer); | 260 | procedure zlibFreeMem(AppData, Block: Pointer); cdecl; |
266 | begin | 261 | begin |
267 | FreeMem(Block); | 262 | FreeMem(Block); |
268 | end; | 263 | end; |
269 | 264 | ||
270 | function zlibCheck(code: Integer): Integer; | 265 | {function zlibCheck(code: Integer): Integer; |
271 | begin | 266 | begin |
272 | Result := code; | 267 | Result := code; |
273 | if code < 0 then | 268 | if code < 0 then |
274 | raise EZlibError.Create('error'); //!! | 269 | raise EZlibError.Create('error'); //!! |
275 | end; | 270 | end;} |
276 | 271 | ||
277 | function CCheck(code: Integer): Integer; | 272 | function CCheck(code: Integer): Integer; |
278 | begin | 273 | begin |
@@ -295,6 +290,8 @@ var | |||
295 | P: Pointer; | 290 | P: Pointer; |
296 | begin | 291 | begin |
297 | FillChar(strm, sizeof(strm), 0); | 292 | FillChar(strm, sizeof(strm), 0); |
293 | strm.zalloc := zlibAllocMem; | ||
294 | strm.zfree := zlibFreeMem; | ||
298 | OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255; | 295 | OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255; |
299 | GetMem(OutBuf, OutBytes); | 296 | GetMem(OutBuf, OutBytes); |
300 | try | 297 | try |
@@ -332,6 +329,8 @@ var | |||
332 | BufInc: Integer; | 329 | BufInc: Integer; |
333 | begin | 330 | begin |
334 | FillChar(strm, sizeof(strm), 0); | 331 | FillChar(strm, sizeof(strm), 0); |
332 | strm.zalloc := zlibAllocMem; | ||
333 | strm.zfree := zlibFreeMem; | ||
335 | BufInc := (InBytes + 255) and not 255; | 334 | BufInc := (InBytes + 255) and not 255; |
336 | if OutEstimate = 0 then | 335 | if OutEstimate = 0 then |
337 | OutBytes := BufInc | 336 | OutBytes := BufInc |
@@ -364,6 +363,26 @@ begin | |||
364 | end; | 363 | end; |
365 | end; | 364 | end; |
366 | 365 | ||
366 | procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; | ||
367 | const OutBuf: Pointer; BufSize: Integer); | ||
368 | var | ||
369 | strm: TZStreamRec; | ||
370 | begin | ||
371 | FillChar(strm, sizeof(strm), 0); | ||
372 | strm.zalloc := zlibAllocMem; | ||
373 | strm.zfree := zlibFreeMem; | ||
374 | strm.next_in := InBuf; | ||
375 | strm.avail_in := InBytes; | ||
376 | strm.next_out := OutBuf; | ||
377 | strm.avail_out := BufSize; | ||
378 | DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); | ||
379 | try | ||
380 | if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then | ||
381 | raise EZlibError.CreateRes(@sTargetBufferTooSmall); | ||
382 | finally | ||
383 | DCheck(inflateEnd(strm)); | ||
384 | end; | ||
385 | end; | ||
367 | 386 | ||
368 | // TCustomZlibStream | 387 | // TCustomZlibStream |
369 | 388 | ||
@@ -372,6 +391,8 @@ begin | |||
372 | inherited Create; | 391 | inherited Create; |
373 | FStrm := Strm; | 392 | FStrm := Strm; |
374 | FStrmPos := Strm.Position; | 393 | FStrmPos := Strm.Position; |
394 | FZRec.zalloc := zlibAllocMem; | ||
395 | FZRec.zfree := zlibFreeMem; | ||
375 | end; | 396 | end; |
376 | 397 | ||
377 | procedure TCustomZLibStream.Progress(Sender: TObject); | 398 | procedure TCustomZLibStream.Progress(Sender: TObject); |
@@ -417,7 +438,7 @@ end; | |||
417 | 438 | ||
418 | function TCompressionStream.Read(var Buffer; Count: Longint): Longint; | 439 | function TCompressionStream.Read(var Buffer; Count: Longint): Longint; |
419 | begin | 440 | begin |
420 | raise ECompressionError.Create('Invalid stream operation'); | 441 | raise ECompressionError.CreateRes(@sInvalidStreamOp); |
421 | end; | 442 | end; |
422 | 443 | ||
423 | function TCompressionStream.Write(const Buffer; Count: Longint): Longint; | 444 | function TCompressionStream.Write(const Buffer; Count: Longint): Longint; |
@@ -445,7 +466,7 @@ begin | |||
445 | if (Offset = 0) and (Origin = soFromCurrent) then | 466 | if (Offset = 0) and (Origin = soFromCurrent) then |
446 | Result := FZRec.total_in | 467 | Result := FZRec.total_in |
447 | else | 468 | else |
448 | raise ECompressionError.Create('Invalid stream operation'); | 469 | raise ECompressionError.CreateRes(@sInvalidStreamOp); |
449 | end; | 470 | end; |
450 | 471 | ||
451 | function TCompressionStream.GetCompressionRate: Single; | 472 | function TCompressionStream.GetCompressionRate: Single; |
@@ -469,6 +490,7 @@ end; | |||
469 | 490 | ||
470 | destructor TDecompressionStream.Destroy; | 491 | destructor TDecompressionStream.Destroy; |
471 | begin | 492 | begin |
493 | FStrm.Seek(-FZRec.avail_in, 1); | ||
472 | inflateEnd(FZRec); | 494 | inflateEnd(FZRec); |
473 | inherited Destroy; | 495 | inherited Destroy; |
474 | end; | 496 | end; |
@@ -484,22 +506,22 @@ begin | |||
484 | begin | 506 | begin |
485 | FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); | 507 | FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer)); |
486 | if FZRec.avail_in = 0 then | 508 | if FZRec.avail_in = 0 then |
487 | begin | 509 | begin |
488 | Result := Count - FZRec.avail_out; | 510 | Result := Count - FZRec.avail_out; |
489 | Exit; | 511 | Exit; |
490 | end; | 512 | end; |
491 | FZRec.next_in := FBuffer; | 513 | FZRec.next_in := FBuffer; |
492 | FStrmPos := FStrm.Position; | 514 | FStrmPos := FStrm.Position; |
493 | Progress(Self); | 515 | Progress(Self); |
494 | end; | 516 | end; |
495 | DCheck(inflate(FZRec, 0)); | 517 | CCheck(inflate(FZRec, 0)); |
496 | end; | 518 | end; |
497 | Result := Count; | 519 | Result := Count; |
498 | end; | 520 | end; |
499 | 521 | ||
500 | function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; | 522 | function TDecompressionStream.Write(const Buffer; Count: Longint): Longint; |
501 | begin | 523 | begin |
502 | raise EDecompressionError.Create('Invalid stream operation'); | 524 | raise EDecompressionError.CreateRes(@sInvalidStreamOp); |
503 | end; | 525 | end; |
504 | 526 | ||
505 | function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; | 527 | function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint; |
@@ -527,8 +549,9 @@ begin | |||
527 | end; | 549 | end; |
528 | end | 550 | end |
529 | else | 551 | else |
530 | raise EDecompressionError.Create('Invalid stream operation'); | 552 | raise EDecompressionError.CreateRes(@sInvalidStreamOp); |
531 | Result := FZRec.total_out; | 553 | Result := FZRec.total_out; |
532 | end; | 554 | end; |
533 | 555 | ||
556 | |||
534 | end. | 557 | end. |