1 /* example.c -- usage example of the zlib compression library
2 * Copyright (C) 1995-2003 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
14 extern void exit
OF((int));
17 #if defined(VMS) || defined(RISCOS)
18 # define TESTFILE "foo-gz"
20 # define TESTFILE "foo.gz"
23 #define CHECK_ERR(err, msg) { \
25 fprintf(stderr, "%s error: %d\n", msg, err); \
30 const char hello
[] = "hello, hello!";
31 /* "hello world" would be more standard, but the repeated "hello"
32 * stresses the compression code better, sorry...
35 const char dictionary
[] = "hello";
36 uLong dictId
; /* Adler32 value of the dictionary */
38 void test_compress
OF((Byte
*compr
, uLong comprLen
,
39 Byte
*uncompr
, uLong uncomprLen
));
40 void test_gzio
OF((const char *fname
,
41 Byte
*uncompr
, uLong uncomprLen
));
42 void test_deflate
OF((Byte
*compr
, uLong comprLen
));
43 void test_inflate
OF((Byte
*compr
, uLong comprLen
,
44 Byte
*uncompr
, uLong uncomprLen
));
45 void test_large_deflate
OF((Byte
*compr
, uLong comprLen
,
46 Byte
*uncompr
, uLong uncomprLen
));
47 void test_large_inflate
OF((Byte
*compr
, uLong comprLen
,
48 Byte
*uncompr
, uLong uncomprLen
));
49 void test_flush
OF((Byte
*compr
, uLong
*comprLen
));
50 void test_sync
OF((Byte
*compr
, uLong comprLen
,
51 Byte
*uncompr
, uLong uncomprLen
));
52 void test_dict_deflate
OF((Byte
*compr
, uLong comprLen
));
53 void test_dict_inflate
OF((Byte
*compr
, uLong comprLen
,
54 Byte
*uncompr
, uLong uncomprLen
));
55 int main
OF((int argc
, char *argv
[]));
57 /* ===========================================================================
58 * Test compress() and uncompress()
60 void test_compress(compr
, comprLen
, uncompr
, uncomprLen
)
61 Byte
*compr
, *uncompr
;
62 uLong comprLen
, uncomprLen
;
65 uLong len
= (uLong
)strlen(hello
)+1;
67 err
= compress(compr
, &comprLen
, (const Bytef
*)hello
, len
);
68 CHECK_ERR(err
, "compress");
70 strcpy((char*)uncompr
, "garbage");
72 err
= uncompress(uncompr
, &uncomprLen
, compr
, comprLen
);
73 CHECK_ERR(err
, "uncompress");
75 if (strcmp((char*)uncompr
, hello
)) {
76 fprintf(stderr
, "bad uncompress\n");
79 printf("uncompress(): %s\n", (char *)uncompr
);
83 /* ===========================================================================
84 * Test read/write of .gz files
86 void test_gzio(fname
, uncompr
, uncomprLen
)
87 const char *fname
; /* compressed file name */
92 fprintf(stderr
, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
95 int len
= (int)strlen(hello
)+1;
99 file
= gzopen(fname
, "wb");
101 fprintf(stderr
, "gzopen error\n");
105 if (gzputs(file
, "ello") != 4) {
106 fprintf(stderr
, "gzputs err: %s\n", gzerror(file
, &err
));
109 if (gzprintf(file
, ", %s!", "hello") != 8) {
110 fprintf(stderr
, "gzprintf err: %s\n", gzerror(file
, &err
));
113 gzseek(file
, 1L, SEEK_CUR
); /* add one zero byte */
116 file
= gzopen(fname
, "rb");
118 fprintf(stderr
, "gzopen error\n");
121 strcpy((char*)uncompr
, "garbage");
123 if (gzread(file
, uncompr
, (unsigned)uncomprLen
) != len
) {
124 fprintf(stderr
, "gzread err: %s\n", gzerror(file
, &err
));
127 if (strcmp((char*)uncompr
, hello
)) {
128 fprintf(stderr
, "bad gzread: %s\n", (char*)uncompr
);
131 printf("gzread(): %s\n", (char*)uncompr
);
134 pos
= gzseek(file
, -8L, SEEK_CUR
);
135 if (pos
!= 6 || gztell(file
) != pos
) {
136 fprintf(stderr
, "gzseek error, pos=%ld, gztell=%ld\n",
137 (long)pos
, (long)gztell(file
));
141 if (gzgetc(file
) != ' ') {
142 fprintf(stderr
, "gzgetc error\n");
146 if (gzungetc(' ', file
) != ' ') {
147 fprintf(stderr
, "gzungetc error\n");
151 gzgets(file
, (char*)uncompr
, (int)uncomprLen
);
152 if (strlen((char*)uncompr
) != 7) { /* " hello!" */
153 fprintf(stderr
, "gzgets err after gzseek: %s\n", gzerror(file
, &err
));
156 if (strcmp((char*)uncompr
, hello
+ 6)) {
157 fprintf(stderr
, "bad gzgets after gzseek\n");
160 printf("gzgets() after gzseek: %s\n", (char*)uncompr
);
167 /* ===========================================================================
168 * Test deflate() with small buffers
170 void test_deflate(compr
, comprLen
)
174 z_stream c_stream
; /* compression stream */
176 uLong len
= (uLong
)strlen(hello
)+1;
178 c_stream
.zalloc
= (alloc_func
)0;
179 c_stream
.zfree
= (free_func
)0;
180 c_stream
.opaque
= (voidpf
)0;
182 err
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
);
183 CHECK_ERR(err
, "deflateInit");
185 c_stream
.next_in
= (Bytef
*)hello
;
186 c_stream
.next_out
= compr
;
188 while (c_stream
.total_in
!= len
&& c_stream
.total_out
< comprLen
) {
189 c_stream
.avail_in
= c_stream
.avail_out
= 1; /* force small buffers */
190 err
= deflate(&c_stream
, Z_NO_FLUSH
);
191 CHECK_ERR(err
, "deflate");
193 /* Finish the stream, still forcing small buffers: */
195 c_stream
.avail_out
= 1;
196 err
= deflate(&c_stream
, Z_FINISH
);
197 if (err
== Z_STREAM_END
) break;
198 CHECK_ERR(err
, "deflate");
201 err
= deflateEnd(&c_stream
);
202 CHECK_ERR(err
, "deflateEnd");
205 /* ===========================================================================
206 * Test inflate() with small buffers
208 void test_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
209 Byte
*compr
, *uncompr
;
210 uLong comprLen
, uncomprLen
;
213 z_stream d_stream
; /* decompression stream */
215 strcpy((char*)uncompr
, "garbage");
217 d_stream
.zalloc
= (alloc_func
)0;
218 d_stream
.zfree
= (free_func
)0;
219 d_stream
.opaque
= (voidpf
)0;
221 d_stream
.next_in
= compr
;
222 d_stream
.avail_in
= 0;
223 d_stream
.next_out
= uncompr
;
225 err
= inflateInit(&d_stream
);
226 CHECK_ERR(err
, "inflateInit");
228 while (d_stream
.total_out
< uncomprLen
&& d_stream
.total_in
< comprLen
) {
229 d_stream
.avail_in
= d_stream
.avail_out
= 1; /* force small buffers */
230 err
= inflate(&d_stream
, Z_NO_FLUSH
);
231 if (err
== Z_STREAM_END
) break;
232 CHECK_ERR(err
, "inflate");
235 err
= inflateEnd(&d_stream
);
236 CHECK_ERR(err
, "inflateEnd");
238 if (strcmp((char*)uncompr
, hello
)) {
239 fprintf(stderr
, "bad inflate\n");
242 printf("inflate(): %s\n", (char *)uncompr
);
246 /* ===========================================================================
247 * Test deflate() with large buffers and dynamic change of compression level
249 void test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
)
250 Byte
*compr
, *uncompr
;
251 uLong comprLen
, uncomprLen
;
253 z_stream c_stream
; /* compression stream */
256 c_stream
.zalloc
= (alloc_func
)0;
257 c_stream
.zfree
= (free_func
)0;
258 c_stream
.opaque
= (voidpf
)0;
260 err
= deflateInit(&c_stream
, Z_BEST_SPEED
);
261 CHECK_ERR(err
, "deflateInit");
263 c_stream
.next_out
= compr
;
264 c_stream
.avail_out
= (uInt
)comprLen
;
266 /* At this point, uncompr is still mostly zeroes, so it should compress
269 c_stream
.next_in
= uncompr
;
270 c_stream
.avail_in
= (uInt
)uncomprLen
;
271 err
= deflate(&c_stream
, Z_NO_FLUSH
);
272 CHECK_ERR(err
, "deflate");
273 if (c_stream
.avail_in
!= 0) {
274 fprintf(stderr
, "deflate not greedy\n");
278 /* Feed in already compressed data and switch to no compression: */
279 deflateParams(&c_stream
, Z_NO_COMPRESSION
, Z_DEFAULT_STRATEGY
);
280 c_stream
.next_in
= compr
;
281 c_stream
.avail_in
= (uInt
)comprLen
/2;
282 err
= deflate(&c_stream
, Z_NO_FLUSH
);
283 CHECK_ERR(err
, "deflate");
285 /* Switch back to compressing mode: */
286 deflateParams(&c_stream
, Z_BEST_COMPRESSION
, Z_FILTERED
);
287 c_stream
.next_in
= uncompr
;
288 c_stream
.avail_in
= (uInt
)uncomprLen
;
289 err
= deflate(&c_stream
, Z_NO_FLUSH
);
290 CHECK_ERR(err
, "deflate");
292 err
= deflate(&c_stream
, Z_FINISH
);
293 if (err
!= Z_STREAM_END
) {
294 fprintf(stderr
, "deflate should report Z_STREAM_END\n");
297 err
= deflateEnd(&c_stream
);
298 CHECK_ERR(err
, "deflateEnd");
301 /* ===========================================================================
302 * Test inflate() with large buffers
304 void test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
305 Byte
*compr
, *uncompr
;
306 uLong comprLen
, uncomprLen
;
309 z_stream d_stream
; /* decompression stream */
311 strcpy((char*)uncompr
, "garbage");
313 d_stream
.zalloc
= (alloc_func
)0;
314 d_stream
.zfree
= (free_func
)0;
315 d_stream
.opaque
= (voidpf
)0;
317 d_stream
.next_in
= compr
;
318 d_stream
.avail_in
= (uInt
)comprLen
;
320 err
= inflateInit(&d_stream
);
321 CHECK_ERR(err
, "inflateInit");
324 d_stream
.next_out
= uncompr
; /* discard the output */
325 d_stream
.avail_out
= (uInt
)uncomprLen
;
326 err
= inflate(&d_stream
, Z_NO_FLUSH
);
327 if (err
== Z_STREAM_END
) break;
328 CHECK_ERR(err
, "large inflate");
331 err
= inflateEnd(&d_stream
);
332 CHECK_ERR(err
, "inflateEnd");
334 if (d_stream
.total_out
!= 2*uncomprLen
+ comprLen
/2) {
335 fprintf(stderr
, "bad large inflate: %ld\n", d_stream
.total_out
);
338 printf("large_inflate(): OK\n");
342 /* ===========================================================================
343 * Test deflate() with full flush
345 void test_flush(compr
, comprLen
)
349 z_stream c_stream
; /* compression stream */
351 uInt len
= (uInt
)strlen(hello
)+1;
353 c_stream
.zalloc
= (alloc_func
)0;
354 c_stream
.zfree
= (free_func
)0;
355 c_stream
.opaque
= (voidpf
)0;
357 err
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
);
358 CHECK_ERR(err
, "deflateInit");
360 c_stream
.next_in
= (Bytef
*)hello
;
361 c_stream
.next_out
= compr
;
362 c_stream
.avail_in
= 3;
363 c_stream
.avail_out
= (uInt
)*comprLen
;
364 err
= deflate(&c_stream
, Z_FULL_FLUSH
);
365 CHECK_ERR(err
, "deflate");
367 compr
[3]++; /* force an error in first compressed block */
368 c_stream
.avail_in
= len
- 3;
370 err
= deflate(&c_stream
, Z_FINISH
);
371 if (err
!= Z_STREAM_END
) {
372 CHECK_ERR(err
, "deflate");
374 err
= deflateEnd(&c_stream
);
375 CHECK_ERR(err
, "deflateEnd");
377 *comprLen
= c_stream
.total_out
;
380 /* ===========================================================================
383 void test_sync(compr
, comprLen
, uncompr
, uncomprLen
)
384 Byte
*compr
, *uncompr
;
385 uLong comprLen
, uncomprLen
;
388 z_stream d_stream
; /* decompression stream */
390 strcpy((char*)uncompr
, "garbage");
392 d_stream
.zalloc
= (alloc_func
)0;
393 d_stream
.zfree
= (free_func
)0;
394 d_stream
.opaque
= (voidpf
)0;
396 d_stream
.next_in
= compr
;
397 d_stream
.avail_in
= 2; /* just read the zlib header */
399 err
= inflateInit(&d_stream
);
400 CHECK_ERR(err
, "inflateInit");
402 d_stream
.next_out
= uncompr
;
403 d_stream
.avail_out
= (uInt
)uncomprLen
;
405 inflate(&d_stream
, Z_NO_FLUSH
);
406 CHECK_ERR(err
, "inflate");
408 d_stream
.avail_in
= (uInt
)comprLen
-2; /* read all compressed data */
409 err
= inflateSync(&d_stream
); /* but skip the damaged part */
410 CHECK_ERR(err
, "inflateSync");
412 err
= inflate(&d_stream
, Z_FINISH
);
413 if (err
!= Z_DATA_ERROR
) {
414 fprintf(stderr
, "inflate should report DATA_ERROR\n");
415 /* Because of incorrect adler32 */
418 err
= inflateEnd(&d_stream
);
419 CHECK_ERR(err
, "inflateEnd");
421 printf("after inflateSync(): hel%s\n", (char *)uncompr
);
424 /* ===========================================================================
425 * Test deflate() with preset dictionary
427 void test_dict_deflate(compr
, comprLen
)
431 z_stream c_stream
; /* compression stream */
434 c_stream
.zalloc
= (alloc_func
)0;
435 c_stream
.zfree
= (free_func
)0;
436 c_stream
.opaque
= (voidpf
)0;
438 err
= deflateInit(&c_stream
, Z_BEST_COMPRESSION
);
439 CHECK_ERR(err
, "deflateInit");
441 err
= deflateSetDictionary(&c_stream
,
442 (const Bytef
*)dictionary
, sizeof(dictionary
));
443 CHECK_ERR(err
, "deflateSetDictionary");
445 dictId
= c_stream
.adler
;
446 c_stream
.next_out
= compr
;
447 c_stream
.avail_out
= (uInt
)comprLen
;
449 c_stream
.next_in
= (Bytef
*)hello
;
450 c_stream
.avail_in
= (uInt
)strlen(hello
)+1;
452 err
= deflate(&c_stream
, Z_FINISH
);
453 if (err
!= Z_STREAM_END
) {
454 fprintf(stderr
, "deflate should report Z_STREAM_END\n");
457 err
= deflateEnd(&c_stream
);
458 CHECK_ERR(err
, "deflateEnd");
461 /* ===========================================================================
462 * Test inflate() with a preset dictionary
464 void test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
465 Byte
*compr
, *uncompr
;
466 uLong comprLen
, uncomprLen
;
469 z_stream d_stream
; /* decompression stream */
471 strcpy((char*)uncompr
, "garbage");
473 d_stream
.zalloc
= (alloc_func
)0;
474 d_stream
.zfree
= (free_func
)0;
475 d_stream
.opaque
= (voidpf
)0;
477 d_stream
.next_in
= compr
;
478 d_stream
.avail_in
= (uInt
)comprLen
;
480 err
= inflateInit(&d_stream
);
481 CHECK_ERR(err
, "inflateInit");
483 d_stream
.next_out
= uncompr
;
484 d_stream
.avail_out
= (uInt
)uncomprLen
;
487 err
= inflate(&d_stream
, Z_NO_FLUSH
);
488 if (err
== Z_STREAM_END
) break;
489 if (err
== Z_NEED_DICT
) {
490 if (d_stream
.adler
!= dictId
) {
491 fprintf(stderr
, "unexpected dictionary");
494 err
= inflateSetDictionary(&d_stream
, (const Bytef
*)dictionary
,
497 CHECK_ERR(err
, "inflate with dict");
500 err
= inflateEnd(&d_stream
);
501 CHECK_ERR(err
, "inflateEnd");
503 if (strcmp((char*)uncompr
, hello
)) {
504 fprintf(stderr
, "bad inflate with dict\n");
507 printf("inflate with dictionary: %s\n", (char *)uncompr
);
511 /* ===========================================================================
512 * Usage: example [output.gz [input.gz]]
519 Byte
*compr
, *uncompr
;
520 uLong comprLen
= 10000*sizeof(int); /* don't overflow on MSDOS */
521 uLong uncomprLen
= comprLen
;
522 static const char* myVersion
= ZLIB_VERSION
;
524 if (zlibVersion()[0] != myVersion
[0]) {
525 fprintf(stderr
, "incompatible zlib version\n");
528 } else if (strcmp(zlibVersion(), ZLIB_VERSION
) != 0) {
529 fprintf(stderr
, "warning: different zlib version\n");
532 printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
533 ZLIB_VERSION
, ZLIB_VERNUM
, zlibCompileFlags());
535 compr
= (Byte
*)calloc((uInt
)comprLen
, 1);
536 uncompr
= (Byte
*)calloc((uInt
)uncomprLen
, 1);
537 /* compr and uncompr are cleared to avoid reading uninitialized
538 * data and to ensure that uncompr compresses well.
540 if (compr
== Z_NULL
|| uncompr
== Z_NULL
) {
541 printf("out of memory\n");
544 test_compress(compr
, comprLen
, uncompr
, uncomprLen
);
546 test_gzio((argc
> 1 ? argv
[1] : TESTFILE
),
547 uncompr
, uncomprLen
);
549 test_deflate(compr
, comprLen
);
550 test_inflate(compr
, comprLen
, uncompr
, uncomprLen
);
552 test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
);
553 test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
);
555 test_flush(compr
, &comprLen
);
556 test_sync(compr
, comprLen
, uncompr
, uncomprLen
);
557 comprLen
= uncomprLen
;
559 test_dict_deflate(compr
, comprLen
);
560 test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
);