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