|
kusano |
fc6ab3 |
(* example.c -- usage example of the zlib compression library
|
|
kusano |
fc6ab3 |
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
|
kusano |
fc6ab3 |
* For conditions of distribution and use, see copyright notice in zlib.h
|
|
kusano |
fc6ab3 |
*
|
|
kusano |
fc6ab3 |
* Pascal translation
|
|
kusano |
fc6ab3 |
* Copyright (C) 1998 by Jacques Nomssi Nzali.
|
|
kusano |
fc6ab3 |
* For conditions of distribution and use, see copyright notice in readme.txt
|
|
kusano |
fc6ab3 |
*
|
|
kusano |
fc6ab3 |
* Adaptation to the zlibpas interface
|
|
kusano |
fc6ab3 |
* Copyright (C) 2003 by Cosmin Truta.
|
|
kusano |
fc6ab3 |
* For conditions of distribution and use, see copyright notice in readme.txt
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
program example;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
{$DEFINE TEST_COMPRESS}
|
|
kusano |
fc6ab3 |
{DO NOT $DEFINE TEST_GZIO}
|
|
kusano |
fc6ab3 |
{$DEFINE TEST_DEFLATE}
|
|
kusano |
fc6ab3 |
{$DEFINE TEST_INFLATE}
|
|
kusano |
fc6ab3 |
{$DEFINE TEST_FLUSH}
|
|
kusano |
fc6ab3 |
{$DEFINE TEST_SYNC}
|
|
kusano |
fc6ab3 |
{$DEFINE TEST_DICT}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
uses SysUtils, zlibpas;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
const TESTFILE = 'foo.gz';
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* "hello world" would be more standard, but the repeated "hello"
|
|
kusano |
fc6ab3 |
* stresses the compression code better, sorry...
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
const hello: PChar = 'hello, hello!';
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
const dictionary: PChar = 'hello';
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
var dictId: LongInt; (* Adler32 value of the dictionary *)
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
procedure CHECK_ERR(err: Integer; msg: String);
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
if err <> Z_OK then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn(msg, ' error: ', err);
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
procedure EXIT_ERR(const msg: String);
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('Error: ', msg);
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test compress and uncompress
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_COMPRESS}
|
|
kusano |
fc6ab3 |
procedure test_compress(compr: Pointer; comprLen: LongInt;
|
|
kusano |
fc6ab3 |
uncompr: Pointer; uncomprLen: LongInt);
|
|
kusano |
fc6ab3 |
var err: Integer;
|
|
kusano |
fc6ab3 |
len: LongInt;
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
len := StrLen(hello)+1;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := compress(compr, comprLen, hello, len);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'compress');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
StrCopy(PChar(uncompr), 'garbage');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := uncompress(uncompr, uncomprLen, compr, comprLen);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'uncompress');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
if StrComp(PChar(uncompr), hello) <> 0 then
|
|
kusano |
fc6ab3 |
EXIT_ERR('bad uncompress')
|
|
kusano |
fc6ab3 |
else
|
|
kusano |
fc6ab3 |
WriteLn('uncompress(): ', PChar(uncompr));
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test read/write of .gz files
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_GZIO}
|
|
kusano |
fc6ab3 |
procedure test_gzio(const fname: PChar; (* compressed file name *)
|
|
kusano |
fc6ab3 |
uncompr: Pointer;
|
|
kusano |
fc6ab3 |
uncomprLen: LongInt);
|
|
kusano |
fc6ab3 |
var err: Integer;
|
|
kusano |
fc6ab3 |
len: Integer;
|
|
kusano |
fc6ab3 |
zfile: gzFile;
|
|
kusano |
fc6ab3 |
pos: LongInt;
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
len := StrLen(hello)+1;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
zfile := gzopen(fname, 'wb');
|
|
kusano |
fc6ab3 |
if zfile = NIL then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzopen error');
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
gzputc(zfile, 'h');
|
|
kusano |
fc6ab3 |
if gzputs(zfile, 'ello') <> 4 then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzputs err: ', gzerror(zfile, err));
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$IFDEF GZ_FORMAT_STRING}
|
|
kusano |
fc6ab3 |
if gzprintf(zfile, ', %s!', 'hello') <> 8 then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzprintf err: ', gzerror(zfile, err));
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ELSE}
|
|
kusano |
fc6ab3 |
if gzputs(zfile, ', hello!') <> 8 then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzputs err: ', gzerror(zfile, err));
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)
|
|
kusano |
fc6ab3 |
gzclose(zfile);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
zfile := gzopen(fname, 'rb');
|
|
kusano |
fc6ab3 |
if zfile = NIL then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzopen error');
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
StrCopy(PChar(uncompr), 'garbage');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
if gzread(zfile, uncompr, uncomprLen) <> len then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzread err: ', gzerror(zfile, err));
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
if StrComp(PChar(uncompr), hello) <> 0 then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('bad gzread: ', PChar(uncompr));
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end
|
|
kusano |
fc6ab3 |
else
|
|
kusano |
fc6ab3 |
WriteLn('gzread(): ', PChar(uncompr));
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
pos := gzseek(zfile, -8, SEEK_CUR);
|
|
kusano |
fc6ab3 |
if (pos <> 6) or (gztell(zfile) <> pos) then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
if gzgetc(zfile) <> ' ' then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzgetc error');
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
if gzungetc(' ', zfile) <> ' ' then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzungetc error');
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
gzgets(zfile, PChar(uncompr), uncomprLen);
|
|
kusano |
fc6ab3 |
uncomprLen := StrLen(PChar(uncompr));
|
|
kusano |
fc6ab3 |
if uncomprLen <> 7 then (* " hello!" *)
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
if StrComp(PChar(uncompr), hello + 6) <> 0 then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('bad gzgets after gzseek');
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end
|
|
kusano |
fc6ab3 |
else
|
|
kusano |
fc6ab3 |
WriteLn('gzgets() after gzseek: ', PChar(uncompr));
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
gzclose(zfile);
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test deflate with small buffers
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_DEFLATE}
|
|
kusano |
fc6ab3 |
procedure test_deflate(compr: Pointer; comprLen: LongInt);
|
|
kusano |
fc6ab3 |
var c_stream: z_stream; (* compression stream *)
|
|
kusano |
fc6ab3 |
err: Integer;
|
|
kusano |
fc6ab3 |
len: LongInt;
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
len := StrLen(hello)+1;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
c_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
c_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
c_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
c_stream.next_in := hello;
|
|
kusano |
fc6ab3 |
c_stream.next_out := compr;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
while (c_stream.total_in <> len) and
|
|
kusano |
fc6ab3 |
(c_stream.total_out < comprLen) do
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
c_stream.avail_out := 1; { force small buffers }
|
|
kusano |
fc6ab3 |
c_stream.avail_in := 1;
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflate');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* Finish the stream, still forcing small buffers: *)
|
|
kusano |
fc6ab3 |
while TRUE do
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
c_stream.avail_out := 1;
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_FINISH);
|
|
kusano |
fc6ab3 |
if err = Z_STREAM_END then
|
|
kusano |
fc6ab3 |
break;
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflate');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateEnd(c_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateEnd');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test inflate with small buffers
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_INFLATE}
|
|
kusano |
fc6ab3 |
procedure test_inflate(compr: Pointer; comprLen : LongInt;
|
|
kusano |
fc6ab3 |
uncompr: Pointer; uncomprLen : LongInt);
|
|
kusano |
fc6ab3 |
var err: Integer;
|
|
kusano |
fc6ab3 |
d_stream: z_stream; (* decompression stream *)
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
StrCopy(PChar(uncompr), 'garbage');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
d_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
d_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.next_in := compr;
|
|
kusano |
fc6ab3 |
d_stream.avail_in := 0;
|
|
kusano |
fc6ab3 |
d_stream.next_out := uncompr;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateInit(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
while (d_stream.total_out < uncomprLen) and
|
|
kusano |
fc6ab3 |
(d_stream.total_in < comprLen) do
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
d_stream.avail_out := 1; (* force small buffers *)
|
|
kusano |
fc6ab3 |
d_stream.avail_in := 1;
|
|
kusano |
fc6ab3 |
err := inflate(d_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
if err = Z_STREAM_END then
|
|
kusano |
fc6ab3 |
break;
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflate');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateEnd(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateEnd');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
if StrComp(PChar(uncompr), hello) <> 0 then
|
|
kusano |
fc6ab3 |
EXIT_ERR('bad inflate')
|
|
kusano |
fc6ab3 |
else
|
|
kusano |
fc6ab3 |
WriteLn('inflate(): ', PChar(uncompr));
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test deflate with large buffers and dynamic change of compression level
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_DEFLATE}
|
|
kusano |
fc6ab3 |
procedure test_large_deflate(compr: Pointer; comprLen: LongInt;
|
|
kusano |
fc6ab3 |
uncompr: Pointer; uncomprLen: LongInt);
|
|
kusano |
fc6ab3 |
var c_stream: z_stream; (* compression stream *)
|
|
kusano |
fc6ab3 |
err: Integer;
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
c_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
c_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
c_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateInit(c_stream, Z_BEST_SPEED);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
c_stream.next_out := compr;
|
|
kusano |
fc6ab3 |
c_stream.avail_out := Integer(comprLen);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* At this point, uncompr is still mostly zeroes, so it should compress
|
|
kusano |
fc6ab3 |
* very well:
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
c_stream.next_in := uncompr;
|
|
kusano |
fc6ab3 |
c_stream.avail_in := Integer(uncomprLen);
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflate');
|
|
kusano |
fc6ab3 |
if c_stream.avail_in <> 0 then
|
|
kusano |
fc6ab3 |
EXIT_ERR('deflate not greedy');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* Feed in already compressed data and switch to no compression: *)
|
|
kusano |
fc6ab3 |
deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
|
|
kusano |
fc6ab3 |
c_stream.next_in := compr;
|
|
kusano |
fc6ab3 |
c_stream.avail_in := Integer(comprLen div 2);
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflate');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* Switch back to compressing mode: *)
|
|
kusano |
fc6ab3 |
deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
|
|
kusano |
fc6ab3 |
c_stream.next_in := uncompr;
|
|
kusano |
fc6ab3 |
c_stream.avail_in := Integer(uncomprLen);
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflate');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_FINISH);
|
|
kusano |
fc6ab3 |
if err <> Z_STREAM_END then
|
|
kusano |
fc6ab3 |
EXIT_ERR('deflate should report Z_STREAM_END');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateEnd(c_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateEnd');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test inflate with large buffers
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_INFLATE}
|
|
kusano |
fc6ab3 |
procedure test_large_inflate(compr: Pointer; comprLen: LongInt;
|
|
kusano |
fc6ab3 |
uncompr: Pointer; uncomprLen: LongInt);
|
|
kusano |
fc6ab3 |
var err: Integer;
|
|
kusano |
fc6ab3 |
d_stream: z_stream; (* decompression stream *)
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
StrCopy(PChar(uncompr), 'garbage');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
d_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
d_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.next_in := compr;
|
|
kusano |
fc6ab3 |
d_stream.avail_in := Integer(comprLen);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateInit(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
while TRUE do
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
d_stream.next_out := uncompr; (* discard the output *)
|
|
kusano |
fc6ab3 |
d_stream.avail_out := Integer(uncomprLen);
|
|
kusano |
fc6ab3 |
err := inflate(d_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
if err = Z_STREAM_END then
|
|
kusano |
fc6ab3 |
break;
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'large inflate');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateEnd(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateEnd');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
WriteLn('bad large inflate: ', d_stream.total_out);
|
|
kusano |
fc6ab3 |
Halt(1);
|
|
kusano |
fc6ab3 |
end
|
|
kusano |
fc6ab3 |
else
|
|
kusano |
fc6ab3 |
WriteLn('large_inflate(): OK');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test deflate with full flush
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_FLUSH}
|
|
kusano |
fc6ab3 |
procedure test_flush(compr: Pointer; var comprLen : LongInt);
|
|
kusano |
fc6ab3 |
var c_stream: z_stream; (* compression stream *)
|
|
kusano |
fc6ab3 |
err: Integer;
|
|
kusano |
fc6ab3 |
len: Integer;
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
len := StrLen(hello)+1;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
c_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
c_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
c_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
c_stream.next_in := hello;
|
|
kusano |
fc6ab3 |
c_stream.next_out := compr;
|
|
kusano |
fc6ab3 |
c_stream.avail_in := 3;
|
|
kusano |
fc6ab3 |
c_stream.avail_out := Integer(comprLen);
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_FULL_FLUSH);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflate');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)
|
|
kusano |
fc6ab3 |
c_stream.avail_in := len - 3;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_FINISH);
|
|
kusano |
fc6ab3 |
if err <> Z_STREAM_END then
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflate');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateEnd(c_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateEnd');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
comprLen := c_stream.total_out;
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test inflateSync()
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_SYNC}
|
|
kusano |
fc6ab3 |
procedure test_sync(compr: Pointer; comprLen: LongInt;
|
|
kusano |
fc6ab3 |
uncompr: Pointer; uncomprLen : LongInt);
|
|
kusano |
fc6ab3 |
var err: Integer;
|
|
kusano |
fc6ab3 |
d_stream: z_stream; (* decompression stream *)
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
StrCopy(PChar(uncompr), 'garbage');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
d_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
d_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.next_in := compr;
|
|
kusano |
fc6ab3 |
d_stream.avail_in := 2; (* just read the zlib header *)
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateInit(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.next_out := uncompr;
|
|
kusano |
fc6ab3 |
d_stream.avail_out := Integer(uncomprLen);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
inflate(d_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflate');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *)
|
|
kusano |
fc6ab3 |
err := inflateSync(d_stream); (* but skip the damaged part *)
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateSync');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflate(d_stream, Z_FINISH);
|
|
kusano |
fc6ab3 |
if err <> Z_DATA_ERROR then
|
|
kusano |
fc6ab3 |
EXIT_ERR('inflate should report DATA_ERROR');
|
|
kusano |
fc6ab3 |
(* Because of incorrect adler32 *)
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateEnd(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateEnd');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
WriteLn('after inflateSync(): hel', PChar(uncompr));
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test deflate with preset dictionary
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_DICT}
|
|
kusano |
fc6ab3 |
procedure test_dict_deflate(compr: Pointer; comprLen: LongInt);
|
|
kusano |
fc6ab3 |
var c_stream: z_stream; (* compression stream *)
|
|
kusano |
fc6ab3 |
err: Integer;
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
c_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
c_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
c_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateInit(c_stream, Z_BEST_COMPRESSION);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateSetDictionary');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
dictId := c_stream.adler;
|
|
kusano |
fc6ab3 |
c_stream.next_out := compr;
|
|
kusano |
fc6ab3 |
c_stream.avail_out := Integer(comprLen);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
c_stream.next_in := hello;
|
|
kusano |
fc6ab3 |
c_stream.avail_in := StrLen(hello)+1;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflate(c_stream, Z_FINISH);
|
|
kusano |
fc6ab3 |
if err <> Z_STREAM_END then
|
|
kusano |
fc6ab3 |
EXIT_ERR('deflate should report Z_STREAM_END');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := deflateEnd(c_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'deflateEnd');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
(* ===========================================================================
|
|
kusano |
fc6ab3 |
* Test inflate with a preset dictionary
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_DICT}
|
|
kusano |
fc6ab3 |
procedure test_dict_inflate(compr: Pointer; comprLen: LongInt;
|
|
kusano |
fc6ab3 |
uncompr: Pointer; uncomprLen: LongInt);
|
|
kusano |
fc6ab3 |
var err: Integer;
|
|
kusano |
fc6ab3 |
d_stream: z_stream; (* decompression stream *)
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
StrCopy(PChar(uncompr), 'garbage');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.zalloc := NIL;
|
|
kusano |
fc6ab3 |
d_stream.zfree := NIL;
|
|
kusano |
fc6ab3 |
d_stream.opaque := NIL;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.next_in := compr;
|
|
kusano |
fc6ab3 |
d_stream.avail_in := Integer(comprLen);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateInit(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateInit');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
d_stream.next_out := uncompr;
|
|
kusano |
fc6ab3 |
d_stream.avail_out := Integer(uncomprLen);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
while TRUE do
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
err := inflate(d_stream, Z_NO_FLUSH);
|
|
kusano |
fc6ab3 |
if err = Z_STREAM_END then
|
|
kusano |
fc6ab3 |
break;
|
|
kusano |
fc6ab3 |
if err = Z_NEED_DICT then
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
if d_stream.adler <> dictId then
|
|
kusano |
fc6ab3 |
EXIT_ERR('unexpected dictionary');
|
|
kusano |
fc6ab3 |
err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflate with dict');
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
err := inflateEnd(d_stream);
|
|
kusano |
fc6ab3 |
CHECK_ERR(err, 'inflateEnd');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
if StrComp(PChar(uncompr), hello) <> 0 then
|
|
kusano |
fc6ab3 |
EXIT_ERR('bad inflate with dict')
|
|
kusano |
fc6ab3 |
else
|
|
kusano |
fc6ab3 |
WriteLn('inflate with dictionary: ', PChar(uncompr));
|
|
kusano |
fc6ab3 |
end;
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
var compr, uncompr: Pointer;
|
|
kusano |
fc6ab3 |
comprLen, uncomprLen: LongInt;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
begin
|
|
kusano |
fc6ab3 |
if zlibVersion^ <> ZLIB_VERSION[1] then
|
|
kusano |
fc6ab3 |
EXIT_ERR('Incompatible zlib version');
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
WriteLn('zlib version: ', zlibVersion);
|
|
kusano |
fc6ab3 |
WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)
|
|
kusano |
fc6ab3 |
uncomprLen := comprLen;
|
|
kusano |
fc6ab3 |
GetMem(compr, comprLen);
|
|
kusano |
fc6ab3 |
GetMem(uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
if (compr = NIL) or (uncompr = NIL) then
|
|
kusano |
fc6ab3 |
EXIT_ERR('Out of memory');
|
|
kusano |
fc6ab3 |
(* compr and uncompr are cleared to avoid reading uninitialized
|
|
kusano |
fc6ab3 |
* data and to ensure that uncompr compresses well.
|
|
kusano |
fc6ab3 |
*)
|
|
kusano |
fc6ab3 |
FillChar(compr^, comprLen, 0);
|
|
kusano |
fc6ab3 |
FillChar(uncompr^, uncomprLen, 0);
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_COMPRESS}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing compress');
|
|
kusano |
fc6ab3 |
test_compress(compr, comprLen, uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_GZIO}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing gzio');
|
|
kusano |
fc6ab3 |
if ParamCount >= 1 then
|
|
kusano |
fc6ab3 |
test_gzio(ParamStr(1), uncompr, uncomprLen)
|
|
kusano |
fc6ab3 |
else
|
|
kusano |
fc6ab3 |
test_gzio(TESTFILE, uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_DEFLATE}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing deflate with small buffers');
|
|
kusano |
fc6ab3 |
test_deflate(compr, comprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_INFLATE}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing inflate with small buffers');
|
|
kusano |
fc6ab3 |
test_inflate(compr, comprLen, uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_DEFLATE}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing deflate with large buffers');
|
|
kusano |
fc6ab3 |
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_INFLATE}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing inflate with large buffers');
|
|
kusano |
fc6ab3 |
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_FLUSH}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing deflate with full flush');
|
|
kusano |
fc6ab3 |
test_flush(compr, comprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_SYNC}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing inflateSync');
|
|
kusano |
fc6ab3 |
test_sync(compr, comprLen, uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
comprLen := uncomprLen;
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
{$IFDEF TEST_DICT}
|
|
kusano |
fc6ab3 |
WriteLn('** Testing deflate and inflate with preset dictionary');
|
|
kusano |
fc6ab3 |
test_dict_deflate(compr, comprLen);
|
|
kusano |
fc6ab3 |
test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
{$ENDIF}
|
|
kusano |
fc6ab3 |
|
|
kusano |
fc6ab3 |
FreeMem(compr, comprLen);
|
|
kusano |
fc6ab3 |
FreeMem(uncompr, uncomprLen);
|
|
kusano |
fc6ab3 |
end.
|