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