1 /* $NetBSD: example.c,v 1.1.1.1 2006/01/14 20:10:28 christos Exp $ */
3 /* example.c -- usage example of the zlib compression library
4 * Copyright (C) 1995-2004 Jean-loup Gailly.
5 * For conditions of distribution and use, see copyright notice in zlib.h
18 #if defined(VMS) || defined(RISCOS)
19 # define TESTFILE "foo-gz"
21 # define TESTFILE "foo.gz"
24 #define CHECK_ERR(err, msg) { \
26 fprintf(stderr, "%s error: %d\n", msg, err); \
31 const char hello
[] = "hello, hello!";
32 /* "hello world" would be more standard, but the repeated "hello"
33 * stresses the compression code better, sorry...
36 const char dictionary
[] = "hello";
37 uLong dictId
; /* Adler32 value of the dictionary */
39 void test_compress
OF((Byte
*compr
, uLong comprLen
,
40 Byte
*uncompr
, uLong uncomprLen
));
41 void test_gzio
OF((const char *fname
,
42 Byte
*uncompr
, uLong uncomprLen
));
43 void test_deflate
OF((Byte
*compr
, uLong comprLen
));
44 void test_inflate
OF((Byte
*compr
, uLong comprLen
,
45 Byte
*uncompr
, uLong uncomprLen
));
46 void test_large_deflate
OF((Byte
*compr
, uLong comprLen
,
47 Byte
*uncompr
, uLong uncomprLen
));
48 void test_large_inflate
OF((Byte
*compr
, uLong comprLen
,
49 Byte
*uncompr
, uLong uncomprLen
));
50 void test_flush
OF((Byte
*compr
, uLong
*comprLen
));
51 void test_sync
OF((Byte
*compr
, uLong comprLen
,
52 Byte
*uncompr
, uLong uncomprLen
));
53 void test_dict_deflate
OF((Byte
*compr
, uLong comprLen
));
54 void test_dict_inflate
OF((Byte
*compr
, uLong comprLen
,
55 Byte
*uncompr
, uLong uncomprLen
));
56 int main
OF((int argc
, char *argv
[]));
58 /* ===========================================================================
59 * Test compress() and uncompress()
61 void test_compress(compr
, comprLen
, uncompr
, uncomprLen
)
62 Byte
*compr
, *uncompr
;
63 uLong comprLen
, uncomprLen
;
66 uLong len
= (uLong
)strlen(hello
)+1;
68 err
= compress(compr
, &comprLen
, (const Bytef
*)hello
, len
);
69 CHECK_ERR(err
, "compress");
71 strcpy((char*)uncompr
, "garbage");
73 err
= uncompress(uncompr
, &uncomprLen
, compr
, comprLen
);
74 CHECK_ERR(err
, "uncompress");
76 if (strcmp((char*)uncompr
, hello
)) {
77 fprintf(stderr
, "bad uncompress\n");
80 printf("uncompress(): %s\n", (char *)uncompr
);
84 /* ===========================================================================
85 * Test read/write of .gz files
87 void test_gzio(fname
, uncompr
, uncomprLen
)
88 const char *fname
; /* compressed file name */
93 fprintf(stderr
, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
96 int len
= (int)strlen(hello
)+1;
100 file
= gzopen(fname
, "wb");
102 fprintf(stderr
, "gzopen error\n");
106 if (gzputs(file
, "ello") != 4) {
107 fprintf(stderr
, "gzputs err: %s\n", gzerror(file
, &err
));
110 if (gzprintf(file
, ", %s!", "hello") != 8) {
111 fprintf(stderr
, "gzprintf err: %s\n", gzerror(file
, &err
));
114 gzseek(file
, 1L, SEEK_CUR
); /* add one zero byte */
117 file
= gzopen(fname
, "rb");
119 fprintf(stderr
, "gzopen error\n");
122 strcpy((char*)uncompr
, "garbage");
124 if (gzread(file
, uncompr
, (unsigned)uncomprLen
) != len
) {
125 fprintf(stderr
, "gzread err: %s\n", gzerror(file
, &err
));
128 if (strcmp((char*)uncompr
, hello
)) {
129 fprintf(stderr
, "bad gzread: %s\n", (char*)uncompr
);
132 printf("gzread(): %s\n", (char*)uncompr
);
135 pos
= gzseek(file
, -8L, SEEK_CUR
);
136 if (pos
!= 6 || gztell(file
) != pos
) {
137 fprintf(stderr
, "gzseek error, pos=%ld, gztell=%ld\n",
138 (long)pos
, (long)gztell(file
));
142 if (gzgetc(file
) != ' ') {
143 fprintf(stderr
, "gzgetc error\n");
147 if (gzungetc(' ', file
) != ' ') {
148 fprintf(stderr
, "gzungetc error\n");
152 gzgets(file
, (char*)uncompr
, (int)uncomprLen
);
153 if (strlen((char*)uncompr
) != 7) { /* " hello!" */
154 fprintf(stderr
, "gzgets err after gzseek: %s\n", gzerror(file
, &err
));
157 if (strcmp((char*)uncompr
, hello
+ 6)) {
158 fprintf(stderr
, "bad gzgets after gzseek\n");
161 printf("gzgets() after gzseek: %s\n", (char*)uncompr
);
168 /* ===========================================================================
169 * Test deflate() with small buffers
171 void test_deflate(compr
, comprLen
)
175 z_stream c_stream
; /* compression stream */
177 uLong len
= (uLong
)strlen(hello
)+1;
179 c_stream
.zalloc
= (alloc_func
)0;
180 c_stream
.zfree
= (free_func
)0;
181 c_stream
.opaque
= (voidpf
)0;
183 err
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
);
184 CHECK_ERR(err
, "deflateInit");
186 c_stream
.next_in
= (Bytef
*)hello
;
187 c_stream
.next_out
= compr
;
189 while (c_stream
.total_in
!= len
&& c_stream
.total_out
< comprLen
) {
190 c_stream
.avail_in
= c_stream
.avail_out
= 1; /* force small buffers */
191 err
= deflate(&c_stream
, Z_NO_FLUSH
);
192 CHECK_ERR(err
, "deflate");
194 /* Finish the stream, still forcing small buffers: */
196 c_stream
.avail_out
= 1;
197 err
= deflate(&c_stream
, Z_FINISH
);
198 if (err
== Z_STREAM_END
) break;
199 CHECK_ERR(err
, "deflate");
202 err
= deflateEnd(&c_stream
);
203 CHECK_ERR(err
, "deflateEnd");
206 /* ===========================================================================
207 * Test inflate() with small buffers
209 void test_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
210 Byte
*compr
, *uncompr
;
211 uLong comprLen
, uncomprLen
;
214 z_stream d_stream
; /* decompression stream */
216 strcpy((char*)uncompr
, "garbage");
218 d_stream
.zalloc
= (alloc_func
)0;
219 d_stream
.zfree
= (free_func
)0;
220 d_stream
.opaque
= (voidpf
)0;
222 d_stream
.next_in
= compr
;
223 d_stream
.avail_in
= 0;
224 d_stream
.next_out
= uncompr
;
226 err
= inflateInit(&d_stream
);
227 CHECK_ERR(err
, "inflateInit");
229 while (d_stream
.total_out
< uncomprLen
&& d_stream
.total_in
< comprLen
) {
230 d_stream
.avail_in
= d_stream
.avail_out
= 1; /* force small buffers */
231 err
= inflate(&d_stream
, Z_NO_FLUSH
);
232 if (err
== Z_STREAM_END
) break;
233 CHECK_ERR(err
, "inflate");
236 err
= inflateEnd(&d_stream
);
237 CHECK_ERR(err
, "inflateEnd");
239 if (strcmp((char*)uncompr
, hello
)) {
240 fprintf(stderr
, "bad inflate\n");
243 printf("inflate(): %s\n", (char *)uncompr
);
247 /* ===========================================================================
248 * Test deflate() with large buffers and dynamic change of compression level
250 void test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
)
251 Byte
*compr
, *uncompr
;
252 uLong comprLen
, uncomprLen
;
254 z_stream c_stream
; /* compression stream */
257 c_stream
.zalloc
= (alloc_func
)0;
258 c_stream
.zfree
= (free_func
)0;
259 c_stream
.opaque
= (voidpf
)0;
261 err
= deflateInit(&c_stream
, Z_BEST_SPEED
);
262 CHECK_ERR(err
, "deflateInit");
264 c_stream
.next_out
= compr
;
265 c_stream
.avail_out
= (uInt
)comprLen
;
267 /* At this point, uncompr is still mostly zeroes, so it should compress
270 c_stream
.next_in
= uncompr
;
271 c_stream
.avail_in
= (uInt
)uncomprLen
;
272 err
= deflate(&c_stream
, Z_NO_FLUSH
);
273 CHECK_ERR(err
, "deflate");
274 if (c_stream
.avail_in
!= 0) {
275 fprintf(stderr
, "deflate not greedy\n");
279 /* Feed in already compressed data and switch to no compression: */
280 deflateParams(&c_stream
, Z_NO_COMPRESSION
, Z_DEFAULT_STRATEGY
);
281 c_stream
.next_in
= compr
;
282 c_stream
.avail_in
= (uInt
)comprLen
/2;
283 err
= deflate(&c_stream
, Z_NO_FLUSH
);
284 CHECK_ERR(err
, "deflate");
286 /* Switch back to compressing mode: */
287 deflateParams(&c_stream
, Z_BEST_COMPRESSION
, Z_FILTERED
);
288 c_stream
.next_in
= uncompr
;
289 c_stream
.avail_in
= (uInt
)uncomprLen
;
290 err
= deflate(&c_stream
, Z_NO_FLUSH
);
291 CHECK_ERR(err
, "deflate");
293 err
= deflate(&c_stream
, Z_FINISH
);
294 if (err
!= Z_STREAM_END
) {
295 fprintf(stderr
, "deflate should report Z_STREAM_END\n");
298 err
= deflateEnd(&c_stream
);
299 CHECK_ERR(err
, "deflateEnd");
302 /* ===========================================================================
303 * Test inflate() with large buffers
305 void test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
306 Byte
*compr
, *uncompr
;
307 uLong comprLen
, uncomprLen
;
310 z_stream d_stream
; /* decompression stream */
312 strcpy((char*)uncompr
, "garbage");
314 d_stream
.zalloc
= (alloc_func
)0;
315 d_stream
.zfree
= (free_func
)0;
316 d_stream
.opaque
= (voidpf
)0;
318 d_stream
.next_in
= compr
;
319 d_stream
.avail_in
= (uInt
)comprLen
;
321 err
= inflateInit(&d_stream
);
322 CHECK_ERR(err
, "inflateInit");
325 d_stream
.next_out
= uncompr
; /* discard the output */
326 d_stream
.avail_out
= (uInt
)uncomprLen
;
327 err
= inflate(&d_stream
, Z_NO_FLUSH
);
328 if (err
== Z_STREAM_END
) break;
329 CHECK_ERR(err
, "large inflate");
332 err
= inflateEnd(&d_stream
);
333 CHECK_ERR(err
, "inflateEnd");
335 if (d_stream
.total_out
!= 2*uncomprLen
+ comprLen
/2) {
336 fprintf(stderr
, "bad large inflate: %ld\n", d_stream
.total_out
);
339 printf("large_inflate(): OK\n");
343 /* ===========================================================================
344 * Test deflate() with full flush
346 void test_flush(compr
, comprLen
)
350 z_stream c_stream
; /* compression stream */
352 uInt len
= (uInt
)strlen(hello
)+1;
354 c_stream
.zalloc
= (alloc_func
)0;
355 c_stream
.zfree
= (free_func
)0;
356 c_stream
.opaque
= (voidpf
)0;
358 err
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
);
359 CHECK_ERR(err
, "deflateInit");
361 c_stream
.next_in
= (Bytef
*)hello
;
362 c_stream
.next_out
= compr
;
363 c_stream
.avail_in
= 3;
364 c_stream
.avail_out
= (uInt
)*comprLen
;
365 err
= deflate(&c_stream
, Z_FULL_FLUSH
);
366 CHECK_ERR(err
, "deflate");
368 compr
[3]++; /* force an error in first compressed block */
369 c_stream
.avail_in
= len
- 3;
371 err
= deflate(&c_stream
, Z_FINISH
);
372 if (err
!= Z_STREAM_END
) {
373 CHECK_ERR(err
, "deflate");
375 err
= deflateEnd(&c_stream
);
376 CHECK_ERR(err
, "deflateEnd");
378 *comprLen
= c_stream
.total_out
;
381 /* ===========================================================================
384 void test_sync(compr
, comprLen
, uncompr
, uncomprLen
)
385 Byte
*compr
, *uncompr
;
386 uLong comprLen
, uncomprLen
;
389 z_stream d_stream
; /* decompression stream */
391 strcpy((char*)uncompr
, "garbage");
393 d_stream
.zalloc
= (alloc_func
)0;
394 d_stream
.zfree
= (free_func
)0;
395 d_stream
.opaque
= (voidpf
)0;
397 d_stream
.next_in
= compr
;
398 d_stream
.avail_in
= 2; /* just read the zlib header */
400 err
= inflateInit(&d_stream
);
401 CHECK_ERR(err
, "inflateInit");
403 d_stream
.next_out
= uncompr
;
404 d_stream
.avail_out
= (uInt
)uncomprLen
;
406 inflate(&d_stream
, Z_NO_FLUSH
);
407 CHECK_ERR(err
, "inflate");
409 d_stream
.avail_in
= (uInt
)comprLen
-2; /* read all compressed data */
410 err
= inflateSync(&d_stream
); /* but skip the damaged part */
411 CHECK_ERR(err
, "inflateSync");
413 err
= inflate(&d_stream
, Z_FINISH
);
414 if (err
!= Z_DATA_ERROR
) {
415 fprintf(stderr
, "inflate should report DATA_ERROR\n");
416 /* Because of incorrect adler32 */
419 err
= inflateEnd(&d_stream
);
420 CHECK_ERR(err
, "inflateEnd");
422 printf("after inflateSync(): hel%s\n", (char *)uncompr
);
425 /* ===========================================================================
426 * Test deflate() with preset dictionary
428 void test_dict_deflate(compr
, comprLen
)
432 z_stream c_stream
; /* compression stream */
435 c_stream
.zalloc
= (alloc_func
)0;
436 c_stream
.zfree
= (free_func
)0;
437 c_stream
.opaque
= (voidpf
)0;
439 err
= deflateInit(&c_stream
, Z_BEST_COMPRESSION
);
440 CHECK_ERR(err
, "deflateInit");
442 err
= deflateSetDictionary(&c_stream
,
443 (const Bytef
*)dictionary
, sizeof(dictionary
));
444 CHECK_ERR(err
, "deflateSetDictionary");
446 dictId
= c_stream
.adler
;
447 c_stream
.next_out
= compr
;
448 c_stream
.avail_out
= (uInt
)comprLen
;
450 c_stream
.next_in
= (Bytef
*)hello
;
451 c_stream
.avail_in
= (uInt
)strlen(hello
)+1;
453 err
= deflate(&c_stream
, Z_FINISH
);
454 if (err
!= Z_STREAM_END
) {
455 fprintf(stderr
, "deflate should report Z_STREAM_END\n");
458 err
= deflateEnd(&c_stream
);
459 CHECK_ERR(err
, "deflateEnd");
462 /* ===========================================================================
463 * Test inflate() with a preset dictionary
465 void test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
466 Byte
*compr
, *uncompr
;
467 uLong comprLen
, uncomprLen
;
470 z_stream d_stream
; /* decompression stream */
472 strcpy((char*)uncompr
, "garbage");
474 d_stream
.zalloc
= (alloc_func
)0;
475 d_stream
.zfree
= (free_func
)0;
476 d_stream
.opaque
= (voidpf
)0;
478 d_stream
.next_in
= compr
;
479 d_stream
.avail_in
= (uInt
)comprLen
;
481 err
= inflateInit(&d_stream
);
482 CHECK_ERR(err
, "inflateInit");
484 d_stream
.next_out
= uncompr
;
485 d_stream
.avail_out
= (uInt
)uncomprLen
;
488 err
= inflate(&d_stream
, Z_NO_FLUSH
);
489 if (err
== Z_STREAM_END
) break;
490 if (err
== Z_NEED_DICT
) {
491 if (d_stream
.adler
!= dictId
) {
492 fprintf(stderr
, "unexpected dictionary");
495 err
= inflateSetDictionary(&d_stream
, (const Bytef
*)dictionary
,
498 CHECK_ERR(err
, "inflate with dict");
501 err
= inflateEnd(&d_stream
);
502 CHECK_ERR(err
, "inflateEnd");
504 if (strcmp((char*)uncompr
, hello
)) {
505 fprintf(stderr
, "bad inflate with dict\n");
508 printf("inflate with dictionary: %s\n", (char *)uncompr
);
512 /* ===========================================================================
513 * Usage: example [output.gz [input.gz]]
520 Byte
*compr
, *uncompr
;
521 uLong comprLen
= 10000*sizeof(int); /* don't overflow on MSDOS */
522 uLong uncomprLen
= comprLen
;
523 static const char* myVersion
= ZLIB_VERSION
;
525 if (zlibVersion()[0] != myVersion
[0]) {
526 fprintf(stderr
, "incompatible zlib version\n");
529 } else if (strcmp(zlibVersion(), ZLIB_VERSION
) != 0) {
530 fprintf(stderr
, "warning: different zlib version\n");
533 printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
534 ZLIB_VERSION
, ZLIB_VERNUM
, zlibCompileFlags());
536 compr
= (Byte
*)calloc((uInt
)comprLen
, 1);
537 uncompr
= (Byte
*)calloc((uInt
)uncomprLen
, 1);
538 /* compr and uncompr are cleared to avoid reading uninitialized
539 * data and to ensure that uncompr compresses well.
541 if (compr
== Z_NULL
|| uncompr
== Z_NULL
) {
542 printf("out of memory\n");
545 test_compress(compr
, comprLen
, uncompr
, uncomprLen
);
547 test_gzio((argc
> 1 ? argv
[1] : TESTFILE
),
548 uncompr
, uncomprLen
);
550 test_deflate(compr
, comprLen
);
551 test_inflate(compr
, comprLen
, uncompr
, uncomprLen
);
553 test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
);
554 test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
);
556 test_flush(compr
, &comprLen
);
557 test_sync(compr
, comprLen
, uncompr
, uncomprLen
);
558 comprLen
= uncomprLen
;
560 test_dict_deflate(compr
, comprLen
);
561 test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
);