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