xref: /freebsd-src/sys/contrib/zstd/zlibWrapper/examples/example_original.c (revision 55b1c6e7e4a6909004e13c6d2f328f911a8e7b83)
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