source: trunk/third/zlib/example.c @ 17315

Revision 17315, 15.5 KB checked in by zacheiss, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17314, which included commits to RCS files with non-trunk default branches.
Line 
1/* example.c -- usage example of the zlib compression library
2 * Copyright (C) 1995-2002 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* @(#) $Id: example.c,v 1.1.1.2 2002-03-12 17:19:03 zacheiss Exp $ */
7
8#include <stdio.h>
9#include "zlib.h"
10
11#ifdef STDC
12#  include <string.h>
13#  include <stdlib.h>
14#else
15   extern void exit  OF((int));
16#endif
17
18#if defined(VMS) || defined(RISCOS)
19#  define TESTFILE "foo-gz"
20#else
21#  define TESTFILE "foo.gz"
22#endif
23
24#define CHECK_ERR(err, msg) { \
25    if (err != Z_OK) { \
26        fprintf(stderr, "%s error: %d\n", msg, err); \
27        exit(1); \
28    } \
29}
30
31const char hello[] = "hello, hello!";
32/* "hello world" would be more standard, but the repeated "hello"
33 * stresses the compression code better, sorry...
34 */
35
36const char dictionary[] = "hello";
37uLong dictId; /* Adler32 value of the dictionary */
38
39void test_compress      OF((Byte *compr, uLong comprLen,
40                            Byte *uncompr, uLong uncomprLen));
41void test_gzio          OF((const char *out, const char *in,
42                            Byte *uncompr, int uncomprLen));
43void test_deflate       OF((Byte *compr, uLong comprLen));
44void test_inflate       OF((Byte *compr, uLong comprLen,
45                            Byte *uncompr, uLong uncomprLen));
46void test_large_deflate OF((Byte *compr, uLong comprLen,
47                            Byte *uncompr, uLong uncomprLen));
48void test_large_inflate OF((Byte *compr, uLong comprLen,
49                            Byte *uncompr, uLong uncomprLen));
50void test_flush         OF((Byte *compr, uLong *comprLen));
51void test_sync          OF((Byte *compr, uLong comprLen,
52                            Byte *uncompr, uLong uncomprLen));
53void test_dict_deflate  OF((Byte *compr, uLong comprLen));
54void test_dict_inflate  OF((Byte *compr, uLong comprLen,
55                            Byte *uncompr, uLong uncomprLen));
56int  main               OF((int argc, char *argv[]));
57
58/* ===========================================================================
59 * Test compress() and uncompress()
60 */
61void test_compress(compr, comprLen, uncompr, uncomprLen)
62    Byte *compr, *uncompr;
63    uLong comprLen, uncomprLen;
64{
65    int err;
66    uLong len = strlen(hello)+1;
67
68    err = compress(compr, &comprLen, (const Bytef*)hello, len);
69    CHECK_ERR(err, "compress");
70
71    strcpy((char*)uncompr, "garbage");
72
73    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
74    CHECK_ERR(err, "uncompress");
75
76    if (strcmp((char*)uncompr, hello)) {
77        fprintf(stderr, "bad uncompress\n");
78        exit(1);
79    } else {
80        printf("uncompress(): %s\n", (char *)uncompr);
81    }
82}
83
84/* ===========================================================================
85 * Test read/write of .gz files
86 */
87void test_gzio(out, in, uncompr, uncomprLen)
88    const char *out; /* compressed output file */
89    const char *in;  /* compressed input file */
90    Byte *uncompr;
91    int  uncomprLen;
92{
93    int err;
94    int len = strlen(hello)+1;
95    gzFile file;
96    z_off_t pos;
97
98    file = gzopen(out, "wb");
99    if (file == NULL) {
100        fprintf(stderr, "gzopen error\n");
101        exit(1);
102    }
103    gzputc(file, 'h');
104    if (gzputs(file, "ello") != 4) {
105        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
106        exit(1);
107    }
108    if (gzprintf(file, ", %s!", "hello") != 8) {
109        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
110        exit(1);
111    }
112    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
113    gzclose(file);
114
115    file = gzopen(in, "rb");
116    if (file == NULL) {
117        fprintf(stderr, "gzopen error\n");
118    }
119    strcpy((char*)uncompr, "garbage");
120
121    uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
122    if (uncomprLen != len) {
123        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
124        exit(1);
125    }
126    if (strcmp((char*)uncompr, hello)) {
127        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
128        exit(1);
129    } else {
130        printf("gzread(): %s\n", (char *)uncompr);
131    }
132
133    pos = gzseek(file, -8L, SEEK_CUR);
134    if (pos != 6 || gztell(file) != pos) {
135        fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
136                (long)pos, (long)gztell(file));
137        exit(1);
138    }
139
140    if (gzgetc(file) != ' ') {
141        fprintf(stderr, "gzgetc error\n");
142        exit(1);
143    }
144
145    gzgets(file, (char*)uncompr, uncomprLen);
146    uncomprLen = strlen((char*)uncompr);
147    if (uncomprLen != 6) { /* "hello!" */
148        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
149        exit(1);
150    }
151    if (strcmp((char*)uncompr, hello+7)) {
152        fprintf(stderr, "bad gzgets after gzseek\n");
153        exit(1);
154    } else {
155        printf("gzgets() after gzseek: %s\n", (char *)uncompr);
156    }
157
158    gzclose(file);
159}
160
161/* ===========================================================================
162 * Test deflate() with small buffers
163 */
164void test_deflate(compr, comprLen)
165    Byte *compr;
166    uLong comprLen;
167{
168    z_stream c_stream; /* compression stream */
169    int err;
170    int len = strlen(hello)+1;
171
172    c_stream.zalloc = (alloc_func)0;
173    c_stream.zfree = (free_func)0;
174    c_stream.opaque = (voidpf)0;
175
176    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
177    CHECK_ERR(err, "deflateInit");
178
179    c_stream.next_in  = (Bytef*)hello;
180    c_stream.next_out = compr;
181
182    while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
183        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
184        err = deflate(&c_stream, Z_NO_FLUSH);
185        CHECK_ERR(err, "deflate");
186    }
187    /* Finish the stream, still forcing small buffers: */
188    for (;;) {
189        c_stream.avail_out = 1;
190        err = deflate(&c_stream, Z_FINISH);
191        if (err == Z_STREAM_END) break;
192        CHECK_ERR(err, "deflate");
193    }
194
195    err = deflateEnd(&c_stream);
196    CHECK_ERR(err, "deflateEnd");
197}
198
199/* ===========================================================================
200 * Test inflate() with small buffers
201 */
202void test_inflate(compr, comprLen, uncompr, uncomprLen)
203    Byte *compr, *uncompr;
204    uLong comprLen, uncomprLen;
205{
206    int err;
207    z_stream d_stream; /* decompression stream */
208
209    strcpy((char*)uncompr, "garbage");
210
211    d_stream.zalloc = (alloc_func)0;
212    d_stream.zfree = (free_func)0;
213    d_stream.opaque = (voidpf)0;
214
215    d_stream.next_in  = compr;
216    d_stream.avail_in = 0;
217    d_stream.next_out = uncompr;
218
219    err = inflateInit(&d_stream);
220    CHECK_ERR(err, "inflateInit");
221
222    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
223        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
224        err = inflate(&d_stream, Z_NO_FLUSH);
225        if (err == Z_STREAM_END) break;
226        CHECK_ERR(err, "inflate");
227    }
228
229    err = inflateEnd(&d_stream);
230    CHECK_ERR(err, "inflateEnd");
231
232    if (strcmp((char*)uncompr, hello)) {
233        fprintf(stderr, "bad inflate\n");
234        exit(1);
235    } else {
236        printf("inflate(): %s\n", (char *)uncompr);
237    }
238}
239
240/* ===========================================================================
241 * Test deflate() with large buffers and dynamic change of compression level
242 */
243void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
244    Byte *compr, *uncompr;
245    uLong comprLen, uncomprLen;
246{
247    z_stream c_stream; /* compression stream */
248    int err;
249
250    c_stream.zalloc = (alloc_func)0;
251    c_stream.zfree = (free_func)0;
252    c_stream.opaque = (voidpf)0;
253
254    err = deflateInit(&c_stream, Z_BEST_SPEED);
255    CHECK_ERR(err, "deflateInit");
256
257    c_stream.next_out = compr;
258    c_stream.avail_out = (uInt)comprLen;
259
260    /* At this point, uncompr is still mostly zeroes, so it should compress
261     * very well:
262     */
263    c_stream.next_in = uncompr;
264    c_stream.avail_in = (uInt)uncomprLen;
265    err = deflate(&c_stream, Z_NO_FLUSH);
266    CHECK_ERR(err, "deflate");
267    if (c_stream.avail_in != 0) {
268        fprintf(stderr, "deflate not greedy\n");
269        exit(1);
270    }
271
272    /* Feed in already compressed data and switch to no compression: */
273    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
274    c_stream.next_in = compr;
275    c_stream.avail_in = (uInt)comprLen/2;
276    err = deflate(&c_stream, Z_NO_FLUSH);
277    CHECK_ERR(err, "deflate");
278
279    /* Switch back to compressing mode: */
280    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
281    c_stream.next_in = uncompr;
282    c_stream.avail_in = (uInt)uncomprLen;
283    err = deflate(&c_stream, Z_NO_FLUSH);
284    CHECK_ERR(err, "deflate");
285
286    err = deflate(&c_stream, Z_FINISH);
287    if (err != Z_STREAM_END) {
288        fprintf(stderr, "deflate should report Z_STREAM_END\n");
289        exit(1);
290    }
291    err = deflateEnd(&c_stream);
292    CHECK_ERR(err, "deflateEnd");
293}
294
295/* ===========================================================================
296 * Test inflate() with large buffers
297 */
298void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
299    Byte *compr, *uncompr;
300    uLong comprLen, uncomprLen;
301{
302    int err;
303    z_stream d_stream; /* decompression stream */
304
305    strcpy((char*)uncompr, "garbage");
306
307    d_stream.zalloc = (alloc_func)0;
308    d_stream.zfree = (free_func)0;
309    d_stream.opaque = (voidpf)0;
310
311    d_stream.next_in  = compr;
312    d_stream.avail_in = (uInt)comprLen;
313
314    err = inflateInit(&d_stream);
315    CHECK_ERR(err, "inflateInit");
316
317    for (;;) {
318        d_stream.next_out = uncompr;            /* discard the output */
319        d_stream.avail_out = (uInt)uncomprLen;
320        err = inflate(&d_stream, Z_NO_FLUSH);
321        if (err == Z_STREAM_END) break;
322        CHECK_ERR(err, "large inflate");
323    }
324
325    err = inflateEnd(&d_stream);
326    CHECK_ERR(err, "inflateEnd");
327
328    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
329        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
330        exit(1);
331    } else {
332        printf("large_inflate(): OK\n");
333    }
334}
335
336/* ===========================================================================
337 * Test deflate() with full flush
338 */
339void test_flush(compr, comprLen)
340    Byte *compr;
341    uLong *comprLen;
342{
343    z_stream c_stream; /* compression stream */
344    int err;
345    int len = strlen(hello)+1;
346
347    c_stream.zalloc = (alloc_func)0;
348    c_stream.zfree = (free_func)0;
349    c_stream.opaque = (voidpf)0;
350
351    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
352    CHECK_ERR(err, "deflateInit");
353
354    c_stream.next_in  = (Bytef*)hello;
355    c_stream.next_out = compr;
356    c_stream.avail_in = 3;
357    c_stream.avail_out = (uInt)*comprLen;
358    err = deflate(&c_stream, Z_FULL_FLUSH);
359    CHECK_ERR(err, "deflate");
360
361    compr[3]++; /* force an error in first compressed block */
362    c_stream.avail_in = len - 3;
363
364    err = deflate(&c_stream, Z_FINISH);
365    if (err != Z_STREAM_END) {
366        CHECK_ERR(err, "deflate");
367    }
368    err = deflateEnd(&c_stream);
369    CHECK_ERR(err, "deflateEnd");
370
371    *comprLen = c_stream.total_out;
372}
373
374/* ===========================================================================
375 * Test inflateSync()
376 */
377void test_sync(compr, comprLen, uncompr, uncomprLen)
378    Byte *compr, *uncompr;
379    uLong comprLen, uncomprLen;
380{
381    int err;
382    z_stream d_stream; /* decompression stream */
383
384    strcpy((char*)uncompr, "garbage");
385
386    d_stream.zalloc = (alloc_func)0;
387    d_stream.zfree = (free_func)0;
388    d_stream.opaque = (voidpf)0;
389
390    d_stream.next_in  = compr;
391    d_stream.avail_in = 2; /* just read the zlib header */
392
393    err = inflateInit(&d_stream);
394    CHECK_ERR(err, "inflateInit");
395
396    d_stream.next_out = uncompr;
397    d_stream.avail_out = (uInt)uncomprLen;
398
399    inflate(&d_stream, Z_NO_FLUSH);
400    CHECK_ERR(err, "inflate");
401
402    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
403    err = inflateSync(&d_stream);           /* but skip the damaged part */
404    CHECK_ERR(err, "inflateSync");
405
406    err = inflate(&d_stream, Z_FINISH);
407    if (err != Z_DATA_ERROR) {
408        fprintf(stderr, "inflate should report DATA_ERROR\n");
409        /* Because of incorrect adler32 */
410        exit(1);
411    }
412    err = inflateEnd(&d_stream);
413    CHECK_ERR(err, "inflateEnd");
414
415    printf("after inflateSync(): hel%s\n", (char *)uncompr);
416}
417
418/* ===========================================================================
419 * Test deflate() with preset dictionary
420 */
421void test_dict_deflate(compr, comprLen)
422    Byte *compr;
423    uLong comprLen;
424{
425    z_stream c_stream; /* compression stream */
426    int err;
427
428    c_stream.zalloc = (alloc_func)0;
429    c_stream.zfree = (free_func)0;
430    c_stream.opaque = (voidpf)0;
431
432    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
433    CHECK_ERR(err, "deflateInit");
434
435    err = deflateSetDictionary(&c_stream,
436                               (const Bytef*)dictionary, sizeof(dictionary));
437    CHECK_ERR(err, "deflateSetDictionary");
438
439    dictId = c_stream.adler;
440    c_stream.next_out = compr;
441    c_stream.avail_out = (uInt)comprLen;
442
443    c_stream.next_in = (Bytef*)hello;
444    c_stream.avail_in = (uInt)strlen(hello)+1;
445
446    err = deflate(&c_stream, Z_FINISH);
447    if (err != Z_STREAM_END) {
448        fprintf(stderr, "deflate should report Z_STREAM_END\n");
449        exit(1);
450    }
451    err = deflateEnd(&c_stream);
452    CHECK_ERR(err, "deflateEnd");
453}
454
455/* ===========================================================================
456 * Test inflate() with a preset dictionary
457 */
458void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
459    Byte *compr, *uncompr;
460    uLong comprLen, uncomprLen;
461{
462    int err;
463    z_stream d_stream; /* decompression stream */
464
465    strcpy((char*)uncompr, "garbage");
466
467    d_stream.zalloc = (alloc_func)0;
468    d_stream.zfree = (free_func)0;
469    d_stream.opaque = (voidpf)0;
470
471    d_stream.next_in  = compr;
472    d_stream.avail_in = (uInt)comprLen;
473
474    err = inflateInit(&d_stream);
475    CHECK_ERR(err, "inflateInit");
476
477    d_stream.next_out = uncompr;
478    d_stream.avail_out = (uInt)uncomprLen;
479
480    for (;;) {
481        err = inflate(&d_stream, Z_NO_FLUSH);
482        if (err == Z_STREAM_END) break;
483        if (err == Z_NEED_DICT) {
484            if (d_stream.adler != dictId) {
485                fprintf(stderr, "unexpected dictionary");
486                exit(1);
487            }
488            err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
489                                       sizeof(dictionary));
490        }
491        CHECK_ERR(err, "inflate with dict");
492    }
493
494    err = inflateEnd(&d_stream);
495    CHECK_ERR(err, "inflateEnd");
496
497    if (strcmp((char*)uncompr, hello)) {
498        fprintf(stderr, "bad inflate with dict\n");
499        exit(1);
500    } else {
501        printf("inflate with dictionary: %s\n", (char *)uncompr);
502    }
503}
504
505/* ===========================================================================
506 * Usage:  example [output.gz  [input.gz]]
507 */
508
509int main(argc, argv)
510    int argc;
511    char *argv[];
512{
513    Byte *compr, *uncompr;
514    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
515    uLong uncomprLen = comprLen;
516    static const char* myVersion = ZLIB_VERSION;
517
518    if (zlibVersion()[0] != myVersion[0]) {
519        fprintf(stderr, "incompatible zlib version\n");
520        exit(1);
521
522    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
523        fprintf(stderr, "warning: different zlib version\n");
524    }
525
526    compr    = (Byte*)calloc((uInt)comprLen, 1);
527    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
528    /* compr and uncompr are cleared to avoid reading uninitialized
529     * data and to ensure that uncompr compresses well.
530     */
531    if (compr == Z_NULL || uncompr == Z_NULL) {
532        printf("out of memory\n");
533        exit(1);
534    }
535    test_compress(compr, comprLen, uncompr, uncomprLen);
536
537    test_gzio((argc > 1 ? argv[1] : TESTFILE),
538              (argc > 2 ? argv[2] : TESTFILE),
539              uncompr, (int)uncomprLen);
540
541    test_deflate(compr, comprLen);
542    test_inflate(compr, comprLen, uncompr, uncomprLen);
543
544    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
545    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
546
547    test_flush(compr, &comprLen);
548    test_sync(compr, comprLen, uncompr, uncomprLen);
549    comprLen = uncomprLen;
550
551    test_dict_deflate(compr, comprLen);
552    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
553
554    exit(0);
555    return 0; /* to avoid warning */
556}
Note: See TracBrowser for help on using the repository browser.