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