1 /* example.c -- usage example of the zlib compression library
2 * Copyright (C) 1995-2006, 2011, 2016 Jean-loup Gailly
3 * For conditions of distribution and use, see copyright notice in zlib.h
16 #if defined(VMS) || defined(RISCOS)
17 # define TESTFILE "foo-gz"
19 # define TESTFILE "foo.gz"
22 #define CHECK_ERR(err, msg) { \
24 fprintf(stderr, "%s error: %d\n", msg, err); \
29 static z_const
char hello
[] = "hello, hello!";
30 /* "hello world" would be more standard, but the repeated "hello"
31 * stresses the compression code better, sorry...
34 static const char dictionary
[] = "hello";
35 static uLong dictId
; /* Adler32 value of the dictionary */
37 void test_deflate
OF((Byte
*compr
, uLong comprLen
));
38 void test_inflate
OF((Byte
*compr
, uLong comprLen
,
39 Byte
*uncompr
, uLong uncomprLen
));
40 void test_large_deflate
OF((Byte
*compr
, uLong comprLen
,
41 Byte
*uncompr
, uLong uncomprLen
));
42 void test_large_inflate
OF((Byte
*compr
, uLong comprLen
,
43 Byte
*uncompr
, uLong uncomprLen
));
44 void test_flush
OF((Byte
*compr
, uLong
*comprLen
));
45 void test_sync
OF((Byte
*compr
, uLong comprLen
,
46 Byte
*uncompr
, uLong uncomprLen
));
47 void test_dict_deflate
OF((Byte
*compr
, uLong comprLen
));
48 void test_dict_inflate
OF((Byte
*compr
, uLong comprLen
,
49 Byte
*uncompr
, uLong uncomprLen
));
50 int main
OF((int argc
, char *argv
[]));
55 void *myalloc
OF((void *, unsigned, unsigned));
56 void myfree
OF((void *, void *));
58 void *myalloc(q
, n
, m
)
66 void myfree(void *q
, void *p
)
72 static alloc_func zalloc
= myalloc
;
73 static free_func zfree
= myfree
;
77 static alloc_func zalloc
= (alloc_func
)0;
78 static free_func zfree
= (free_func
)0;
80 void test_compress
OF((Byte
*compr
, uLong comprLen
,
81 Byte
*uncompr
, uLong uncomprLen
));
82 void test_gzio
OF((const char *fname
,
83 Byte
*uncompr
, uLong uncomprLen
));
85 /* ===========================================================================
86 * Test compress() and uncompress()
88 void test_compress(compr
, comprLen
, uncompr
, uncomprLen
)
89 Byte
*compr
, *uncompr
;
90 uLong comprLen
, uncomprLen
;
93 uLong len
= (uLong
)strlen(hello
)+1;
95 err
= compress(compr
, &comprLen
, (const Bytef
*)hello
, len
);
96 CHECK_ERR(err
, "compress");
98 strcpy((char*)uncompr
, "garbage");
100 err
= uncompress(uncompr
, &uncomprLen
, compr
, comprLen
);
101 CHECK_ERR(err
, "uncompress");
103 if (strcmp((char*)uncompr
, hello
)) {
104 fprintf(stderr
, "bad uncompress\n");
107 printf("uncompress(): %s\n", (char *)uncompr
);
111 /* ===========================================================================
112 * Test read/write of .gz files
114 void test_gzio(fname
, uncompr
, uncomprLen
)
115 const char *fname
; /* compressed file name */
120 fprintf(stderr
, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
123 int len
= (int)strlen(hello
)+1;
127 file
= gzopen(fname
, "wb");
129 fprintf(stderr
, "gzopen error\n");
133 if (gzputs(file
, "ello") != 4) {
134 fprintf(stderr
, "gzputs err: %s\n", gzerror(file
, &err
));
137 if (gzprintf(file
, ", %s!", "hello") != 8) {
138 fprintf(stderr
, "gzprintf err: %s\n", gzerror(file
, &err
));
141 gzseek(file
, 1L, SEEK_CUR
); /* add one zero byte */
144 file
= gzopen(fname
, "rb");
146 fprintf(stderr
, "gzopen error\n");
149 strcpy((char*)uncompr
, "garbage");
151 if (gzread(file
, uncompr
, (unsigned)uncomprLen
) != len
) {
152 fprintf(stderr
, "gzread err: %s\n", gzerror(file
, &err
));
155 if (strcmp((char*)uncompr
, hello
)) {
156 fprintf(stderr
, "bad gzread: %s\n", (char*)uncompr
);
159 printf("gzread(): %s\n", (char*)uncompr
);
162 pos
= gzseek(file
, -8L, SEEK_CUR
);
163 if (pos
!= 6 || gztell(file
) != pos
) {
164 fprintf(stderr
, "gzseek error, pos=%ld, gztell=%ld\n",
165 (long)pos
, (long)gztell(file
));
169 if (gzgetc(file
) != ' ') {
170 fprintf(stderr
, "gzgetc error\n");
174 if (gzungetc(' ', file
) != ' ') {
175 fprintf(stderr
, "gzungetc error\n");
179 gzgets(file
, (char*)uncompr
, (int)uncomprLen
);
180 if (strlen((char*)uncompr
) != 7) { /* " hello!" */
181 fprintf(stderr
, "gzgets err after gzseek: %s\n", gzerror(file
, &err
));
184 if (strcmp((char*)uncompr
, hello
+ 6)) {
185 fprintf(stderr
, "bad gzgets after gzseek\n");
188 printf("gzgets() after gzseek: %s\n", (char*)uncompr
);
197 /* ===========================================================================
198 * Test deflate() with small buffers
200 void test_deflate(compr
, comprLen
)
204 z_stream c_stream
; /* compression stream */
206 uLong len
= (uLong
)strlen(hello
)+1;
208 c_stream
.zalloc
= zalloc
;
209 c_stream
.zfree
= zfree
;
210 c_stream
.opaque
= (voidpf
)0;
212 err
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
);
213 CHECK_ERR(err
, "deflateInit");
215 c_stream
.next_in
= (z_const
unsigned char *)hello
;
216 c_stream
.next_out
= compr
;
218 while (c_stream
.total_in
!= len
&& c_stream
.total_out
< comprLen
) {
219 c_stream
.avail_in
= c_stream
.avail_out
= 1; /* force small buffers */
220 err
= deflate(&c_stream
, Z_NO_FLUSH
);
221 CHECK_ERR(err
, "deflate");
223 /* Finish the stream, still forcing small buffers: */
225 c_stream
.avail_out
= 1;
226 err
= deflate(&c_stream
, Z_FINISH
);
227 if (err
== Z_STREAM_END
) break;
228 CHECK_ERR(err
, "deflate");
231 err
= deflateEnd(&c_stream
);
232 CHECK_ERR(err
, "deflateEnd");
235 /* ===========================================================================
236 * Test inflate() with small buffers
238 void test_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
239 Byte
*compr
, *uncompr
;
240 uLong comprLen
, uncomprLen
;
243 z_stream d_stream
; /* decompression stream */
245 strcpy((char*)uncompr
, "garbage");
247 d_stream
.zalloc
= zalloc
;
248 d_stream
.zfree
= zfree
;
249 d_stream
.opaque
= (voidpf
)0;
251 d_stream
.next_in
= compr
;
252 d_stream
.avail_in
= 0;
253 d_stream
.next_out
= uncompr
;
255 err
= inflateInit(&d_stream
);
256 CHECK_ERR(err
, "inflateInit");
258 while (d_stream
.total_out
< uncomprLen
&& d_stream
.total_in
< comprLen
) {
259 d_stream
.avail_in
= d_stream
.avail_out
= 1; /* force small buffers */
260 err
= inflate(&d_stream
, Z_NO_FLUSH
);
261 if (err
== Z_STREAM_END
) break;
262 CHECK_ERR(err
, "inflate");
265 err
= inflateEnd(&d_stream
);
266 CHECK_ERR(err
, "inflateEnd");
268 if (strcmp((char*)uncompr
, hello
)) {
269 fprintf(stderr
, "bad inflate\n");
272 printf("inflate(): %s\n", (char *)uncompr
);
276 /* ===========================================================================
277 * Test deflate() with large buffers and dynamic change of compression level
279 void test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
)
280 Byte
*compr
, *uncompr
;
281 uLong comprLen
, uncomprLen
;
283 z_stream c_stream
; /* compression stream */
286 c_stream
.zalloc
= zalloc
;
287 c_stream
.zfree
= zfree
;
288 c_stream
.opaque
= (voidpf
)0;
290 err
= deflateInit(&c_stream
, Z_BEST_SPEED
);
291 CHECK_ERR(err
, "deflateInit");
293 c_stream
.next_out
= compr
;
294 c_stream
.avail_out
= (uInt
)comprLen
;
296 /* At this point, uncompr is still mostly zeroes, so it should compress
299 c_stream
.next_in
= uncompr
;
300 c_stream
.avail_in
= (uInt
)uncomprLen
;
301 err
= deflate(&c_stream
, Z_NO_FLUSH
);
302 CHECK_ERR(err
, "deflate");
303 if (c_stream
.avail_in
!= 0) {
304 fprintf(stderr
, "deflate not greedy\n");
308 /* Feed in already compressed data and switch to no compression: */
309 deflateParams(&c_stream
, Z_NO_COMPRESSION
, Z_DEFAULT_STRATEGY
);
310 c_stream
.next_in
= compr
;
311 c_stream
.avail_in
= (uInt
)comprLen
/2;
312 err
= deflate(&c_stream
, Z_NO_FLUSH
);
313 CHECK_ERR(err
, "deflate");
315 /* Switch back to compressing mode: */
316 deflateParams(&c_stream
, Z_BEST_COMPRESSION
, Z_FILTERED
);
317 c_stream
.next_in
= uncompr
;
318 c_stream
.avail_in
= (uInt
)uncomprLen
;
319 err
= deflate(&c_stream
, Z_NO_FLUSH
);
320 CHECK_ERR(err
, "deflate");
322 err
= deflate(&c_stream
, Z_FINISH
);
323 if (err
!= Z_STREAM_END
) {
324 fprintf(stderr
, "deflate should report Z_STREAM_END\n");
327 err
= deflateEnd(&c_stream
);
328 CHECK_ERR(err
, "deflateEnd");
331 /* ===========================================================================
332 * Test inflate() with large buffers
334 void test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
335 Byte
*compr
, *uncompr
;
336 uLong comprLen
, uncomprLen
;
339 z_stream d_stream
; /* decompression stream */
341 strcpy((char*)uncompr
, "garbage");
343 d_stream
.zalloc
= zalloc
;
344 d_stream
.zfree
= zfree
;
345 d_stream
.opaque
= (voidpf
)0;
347 d_stream
.next_in
= compr
;
348 d_stream
.avail_in
= (uInt
)comprLen
;
350 err
= inflateInit(&d_stream
);
351 CHECK_ERR(err
, "inflateInit");
354 d_stream
.next_out
= uncompr
; /* discard the output */
355 d_stream
.avail_out
= (uInt
)uncomprLen
;
356 err
= inflate(&d_stream
, Z_NO_FLUSH
);
357 if (err
== Z_STREAM_END
) break;
358 CHECK_ERR(err
, "large inflate");
361 err
= inflateEnd(&d_stream
);
362 CHECK_ERR(err
, "inflateEnd");
364 if (d_stream
.total_out
!= 2*uncomprLen
+ comprLen
/2) {
365 fprintf(stderr
, "bad large inflate: %ld\n", d_stream
.total_out
);
368 printf("large_inflate(): OK\n");
372 /* ===========================================================================
373 * Test deflate() with full flush
375 void test_flush(compr
, comprLen
)
379 z_stream c_stream
; /* compression stream */
381 uInt len
= (uInt
)strlen(hello
)+1;
383 c_stream
.zalloc
= zalloc
;
384 c_stream
.zfree
= zfree
;
385 c_stream
.opaque
= (voidpf
)0;
387 err
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
);
388 CHECK_ERR(err
, "deflateInit");
390 c_stream
.next_in
= (z_const
unsigned char *)hello
;
391 c_stream
.next_out
= compr
;
392 c_stream
.avail_in
= 3;
393 c_stream
.avail_out
= (uInt
)*comprLen
;
394 err
= deflate(&c_stream
, Z_FULL_FLUSH
);
395 CHECK_ERR(err
, "deflate");
397 compr
[3]++; /* force an error in first compressed block */
398 c_stream
.avail_in
= len
- 3;
400 err
= deflate(&c_stream
, Z_FINISH
);
401 if (err
!= Z_STREAM_END
) {
402 CHECK_ERR(err
, "deflate");
404 err
= deflateEnd(&c_stream
);
405 CHECK_ERR(err
, "deflateEnd");
407 *comprLen
= c_stream
.total_out
;
410 /* ===========================================================================
413 void test_sync(compr
, comprLen
, uncompr
, uncomprLen
)
414 Byte
*compr
, *uncompr
;
415 uLong comprLen
, uncomprLen
;
418 z_stream d_stream
; /* decompression stream */
420 strcpy((char*)uncompr
, "garbage");
422 d_stream
.zalloc
= zalloc
;
423 d_stream
.zfree
= zfree
;
424 d_stream
.opaque
= (voidpf
)0;
426 d_stream
.next_in
= compr
;
427 d_stream
.avail_in
= 2; /* just read the zlib header */
429 err
= inflateInit(&d_stream
);
430 CHECK_ERR(err
, "inflateInit");
432 d_stream
.next_out
= uncompr
;
433 d_stream
.avail_out
= (uInt
)uncomprLen
;
435 err
= inflate(&d_stream
, Z_NO_FLUSH
);
436 CHECK_ERR(err
, "inflate");
438 d_stream
.avail_in
= (uInt
)comprLen
-2; /* read all compressed data */
439 err
= inflateSync(&d_stream
); /* but skip the damaged part */
440 CHECK_ERR(err
, "inflateSync");
442 err
= inflate(&d_stream
, Z_FINISH
);
443 if (err
!= Z_DATA_ERROR
) {
444 fprintf(stderr
, "inflate should report DATA_ERROR\n");
445 /* Because of incorrect adler32 */
448 err
= inflateEnd(&d_stream
);
449 CHECK_ERR(err
, "inflateEnd");
451 printf("after inflateSync(): hel%s\n", (char *)uncompr
);
454 /* ===========================================================================
455 * Test deflate() with preset dictionary
457 void test_dict_deflate(compr
, comprLen
)
461 z_stream c_stream
; /* compression stream */
464 c_stream
.zalloc
= zalloc
;
465 c_stream
.zfree
= zfree
;
466 c_stream
.opaque
= (voidpf
)0;
468 err
= deflateInit(&c_stream
, Z_BEST_COMPRESSION
);
469 CHECK_ERR(err
, "deflateInit");
471 err
= deflateSetDictionary(&c_stream
,
472 (const Bytef
*)dictionary
, (int)sizeof(dictionary
));
473 CHECK_ERR(err
, "deflateSetDictionary");
475 dictId
= c_stream
.adler
;
476 c_stream
.next_out
= compr
;
477 c_stream
.avail_out
= (uInt
)comprLen
;
479 c_stream
.next_in
= (z_const
unsigned char *)hello
;
480 c_stream
.avail_in
= (uInt
)strlen(hello
)+1;
482 err
= deflate(&c_stream
, Z_FINISH
);
483 if (err
!= Z_STREAM_END
) {
484 fprintf(stderr
, "deflate should report Z_STREAM_END\n");
487 err
= deflateEnd(&c_stream
);
488 CHECK_ERR(err
, "deflateEnd");
491 /* ===========================================================================
492 * Test inflate() with a preset dictionary
494 void test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
)
495 Byte
*compr
, *uncompr
;
496 uLong comprLen
, uncomprLen
;
499 z_stream d_stream
; /* decompression stream */
501 strcpy((char*)uncompr
, "garbage");
503 d_stream
.zalloc
= zalloc
;
504 d_stream
.zfree
= zfree
;
505 d_stream
.opaque
= (voidpf
)0;
507 d_stream
.next_in
= compr
;
508 d_stream
.avail_in
= (uInt
)comprLen
;
510 err
= inflateInit(&d_stream
);
511 CHECK_ERR(err
, "inflateInit");
513 d_stream
.next_out
= uncompr
;
514 d_stream
.avail_out
= (uInt
)uncomprLen
;
517 err
= inflate(&d_stream
, Z_NO_FLUSH
);
518 if (err
== Z_STREAM_END
) break;
519 if (err
== Z_NEED_DICT
) {
520 if (d_stream
.adler
!= dictId
) {
521 fprintf(stderr
, "unexpected dictionary");
524 err
= inflateSetDictionary(&d_stream
, (const Bytef
*)dictionary
,
525 (int)sizeof(dictionary
));
527 CHECK_ERR(err
, "inflate with dict");
530 err
= inflateEnd(&d_stream
);
531 CHECK_ERR(err
, "inflateEnd");
533 if (strcmp((char*)uncompr
, hello
)) {
534 fprintf(stderr
, "bad inflate with dict\n");
537 printf("inflate with dictionary: %s\n", (char *)uncompr
);
541 /* ===========================================================================
542 * Usage: example [output.gz [input.gz]]
549 Byte
*compr
, *uncompr
;
550 uLong comprLen
= 10000*sizeof(int); /* don't overflow on MSDOS */
551 uLong uncomprLen
= comprLen
;
552 static const char* myVersion
= ZLIB_VERSION
;
554 if (zlibVersion()[0] != myVersion
[0]) {
555 fprintf(stderr
, "incompatible zlib version\n");
558 } else if (strcmp(zlibVersion(), ZLIB_VERSION
) != 0) {
559 fprintf(stderr
, "warning: different zlib version\n");
562 printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
563 ZLIB_VERSION
, ZLIB_VERNUM
, zlibCompileFlags());
565 compr
= (Byte
*)calloc((uInt
)comprLen
, 1);
566 uncompr
= (Byte
*)calloc((uInt
)uncomprLen
, 1);
567 /* compr and uncompr are cleared to avoid reading uninitialized
568 * data and to ensure that uncompr compresses well.
570 if (compr
== Z_NULL
|| uncompr
== Z_NULL
) {
571 printf("out of memory\n");
579 test_compress(compr
, comprLen
, uncompr
, uncomprLen
);
581 test_gzio((argc
> 1 ? argv
[1] : TESTFILE
),
582 uncompr
, uncomprLen
);
585 test_deflate(compr
, comprLen
);
586 test_inflate(compr
, comprLen
, uncompr
, uncomprLen
);
588 test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
);
589 test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
);
591 test_flush(compr
, &comprLen
);
592 test_sync(compr
, comprLen
, uncompr
, uncomprLen
);
593 comprLen
= uncomprLen
;
595 test_dict_deflate(compr
, comprLen
);
596 test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
);