1*aaf4ece6Schristos (* example.c -- usage example of the zlib compression library 2*aaf4ece6Schristos * Copyright (C) 1995-2003 Jean-loup Gailly. 3*aaf4ece6Schristos * For conditions of distribution and use, see copyright notice in zlib.h 4*aaf4ece6Schristos * 5*aaf4ece6Schristos * Pascal translation 6*aaf4ece6Schristos * Copyright (C) 1998 by Jacques Nomssi Nzali. 7*aaf4ece6Schristos * For conditions of distribution and use, see copyright notice in readme.txt 8*aaf4ece6Schristos * 9*aaf4ece6Schristos * Adaptation to the zlibpas interface 10*aaf4ece6Schristos * Copyright (C) 2003 by Cosmin Truta. 11*aaf4ece6Schristos * For conditions of distribution and use, see copyright notice in readme.txt 12*aaf4ece6Schristos *) 13*aaf4ece6Schristos 14*aaf4ece6Schristos program example; 15*aaf4ece6Schristos 16*aaf4ece6Schristos {$DEFINE TEST_COMPRESS} 17*aaf4ece6Schristos {DO NOT $DEFINE TEST_GZIO} 18*aaf4ece6Schristos {$DEFINE TEST_DEFLATE} 19*aaf4ece6Schristos {$DEFINE TEST_INFLATE} 20*aaf4ece6Schristos {$DEFINE TEST_FLUSH} 21*aaf4ece6Schristos {$DEFINE TEST_SYNC} 22*aaf4ece6Schristos {$DEFINE TEST_DICT} 23*aaf4ece6Schristos 24*aaf4ece6Schristos uses SysUtils, zlibpas; 25*aaf4ece6Schristos 26*aaf4ece6Schristos const TESTFILE = 'foo.gz'; 27*aaf4ece6Schristos 28*aaf4ece6Schristos (* "hello world" would be more standard, but the repeated "hello" 29*aaf4ece6Schristos * stresses the compression code better, sorry... 30*aaf4ece6Schristos *) 31*aaf4ece6Schristos const hello: PChar = 'hello, hello!'; 32*aaf4ece6Schristos 33*aaf4ece6Schristos const dictionary: PChar = 'hello'; 34*aaf4ece6Schristos 35*aaf4ece6Schristos var dictId: LongInt; (* Adler32 value of the dictionary *) 36*aaf4ece6Schristos 37*aaf4ece6Schristos procedure CHECK_ERR(err: Integer; msg: String); 38*aaf4ece6Schristos begin 39*aaf4ece6Schristos if err <> Z_OK then 40*aaf4ece6Schristos begin 41*aaf4ece6Schristos WriteLn(msg, ' error: ', err); 42*aaf4ece6Schristos Halt(1); 43*aaf4ece6Schristos end; 44*aaf4ece6Schristos end; 45*aaf4ece6Schristos 46*aaf4ece6Schristos procedure EXIT_ERR(const msg: String); 47*aaf4ece6Schristos begin 48*aaf4ece6Schristos WriteLn('Error: ', msg); 49*aaf4ece6Schristos Halt(1); 50*aaf4ece6Schristos end; 51*aaf4ece6Schristos 52*aaf4ece6Schristos (* =========================================================================== 53*aaf4ece6Schristos * Test compress and uncompress 54*aaf4ece6Schristos *) 55*aaf4ece6Schristos {$IFDEF TEST_COMPRESS} 56*aaf4ece6Schristos procedure test_compress(compr: Pointer; comprLen: LongInt; 57*aaf4ece6Schristos uncompr: Pointer; uncomprLen: LongInt); 58*aaf4ece6Schristos var err: Integer; 59*aaf4ece6Schristos len: LongInt; 60*aaf4ece6Schristos begin 61*aaf4ece6Schristos len := StrLen(hello)+1; 62*aaf4ece6Schristos 63*aaf4ece6Schristos err := compress(compr, comprLen, hello, len); 64*aaf4ece6Schristos CHECK_ERR(err, 'compress'); 65*aaf4ece6Schristos 66*aaf4ece6Schristos StrCopy(PChar(uncompr), 'garbage'); 67*aaf4ece6Schristos 68*aaf4ece6Schristos err := uncompress(uncompr, uncomprLen, compr, comprLen); 69*aaf4ece6Schristos CHECK_ERR(err, 'uncompress'); 70*aaf4ece6Schristos 71*aaf4ece6Schristos if StrComp(PChar(uncompr), hello) <> 0 then 72*aaf4ece6Schristos EXIT_ERR('bad uncompress') 73*aaf4ece6Schristos else 74*aaf4ece6Schristos WriteLn('uncompress(): ', PChar(uncompr)); 75*aaf4ece6Schristos end; 76*aaf4ece6Schristos {$ENDIF} 77*aaf4ece6Schristos 78*aaf4ece6Schristos (* =========================================================================== 79*aaf4ece6Schristos * Test read/write of .gz files 80*aaf4ece6Schristos *) 81*aaf4ece6Schristos {$IFDEF TEST_GZIO} 82*aaf4ece6Schristos procedure test_gzio(const fname: PChar; (* compressed file name *) 83*aaf4ece6Schristos uncompr: Pointer; 84*aaf4ece6Schristos uncomprLen: LongInt); 85*aaf4ece6Schristos var err: Integer; 86*aaf4ece6Schristos len: Integer; 87*aaf4ece6Schristos zfile: gzFile; 88*aaf4ece6Schristos pos: LongInt; 89*aaf4ece6Schristos begin 90*aaf4ece6Schristos len := StrLen(hello)+1; 91*aaf4ece6Schristos 92*aaf4ece6Schristos zfile := gzopen(fname, 'wb'); 93*aaf4ece6Schristos if zfile = NIL then 94*aaf4ece6Schristos begin 95*aaf4ece6Schristos WriteLn('gzopen error'); 96*aaf4ece6Schristos Halt(1); 97*aaf4ece6Schristos end; 98*aaf4ece6Schristos gzputc(zfile, 'h'); 99*aaf4ece6Schristos if gzputs(zfile, 'ello') <> 4 then 100*aaf4ece6Schristos begin 101*aaf4ece6Schristos WriteLn('gzputs err: ', gzerror(zfile, err)); 102*aaf4ece6Schristos Halt(1); 103*aaf4ece6Schristos end; 104*aaf4ece6Schristos {$IFDEF GZ_FORMAT_STRING} 105*aaf4ece6Schristos if gzprintf(zfile, ', %s!', 'hello') <> 8 then 106*aaf4ece6Schristos begin 107*aaf4ece6Schristos WriteLn('gzprintf err: ', gzerror(zfile, err)); 108*aaf4ece6Schristos Halt(1); 109*aaf4ece6Schristos end; 110*aaf4ece6Schristos {$ELSE} 111*aaf4ece6Schristos if gzputs(zfile, ', hello!') <> 8 then 112*aaf4ece6Schristos begin 113*aaf4ece6Schristos WriteLn('gzputs err: ', gzerror(zfile, err)); 114*aaf4ece6Schristos Halt(1); 115*aaf4ece6Schristos end; 116*aaf4ece6Schristos {$ENDIF} 117*aaf4ece6Schristos gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *) 118*aaf4ece6Schristos gzclose(zfile); 119*aaf4ece6Schristos 120*aaf4ece6Schristos zfile := gzopen(fname, 'rb'); 121*aaf4ece6Schristos if zfile = NIL then 122*aaf4ece6Schristos begin 123*aaf4ece6Schristos WriteLn('gzopen error'); 124*aaf4ece6Schristos Halt(1); 125*aaf4ece6Schristos end; 126*aaf4ece6Schristos 127*aaf4ece6Schristos StrCopy(PChar(uncompr), 'garbage'); 128*aaf4ece6Schristos 129*aaf4ece6Schristos if gzread(zfile, uncompr, uncomprLen) <> len then 130*aaf4ece6Schristos begin 131*aaf4ece6Schristos WriteLn('gzread err: ', gzerror(zfile, err)); 132*aaf4ece6Schristos Halt(1); 133*aaf4ece6Schristos end; 134*aaf4ece6Schristos if StrComp(PChar(uncompr), hello) <> 0 then 135*aaf4ece6Schristos begin 136*aaf4ece6Schristos WriteLn('bad gzread: ', PChar(uncompr)); 137*aaf4ece6Schristos Halt(1); 138*aaf4ece6Schristos end 139*aaf4ece6Schristos else 140*aaf4ece6Schristos WriteLn('gzread(): ', PChar(uncompr)); 141*aaf4ece6Schristos 142*aaf4ece6Schristos pos := gzseek(zfile, -8, SEEK_CUR); 143*aaf4ece6Schristos if (pos <> 6) or (gztell(zfile) <> pos) then 144*aaf4ece6Schristos begin 145*aaf4ece6Schristos WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile)); 146*aaf4ece6Schristos Halt(1); 147*aaf4ece6Schristos end; 148*aaf4ece6Schristos 149*aaf4ece6Schristos if gzgetc(zfile) <> ' ' then 150*aaf4ece6Schristos begin 151*aaf4ece6Schristos WriteLn('gzgetc error'); 152*aaf4ece6Schristos Halt(1); 153*aaf4ece6Schristos end; 154*aaf4ece6Schristos 155*aaf4ece6Schristos if gzungetc(' ', zfile) <> ' ' then 156*aaf4ece6Schristos begin 157*aaf4ece6Schristos WriteLn('gzungetc error'); 158*aaf4ece6Schristos Halt(1); 159*aaf4ece6Schristos end; 160*aaf4ece6Schristos 161*aaf4ece6Schristos gzgets(zfile, PChar(uncompr), uncomprLen); 162*aaf4ece6Schristos uncomprLen := StrLen(PChar(uncompr)); 163*aaf4ece6Schristos if uncomprLen <> 7 then (* " hello!" *) 164*aaf4ece6Schristos begin 165*aaf4ece6Schristos WriteLn('gzgets err after gzseek: ', gzerror(zfile, err)); 166*aaf4ece6Schristos Halt(1); 167*aaf4ece6Schristos end; 168*aaf4ece6Schristos if StrComp(PChar(uncompr), hello + 6) <> 0 then 169*aaf4ece6Schristos begin 170*aaf4ece6Schristos WriteLn('bad gzgets after gzseek'); 171*aaf4ece6Schristos Halt(1); 172*aaf4ece6Schristos end 173*aaf4ece6Schristos else 174*aaf4ece6Schristos WriteLn('gzgets() after gzseek: ', PChar(uncompr)); 175*aaf4ece6Schristos 176*aaf4ece6Schristos gzclose(zfile); 177*aaf4ece6Schristos end; 178*aaf4ece6Schristos {$ENDIF} 179*aaf4ece6Schristos 180*aaf4ece6Schristos (* =========================================================================== 181*aaf4ece6Schristos * Test deflate with small buffers 182*aaf4ece6Schristos *) 183*aaf4ece6Schristos {$IFDEF TEST_DEFLATE} 184*aaf4ece6Schristos procedure test_deflate(compr: Pointer; comprLen: LongInt); 185*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *) 186*aaf4ece6Schristos err: Integer; 187*aaf4ece6Schristos len: LongInt; 188*aaf4ece6Schristos begin 189*aaf4ece6Schristos len := StrLen(hello)+1; 190*aaf4ece6Schristos 191*aaf4ece6Schristos c_stream.zalloc := NIL; 192*aaf4ece6Schristos c_stream.zfree := NIL; 193*aaf4ece6Schristos c_stream.opaque := NIL; 194*aaf4ece6Schristos 195*aaf4ece6Schristos err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); 196*aaf4ece6Schristos CHECK_ERR(err, 'deflateInit'); 197*aaf4ece6Schristos 198*aaf4ece6Schristos c_stream.next_in := hello; 199*aaf4ece6Schristos c_stream.next_out := compr; 200*aaf4ece6Schristos 201*aaf4ece6Schristos while (c_stream.total_in <> len) and 202*aaf4ece6Schristos (c_stream.total_out < comprLen) do 203*aaf4ece6Schristos begin 204*aaf4ece6Schristos c_stream.avail_out := 1; { force small buffers } 205*aaf4ece6Schristos c_stream.avail_in := 1; 206*aaf4ece6Schristos err := deflate(c_stream, Z_NO_FLUSH); 207*aaf4ece6Schristos CHECK_ERR(err, 'deflate'); 208*aaf4ece6Schristos end; 209*aaf4ece6Schristos 210*aaf4ece6Schristos (* Finish the stream, still forcing small buffers: *) 211*aaf4ece6Schristos while TRUE do 212*aaf4ece6Schristos begin 213*aaf4ece6Schristos c_stream.avail_out := 1; 214*aaf4ece6Schristos err := deflate(c_stream, Z_FINISH); 215*aaf4ece6Schristos if err = Z_STREAM_END then 216*aaf4ece6Schristos break; 217*aaf4ece6Schristos CHECK_ERR(err, 'deflate'); 218*aaf4ece6Schristos end; 219*aaf4ece6Schristos 220*aaf4ece6Schristos err := deflateEnd(c_stream); 221*aaf4ece6Schristos CHECK_ERR(err, 'deflateEnd'); 222*aaf4ece6Schristos end; 223*aaf4ece6Schristos {$ENDIF} 224*aaf4ece6Schristos 225*aaf4ece6Schristos (* =========================================================================== 226*aaf4ece6Schristos * Test inflate with small buffers 227*aaf4ece6Schristos *) 228*aaf4ece6Schristos {$IFDEF TEST_INFLATE} 229*aaf4ece6Schristos procedure test_inflate(compr: Pointer; comprLen : LongInt; 230*aaf4ece6Schristos uncompr: Pointer; uncomprLen : LongInt); 231*aaf4ece6Schristos var err: Integer; 232*aaf4ece6Schristos d_stream: z_stream; (* decompression stream *) 233*aaf4ece6Schristos begin 234*aaf4ece6Schristos StrCopy(PChar(uncompr), 'garbage'); 235*aaf4ece6Schristos 236*aaf4ece6Schristos d_stream.zalloc := NIL; 237*aaf4ece6Schristos d_stream.zfree := NIL; 238*aaf4ece6Schristos d_stream.opaque := NIL; 239*aaf4ece6Schristos 240*aaf4ece6Schristos d_stream.next_in := compr; 241*aaf4ece6Schristos d_stream.avail_in := 0; 242*aaf4ece6Schristos d_stream.next_out := uncompr; 243*aaf4ece6Schristos 244*aaf4ece6Schristos err := inflateInit(d_stream); 245*aaf4ece6Schristos CHECK_ERR(err, 'inflateInit'); 246*aaf4ece6Schristos 247*aaf4ece6Schristos while (d_stream.total_out < uncomprLen) and 248*aaf4ece6Schristos (d_stream.total_in < comprLen) do 249*aaf4ece6Schristos begin 250*aaf4ece6Schristos d_stream.avail_out := 1; (* force small buffers *) 251*aaf4ece6Schristos d_stream.avail_in := 1; 252*aaf4ece6Schristos err := inflate(d_stream, Z_NO_FLUSH); 253*aaf4ece6Schristos if err = Z_STREAM_END then 254*aaf4ece6Schristos break; 255*aaf4ece6Schristos CHECK_ERR(err, 'inflate'); 256*aaf4ece6Schristos end; 257*aaf4ece6Schristos 258*aaf4ece6Schristos err := inflateEnd(d_stream); 259*aaf4ece6Schristos CHECK_ERR(err, 'inflateEnd'); 260*aaf4ece6Schristos 261*aaf4ece6Schristos if StrComp(PChar(uncompr), hello) <> 0 then 262*aaf4ece6Schristos EXIT_ERR('bad inflate') 263*aaf4ece6Schristos else 264*aaf4ece6Schristos WriteLn('inflate(): ', PChar(uncompr)); 265*aaf4ece6Schristos end; 266*aaf4ece6Schristos {$ENDIF} 267*aaf4ece6Schristos 268*aaf4ece6Schristos (* =========================================================================== 269*aaf4ece6Schristos * Test deflate with large buffers and dynamic change of compression level 270*aaf4ece6Schristos *) 271*aaf4ece6Schristos {$IFDEF TEST_DEFLATE} 272*aaf4ece6Schristos procedure test_large_deflate(compr: Pointer; comprLen: LongInt; 273*aaf4ece6Schristos uncompr: Pointer; uncomprLen: LongInt); 274*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *) 275*aaf4ece6Schristos err: Integer; 276*aaf4ece6Schristos begin 277*aaf4ece6Schristos c_stream.zalloc := NIL; 278*aaf4ece6Schristos c_stream.zfree := NIL; 279*aaf4ece6Schristos c_stream.opaque := NIL; 280*aaf4ece6Schristos 281*aaf4ece6Schristos err := deflateInit(c_stream, Z_BEST_SPEED); 282*aaf4ece6Schristos CHECK_ERR(err, 'deflateInit'); 283*aaf4ece6Schristos 284*aaf4ece6Schristos c_stream.next_out := compr; 285*aaf4ece6Schristos c_stream.avail_out := Integer(comprLen); 286*aaf4ece6Schristos 287*aaf4ece6Schristos (* At this point, uncompr is still mostly zeroes, so it should compress 288*aaf4ece6Schristos * very well: 289*aaf4ece6Schristos *) 290*aaf4ece6Schristos c_stream.next_in := uncompr; 291*aaf4ece6Schristos c_stream.avail_in := Integer(uncomprLen); 292*aaf4ece6Schristos err := deflate(c_stream, Z_NO_FLUSH); 293*aaf4ece6Schristos CHECK_ERR(err, 'deflate'); 294*aaf4ece6Schristos if c_stream.avail_in <> 0 then 295*aaf4ece6Schristos EXIT_ERR('deflate not greedy'); 296*aaf4ece6Schristos 297*aaf4ece6Schristos (* Feed in already compressed data and switch to no compression: *) 298*aaf4ece6Schristos deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); 299*aaf4ece6Schristos c_stream.next_in := compr; 300*aaf4ece6Schristos c_stream.avail_in := Integer(comprLen div 2); 301*aaf4ece6Schristos err := deflate(c_stream, Z_NO_FLUSH); 302*aaf4ece6Schristos CHECK_ERR(err, 'deflate'); 303*aaf4ece6Schristos 304*aaf4ece6Schristos (* Switch back to compressing mode: *) 305*aaf4ece6Schristos deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED); 306*aaf4ece6Schristos c_stream.next_in := uncompr; 307*aaf4ece6Schristos c_stream.avail_in := Integer(uncomprLen); 308*aaf4ece6Schristos err := deflate(c_stream, Z_NO_FLUSH); 309*aaf4ece6Schristos CHECK_ERR(err, 'deflate'); 310*aaf4ece6Schristos 311*aaf4ece6Schristos err := deflate(c_stream, Z_FINISH); 312*aaf4ece6Schristos if err <> Z_STREAM_END then 313*aaf4ece6Schristos EXIT_ERR('deflate should report Z_STREAM_END'); 314*aaf4ece6Schristos 315*aaf4ece6Schristos err := deflateEnd(c_stream); 316*aaf4ece6Schristos CHECK_ERR(err, 'deflateEnd'); 317*aaf4ece6Schristos end; 318*aaf4ece6Schristos {$ENDIF} 319*aaf4ece6Schristos 320*aaf4ece6Schristos (* =========================================================================== 321*aaf4ece6Schristos * Test inflate with large buffers 322*aaf4ece6Schristos *) 323*aaf4ece6Schristos {$IFDEF TEST_INFLATE} 324*aaf4ece6Schristos procedure test_large_inflate(compr: Pointer; comprLen: LongInt; 325*aaf4ece6Schristos uncompr: Pointer; uncomprLen: LongInt); 326*aaf4ece6Schristos var err: Integer; 327*aaf4ece6Schristos d_stream: z_stream; (* decompression stream *) 328*aaf4ece6Schristos begin 329*aaf4ece6Schristos StrCopy(PChar(uncompr), 'garbage'); 330*aaf4ece6Schristos 331*aaf4ece6Schristos d_stream.zalloc := NIL; 332*aaf4ece6Schristos d_stream.zfree := NIL; 333*aaf4ece6Schristos d_stream.opaque := NIL; 334*aaf4ece6Schristos 335*aaf4ece6Schristos d_stream.next_in := compr; 336*aaf4ece6Schristos d_stream.avail_in := Integer(comprLen); 337*aaf4ece6Schristos 338*aaf4ece6Schristos err := inflateInit(d_stream); 339*aaf4ece6Schristos CHECK_ERR(err, 'inflateInit'); 340*aaf4ece6Schristos 341*aaf4ece6Schristos while TRUE do 342*aaf4ece6Schristos begin 343*aaf4ece6Schristos d_stream.next_out := uncompr; (* discard the output *) 344*aaf4ece6Schristos d_stream.avail_out := Integer(uncomprLen); 345*aaf4ece6Schristos err := inflate(d_stream, Z_NO_FLUSH); 346*aaf4ece6Schristos if err = Z_STREAM_END then 347*aaf4ece6Schristos break; 348*aaf4ece6Schristos CHECK_ERR(err, 'large inflate'); 349*aaf4ece6Schristos end; 350*aaf4ece6Schristos 351*aaf4ece6Schristos err := inflateEnd(d_stream); 352*aaf4ece6Schristos CHECK_ERR(err, 'inflateEnd'); 353*aaf4ece6Schristos 354*aaf4ece6Schristos if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then 355*aaf4ece6Schristos begin 356*aaf4ece6Schristos WriteLn('bad large inflate: ', d_stream.total_out); 357*aaf4ece6Schristos Halt(1); 358*aaf4ece6Schristos end 359*aaf4ece6Schristos else 360*aaf4ece6Schristos WriteLn('large_inflate(): OK'); 361*aaf4ece6Schristos end; 362*aaf4ece6Schristos {$ENDIF} 363*aaf4ece6Schristos 364*aaf4ece6Schristos (* =========================================================================== 365*aaf4ece6Schristos * Test deflate with full flush 366*aaf4ece6Schristos *) 367*aaf4ece6Schristos {$IFDEF TEST_FLUSH} 368*aaf4ece6Schristos procedure test_flush(compr: Pointer; var comprLen : LongInt); 369*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *) 370*aaf4ece6Schristos err: Integer; 371*aaf4ece6Schristos len: Integer; 372*aaf4ece6Schristos begin 373*aaf4ece6Schristos len := StrLen(hello)+1; 374*aaf4ece6Schristos 375*aaf4ece6Schristos c_stream.zalloc := NIL; 376*aaf4ece6Schristos c_stream.zfree := NIL; 377*aaf4ece6Schristos c_stream.opaque := NIL; 378*aaf4ece6Schristos 379*aaf4ece6Schristos err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION); 380*aaf4ece6Schristos CHECK_ERR(err, 'deflateInit'); 381*aaf4ece6Schristos 382*aaf4ece6Schristos c_stream.next_in := hello; 383*aaf4ece6Schristos c_stream.next_out := compr; 384*aaf4ece6Schristos c_stream.avail_in := 3; 385*aaf4ece6Schristos c_stream.avail_out := Integer(comprLen); 386*aaf4ece6Schristos err := deflate(c_stream, Z_FULL_FLUSH); 387*aaf4ece6Schristos CHECK_ERR(err, 'deflate'); 388*aaf4ece6Schristos 389*aaf4ece6Schristos Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *) 390*aaf4ece6Schristos c_stream.avail_in := len - 3; 391*aaf4ece6Schristos 392*aaf4ece6Schristos err := deflate(c_stream, Z_FINISH); 393*aaf4ece6Schristos if err <> Z_STREAM_END then 394*aaf4ece6Schristos CHECK_ERR(err, 'deflate'); 395*aaf4ece6Schristos 396*aaf4ece6Schristos err := deflateEnd(c_stream); 397*aaf4ece6Schristos CHECK_ERR(err, 'deflateEnd'); 398*aaf4ece6Schristos 399*aaf4ece6Schristos comprLen := c_stream.total_out; 400*aaf4ece6Schristos end; 401*aaf4ece6Schristos {$ENDIF} 402*aaf4ece6Schristos 403*aaf4ece6Schristos (* =========================================================================== 404*aaf4ece6Schristos * Test inflateSync() 405*aaf4ece6Schristos *) 406*aaf4ece6Schristos {$IFDEF TEST_SYNC} 407*aaf4ece6Schristos procedure test_sync(compr: Pointer; comprLen: LongInt; 408*aaf4ece6Schristos uncompr: Pointer; uncomprLen : LongInt); 409*aaf4ece6Schristos var err: Integer; 410*aaf4ece6Schristos d_stream: z_stream; (* decompression stream *) 411*aaf4ece6Schristos begin 412*aaf4ece6Schristos StrCopy(PChar(uncompr), 'garbage'); 413*aaf4ece6Schristos 414*aaf4ece6Schristos d_stream.zalloc := NIL; 415*aaf4ece6Schristos d_stream.zfree := NIL; 416*aaf4ece6Schristos d_stream.opaque := NIL; 417*aaf4ece6Schristos 418*aaf4ece6Schristos d_stream.next_in := compr; 419*aaf4ece6Schristos d_stream.avail_in := 2; (* just read the zlib header *) 420*aaf4ece6Schristos 421*aaf4ece6Schristos err := inflateInit(d_stream); 422*aaf4ece6Schristos CHECK_ERR(err, 'inflateInit'); 423*aaf4ece6Schristos 424*aaf4ece6Schristos d_stream.next_out := uncompr; 425*aaf4ece6Schristos d_stream.avail_out := Integer(uncomprLen); 426*aaf4ece6Schristos 427*aaf4ece6Schristos inflate(d_stream, Z_NO_FLUSH); 428*aaf4ece6Schristos CHECK_ERR(err, 'inflate'); 429*aaf4ece6Schristos 430*aaf4ece6Schristos d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *) 431*aaf4ece6Schristos err := inflateSync(d_stream); (* but skip the damaged part *) 432*aaf4ece6Schristos CHECK_ERR(err, 'inflateSync'); 433*aaf4ece6Schristos 434*aaf4ece6Schristos err := inflate(d_stream, Z_FINISH); 435*aaf4ece6Schristos if err <> Z_DATA_ERROR then 436*aaf4ece6Schristos EXIT_ERR('inflate should report DATA_ERROR'); 437*aaf4ece6Schristos (* Because of incorrect adler32 *) 438*aaf4ece6Schristos 439*aaf4ece6Schristos err := inflateEnd(d_stream); 440*aaf4ece6Schristos CHECK_ERR(err, 'inflateEnd'); 441*aaf4ece6Schristos 442*aaf4ece6Schristos WriteLn('after inflateSync(): hel', PChar(uncompr)); 443*aaf4ece6Schristos end; 444*aaf4ece6Schristos {$ENDIF} 445*aaf4ece6Schristos 446*aaf4ece6Schristos (* =========================================================================== 447*aaf4ece6Schristos * Test deflate with preset dictionary 448*aaf4ece6Schristos *) 449*aaf4ece6Schristos {$IFDEF TEST_DICT} 450*aaf4ece6Schristos procedure test_dict_deflate(compr: Pointer; comprLen: LongInt); 451*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *) 452*aaf4ece6Schristos err: Integer; 453*aaf4ece6Schristos begin 454*aaf4ece6Schristos c_stream.zalloc := NIL; 455*aaf4ece6Schristos c_stream.zfree := NIL; 456*aaf4ece6Schristos c_stream.opaque := NIL; 457*aaf4ece6Schristos 458*aaf4ece6Schristos err := deflateInit(c_stream, Z_BEST_COMPRESSION); 459*aaf4ece6Schristos CHECK_ERR(err, 'deflateInit'); 460*aaf4ece6Schristos 461*aaf4ece6Schristos err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary)); 462*aaf4ece6Schristos CHECK_ERR(err, 'deflateSetDictionary'); 463*aaf4ece6Schristos 464*aaf4ece6Schristos dictId := c_stream.adler; 465*aaf4ece6Schristos c_stream.next_out := compr; 466*aaf4ece6Schristos c_stream.avail_out := Integer(comprLen); 467*aaf4ece6Schristos 468*aaf4ece6Schristos c_stream.next_in := hello; 469*aaf4ece6Schristos c_stream.avail_in := StrLen(hello)+1; 470*aaf4ece6Schristos 471*aaf4ece6Schristos err := deflate(c_stream, Z_FINISH); 472*aaf4ece6Schristos if err <> Z_STREAM_END then 473*aaf4ece6Schristos EXIT_ERR('deflate should report Z_STREAM_END'); 474*aaf4ece6Schristos 475*aaf4ece6Schristos err := deflateEnd(c_stream); 476*aaf4ece6Schristos CHECK_ERR(err, 'deflateEnd'); 477*aaf4ece6Schristos end; 478*aaf4ece6Schristos {$ENDIF} 479*aaf4ece6Schristos 480*aaf4ece6Schristos (* =========================================================================== 481*aaf4ece6Schristos * Test inflate with a preset dictionary 482*aaf4ece6Schristos *) 483*aaf4ece6Schristos {$IFDEF TEST_DICT} 484*aaf4ece6Schristos procedure test_dict_inflate(compr: Pointer; comprLen: LongInt; 485*aaf4ece6Schristos uncompr: Pointer; uncomprLen: LongInt); 486*aaf4ece6Schristos var err: Integer; 487*aaf4ece6Schristos d_stream: z_stream; (* decompression stream *) 488*aaf4ece6Schristos begin 489*aaf4ece6Schristos StrCopy(PChar(uncompr), 'garbage'); 490*aaf4ece6Schristos 491*aaf4ece6Schristos d_stream.zalloc := NIL; 492*aaf4ece6Schristos d_stream.zfree := NIL; 493*aaf4ece6Schristos d_stream.opaque := NIL; 494*aaf4ece6Schristos 495*aaf4ece6Schristos d_stream.next_in := compr; 496*aaf4ece6Schristos d_stream.avail_in := Integer(comprLen); 497*aaf4ece6Schristos 498*aaf4ece6Schristos err := inflateInit(d_stream); 499*aaf4ece6Schristos CHECK_ERR(err, 'inflateInit'); 500*aaf4ece6Schristos 501*aaf4ece6Schristos d_stream.next_out := uncompr; 502*aaf4ece6Schristos d_stream.avail_out := Integer(uncomprLen); 503*aaf4ece6Schristos 504*aaf4ece6Schristos while TRUE do 505*aaf4ece6Schristos begin 506*aaf4ece6Schristos err := inflate(d_stream, Z_NO_FLUSH); 507*aaf4ece6Schristos if err = Z_STREAM_END then 508*aaf4ece6Schristos break; 509*aaf4ece6Schristos if err = Z_NEED_DICT then 510*aaf4ece6Schristos begin 511*aaf4ece6Schristos if d_stream.adler <> dictId then 512*aaf4ece6Schristos EXIT_ERR('unexpected dictionary'); 513*aaf4ece6Schristos err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary)); 514*aaf4ece6Schristos end; 515*aaf4ece6Schristos CHECK_ERR(err, 'inflate with dict'); 516*aaf4ece6Schristos end; 517*aaf4ece6Schristos 518*aaf4ece6Schristos err := inflateEnd(d_stream); 519*aaf4ece6Schristos CHECK_ERR(err, 'inflateEnd'); 520*aaf4ece6Schristos 521*aaf4ece6Schristos if StrComp(PChar(uncompr), hello) <> 0 then 522*aaf4ece6Schristos EXIT_ERR('bad inflate with dict') 523*aaf4ece6Schristos else 524*aaf4ece6Schristos WriteLn('inflate with dictionary: ', PChar(uncompr)); 525*aaf4ece6Schristos end; 526*aaf4ece6Schristos {$ENDIF} 527*aaf4ece6Schristos 528*aaf4ece6Schristos var compr, uncompr: Pointer; 529*aaf4ece6Schristos comprLen, uncomprLen: LongInt; 530*aaf4ece6Schristos 531*aaf4ece6Schristos begin 532*aaf4ece6Schristos if zlibVersion^ <> ZLIB_VERSION[1] then 533*aaf4ece6Schristos EXIT_ERR('Incompatible zlib version'); 534*aaf4ece6Schristos 535*aaf4ece6Schristos WriteLn('zlib version: ', zlibVersion); 536*aaf4ece6Schristos WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags])); 537*aaf4ece6Schristos 538*aaf4ece6Schristos comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *) 539*aaf4ece6Schristos uncomprLen := comprLen; 540*aaf4ece6Schristos GetMem(compr, comprLen); 541*aaf4ece6Schristos GetMem(uncompr, uncomprLen); 542*aaf4ece6Schristos if (compr = NIL) or (uncompr = NIL) then 543*aaf4ece6Schristos EXIT_ERR('Out of memory'); 544*aaf4ece6Schristos (* compr and uncompr are cleared to avoid reading uninitialized 545*aaf4ece6Schristos * data and to ensure that uncompr compresses well. 546*aaf4ece6Schristos *) 547*aaf4ece6Schristos FillChar(compr^, comprLen, 0); 548*aaf4ece6Schristos FillChar(uncompr^, uncomprLen, 0); 549*aaf4ece6Schristos 550*aaf4ece6Schristos {$IFDEF TEST_COMPRESS} 551*aaf4ece6Schristos WriteLn('** Testing compress'); 552*aaf4ece6Schristos test_compress(compr, comprLen, uncompr, uncomprLen); 553*aaf4ece6Schristos {$ENDIF} 554*aaf4ece6Schristos 555*aaf4ece6Schristos {$IFDEF TEST_GZIO} 556*aaf4ece6Schristos WriteLn('** Testing gzio'); 557*aaf4ece6Schristos if ParamCount >= 1 then 558*aaf4ece6Schristos test_gzio(ParamStr(1), uncompr, uncomprLen) 559*aaf4ece6Schristos else 560*aaf4ece6Schristos test_gzio(TESTFILE, uncompr, uncomprLen); 561*aaf4ece6Schristos {$ENDIF} 562*aaf4ece6Schristos 563*aaf4ece6Schristos {$IFDEF TEST_DEFLATE} 564*aaf4ece6Schristos WriteLn('** Testing deflate with small buffers'); 565*aaf4ece6Schristos test_deflate(compr, comprLen); 566*aaf4ece6Schristos {$ENDIF} 567*aaf4ece6Schristos {$IFDEF TEST_INFLATE} 568*aaf4ece6Schristos WriteLn('** Testing inflate with small buffers'); 569*aaf4ece6Schristos test_inflate(compr, comprLen, uncompr, uncomprLen); 570*aaf4ece6Schristos {$ENDIF} 571*aaf4ece6Schristos 572*aaf4ece6Schristos {$IFDEF TEST_DEFLATE} 573*aaf4ece6Schristos WriteLn('** Testing deflate with large buffers'); 574*aaf4ece6Schristos test_large_deflate(compr, comprLen, uncompr, uncomprLen); 575*aaf4ece6Schristos {$ENDIF} 576*aaf4ece6Schristos {$IFDEF TEST_INFLATE} 577*aaf4ece6Schristos WriteLn('** Testing inflate with large buffers'); 578*aaf4ece6Schristos test_large_inflate(compr, comprLen, uncompr, uncomprLen); 579*aaf4ece6Schristos {$ENDIF} 580*aaf4ece6Schristos 581*aaf4ece6Schristos {$IFDEF TEST_FLUSH} 582*aaf4ece6Schristos WriteLn('** Testing deflate with full flush'); 583*aaf4ece6Schristos test_flush(compr, comprLen); 584*aaf4ece6Schristos {$ENDIF} 585*aaf4ece6Schristos {$IFDEF TEST_SYNC} 586*aaf4ece6Schristos WriteLn('** Testing inflateSync'); 587*aaf4ece6Schristos test_sync(compr, comprLen, uncompr, uncomprLen); 588*aaf4ece6Schristos {$ENDIF} 589*aaf4ece6Schristos comprLen := uncomprLen; 590*aaf4ece6Schristos 591*aaf4ece6Schristos {$IFDEF TEST_DICT} 592*aaf4ece6Schristos WriteLn('** Testing deflate and inflate with preset dictionary'); 593*aaf4ece6Schristos test_dict_deflate(compr, comprLen); 594*aaf4ece6Schristos test_dict_inflate(compr, comprLen, uncompr, uncomprLen); 595*aaf4ece6Schristos {$ENDIF} 596*aaf4ece6Schristos 597*aaf4ece6Schristos FreeMem(compr, comprLen); 598*aaf4ece6Schristos FreeMem(uncompr, uncomprLen); 599*aaf4ece6Schristos end. 600