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