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(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)
108 uLong len = (uLong)strlen(hello)+1;
110 err = compress(compr, &comprLen, (const Bytef*)hello, len);
111 CHECK_ERR(err, "compress");
113 strcpy((char*)uncompr, "garbage");
115 err = uncompress(uncompr, &uncomprLen, compr, comprLen);
116 CHECK_ERR(err, "uncompress");
118 if (strcmp((char*)uncompr, hello)) {
119 fprintf(stderr, "bad uncompress\n");
122 printf("uncompress(): %s\n", (char *)uncompr);
126 /* ===========================================================================
127 * Test read/write of .gz files
129 void test_gzio(const char *fname /* compressed file name */, Byte *uncompr,
133 fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
136 int len = (int)strlen(hello)+1;
140 file = gzopen(fname, "wb");
142 fprintf(stderr, "gzopen error\n");
146 if (gzputs(file, "ello") != 4) {
147 fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
150 if (gzprintf(file, ", %s!", "hello") != 8) {
151 fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
154 gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
157 file = gzopen(fname, "rb");
159 fprintf(stderr, "gzopen error\n");
162 strcpy((char*)uncompr, "garbage");
164 if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
165 fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
168 if (strcmp((char*)uncompr, hello)) {
169 fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
172 printf("gzread(): %s\n", (char*)uncompr);
175 pos = gzseek(file, -8L, SEEK_CUR);
176 if (pos != 6 || gztell(file) != pos) {
177 fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
178 (long)pos, (long)gztell(file));
182 if (gzgetc(file) != ' ') {
183 fprintf(stderr, "gzgetc error\n");
187 if (gzungetc(' ', file) != ' ') {
188 fprintf(stderr, "gzungetc error\n");
192 gzgets(file, (char*)uncompr, (int)uncomprLen);
193 if (strlen((char*)uncompr) != 7) { /* " hello!" */
194 fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
197 if (strcmp((char*)uncompr, hello + 6)) {
198 fprintf(stderr, "bad gzgets after gzseek\n");
201 printf("gzgets() after gzseek: %s\n", (char*)uncompr);
210 /* ===========================================================================
211 * Test deflate() with small buffers
213 void test_deflate(Byte *compr, uLong comprLen)
215 z_stream c_stream; /* compression stream */
217 uLong len = (uLong)strlen(hello)+1;
219 c_stream.zalloc = zalloc;
220 c_stream.zfree = zfree;
221 c_stream.opaque = (voidpf)0;
223 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
224 CHECK_ERR(err, "deflateInit");
226 c_stream.next_in = (z_const unsigned char *)hello;
227 c_stream.next_out = compr;
229 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
230 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
231 err = deflate(&c_stream, Z_NO_FLUSH);
232 CHECK_ERR(err, "deflate");
234 /* Finish the stream, still forcing small buffers: */
236 c_stream.avail_out = 1;
237 err = deflate(&c_stream, Z_FINISH);
238 if (err == Z_STREAM_END) break;
239 CHECK_ERR(err, "deflate");
242 err = deflateEnd(&c_stream);
243 CHECK_ERR(err, "deflateEnd");
246 /* ===========================================================================
247 * Test inflate() with small buffers
249 void test_inflate(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)
252 z_stream d_stream; /* decompression stream */
254 strcpy((char*)uncompr, "garbage");
256 d_stream.zalloc = zalloc;
257 d_stream.zfree = zfree;
258 d_stream.opaque = (voidpf)0;
260 d_stream.next_in = compr;
261 d_stream.avail_in = 0;
262 d_stream.next_out = uncompr;
264 err = inflateInit(&d_stream);
265 CHECK_ERR(err, "inflateInit");
267 while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
268 d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
269 err = inflate(&d_stream, Z_NO_FLUSH);
270 if (err == Z_STREAM_END) break;
271 CHECK_ERR(err, "inflate");
274 err = inflateEnd(&d_stream);
275 CHECK_ERR(err, "inflateEnd");
277 if (strcmp((char*)uncompr, hello)) {
278 fprintf(stderr, "bad inflate\n");
281 printf("inflate(): %s\n", (char *)uncompr);
285 /* ===========================================================================
286 * Test deflate() with large buffers and dynamic change of compression level
288 void test_large_deflate(Byte *compr, uLong comprLen, Byte *uncompr,
291 z_stream c_stream; /* compression stream */
294 c_stream.zalloc = zalloc;
295 c_stream.zfree = zfree;
296 c_stream.opaque = (voidpf)0;
298 err = deflateInit(&c_stream, Z_BEST_SPEED);
299 CHECK_ERR(err, "deflateInit");
301 c_stream.next_out = compr;
302 c_stream.avail_out = (uInt)comprLen;
304 /* At this point, uncompr is still mostly zeroes, so it should compress
307 c_stream.next_in = uncompr;
308 c_stream.avail_in = (uInt)uncomprLen;
309 err = deflate(&c_stream, Z_NO_FLUSH);
310 CHECK_ERR(err, "deflate");
311 if (c_stream.avail_in != 0) {
312 fprintf(stderr, "deflate not greedy\n");
316 /* Feed in already compressed data and switch to no compression: */
317 deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
318 c_stream.next_in = compr;
319 c_stream.avail_in = (uInt)comprLen/2;
320 err = deflate(&c_stream, Z_NO_FLUSH);
321 CHECK_ERR(err, "deflate");
323 /* Switch back to compressing mode: */
324 deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
325 c_stream.next_in = uncompr;
326 c_stream.avail_in = (uInt)uncomprLen;
327 err = deflate(&c_stream, Z_NO_FLUSH);
328 CHECK_ERR(err, "deflate");
330 err = deflate(&c_stream, Z_FINISH);
331 if (err != Z_STREAM_END) {
332 fprintf(stderr, "deflate should report Z_STREAM_END\n");
335 err = deflateEnd(&c_stream);
336 CHECK_ERR(err, "deflateEnd");
339 /* ===========================================================================
340 * Test inflate() with large buffers
342 void test_large_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
346 z_stream d_stream; /* decompression stream */
348 strcpy((char*)uncompr, "garbage");
350 d_stream.zalloc = zalloc;
351 d_stream.zfree = zfree;
352 d_stream.opaque = (voidpf)0;
354 d_stream.next_in = compr;
355 d_stream.avail_in = (uInt)comprLen;
357 err = inflateInit(&d_stream);
358 CHECK_ERR(err, "inflateInit");
361 d_stream.next_out = uncompr; /* discard the output */
362 d_stream.avail_out = (uInt)uncomprLen;
363 err = inflate(&d_stream, Z_NO_FLUSH);
364 if (err == Z_STREAM_END) break;
365 CHECK_ERR(err, "large inflate");
368 err = inflateEnd(&d_stream);
369 CHECK_ERR(err, "inflateEnd");
371 if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
372 fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
375 printf("large_inflate(): OK\n");
379 /* ===========================================================================
380 * Test deflate() with full flush
382 void test_flush(Byte *compr, uLong comprLen)
384 z_stream c_stream; /* compression stream */
386 uInt len = (uInt)strlen(hello)+1;
388 c_stream.zalloc = zalloc;
389 c_stream.zfree = zfree;
390 c_stream.opaque = (voidpf)0;
392 err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
393 CHECK_ERR(err, "deflateInit");
395 c_stream.next_in = (z_const unsigned char *)hello;
396 c_stream.next_out = compr;
397 c_stream.avail_in = 3;
398 c_stream.avail_out = (uInt)*comprLen;
399 err = deflate(&c_stream, Z_FULL_FLUSH);
400 CHECK_ERR(err, "deflate");
402 compr[3]++; /* force an error in first compressed block */
403 c_stream.avail_in = len - 3;
405 err = deflate(&c_stream, Z_FINISH);
406 if (err != Z_STREAM_END) {
407 CHECK_ERR(err, "deflate");
409 err = deflateEnd(&c_stream);
410 CHECK_ERR(err, "deflateEnd");
412 *comprLen = c_stream.total_out;
415 /* ===========================================================================
418 void test_sync(Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)
421 z_stream d_stream; /* decompression stream */
423 strcpy((char*)uncompr, "garbage");
425 d_stream.zalloc = zalloc;
426 d_stream.zfree = zfree;
427 d_stream.opaque = (voidpf)0;
429 d_stream.next_in = compr;
430 d_stream.avail_in = 2; /* just read the zlib header */
432 err = inflateInit(&d_stream);
433 CHECK_ERR(err, "inflateInit");
435 d_stream.next_out = uncompr;
436 d_stream.avail_out = (uInt)uncomprLen;
438 inflate(&d_stream, Z_NO_FLUSH);
439 CHECK_ERR(err, "inflate");
441 d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
442 err = inflateSync(&d_stream); /* but skip the damaged part */
443 CHECK_ERR(err, "inflateSync");
445 err = inflate(&d_stream, Z_FINISH);
446 if (err != Z_DATA_ERROR) {
447 fprintf(stderr, "inflate should report DATA_ERROR\n");
448 /* Because of incorrect adler32 */
451 err = inflateEnd(&d_stream);
452 CHECK_ERR(err, "inflateEnd");
454 printf("after inflateSync(): hel%s\n", (char *)uncompr);
457 /* ===========================================================================
458 * Test deflate() with preset dictionary
460 void test_dict_deflate(Byte *compr, uLong comprLen)
462 z_stream c_stream; /* compression stream */
465 c_stream.zalloc = zalloc;
466 c_stream.zfree = zfree;
467 c_stream.opaque = (voidpf)0;
469 err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
470 CHECK_ERR(err, "deflateInit");
472 err = deflateSetDictionary(&c_stream,
473 (const Bytef*)dictionary, (int)sizeof(dictionary));
474 CHECK_ERR(err, "deflateSetDictionary");
476 dictId = c_stream.adler;
477 c_stream.next_out = compr;
478 c_stream.avail_out = (uInt)comprLen;
480 c_stream.next_in = (z_const unsigned char *)hello;
481 c_stream.avail_in = (uInt)strlen(hello)+1;
483 err = deflate(&c_stream, Z_FINISH);
484 if (err != Z_STREAM_END) {
485 fprintf(stderr, "deflate should report Z_STREAM_END\n");
488 err = deflateEnd(&c_stream);
489 CHECK_ERR(err, "deflateEnd");
492 /* ===========================================================================
493 * Test inflate() with a preset dictionary
495 void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr,
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]]
545 int main(int argc, char *argv[])
547 Byte *compr, *uncompr;
548 uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
549 uLong uncomprLen = comprLen;
550 static const char* myVersion = ZLIB_VERSION;
552 if (zlibVersion()[0] != myVersion[0]) {
553 fprintf(stderr, "incompatible zlib version\n");
556 } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
557 fprintf(stderr, "warning: different zlib version\n");
560 printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
561 ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
563 compr = (Byte*)calloc((uInt)comprLen, 1);
564 uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
565 /* compr and uncompr are cleared to avoid reading uninitialized
566 * data and to ensure that uncompr compresses well.
568 if (compr == Z_NULL || uncompr == Z_NULL) {
569 printf("out of memory\n");
574 argc = strlen(argv[0]);
576 test_compress(compr, comprLen, uncompr, uncomprLen);
578 test_gzio((argc > 1 ? argv[1] : TESTFILE),
579 uncompr, uncomprLen);
582 test_deflate(compr, comprLen);
583 test_inflate(compr, comprLen, uncompr, uncomprLen);
585 test_large_deflate(compr, comprLen, uncompr, uncomprLen);
586 test_large_inflate(compr, comprLen, uncompr, uncomprLen);
588 test_flush(compr, &comprLen);
589 test_sync(compr, comprLen, uncompr, uncomprLen);
590 comprLen = uncomprLen;
592 test_dict_deflate(compr, comprLen);
593 test_dict_inflate(compr, comprLen, uncompr, uncomprLen);