1 /* example.c -- usage example of the zlib compression library
4 Copyright (c) 1995-2006, 2011 Jean-loup Gailly
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgement in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
33 #if defined(VMS) || defined(RISCOS)
34 # define TESTFILE "foo-gz"
36 # define TESTFILE "foo.gz"
39 #define CHECK_ERR(err, msg) { \
41 fprintf(stderr, "%s error: %d\n", msg, err); \
46 z_const char hello[] = "hello, hello!";
47 /* "hello world" would be more standard, but the repeated "hello"
48 * stresses the compression code better, sorry...
51 const char dictionary[] = "hello";
52 uLong dictId; /* Adler32 value of the dictionary */
54 void test_deflate _Z_OF((Byte *compr, uLong comprLen));
55 void test_inflate _Z_OF((Byte *compr, uLong comprLen,
56 Byte *uncompr, uLong uncomprLen));
57 void test_large_deflate _Z_OF((Byte *compr, uLong comprLen,
58 Byte *uncompr, uLong uncomprLen));
59 void test_large_inflate _Z_OF((Byte *compr, uLong comprLen,
60 Byte *uncompr, uLong uncomprLen));
61 void test_flush _Z_OF((Byte *compr, uLong *comprLen));
62 void test_sync _Z_OF((Byte *compr, uLong comprLen,
63 Byte *uncompr, uLong uncomprLen));
64 void test_dict_deflate _Z_OF((Byte *compr, uLong comprLen));
65 void test_dict_inflate _Z_OF((Byte *compr, uLong comprLen,
66 Byte *uncompr, uLong uncomprLen));
67 int main _Z_OF((int argc, char *argv[]));
72 void *myalloc _Z_OF((void *, unsigned, unsigned));
73 void myfree _Z_OF((void *, void *));
75 void *myalloc(q, n, m)
83 void myfree(void *q, void *p)
89 static alloc_func zalloc = myalloc;
90 static free_func zfree = myfree;
94 static alloc_func zalloc = (alloc_func)0;
95 static free_func zfree = (free_func)0;
97 void test_compress _Z_OF((Byte *compr, uLong comprLen,
98 Byte *uncompr, uLong uncomprLen));
99 void test_gzio _Z_OF((const char *fname,
100 Byte *uncompr, uLong uncomprLen));
102 /* ===========================================================================
103 * Test compress() and uncompress()
105 void test_compress(compr, comprLen, uncompr, uncomprLen)
106 Byte *compr, *uncompr;
107 uLong comprLen, uncomprLen;
110 uLong len = (uLong)strlen(hello)+1;
112 err = compress(compr, &comprLen, (const Bytef*)hello, len);
113 CHECK_ERR(err, "compress");
115 strcpy((char*)uncompr, "garbage");
117 err = uncompress(uncompr, &uncomprLen, compr, comprLen);
118 CHECK_ERR(err, "uncompress");
120 if (strcmp((char*)uncompr, hello)) {
121 fprintf(stderr, "bad uncompress\n");
124 printf("uncompress(): %s\n", (char *)uncompr);
128 /* ===========================================================================
129 * Test read/write of .gz files
131 void test_gzio(fname, uncompr, uncomprLen)
132 const char *fname; /* compressed file name */
137 fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
140 int len = (int)strlen(hello)+1;
144 file = gzopen(fname, "wb");
146 fprintf(stderr, "gzopen error\n");
150 if (gzputs(file, "ello") != 4) {
151 fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
154 if (gzprintf(file, ", %s!", "hello") != 8) {
155 fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
158 gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
161 file = gzopen(fname, "rb");
163 fprintf(stderr, "gzopen error\n");
166 strcpy((char*)uncompr, "garbage");
168 if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
169 fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
172 if (strcmp((char*)uncompr, hello)) {
173 fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
176 printf("gzread(): %s\n", (char*)uncompr);
179 pos = gzseek(file, -8L, SEEK_CUR);
180 if (pos != 6 || gztell(file) != pos) {
181 fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
182 (long)pos, (long)gztell(file));
186 if (gzgetc(file) != ' ') {
187 fprintf(stderr, "gzgetc error\n");
191 if (gzungetc(' ', file) != ' ') {
192 fprintf(stderr, "gzungetc error\n");
196 gzgets(file, (char*)uncompr, (int)uncomprLen);
197 if (strlen((char*)uncompr) != 7) { /* " hello!" */
198 fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
201 if (strcmp((char*)uncompr, hello + 6)) {
202 fprintf(stderr, "bad gzgets after gzseek\n");
205 printf("gzgets() after gzseek: %s\n", (char*)uncompr);
214 /* ===========================================================================
215 * Test deflate() with small buffers
217 void test_deflate(compr, comprLen)
221 z_stream c_stream; /* compression stream */
223 uLong len = (uLong)strlen(hello)+1;
225 c_stream.zalloc = zalloc;
226 c_stream.zfree = zfree;
227 c_stream.opaque = (voidpf)0;
229 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
230 CHECK_ERR(err, "deflateInit");
232 c_stream.next_in = (z_const unsigned char *)hello;
233 c_stream.next_out = compr;
235 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
236 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
237 err = deflate(&c_stream, Z_NO_FLUSH);
238 CHECK_ERR(err, "deflate");
240 /* Finish the stream, still forcing small buffers: */
242 c_stream.avail_out = 1;
243 err = deflate(&c_stream, Z_FINISH);
244 if (err == Z_STREAM_END) break;
245 CHECK_ERR(err, "deflate");
248 err = deflateEnd(&c_stream);
249 CHECK_ERR(err, "deflateEnd");
252 /* ===========================================================================
253 * Test inflate() with small buffers
255 void test_inflate(compr, comprLen, uncompr, uncomprLen)
256 Byte *compr, *uncompr;
257 uLong comprLen, uncomprLen;
260 z_stream d_stream; /* decompression stream */
262 strcpy((char*)uncompr, "garbage");
264 d_stream.zalloc = zalloc;
265 d_stream.zfree = zfree;
266 d_stream.opaque = (voidpf)0;
268 d_stream.next_in = compr;
269 d_stream.avail_in = 0;
270 d_stream.next_out = uncompr;
272 err = inflateInit(&d_stream);
273 CHECK_ERR(err, "inflateInit");
275 while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
276 d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
277 err = inflate(&d_stream, Z_NO_FLUSH);
278 if (err == Z_STREAM_END) break;
279 CHECK_ERR(err, "inflate");
282 err = inflateEnd(&d_stream);
283 CHECK_ERR(err, "inflateEnd");
285 if (strcmp((char*)uncompr, hello)) {
286 fprintf(stderr, "bad inflate\n");
289 printf("inflate(): %s\n", (char *)uncompr);
293 /* ===========================================================================
294 * Test deflate() with large buffers and dynamic change of compression level
296 void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
297 Byte *compr, *uncompr;
298 uLong comprLen, uncomprLen;
300 z_stream c_stream; /* compression stream */
303 c_stream.zalloc = zalloc;
304 c_stream.zfree = zfree;
305 c_stream.opaque = (voidpf)0;
307 err = deflateInit(&c_stream, Z_BEST_SPEED);
308 CHECK_ERR(err, "deflateInit");
310 c_stream.next_out = compr;
311 c_stream.avail_out = (uInt)comprLen;
313 /* At this point, uncompr is still mostly zeroes, so it should compress
316 c_stream.next_in = uncompr;
317 c_stream.avail_in = (uInt)uncomprLen;
318 err = deflate(&c_stream, Z_NO_FLUSH);
319 CHECK_ERR(err, "deflate");
320 if (c_stream.avail_in != 0) {
321 fprintf(stderr, "deflate not greedy\n");
325 /* Feed in already compressed data and switch to no compression: */
326 deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
327 c_stream.next_in = compr;
328 c_stream.avail_in = (uInt)comprLen/2;
329 err = deflate(&c_stream, Z_NO_FLUSH);
330 CHECK_ERR(err, "deflate");
332 /* Switch back to compressing mode: */
333 deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
334 c_stream.next_in = uncompr;
335 c_stream.avail_in = (uInt)uncomprLen;
336 err = deflate(&c_stream, Z_NO_FLUSH);
337 CHECK_ERR(err, "deflate");
339 err = deflate(&c_stream, Z_FINISH);
340 if (err != Z_STREAM_END) {
341 fprintf(stderr, "deflate should report Z_STREAM_END\n");
344 err = deflateEnd(&c_stream);
345 CHECK_ERR(err, "deflateEnd");
348 /* ===========================================================================
349 * Test inflate() with large buffers
351 void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
352 Byte *compr, *uncompr;
353 uLong comprLen, uncomprLen;
356 z_stream d_stream; /* decompression stream */
358 strcpy((char*)uncompr, "garbage");
360 d_stream.zalloc = zalloc;
361 d_stream.zfree = zfree;
362 d_stream.opaque = (voidpf)0;
364 d_stream.next_in = compr;
365 d_stream.avail_in = (uInt)comprLen;
367 err = inflateInit(&d_stream);
368 CHECK_ERR(err, "inflateInit");
371 d_stream.next_out = uncompr; /* discard the output */
372 d_stream.avail_out = (uInt)uncomprLen;
373 err = inflate(&d_stream, Z_NO_FLUSH);
374 if (err == Z_STREAM_END) break;
375 CHECK_ERR(err, "large inflate");
378 err = inflateEnd(&d_stream);
379 CHECK_ERR(err, "inflateEnd");
381 if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
382 fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
385 printf("large_inflate(): OK\n");
389 /* ===========================================================================
390 * Test deflate() with full flush
392 void test_flush(compr, comprLen)
396 z_stream c_stream; /* compression stream */
398 uInt len = (uInt)strlen(hello)+1;
400 c_stream.zalloc = zalloc;
401 c_stream.zfree = zfree;
402 c_stream.opaque = (voidpf)0;
404 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
405 CHECK_ERR(err, "deflateInit");
407 c_stream.next_in = (z_const unsigned char *)hello;
408 c_stream.next_out = compr;
409 c_stream.avail_in = 3;
410 c_stream.avail_out = (uInt)*comprLen;
411 err = deflate(&c_stream, Z_FULL_FLUSH);
412 CHECK_ERR(err, "deflate");
414 compr[3]++; /* force an error in first compressed block */
415 c_stream.avail_in = len - 3;
417 err = deflate(&c_stream, Z_FINISH);
418 if (err != Z_STREAM_END) {
419 CHECK_ERR(err, "deflate");
421 err = deflateEnd(&c_stream);
422 CHECK_ERR(err, "deflateEnd");
424 *comprLen = c_stream.total_out;
427 /* ===========================================================================
430 void test_sync(compr, comprLen, uncompr, uncomprLen)
431 Byte *compr, *uncompr;
432 uLong comprLen, uncomprLen;
435 z_stream d_stream; /* decompression stream */
437 strcpy((char*)uncompr, "garbage");
439 d_stream.zalloc = zalloc;
440 d_stream.zfree = zfree;
441 d_stream.opaque = (voidpf)0;
443 d_stream.next_in = compr;
444 d_stream.avail_in = 2; /* just read the zlib header */
446 err = inflateInit(&d_stream);
447 CHECK_ERR(err, "inflateInit");
449 d_stream.next_out = uncompr;
450 d_stream.avail_out = (uInt)uncomprLen;
452 inflate(&d_stream, Z_NO_FLUSH);
453 CHECK_ERR(err, "inflate");
455 d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
456 err = inflateSync(&d_stream); /* but skip the damaged part */
457 CHECK_ERR(err, "inflateSync");
459 err = inflate(&d_stream, Z_FINISH);
460 if (err != Z_DATA_ERROR) {
461 fprintf(stderr, "inflate should report DATA_ERROR\n");
462 /* Because of incorrect adler32 */
465 err = inflateEnd(&d_stream);
466 CHECK_ERR(err, "inflateEnd");
468 printf("after inflateSync(): hel%s\n", (char *)uncompr);
471 /* ===========================================================================
472 * Test deflate() with preset dictionary
474 void test_dict_deflate(compr, comprLen)
478 z_stream c_stream; /* compression stream */
481 c_stream.zalloc = zalloc;
482 c_stream.zfree = zfree;
483 c_stream.opaque = (voidpf)0;
485 err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
486 CHECK_ERR(err, "deflateInit");
488 err = deflateSetDictionary(&c_stream,
489 (const Bytef*)dictionary, (int)sizeof(dictionary));
490 CHECK_ERR(err, "deflateSetDictionary");
492 dictId = c_stream.adler;
493 c_stream.next_out = compr;
494 c_stream.avail_out = (uInt)comprLen;
496 c_stream.next_in = (z_const unsigned char *)hello;
497 c_stream.avail_in = (uInt)strlen(hello)+1;
499 err = deflate(&c_stream, Z_FINISH);
500 if (err != Z_STREAM_END) {
501 fprintf(stderr, "deflate should report Z_STREAM_END\n");
504 err = deflateEnd(&c_stream);
505 CHECK_ERR(err, "deflateEnd");
508 /* ===========================================================================
509 * Test inflate() with a preset dictionary
511 void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
512 Byte *compr, *uncompr;
513 uLong comprLen, uncomprLen;
516 z_stream d_stream; /* decompression stream */
518 strcpy((char*)uncompr, "garbage");
520 d_stream.zalloc = zalloc;
521 d_stream.zfree = zfree;
522 d_stream.opaque = (voidpf)0;
524 d_stream.next_in = compr;
525 d_stream.avail_in = (uInt)comprLen;
527 err = inflateInit(&d_stream);
528 CHECK_ERR(err, "inflateInit");
530 d_stream.next_out = uncompr;
531 d_stream.avail_out = (uInt)uncomprLen;
534 err = inflate(&d_stream, Z_NO_FLUSH);
535 if (err == Z_STREAM_END) break;
536 if (err == Z_NEED_DICT) {
537 if (d_stream.adler != dictId) {
538 fprintf(stderr, "unexpected dictionary");
541 err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
542 (int)sizeof(dictionary));
544 CHECK_ERR(err, "inflate with dict");
547 err = inflateEnd(&d_stream);
548 CHECK_ERR(err, "inflateEnd");
550 if (strcmp((char*)uncompr, hello)) {
551 fprintf(stderr, "bad inflate with dict\n");
554 printf("inflate with dictionary: %s\n", (char *)uncompr);
558 /* ===========================================================================
559 * Usage: example [output.gz [input.gz]]
566 Byte *compr, *uncompr;
567 uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
568 uLong uncomprLen = comprLen;
569 static const char* myVersion = ZLIB_VERSION;
571 if (zlibVersion()[0] != myVersion[0]) {
572 fprintf(stderr, "incompatible zlib version\n");
575 } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
576 fprintf(stderr, "warning: different zlib version\n");
579 printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
580 ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
582 compr = (Byte*)calloc((uInt)comprLen, 1);
583 uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
584 /* compr and uncompr are cleared to avoid reading uninitialized
585 * data and to ensure that uncompr compresses well.
587 if (compr == Z_NULL || uncompr == Z_NULL) {
588 printf("out of memory\n");
593 argc = strlen(argv[0]);
595 test_compress(compr, comprLen, uncompr, uncomprLen);
597 test_gzio((argc > 1 ? argv[1] : TESTFILE),
598 uncompr, uncomprLen);
601 test_deflate(compr, comprLen);
602 test_inflate(compr, comprLen, uncompr, uncomprLen);
604 test_large_deflate(compr, comprLen, uncompr, uncomprLen);
605 test_large_inflate(compr, comprLen, uncompr, uncomprLen);
607 test_flush(compr, &comprLen);
608 test_sync(compr, comprLen, uncompr, uncomprLen);
609 comprLen = uncomprLen;
611 test_dict_deflate(compr, comprLen);
612 test_dict_inflate(compr, comprLen, uncompr, uncomprLen);