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