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