1230837Sdelphij/* example.c -- usage example of the zlib compression library
2230837Sdelphij * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
3230837Sdelphij * For conditions of distribution and use, see copyright notice in zlib.h
4230837Sdelphij */
5230837Sdelphij
6230837Sdelphij/* @(#) $Id$ */
7230837Sdelphij
8230837Sdelphij#include "zlib.h"
9230837Sdelphij#include <stdio.h>
10230837Sdelphij
11230837Sdelphij#ifdef STDC
12230837Sdelphij#  include <string.h>
13230837Sdelphij#  include <stdlib.h>
14230837Sdelphij#endif
15230837Sdelphij
16230837Sdelphij#if defined(VMS) || defined(RISCOS)
17230837Sdelphij#  define TESTFILE "foo-gz"
18230837Sdelphij#else
19230837Sdelphij#  define TESTFILE "foo.gz"
20230837Sdelphij#endif
21230837Sdelphij
22230837Sdelphij#define CHECK_ERR(err, msg) { \
23230837Sdelphij    if (err != Z_OK) { \
24230837Sdelphij        fprintf(stderr, "%s error: %d\n", msg, err); \
25230837Sdelphij        exit(1); \
26230837Sdelphij    } \
27230837Sdelphij}
28230837Sdelphij
29250261Sdelphijz_const char hello[] = "hello, hello!";
30230837Sdelphij/* "hello world" would be more standard, but the repeated "hello"
31230837Sdelphij * stresses the compression code better, sorry...
32230837Sdelphij */
33230837Sdelphij
34230837Sdelphijconst char dictionary[] = "hello";
35230837SdelphijuLong dictId; /* Adler32 value of the dictionary */
36230837Sdelphij
37230837Sdelphijvoid test_deflate       OF((Byte *compr, uLong comprLen));
38230837Sdelphijvoid test_inflate       OF((Byte *compr, uLong comprLen,
39230837Sdelphij                            Byte *uncompr, uLong uncomprLen));
40230837Sdelphijvoid test_large_deflate OF((Byte *compr, uLong comprLen,
41230837Sdelphij                            Byte *uncompr, uLong uncomprLen));
42230837Sdelphijvoid test_large_inflate OF((Byte *compr, uLong comprLen,
43230837Sdelphij                            Byte *uncompr, uLong uncomprLen));
44230837Sdelphijvoid test_flush         OF((Byte *compr, uLong *comprLen));
45230837Sdelphijvoid test_sync          OF((Byte *compr, uLong comprLen,
46230837Sdelphij                            Byte *uncompr, uLong uncomprLen));
47230837Sdelphijvoid test_dict_deflate  OF((Byte *compr, uLong comprLen));
48230837Sdelphijvoid test_dict_inflate  OF((Byte *compr, uLong comprLen,
49230837Sdelphij                            Byte *uncompr, uLong uncomprLen));
50230837Sdelphijint  main               OF((int argc, char *argv[]));
51230837Sdelphij
52230837Sdelphij
53230837Sdelphij#ifdef Z_SOLO
54230837Sdelphij
55230837Sdelphijvoid *myalloc OF((void *, unsigned, unsigned));
56230837Sdelphijvoid myfree OF((void *, void *));
57230837Sdelphij
58230837Sdelphijvoid *myalloc(q, n, m)
59230837Sdelphij    void *q;
60230837Sdelphij    unsigned n, m;
61230837Sdelphij{
62230837Sdelphij    q = Z_NULL;
63230837Sdelphij    return calloc(n, m);
64230837Sdelphij}
65230837Sdelphij
66230837Sdelphijvoid myfree(void *q, void *p)
67230837Sdelphij{
68230837Sdelphij    q = Z_NULL;
69230837Sdelphij    free(p);
70230837Sdelphij}
71230837Sdelphij
72230837Sdelphijstatic alloc_func zalloc = myalloc;
73230837Sdelphijstatic free_func zfree = myfree;
74230837Sdelphij
75230837Sdelphij#else /* !Z_SOLO */
76230837Sdelphij
77230837Sdelphijstatic alloc_func zalloc = (alloc_func)0;
78230837Sdelphijstatic free_func zfree = (free_func)0;
79230837Sdelphij
80230837Sdelphijvoid test_compress      OF((Byte *compr, uLong comprLen,
81230837Sdelphij                            Byte *uncompr, uLong uncomprLen));
82230837Sdelphijvoid test_gzio          OF((const char *fname,
83230837Sdelphij                            Byte *uncompr, uLong uncomprLen));
84230837Sdelphij
85230837Sdelphij/* ===========================================================================
86230837Sdelphij * Test compress() and uncompress()
87230837Sdelphij */
88230837Sdelphijvoid test_compress(compr, comprLen, uncompr, uncomprLen)
89230837Sdelphij    Byte *compr, *uncompr;
90230837Sdelphij    uLong comprLen, uncomprLen;
91230837Sdelphij{
92230837Sdelphij    int err;
93230837Sdelphij    uLong len = (uLong)strlen(hello)+1;
94230837Sdelphij
95230837Sdelphij    err = compress(compr, &comprLen, (const Bytef*)hello, len);
96230837Sdelphij    CHECK_ERR(err, "compress");
97230837Sdelphij
98230837Sdelphij    strcpy((char*)uncompr, "garbage");
99230837Sdelphij
100230837Sdelphij    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
101230837Sdelphij    CHECK_ERR(err, "uncompress");
102230837Sdelphij
103230837Sdelphij    if (strcmp((char*)uncompr, hello)) {
104230837Sdelphij        fprintf(stderr, "bad uncompress\n");
105230837Sdelphij        exit(1);
106230837Sdelphij    } else {
107230837Sdelphij        printf("uncompress(): %s\n", (char *)uncompr);
108230837Sdelphij    }
109230837Sdelphij}
110230837Sdelphij
111230837Sdelphij/* ===========================================================================
112230837Sdelphij * Test read/write of .gz files
113230837Sdelphij */
114230837Sdelphijvoid test_gzio(fname, uncompr, uncomprLen)
115230837Sdelphij    const char *fname; /* compressed file name */
116230837Sdelphij    Byte *uncompr;
117230837Sdelphij    uLong uncomprLen;
118230837Sdelphij{
119230837Sdelphij#ifdef NO_GZCOMPRESS
120230837Sdelphij    fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
121230837Sdelphij#else
122230837Sdelphij    int err;
123230837Sdelphij    int len = (int)strlen(hello)+1;
124230837Sdelphij    gzFile file;
125230837Sdelphij    z_off_t pos;
126230837Sdelphij
127230837Sdelphij    file = gzopen(fname, "wb");
128230837Sdelphij    if (file == NULL) {
129230837Sdelphij        fprintf(stderr, "gzopen error\n");
130230837Sdelphij        exit(1);
131230837Sdelphij    }
132230837Sdelphij    gzputc(file, 'h');
133230837Sdelphij    if (gzputs(file, "ello") != 4) {
134230837Sdelphij        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
135230837Sdelphij        exit(1);
136230837Sdelphij    }
137230837Sdelphij    if (gzprintf(file, ", %s!", "hello") != 8) {
138230837Sdelphij        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
139230837Sdelphij        exit(1);
140230837Sdelphij    }
141230837Sdelphij    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
142230837Sdelphij    gzclose(file);
143230837Sdelphij
144230837Sdelphij    file = gzopen(fname, "rb");
145230837Sdelphij    if (file == NULL) {
146230837Sdelphij        fprintf(stderr, "gzopen error\n");
147230837Sdelphij        exit(1);
148230837Sdelphij    }
149230837Sdelphij    strcpy((char*)uncompr, "garbage");
150230837Sdelphij
151230837Sdelphij    if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
152230837Sdelphij        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
153230837Sdelphij        exit(1);
154230837Sdelphij    }
155230837Sdelphij    if (strcmp((char*)uncompr, hello)) {
156230837Sdelphij        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
157230837Sdelphij        exit(1);
158230837Sdelphij    } else {
159230837Sdelphij        printf("gzread(): %s\n", (char*)uncompr);
160230837Sdelphij    }
161230837Sdelphij
162230837Sdelphij    pos = gzseek(file, -8L, SEEK_CUR);
163230837Sdelphij    if (pos != 6 || gztell(file) != pos) {
164230837Sdelphij        fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
165230837Sdelphij                (long)pos, (long)gztell(file));
166230837Sdelphij        exit(1);
167230837Sdelphij    }
168230837Sdelphij
169230837Sdelphij    if (gzgetc(file) != ' ') {
170230837Sdelphij        fprintf(stderr, "gzgetc error\n");
171230837Sdelphij        exit(1);
172230837Sdelphij    }
173230837Sdelphij
174230837Sdelphij    if (gzungetc(' ', file) != ' ') {
175230837Sdelphij        fprintf(stderr, "gzungetc error\n");
176230837Sdelphij        exit(1);
177230837Sdelphij    }
178230837Sdelphij
179230837Sdelphij    gzgets(file, (char*)uncompr, (int)uncomprLen);
180230837Sdelphij    if (strlen((char*)uncompr) != 7) { /* " hello!" */
181230837Sdelphij        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
182230837Sdelphij        exit(1);
183230837Sdelphij    }
184230837Sdelphij    if (strcmp((char*)uncompr, hello + 6)) {
185230837Sdelphij        fprintf(stderr, "bad gzgets after gzseek\n");
186230837Sdelphij        exit(1);
187230837Sdelphij    } else {
188230837Sdelphij        printf("gzgets() after gzseek: %s\n", (char*)uncompr);
189230837Sdelphij    }
190230837Sdelphij
191230837Sdelphij    gzclose(file);
192230837Sdelphij#endif
193230837Sdelphij}
194230837Sdelphij
195230837Sdelphij#endif /* Z_SOLO */
196230837Sdelphij
197230837Sdelphij/* ===========================================================================
198230837Sdelphij * Test deflate() with small buffers
199230837Sdelphij */
200230837Sdelphijvoid test_deflate(compr, comprLen)
201230837Sdelphij    Byte *compr;
202230837Sdelphij    uLong comprLen;
203230837Sdelphij{
204230837Sdelphij    z_stream c_stream; /* compression stream */
205230837Sdelphij    int err;
206230837Sdelphij    uLong len = (uLong)strlen(hello)+1;
207230837Sdelphij
208230837Sdelphij    c_stream.zalloc = zalloc;
209230837Sdelphij    c_stream.zfree = zfree;
210230837Sdelphij    c_stream.opaque = (voidpf)0;
211230837Sdelphij
212230837Sdelphij    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
213230837Sdelphij    CHECK_ERR(err, "deflateInit");
214230837Sdelphij
215250261Sdelphij    c_stream.next_in  = (z_const unsigned char *)hello;
216230837Sdelphij    c_stream.next_out = compr;
217230837Sdelphij
218230837Sdelphij    while (c_stream.total_in != len && c_stream.total_out < comprLen) {
219230837Sdelphij        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
220230837Sdelphij        err = deflate(&c_stream, Z_NO_FLUSH);
221230837Sdelphij        CHECK_ERR(err, "deflate");
222230837Sdelphij    }
223230837Sdelphij    /* Finish the stream, still forcing small buffers: */
224230837Sdelphij    for (;;) {
225230837Sdelphij        c_stream.avail_out = 1;
226230837Sdelphij        err = deflate(&c_stream, Z_FINISH);
227230837Sdelphij        if (err == Z_STREAM_END) break;
228230837Sdelphij        CHECK_ERR(err, "deflate");
229230837Sdelphij    }
230230837Sdelphij
231230837Sdelphij    err = deflateEnd(&c_stream);
232230837Sdelphij    CHECK_ERR(err, "deflateEnd");
233230837Sdelphij}
234230837Sdelphij
235230837Sdelphij/* ===========================================================================
236230837Sdelphij * Test inflate() with small buffers
237230837Sdelphij */
238230837Sdelphijvoid test_inflate(compr, comprLen, uncompr, uncomprLen)
239230837Sdelphij    Byte *compr, *uncompr;
240230837Sdelphij    uLong comprLen, uncomprLen;
241230837Sdelphij{
242230837Sdelphij    int err;
243230837Sdelphij    z_stream d_stream; /* decompression stream */
244230837Sdelphij
245230837Sdelphij    strcpy((char*)uncompr, "garbage");
246230837Sdelphij
247230837Sdelphij    d_stream.zalloc = zalloc;
248230837Sdelphij    d_stream.zfree = zfree;
249230837Sdelphij    d_stream.opaque = (voidpf)0;
250230837Sdelphij
251230837Sdelphij    d_stream.next_in  = compr;
252230837Sdelphij    d_stream.avail_in = 0;
253230837Sdelphij    d_stream.next_out = uncompr;
254230837Sdelphij
255230837Sdelphij    err = inflateInit(&d_stream);
256230837Sdelphij    CHECK_ERR(err, "inflateInit");
257230837Sdelphij
258230837Sdelphij    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
259230837Sdelphij        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
260230837Sdelphij        err = inflate(&d_stream, Z_NO_FLUSH);
261230837Sdelphij        if (err == Z_STREAM_END) break;
262230837Sdelphij        CHECK_ERR(err, "inflate");
263230837Sdelphij    }
264230837Sdelphij
265230837Sdelphij    err = inflateEnd(&d_stream);
266230837Sdelphij    CHECK_ERR(err, "inflateEnd");
267230837Sdelphij
268230837Sdelphij    if (strcmp((char*)uncompr, hello)) {
269230837Sdelphij        fprintf(stderr, "bad inflate\n");
270230837Sdelphij        exit(1);
271230837Sdelphij    } else {
272230837Sdelphij        printf("inflate(): %s\n", (char *)uncompr);
273230837Sdelphij    }
274230837Sdelphij}
275230837Sdelphij
276230837Sdelphij/* ===========================================================================
277230837Sdelphij * Test deflate() with large buffers and dynamic change of compression level
278230837Sdelphij */
279230837Sdelphijvoid test_large_deflate(compr, comprLen, uncompr, uncomprLen)
280230837Sdelphij    Byte *compr, *uncompr;
281230837Sdelphij    uLong comprLen, uncomprLen;
282230837Sdelphij{
283230837Sdelphij    z_stream c_stream; /* compression stream */
284230837Sdelphij    int err;
285230837Sdelphij
286230837Sdelphij    c_stream.zalloc = zalloc;
287230837Sdelphij    c_stream.zfree = zfree;
288230837Sdelphij    c_stream.opaque = (voidpf)0;
289230837Sdelphij
290230837Sdelphij    err = deflateInit(&c_stream, Z_BEST_SPEED);
291230837Sdelphij    CHECK_ERR(err, "deflateInit");
292230837Sdelphij
293230837Sdelphij    c_stream.next_out = compr;
294230837Sdelphij    c_stream.avail_out = (uInt)comprLen;
295230837Sdelphij
296230837Sdelphij    /* At this point, uncompr is still mostly zeroes, so it should compress
297230837Sdelphij     * very well:
298230837Sdelphij     */
299230837Sdelphij    c_stream.next_in = uncompr;
300230837Sdelphij    c_stream.avail_in = (uInt)uncomprLen;
301230837Sdelphij    err = deflate(&c_stream, Z_NO_FLUSH);
302230837Sdelphij    CHECK_ERR(err, "deflate");
303230837Sdelphij    if (c_stream.avail_in != 0) {
304230837Sdelphij        fprintf(stderr, "deflate not greedy\n");
305230837Sdelphij        exit(1);
306230837Sdelphij    }
307230837Sdelphij
308230837Sdelphij    /* Feed in already compressed data and switch to no compression: */
309230837Sdelphij    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
310230837Sdelphij    c_stream.next_in = compr;
311230837Sdelphij    c_stream.avail_in = (uInt)comprLen/2;
312230837Sdelphij    err = deflate(&c_stream, Z_NO_FLUSH);
313230837Sdelphij    CHECK_ERR(err, "deflate");
314230837Sdelphij
315230837Sdelphij    /* Switch back to compressing mode: */
316230837Sdelphij    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
317230837Sdelphij    c_stream.next_in = uncompr;
318230837Sdelphij    c_stream.avail_in = (uInt)uncomprLen;
319230837Sdelphij    err = deflate(&c_stream, Z_NO_FLUSH);
320230837Sdelphij    CHECK_ERR(err, "deflate");
321230837Sdelphij
322230837Sdelphij    err = deflate(&c_stream, Z_FINISH);
323230837Sdelphij    if (err != Z_STREAM_END) {
324230837Sdelphij        fprintf(stderr, "deflate should report Z_STREAM_END\n");
325230837Sdelphij        exit(1);
326230837Sdelphij    }
327230837Sdelphij    err = deflateEnd(&c_stream);
328230837Sdelphij    CHECK_ERR(err, "deflateEnd");
329230837Sdelphij}
330230837Sdelphij
331230837Sdelphij/* ===========================================================================
332230837Sdelphij * Test inflate() with large buffers
333230837Sdelphij */
334230837Sdelphijvoid test_large_inflate(compr, comprLen, uncompr, uncomprLen)
335230837Sdelphij    Byte *compr, *uncompr;
336230837Sdelphij    uLong comprLen, uncomprLen;
337230837Sdelphij{
338230837Sdelphij    int err;
339230837Sdelphij    z_stream d_stream; /* decompression stream */
340230837Sdelphij
341230837Sdelphij    strcpy((char*)uncompr, "garbage");
342230837Sdelphij
343230837Sdelphij    d_stream.zalloc = zalloc;
344230837Sdelphij    d_stream.zfree = zfree;
345230837Sdelphij    d_stream.opaque = (voidpf)0;
346230837Sdelphij
347230837Sdelphij    d_stream.next_in  = compr;
348230837Sdelphij    d_stream.avail_in = (uInt)comprLen;
349230837Sdelphij
350230837Sdelphij    err = inflateInit(&d_stream);
351230837Sdelphij    CHECK_ERR(err, "inflateInit");
352230837Sdelphij
353230837Sdelphij    for (;;) {
354230837Sdelphij        d_stream.next_out = uncompr;            /* discard the output */
355230837Sdelphij        d_stream.avail_out = (uInt)uncomprLen;
356230837Sdelphij        err = inflate(&d_stream, Z_NO_FLUSH);
357230837Sdelphij        if (err == Z_STREAM_END) break;
358230837Sdelphij        CHECK_ERR(err, "large inflate");
359230837Sdelphij    }
360230837Sdelphij
361230837Sdelphij    err = inflateEnd(&d_stream);
362230837Sdelphij    CHECK_ERR(err, "inflateEnd");
363230837Sdelphij
364230837Sdelphij    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
365230837Sdelphij        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
366230837Sdelphij        exit(1);
367230837Sdelphij    } else {
368230837Sdelphij        printf("large_inflate(): OK\n");
369230837Sdelphij    }
370230837Sdelphij}
371230837Sdelphij
372230837Sdelphij/* ===========================================================================
373230837Sdelphij * Test deflate() with full flush
374230837Sdelphij */
375230837Sdelphijvoid test_flush(compr, comprLen)
376230837Sdelphij    Byte *compr;
377230837Sdelphij    uLong *comprLen;
378230837Sdelphij{
379230837Sdelphij    z_stream c_stream; /* compression stream */
380230837Sdelphij    int err;
381230837Sdelphij    uInt len = (uInt)strlen(hello)+1;
382230837Sdelphij
383230837Sdelphij    c_stream.zalloc = zalloc;
384230837Sdelphij    c_stream.zfree = zfree;
385230837Sdelphij    c_stream.opaque = (voidpf)0;
386230837Sdelphij
387230837Sdelphij    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
388230837Sdelphij    CHECK_ERR(err, "deflateInit");
389230837Sdelphij
390250261Sdelphij    c_stream.next_in  = (z_const unsigned char *)hello;
391230837Sdelphij    c_stream.next_out = compr;
392230837Sdelphij    c_stream.avail_in = 3;
393230837Sdelphij    c_stream.avail_out = (uInt)*comprLen;
394230837Sdelphij    err = deflate(&c_stream, Z_FULL_FLUSH);
395230837Sdelphij    CHECK_ERR(err, "deflate");
396230837Sdelphij
397230837Sdelphij    compr[3]++; /* force an error in first compressed block */
398230837Sdelphij    c_stream.avail_in = len - 3;
399230837Sdelphij
400230837Sdelphij    err = deflate(&c_stream, Z_FINISH);
401230837Sdelphij    if (err != Z_STREAM_END) {
402230837Sdelphij        CHECK_ERR(err, "deflate");
403230837Sdelphij    }
404230837Sdelphij    err = deflateEnd(&c_stream);
405230837Sdelphij    CHECK_ERR(err, "deflateEnd");
406230837Sdelphij
407230837Sdelphij    *comprLen = c_stream.total_out;
408230837Sdelphij}
409230837Sdelphij
410230837Sdelphij/* ===========================================================================
411230837Sdelphij * Test inflateSync()
412230837Sdelphij */
413230837Sdelphijvoid test_sync(compr, comprLen, uncompr, uncomprLen)
414230837Sdelphij    Byte *compr, *uncompr;
415230837Sdelphij    uLong comprLen, uncomprLen;
416230837Sdelphij{
417230837Sdelphij    int err;
418230837Sdelphij    z_stream d_stream; /* decompression stream */
419230837Sdelphij
420230837Sdelphij    strcpy((char*)uncompr, "garbage");
421230837Sdelphij
422230837Sdelphij    d_stream.zalloc = zalloc;
423230837Sdelphij    d_stream.zfree = zfree;
424230837Sdelphij    d_stream.opaque = (voidpf)0;
425230837Sdelphij
426230837Sdelphij    d_stream.next_in  = compr;
427230837Sdelphij    d_stream.avail_in = 2; /* just read the zlib header */
428230837Sdelphij
429230837Sdelphij    err = inflateInit(&d_stream);
430230837Sdelphij    CHECK_ERR(err, "inflateInit");
431230837Sdelphij
432230837Sdelphij    d_stream.next_out = uncompr;
433230837Sdelphij    d_stream.avail_out = (uInt)uncomprLen;
434230837Sdelphij
435230837Sdelphij    inflate(&d_stream, Z_NO_FLUSH);
436230837Sdelphij    CHECK_ERR(err, "inflate");
437230837Sdelphij
438230837Sdelphij    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
439230837Sdelphij    err = inflateSync(&d_stream);           /* but skip the damaged part */
440230837Sdelphij    CHECK_ERR(err, "inflateSync");
441230837Sdelphij
442230837Sdelphij    err = inflate(&d_stream, Z_FINISH);
443230837Sdelphij    if (err != Z_DATA_ERROR) {
444230837Sdelphij        fprintf(stderr, "inflate should report DATA_ERROR\n");
445230837Sdelphij        /* Because of incorrect adler32 */
446230837Sdelphij        exit(1);
447230837Sdelphij    }
448230837Sdelphij    err = inflateEnd(&d_stream);
449230837Sdelphij    CHECK_ERR(err, "inflateEnd");
450230837Sdelphij
451230837Sdelphij    printf("after inflateSync(): hel%s\n", (char *)uncompr);
452230837Sdelphij}
453230837Sdelphij
454230837Sdelphij/* ===========================================================================
455230837Sdelphij * Test deflate() with preset dictionary
456230837Sdelphij */
457230837Sdelphijvoid test_dict_deflate(compr, comprLen)
458230837Sdelphij    Byte *compr;
459230837Sdelphij    uLong comprLen;
460230837Sdelphij{
461230837Sdelphij    z_stream c_stream; /* compression stream */
462230837Sdelphij    int err;
463230837Sdelphij
464230837Sdelphij    c_stream.zalloc = zalloc;
465230837Sdelphij    c_stream.zfree = zfree;
466230837Sdelphij    c_stream.opaque = (voidpf)0;
467230837Sdelphij
468230837Sdelphij    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
469230837Sdelphij    CHECK_ERR(err, "deflateInit");
470230837Sdelphij
471230837Sdelphij    err = deflateSetDictionary(&c_stream,
472230837Sdelphij                (const Bytef*)dictionary, (int)sizeof(dictionary));
473230837Sdelphij    CHECK_ERR(err, "deflateSetDictionary");
474230837Sdelphij
475230837Sdelphij    dictId = c_stream.adler;
476230837Sdelphij    c_stream.next_out = compr;
477230837Sdelphij    c_stream.avail_out = (uInt)comprLen;
478230837Sdelphij
479250261Sdelphij    c_stream.next_in = (z_const unsigned char *)hello;
480230837Sdelphij    c_stream.avail_in = (uInt)strlen(hello)+1;
481230837Sdelphij
482230837Sdelphij    err = deflate(&c_stream, Z_FINISH);
483230837Sdelphij    if (err != Z_STREAM_END) {
484230837Sdelphij        fprintf(stderr, "deflate should report Z_STREAM_END\n");
485230837Sdelphij        exit(1);
486230837Sdelphij    }
487230837Sdelphij    err = deflateEnd(&c_stream);
488230837Sdelphij    CHECK_ERR(err, "deflateEnd");
489230837Sdelphij}
490230837Sdelphij
491230837Sdelphij/* ===========================================================================
492230837Sdelphij * Test inflate() with a preset dictionary
493230837Sdelphij */
494230837Sdelphijvoid test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
495230837Sdelphij    Byte *compr, *uncompr;
496230837Sdelphij    uLong comprLen, uncomprLen;
497230837Sdelphij{
498230837Sdelphij    int err;
499230837Sdelphij    z_stream d_stream; /* decompression stream */
500230837Sdelphij
501230837Sdelphij    strcpy((char*)uncompr, "garbage");
502230837Sdelphij
503230837Sdelphij    d_stream.zalloc = zalloc;
504230837Sdelphij    d_stream.zfree = zfree;
505230837Sdelphij    d_stream.opaque = (voidpf)0;
506230837Sdelphij
507230837Sdelphij    d_stream.next_in  = compr;
508230837Sdelphij    d_stream.avail_in = (uInt)comprLen;
509230837Sdelphij
510230837Sdelphij    err = inflateInit(&d_stream);
511230837Sdelphij    CHECK_ERR(err, "inflateInit");
512230837Sdelphij
513230837Sdelphij    d_stream.next_out = uncompr;
514230837Sdelphij    d_stream.avail_out = (uInt)uncomprLen;
515230837Sdelphij
516230837Sdelphij    for (;;) {
517230837Sdelphij        err = inflate(&d_stream, Z_NO_FLUSH);
518230837Sdelphij        if (err == Z_STREAM_END) break;
519230837Sdelphij        if (err == Z_NEED_DICT) {
520230837Sdelphij            if (d_stream.adler != dictId) {
521230837Sdelphij                fprintf(stderr, "unexpected dictionary");
522230837Sdelphij                exit(1);
523230837Sdelphij            }
524230837Sdelphij            err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
525230837Sdelphij                                       (int)sizeof(dictionary));
526230837Sdelphij        }
527230837Sdelphij        CHECK_ERR(err, "inflate with dict");
528230837Sdelphij    }
529230837Sdelphij
530230837Sdelphij    err = inflateEnd(&d_stream);
531230837Sdelphij    CHECK_ERR(err, "inflateEnd");
532230837Sdelphij
533230837Sdelphij    if (strcmp((char*)uncompr, hello)) {
534230837Sdelphij        fprintf(stderr, "bad inflate with dict\n");
535230837Sdelphij        exit(1);
536230837Sdelphij    } else {
537230837Sdelphij        printf("inflate with dictionary: %s\n", (char *)uncompr);
538230837Sdelphij    }
539230837Sdelphij}
540230837Sdelphij
541230837Sdelphij/* ===========================================================================
542230837Sdelphij * Usage:  example [output.gz  [input.gz]]
543230837Sdelphij */
544230837Sdelphij
545230837Sdelphijint main(argc, argv)
546230837Sdelphij    int argc;
547230837Sdelphij    char *argv[];
548230837Sdelphij{
549230837Sdelphij    Byte *compr, *uncompr;
550230837Sdelphij    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
551230837Sdelphij    uLong uncomprLen = comprLen;
552230837Sdelphij    static const char* myVersion = ZLIB_VERSION;
553230837Sdelphij
554230837Sdelphij    if (zlibVersion()[0] != myVersion[0]) {
555230837Sdelphij        fprintf(stderr, "incompatible zlib version\n");
556230837Sdelphij        exit(1);
557230837Sdelphij
558230837Sdelphij    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
559230837Sdelphij        fprintf(stderr, "warning: different zlib version\n");
560230837Sdelphij    }
561230837Sdelphij
562230837Sdelphij    printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
563230837Sdelphij            ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
564230837Sdelphij
565230837Sdelphij    compr    = (Byte*)calloc((uInt)comprLen, 1);
566230837Sdelphij    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
567230837Sdelphij    /* compr and uncompr are cleared to avoid reading uninitialized
568230837Sdelphij     * data and to ensure that uncompr compresses well.
569230837Sdelphij     */
570230837Sdelphij    if (compr == Z_NULL || uncompr == Z_NULL) {
571230837Sdelphij        printf("out of memory\n");
572230837Sdelphij        exit(1);
573230837Sdelphij    }
574230837Sdelphij
575230837Sdelphij#ifdef Z_SOLO
576230837Sdelphij    argc = strlen(argv[0]);
577230837Sdelphij#else
578230837Sdelphij    test_compress(compr, comprLen, uncompr, uncomprLen);
579230837Sdelphij
580230837Sdelphij    test_gzio((argc > 1 ? argv[1] : TESTFILE),
581230837Sdelphij              uncompr, uncomprLen);
582230837Sdelphij#endif
583230837Sdelphij
584230837Sdelphij    test_deflate(compr, comprLen);
585230837Sdelphij    test_inflate(compr, comprLen, uncompr, uncomprLen);
586230837Sdelphij
587230837Sdelphij    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
588230837Sdelphij    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
589230837Sdelphij
590230837Sdelphij    test_flush(compr, &comprLen);
591230837Sdelphij    test_sync(compr, comprLen, uncompr, uncomprLen);
592230837Sdelphij    comprLen = uncomprLen;
593230837Sdelphij
594230837Sdelphij    test_dict_deflate(compr, comprLen);
595230837Sdelphij    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
596230837Sdelphij
597230837Sdelphij    free(compr);
598230837Sdelphij    free(uncompr);
599230837Sdelphij
600230837Sdelphij    return 0;
601230837Sdelphij}
602