xref: /minix3/common/dist/zlib/contrib/pascal/example.pas (revision 44bedb31d842b4b0444105519bcf929a69fe2dc1)
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