1 /* example.c -- usage example of the zlib compression library
2 * Copyright (C) 1995-2006, 2011, 2016 Jean-loup Gailly
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6 #include "zbuild.h"
7 #ifdef ZLIB_COMPAT
8 # include "zlib.h"
9 #else
10 # include "zlib-ng.h"
11 #endif
12 #include "deflate.h"
13
14 #include <stdio.h>
15 #include <stdarg.h>
16 #include <inttypes.h>
17
18 #define TESTFILE "foo.gz"
19
20 static const char hello[] = "hello, hello!";
21 /* "hello world" would be more standard, but the repeated "hello"
22 * stresses the compression code better, sorry...
23 */
24
25 static const char dictionary[] = "hello";
26 static unsigned long dictId = 0; /* Adler32 value of the dictionary */
27
28 /* Maximum dictionary size, according to inflateGetDictionary() description. */
29 #define MAX_DICTIONARY_SIZE 32768
30
31
32 void test_compress (unsigned char *compr, z_size_t comprLen,unsigned char *uncompr, z_size_t uncomprLen);
33 void test_gzio (const char *fname, unsigned char *uncompr, z_size_t uncomprLen);
34 void test_deflate (unsigned char *compr, size_t comprLen);
35 void test_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
36 void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params);
37 void test_large_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
38 void test_flush (unsigned char *compr, z_size_t *comprLen);
39 void test_sync (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
40 void test_dict_deflate (unsigned char *compr, size_t comprLen);
41 void test_dict_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen);
42 int main (int argc, char *argv[]);
43
44
45 static alloc_func zalloc = NULL;
46 static free_func zfree = NULL;
47
48 /* ===========================================================================
49 * Display error message and exit
50 */
error(const char * format,...)51 void error(const char *format, ...) {
52 va_list va;
53
54 va_start(va, format);
55 vfprintf(stderr, format, va);
56 va_end(va);
57
58 exit(1);
59 }
60
61 #define CHECK_ERR(err, msg) { \
62 if (err != Z_OK) \
63 error("%s error: %d\n", msg, err); \
64 }
65
66 /* ===========================================================================
67 * Test compress() and uncompress()
68 */
test_compress(unsigned char * compr,z_size_t comprLen,unsigned char * uncompr,z_size_t uncomprLen)69 void test_compress(unsigned char *compr, z_size_t comprLen, unsigned char *uncompr, z_size_t uncomprLen) {
70 int err;
71 size_t len = strlen(hello)+1;
72
73 err = PREFIX(compress)(compr, &comprLen, (const unsigned char*)hello, (z_size_t)len);
74 CHECK_ERR(err, "compress");
75
76 strcpy((char*)uncompr, "garbage");
77
78 err = PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen);
79 CHECK_ERR(err, "uncompress");
80
81 if (strcmp((char*)uncompr, hello))
82 error("bad uncompress\n");
83 else
84 printf("uncompress(): %s\n", (char *)uncompr);
85 }
86
87 /* ===========================================================================
88 * Test read/write of .gz files
89 */
test_gzio(const char * fname,unsigned char * uncompr,z_size_t uncomprLen)90 void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen) {
91 #ifdef NO_GZCOMPRESS
92 fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
93 #else
94 int err;
95 size_t read;
96 size_t len = strlen(hello)+1;
97 gzFile file;
98 z_off64_t pos;
99 z_off64_t comprLen;
100
101 /* Write gz file with test data */
102 file = PREFIX(gzopen)(fname, "wb");
103 if (file == NULL)
104 error("gzopen error\n");
105 /* Write hello, hello! using gzputs and gzprintf */
106 PREFIX(gzputc)(file, 'h');
107 if (PREFIX(gzputs)(file, "ello") != 4)
108 error("gzputs err: %s\n", PREFIX(gzerror)(file, &err));
109 if (PREFIX(gzprintf)(file, ", %s!", "hello") != 8)
110 error("gzprintf err: %s\n", PREFIX(gzerror)(file, &err));
111 /* Write string null-teriminator using gzseek */
112 if (PREFIX(gzseek)(file, 1L, SEEK_CUR) < 0)
113 error("gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file));
114 /* Write hello, hello! using gzfwrite using best compression level */
115 if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK)
116 error("gzsetparams err: %s\n", PREFIX(gzerror)(file, &err));
117 if (PREFIX(gzfwrite)(hello, len, 1, file) == 0)
118 error("gzfwrite err: %s\n", PREFIX(gzerror)(file, &err));
119 /* Flush compressed bytes to file */
120 if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK)
121 error("gzflush err: %s\n", PREFIX(gzerror)(file, &err));
122 comprLen = PREFIX(gzoffset)(file);
123 if (comprLen <= 0)
124 error("gzoffset err: %s\n", PREFIX(gzerror)(file, &err));
125 PREFIX(gzclose)(file);
126
127 /* Open gz file we previously wrote */
128 file = PREFIX(gzopen)(fname, "rb");
129 if (file == NULL)
130 error("gzopen error\n");
131
132 /* Read uncompressed data - hello, hello! string twice */
133 strcpy((char*)uncompr, "garbages");
134 if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len))
135 error("gzread err: %s\n", PREFIX(gzerror)(file, &err));
136 if (strcmp((char*)uncompr, hello))
137 error("bad gzread: %s\n", (char*)uncompr);
138 else
139 printf("gzread(): %s\n", (char*)uncompr);
140 /* Check position at the end of the gz file */
141 if (PREFIX(gzeof)(file) != 1)
142 error("gzeof err: not reporting end of stream\n");
143
144 /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */
145 pos = PREFIX(gzseek)(file, -22L, SEEK_CUR);
146 if (pos != 6 || PREFIX(gztell)(file) != pos)
147 error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file));
148 if (PREFIX(gzgetc)(file) != ' ')
149 error("gzgetc error\n");
150 if (PREFIX(gzungetc)(' ', file) != ' ')
151 error("gzungetc error\n");
152 /* Read first hello, hello! string with gzgets */
153 strcpy((char*)uncompr, "garbages");
154 PREFIX(gzgets)(file, (char*)uncompr, (int)uncomprLen);
155 if (strlen((char*)uncompr) != 7) /* " hello!" */
156 error("gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err));
157 if (strcmp((char*)uncompr, hello + 6))
158 error("bad gzgets after gzseek\n");
159 else
160 printf("gzgets() after gzseek: %s\n", (char*)uncompr);
161 /* Seek to second hello, hello! string */
162 pos = PREFIX(gzseek)(file, 14L, SEEK_SET);
163 if (pos != 14 || PREFIX(gztell)(file) != pos)
164 error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file));
165 /* Check position not at end of file */
166 if (PREFIX(gzeof)(file) != 0)
167 error("gzeof err: reporting end of stream\n");
168 /* Read first hello, hello! string with gzfread */
169 strcpy((char*)uncompr, "garbages");
170 read = PREFIX(gzfread)(uncompr, uncomprLen, 1, file);
171 if (strcmp((const char *)uncompr, hello) != 0)
172 error("bad gzgets\n");
173 else
174 printf("gzgets(): %s\n", (char*)uncompr);
175 pos = PREFIX(gzoffset)(file);
176 if (pos < 0 || pos != (comprLen + 10))
177 error("gzoffset err: wrong offset at end\n");
178 /* Trigger an error and clear it with gzclearerr */
179 PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file);
180 PREFIX(gzerror)(file, &err);
181 if (err == 0)
182 error("gzerror err: no error returned\n");
183 PREFIX(gzclearerr)(file);
184 PREFIX(gzerror)(file, &err);
185 if (err != 0)
186 error("gzclearerr err: not zero %d\n", err);
187
188 PREFIX(gzclose)(file);
189
190 if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR)
191 error("gzclose unexpected return when handle null\n");
192 Z_UNUSED(read);
193 #endif
194 }
195
196 /* ===========================================================================
197 * Test deflate() with small buffers
198 */
test_deflate(unsigned char * compr,size_t comprLen)199 void test_deflate(unsigned char *compr, size_t comprLen) {
200 PREFIX3(stream) c_stream; /* compression stream */
201 int err;
202 size_t len = strlen(hello)+1;
203
204 c_stream.zalloc = zalloc;
205 c_stream.zfree = zfree;
206 c_stream.opaque = (void *)0;
207 c_stream.total_in = 0;
208 c_stream.total_out = 0;
209
210 err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
211 CHECK_ERR(err, "deflateInit");
212
213 c_stream.next_in = (z_const unsigned char *)hello;
214 c_stream.next_out = compr;
215
216 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
217 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
218 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
219 CHECK_ERR(err, "deflate");
220 }
221 /* Finish the stream, still forcing small buffers: */
222 for (;;) {
223 c_stream.avail_out = 1;
224 err = PREFIX(deflate)(&c_stream, Z_FINISH);
225 if (err == Z_STREAM_END) break;
226 CHECK_ERR(err, "deflate");
227 }
228
229 err = PREFIX(deflateEnd)(&c_stream);
230 CHECK_ERR(err, "deflateEnd");
231 }
232
233 /* ===========================================================================
234 * Test inflate() with small buffers
235 */
test_inflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)236 void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
237 int err;
238 PREFIX3(stream) d_stream; /* decompression stream */
239
240 strcpy((char*)uncompr, "garbage");
241
242 d_stream.zalloc = zalloc;
243 d_stream.zfree = zfree;
244 d_stream.opaque = (void *)0;
245
246 d_stream.next_in = compr;
247 d_stream.avail_in = 0;
248 d_stream.next_out = uncompr;
249 d_stream.total_in = 0;
250 d_stream.total_out = 0;
251
252 err = PREFIX(inflateInit)(&d_stream);
253 CHECK_ERR(err, "inflateInit");
254
255 while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
256 d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
257 err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
258 if (err == Z_STREAM_END) break;
259 CHECK_ERR(err, "inflate");
260 }
261
262 err = PREFIX(inflateEnd)(&d_stream);
263 CHECK_ERR(err, "inflateEnd");
264
265 if (strcmp((char*)uncompr, hello))
266 error("bad inflate\n");
267 else
268 printf("inflate(): %s\n", (char *)uncompr);
269 }
270
271 static unsigned int diff;
272
273 /* ===========================================================================
274 * Test deflate() with large buffers and dynamic change of compression level
275 */
test_large_deflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen,int zng_params)276 void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params) {
277 PREFIX3(stream) c_stream; /* compression stream */
278 int err;
279 #ifndef ZLIB_COMPAT
280 int level = -1;
281 int strategy = -1;
282 zng_deflate_param_value params[2];
283
284 params[0].param = Z_DEFLATE_LEVEL;
285 params[0].buf = &level;
286 params[0].size = sizeof(level);
287
288 params[1].param = Z_DEFLATE_STRATEGY;
289 params[1].buf = &strategy;
290 params[1].size = sizeof(strategy);
291 #endif
292
293 c_stream.zalloc = zalloc;
294 c_stream.zfree = zfree;
295 c_stream.opaque = (void *)0;
296
297 err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED);
298 CHECK_ERR(err, "deflateInit");
299
300 c_stream.next_out = compr;
301 c_stream.avail_out = (unsigned int)comprLen;
302
303 /* At this point, uncompr is still mostly zeroes, so it should compress
304 * very well:
305 */
306 c_stream.next_in = uncompr;
307 c_stream.avail_in = (unsigned int)uncomprLen;
308 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
309 CHECK_ERR(err, "deflate");
310 if (c_stream.avail_in != 0)
311 error("deflate not greedy\n");
312
313 /* Feed in already compressed data and switch to no compression: */
314 if (zng_params) {
315 #ifndef ZLIB_COMPAT
316 zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
317 if (level != Z_BEST_SPEED)
318 error("Expected compression level Z_BEST_SPEED, got %d\n", level);
319 if (strategy != Z_DEFAULT_STRATEGY)
320 error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
321 level = Z_NO_COMPRESSION;
322 strategy = Z_DEFAULT_STRATEGY;
323 zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
324 #else
325 error("test_large_deflate() called with zng_params=1 in compat mode\n");
326 #endif
327 } else {
328 PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
329 }
330 c_stream.next_in = compr;
331 diff = (unsigned int)(c_stream.next_out - compr);
332 c_stream.avail_in = diff;
333 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
334 CHECK_ERR(err, "deflate");
335
336 /* Switch back to compressing mode: */
337 if (zng_params) {
338 #ifndef ZLIB_COMPAT
339 level = -1;
340 strategy = -1;
341 zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
342 if (level != Z_NO_COMPRESSION)
343 error("Expected compression level Z_NO_COMPRESSION, got %d\n", level);
344 if (strategy != Z_DEFAULT_STRATEGY)
345 error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy);
346 level = Z_BEST_COMPRESSION;
347 strategy = Z_FILTERED;
348 zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0]));
349 #else
350 error("test_large_deflate() called with zng_params=1 in compat mode\n");
351 #endif
352 } else {
353 PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
354 }
355 c_stream.next_in = uncompr;
356 c_stream.avail_in = (unsigned int)uncomprLen;
357 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
358 CHECK_ERR(err, "deflate");
359
360 err = PREFIX(deflate)(&c_stream, Z_FINISH);
361 if (err != Z_STREAM_END)
362 error("deflate should report Z_STREAM_END\n");
363 err = PREFIX(deflateEnd)(&c_stream);
364 CHECK_ERR(err, "deflateEnd");
365 }
366
367 /* ===========================================================================
368 * Test inflate() with large buffers
369 */
test_large_inflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)370 void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
371 int err;
372 PREFIX3(stream) d_stream; /* decompression stream */
373
374 strcpy((char*)uncompr, "garbage");
375
376 d_stream.zalloc = zalloc;
377 d_stream.zfree = zfree;
378 d_stream.opaque = (void *)0;
379
380 d_stream.next_in = compr;
381 d_stream.avail_in = (unsigned int)comprLen;
382 d_stream.total_in = 0;
383 d_stream.total_out = 0;
384
385 err = PREFIX(inflateInit)(&d_stream);
386 CHECK_ERR(err, "inflateInit");
387
388 for (;;) {
389 d_stream.next_out = uncompr; /* discard the output */
390 d_stream.avail_out = (unsigned int)uncomprLen;
391 err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
392 if (err == Z_STREAM_END) break;
393 CHECK_ERR(err, "large inflate");
394 }
395
396 err = PREFIX(inflateEnd)(&d_stream);
397 CHECK_ERR(err, "inflateEnd");
398
399 if (d_stream.total_out != 2*uncomprLen + diff)
400 error("bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out);
401 else
402 printf("large_inflate(): OK\n");
403 }
404
405 /* ===========================================================================
406 * Test deflate() with full flush
407 */
test_flush(unsigned char * compr,z_size_t * comprLen)408 void test_flush(unsigned char *compr, z_size_t *comprLen) {
409 PREFIX3(stream) c_stream; /* compression stream */
410 int err;
411 unsigned int len = (unsigned int)strlen(hello)+1;
412
413 c_stream.zalloc = zalloc;
414 c_stream.zfree = zfree;
415 c_stream.opaque = (void *)0;
416
417 err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
418 CHECK_ERR(err, "deflateInit");
419
420 c_stream.next_in = (z_const unsigned char *)hello;
421 c_stream.next_out = compr;
422 c_stream.avail_in = 3;
423 c_stream.avail_out = (unsigned int)*comprLen;
424 err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH);
425 CHECK_ERR(err, "deflate");
426
427 compr[3]++; /* force an error in first compressed block */
428 c_stream.avail_in = len - 3;
429
430 err = PREFIX(deflate)(&c_stream, Z_FINISH);
431 if (err != Z_STREAM_END) {
432 CHECK_ERR(err, "deflate");
433 }
434 err = PREFIX(deflateEnd)(&c_stream);
435 CHECK_ERR(err, "deflateEnd");
436
437 *comprLen = (z_size_t)c_stream.total_out;
438 }
439
440 /* ===========================================================================
441 * Test inflateSync()
442 */
test_sync(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)443 void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
444 int err;
445 PREFIX3(stream) d_stream; /* decompression stream */
446
447 strcpy((char*)uncompr, "garbage");
448
449 d_stream.zalloc = zalloc;
450 d_stream.zfree = zfree;
451 d_stream.opaque = (void *)0;
452
453 d_stream.next_in = compr;
454 d_stream.avail_in = 2; /* just read the zlib header */
455
456 err = PREFIX(inflateInit)(&d_stream);
457 CHECK_ERR(err, "inflateInit");
458
459 d_stream.next_out = uncompr;
460 d_stream.avail_out = (unsigned int)uncomprLen;
461
462 err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
463 CHECK_ERR(err, "inflate");
464
465 d_stream.avail_in = (unsigned int)comprLen-2; /* read all compressed data */
466 err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */
467 CHECK_ERR(err, "inflateSync");
468
469 err = PREFIX(inflate)(&d_stream, Z_FINISH);
470 if (err != Z_STREAM_END)
471 error("inflate should report Z_STREAM_END\n");
472 err = PREFIX(inflateEnd)(&d_stream);
473 CHECK_ERR(err, "inflateEnd");
474
475 printf("after inflateSync(): hel%s\n", (char *)uncompr);
476 }
477
478 /* ===========================================================================
479 * Test deflate() with preset dictionary
480 */
test_dict_deflate(unsigned char * compr,size_t comprLen)481 void test_dict_deflate(unsigned char *compr, size_t comprLen) {
482 PREFIX3(stream) c_stream; /* compression stream */
483 int err;
484
485 c_stream.zalloc = zalloc;
486 c_stream.zfree = zfree;
487 c_stream.opaque = (void *)0;
488 c_stream.adler = 0;
489
490 err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
491 CHECK_ERR(err, "deflateInit");
492
493 err = PREFIX(deflateSetDictionary)(&c_stream,
494 (const unsigned char*)dictionary, (int)sizeof(dictionary));
495 CHECK_ERR(err, "deflateSetDictionary");
496
497 dictId = c_stream.adler;
498 c_stream.next_out = compr;
499 c_stream.avail_out = (unsigned int)comprLen;
500
501 c_stream.next_in = (z_const unsigned char *)hello;
502 c_stream.avail_in = (unsigned int)strlen(hello)+1;
503
504 err = PREFIX(deflate)(&c_stream, Z_FINISH);
505 if (err != Z_STREAM_END)
506 error("deflate should report Z_STREAM_END\n");
507 err = PREFIX(deflateEnd)(&c_stream);
508 CHECK_ERR(err, "deflateEnd");
509 }
510
511 /* ===========================================================================
512 * Test inflate() with a preset dictionary
513 */
test_dict_inflate(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)514 void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
515 int err;
516 uint8_t check_dictionary[MAX_DICTIONARY_SIZE];
517 uint32_t check_dictionary_len = 0;
518 PREFIX3(stream) d_stream; /* decompression stream */
519
520 strcpy((char*)uncompr, "garbage garbage garbage");
521
522 d_stream.zalloc = zalloc;
523 d_stream.zfree = zfree;
524 d_stream.opaque = (void *)0;
525 d_stream.adler = 0;
526 d_stream.next_in = compr;
527 d_stream.avail_in = (unsigned int)comprLen;
528
529 err = PREFIX(inflateInit)(&d_stream);
530 CHECK_ERR(err, "inflateInit");
531
532 d_stream.next_out = uncompr;
533 d_stream.avail_out = (unsigned int)uncomprLen;
534
535 for (;;) {
536 err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH);
537 if (err == Z_STREAM_END) break;
538 if (err == Z_NEED_DICT) {
539 if (d_stream.adler != dictId)
540 error("unexpected dictionary");
541 err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary,
542 (int)sizeof(dictionary));
543 }
544 CHECK_ERR(err, "inflate with dict");
545 }
546
547 err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dictionary_len);
548 CHECK_ERR(err, "inflateGetDictionary");
549 #ifndef S390_DFLTCC_INFLATE
550 if (check_dictionary_len < sizeof(dictionary))
551 error("bad dictionary length\n");
552 #endif
553
554 err = PREFIX(inflateGetDictionary)(&d_stream, check_dictionary, &check_dictionary_len);
555 CHECK_ERR(err, "inflateGetDictionary");
556 #ifndef S390_DFLTCC_INFLATE
557 if (memcmp(dictionary, check_dictionary, sizeof(dictionary)) != 0)
558 error("bad dictionary\n");
559 #endif
560
561 err = PREFIX(inflateEnd)(&d_stream);
562 CHECK_ERR(err, "inflateEnd");
563
564 if (strncmp((char*)uncompr, hello, sizeof(hello)))
565 error("bad inflate with dict\n");
566 else
567 printf("inflate with dictionary: %s\n", (char *)uncompr);
568 }
569
570 /* ===========================================================================
571 * Test deflateBound() with small buffers
572 */
test_deflate_bound(void)573 void test_deflate_bound(void) {
574 PREFIX3(stream) c_stream; /* compression stream */
575 int err;
576 unsigned int len = (unsigned int)strlen(hello)+1;
577 int estimateLen = 0;
578 unsigned char *outBuf = NULL;
579
580 c_stream.zalloc = zalloc;
581 c_stream.zfree = zfree;
582 c_stream.opaque = (voidpf)0;
583 c_stream.avail_in = len;
584 c_stream.next_in = (z_const unsigned char *)hello;
585 c_stream.avail_out = 0;
586 c_stream.next_out = outBuf;
587
588 err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
589 CHECK_ERR(err, "deflateInit");
590
591 /* calculate actual output length and update structure */
592 estimateLen = PREFIX(deflateBound)(&c_stream, len);
593 outBuf = malloc(estimateLen);
594
595 if (outBuf != NULL) {
596 /* update zlib configuration */
597 c_stream.avail_out = estimateLen;
598 c_stream.next_out = outBuf;
599
600 /* do the compression */
601 err = PREFIX(deflate)(&c_stream, Z_FINISH);
602 if (err == Z_STREAM_END) {
603 printf("deflateBound(): OK\n");
604 } else {
605 CHECK_ERR(err, "deflate");
606 }
607 }
608
609 err = PREFIX(deflateEnd)(&c_stream);
610 CHECK_ERR(err, "deflateEnd");
611
612 free(outBuf);
613 }
614
615 /* ===========================================================================
616 * Test deflateCopy() with small buffers
617 */
test_deflate_copy(unsigned char * compr,size_t comprLen)618 void test_deflate_copy(unsigned char *compr, size_t comprLen) {
619 PREFIX3(stream) c_stream, c_stream_copy; /* compression stream */
620 int err;
621 size_t len = strlen(hello)+1;
622
623 memset(&c_stream, 0, sizeof(c_stream));
624
625 c_stream.zalloc = zalloc;
626 c_stream.zfree = zfree;
627 c_stream.opaque = (voidpf)0;
628
629 err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
630 CHECK_ERR(err, "deflateInit");
631
632 c_stream.next_in = (z_const unsigned char *)hello;
633 c_stream.next_out = compr;
634
635 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
636 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
637 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
638 CHECK_ERR(err, "deflate");
639 }
640
641 /* Finish the stream, still forcing small buffers: */
642 for (;;) {
643 c_stream.avail_out = 1;
644 err = PREFIX(deflate)(&c_stream, Z_FINISH);
645 if (err == Z_STREAM_END) break;
646 CHECK_ERR(err, "deflate");
647 }
648
649 err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream);
650 CHECK_ERR(err, "deflate_copy");
651
652 if (c_stream.state->status == c_stream_copy.state->status) {
653 printf("deflate_copy(): OK\n");
654 }
655
656 err = PREFIX(deflateEnd)(&c_stream);
657 CHECK_ERR(err, "deflateEnd original");
658
659 err = PREFIX(deflateEnd)(&c_stream_copy);
660 CHECK_ERR(err, "deflateEnd copy");
661 }
662
663 /* ===========================================================================
664 * Test deflateGetDictionary() with small buffers
665 */
test_deflate_get_dict(unsigned char * compr,size_t comprLen)666 void test_deflate_get_dict(unsigned char *compr, size_t comprLen) {
667 PREFIX3(stream) c_stream; /* compression stream */
668 int err;
669 unsigned char *dictNew = NULL;
670 unsigned int *dictLen;
671
672 c_stream.zalloc = zalloc;
673 c_stream.zfree = zfree;
674 c_stream.opaque = (voidpf)0;
675
676 err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
677 CHECK_ERR(err, "deflateInit");
678
679 c_stream.next_out = compr;
680 c_stream.avail_out = (uInt)comprLen;
681
682 c_stream.next_in = (z_const unsigned char *)hello;
683 c_stream.avail_in = (unsigned int)strlen(hello)+1;
684
685 err = PREFIX(deflate)(&c_stream, Z_FINISH);
686
687 if (err != Z_STREAM_END)
688 error("deflate should report Z_STREAM_END\n");
689
690 dictNew = calloc(256, 1);
691 dictLen = (unsigned int *)calloc(4, 1);
692 err = PREFIX(deflateGetDictionary)(&c_stream, dictNew, dictLen);
693
694 CHECK_ERR(err, "deflateGetDictionary");
695 if (err == Z_OK) {
696 printf("deflateGetDictionary(): %s\n", dictNew);
697 }
698
699 err = PREFIX(deflateEnd)(&c_stream);
700 CHECK_ERR(err, "deflateEnd");
701
702 free(dictNew);
703 free(dictLen);
704 }
705
706 /* ===========================================================================
707 * Test deflatePending() with small buffers
708 */
test_deflate_pending(unsigned char * compr,size_t comprLen)709 void test_deflate_pending(unsigned char *compr, size_t comprLen) {
710 PREFIX3(stream) c_stream; /* compression stream */
711 int err;
712 int *bits = calloc(256, 1);
713 unsigned *ped = calloc(256, 1);
714 size_t len = strlen(hello)+1;
715
716
717 c_stream.zalloc = zalloc;
718 c_stream.zfree = zfree;
719 c_stream.opaque = (voidpf)0;
720
721 err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION);
722 CHECK_ERR(err, "deflateInit");
723
724 c_stream.next_in = (z_const unsigned char *)hello;
725 c_stream.next_out = compr;
726
727 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
728 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
729 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
730 CHECK_ERR(err, "deflate");
731 }
732
733 err = PREFIX(deflatePending)(&c_stream, ped, bits);
734 CHECK_ERR(err, "deflatePending");
735
736 if (*bits >= 0 && *bits <= 7) {
737 printf("deflatePending(): OK\n");
738 } else {
739 printf("deflatePending(): error\n");
740 }
741
742 /* Finish the stream, still forcing small buffers: */
743 for (;;) {
744 c_stream.avail_out = 1;
745 err = PREFIX(deflate)(&c_stream, Z_FINISH);
746 if (err == Z_STREAM_END) break;
747 CHECK_ERR(err, "deflate");
748 }
749
750 err = PREFIX(deflateEnd)(&c_stream);
751 CHECK_ERR(err, "deflateEnd");
752
753 free(bits);
754 free(ped);
755 }
756
757 /* ===========================================================================
758 * Test deflatePrime() wrapping gzip around deflate stream
759 */
test_deflate_prime(unsigned char * compr,size_t comprLen,unsigned char * uncompr,size_t uncomprLen)760 void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) {
761 PREFIX3(stream) c_stream; /* compression stream */
762 PREFIX3(stream) d_stream; /* decompression stream */
763 int err;
764 size_t len = strlen(hello)+1;
765 uint32_t crc = 0;
766
767
768 c_stream.zalloc = zalloc;
769 c_stream.zfree = zfree;
770 c_stream.opaque = (voidpf)0;
771
772 /* Raw deflate windowBits is -15 */
773 err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY);
774 CHECK_ERR(err, "deflateInit2");
775
776 /* Gzip magic number */
777 err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f);
778 CHECK_ERR(err, "deflatePrime");
779 /* Gzip compression method (deflate) */
780 err = PREFIX(deflatePrime)(&c_stream, 8, 0x08);
781 CHECK_ERR(err, "deflatePrime");
782 /* Gzip flags (one byte, using two odd bit calls) */
783 err = PREFIX(deflatePrime)(&c_stream, 3, 0x0);
784 CHECK_ERR(err, "deflatePrime");
785 err = PREFIX(deflatePrime)(&c_stream, 5, 0x0);
786 CHECK_ERR(err, "deflatePrime");
787 /* Gzip modified time */
788 err = PREFIX(deflatePrime)(&c_stream, 32, 0x0);
789 CHECK_ERR(err, "deflatePrime");
790 /* Gzip extra flags */
791 err = PREFIX(deflatePrime)(&c_stream, 8, 0x0);
792 CHECK_ERR(err, "deflatePrime");
793 /* Gzip operating system */
794 err = PREFIX(deflatePrime)(&c_stream, 8, 255);
795 CHECK_ERR(err, "deflatePrime");
796
797 c_stream.next_in = (z_const unsigned char *)hello;
798 c_stream.avail_in = (uint32_t)len;
799 c_stream.next_out = compr;
800 c_stream.avail_out = (uint32_t)comprLen;
801
802 err = PREFIX(deflate)(&c_stream, Z_FINISH);
803 if (err != Z_STREAM_END)
804 CHECK_ERR(err, "deflate");
805
806 /* Gzip uncompressed data crc32 */
807 crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)len);
808 err = PREFIX(deflatePrime)(&c_stream, 32, crc);
809 CHECK_ERR(err, "deflatePrime");
810 /* Gzip uncompressed data length */
811 err = PREFIX(deflatePrime)(&c_stream, 32, (uint32_t)len);
812 CHECK_ERR(err, "deflatePrime");
813
814 err = PREFIX(deflateEnd)(&c_stream);
815 CHECK_ERR(err, "deflateEnd");
816
817 d_stream.zalloc = zalloc;
818 d_stream.zfree = zfree;
819 d_stream.opaque = (void *)0;
820
821 d_stream.next_in = compr;
822 d_stream.avail_in = (uint32_t)c_stream.total_out;
823 d_stream.next_out = uncompr;
824 d_stream.avail_out = (uint32_t)uncomprLen;
825 d_stream.total_in = 0;
826 d_stream.total_out = 0;
827
828 /* Inflate with gzip header */
829 err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32);
830 CHECK_ERR(err, "inflateInit");
831
832 err = PREFIX(inflate)(&d_stream, Z_FINISH);
833 if (err != Z_BUF_ERROR) {
834 CHECK_ERR(err, "inflate");
835 }
836
837 err = PREFIX(inflateEnd)(&d_stream);
838 CHECK_ERR(err, "inflateEnd");
839
840 if (strcmp((const char *)uncompr, hello) != 0)
841 error("bad deflatePrime\n");
842 if (err == Z_OK)
843 printf("deflatePrime(): OK\n");
844 }
845
846 /* ===========================================================================
847 * Test deflateSetHeader() with small buffers
848 */
test_deflate_set_header(unsigned char * compr,size_t comprLen)849 void test_deflate_set_header(unsigned char *compr, size_t comprLen) {
850 PREFIX(gz_header) *head = calloc(1, sizeof(PREFIX(gz_header)));
851 PREFIX3(stream) c_stream; /* compression stream */
852 int err;
853 size_t len = strlen(hello)+1;
854
855
856 if (head == NULL)
857 error("out of memory\n");
858
859 c_stream.zalloc = zalloc;
860 c_stream.zfree = zfree;
861 c_stream.opaque = (voidpf)0;
862
863 /* gzip */
864 err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY);
865 CHECK_ERR(err, "deflateInit2");
866
867 head->text = 1;
868 head->comment = (uint8_t *)"comment";
869 head->name = (uint8_t *)"name";
870 head->hcrc = 1;
871 head->extra = (uint8_t *)"extra";
872 head->extra_len = (uint32_t)strlen((const char *)head->extra);
873
874 err = PREFIX(deflateSetHeader)(&c_stream, head);
875 CHECK_ERR(err, "deflateSetHeader");
876 if (err == Z_OK) {
877 printf("deflateSetHeader(): OK\n");
878 }
879 PREFIX(deflateBound)(&c_stream, (unsigned long)comprLen);
880
881 c_stream.next_in = (unsigned char *)hello;
882 c_stream.next_out = compr;
883
884 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
885 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
886 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
887 CHECK_ERR(err, "deflate");
888 }
889
890 /* Finish the stream, still forcing small buffers: */
891 for (;;) {
892 c_stream.avail_out = 1;
893 err = PREFIX(deflate)(&c_stream, Z_FINISH);
894 if (err == Z_STREAM_END) break;
895 CHECK_ERR(err, "deflate");
896 }
897
898 err = PREFIX(deflateEnd)(&c_stream);
899 CHECK_ERR(err, "deflateEnd");
900
901 free(head);
902 }
903
904 /* ===========================================================================
905 * Test deflateTune() with small buffers
906 */
test_deflate_tune(unsigned char * compr,size_t comprLen)907 void test_deflate_tune(unsigned char *compr, size_t comprLen) {
908 PREFIX3(stream) c_stream; /* compression stream */
909 int err;
910 int good_length = 3;
911 int max_lazy = 5;
912 int nice_length = 18;
913 int max_chain = 6;
914 size_t len = strlen(hello)+1;
915
916
917 c_stream.zalloc = zalloc;
918 c_stream.zfree = zfree;
919 c_stream.opaque = (voidpf)0;
920
921 err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION);
922 CHECK_ERR(err, "deflateInit");
923
924 err = PREFIX(deflateTune)(&c_stream,(uInt)good_length,(uInt)max_lazy,nice_length,(uInt)max_chain);
925 CHECK_ERR(err, "deflateTune");
926 if (err == Z_OK) {
927 printf("deflateTune(): OK\n");
928 }
929
930 c_stream.next_in = (z_const unsigned char *)hello;
931 c_stream.next_out = compr;
932
933 while (c_stream.total_in != len && c_stream.total_out < comprLen) {
934 c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
935 err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH);
936 CHECK_ERR(err, "deflate");
937 }
938
939 /* Finish the stream, still forcing small buffers: */
940 for (;;) {
941 c_stream.avail_out = 1;
942 err = PREFIX(deflate)(&c_stream, Z_FINISH);
943 if (err == Z_STREAM_END) break;
944 CHECK_ERR(err, "deflate");
945 }
946
947 err = PREFIX(deflateEnd)(&c_stream);
948 CHECK_ERR(err, "deflateEnd");
949 }
950
951 /* ===========================================================================
952 * Usage: example [output.gz [input.gz]]
953 */
main(int argc,char * argv[])954 int main(int argc, char *argv[]) {
955 unsigned char *compr, *uncompr;
956 z_size_t comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
957 z_size_t uncomprLen = comprLen;
958 static const char* myVersion = PREFIX2(VERSION);
959
960 if (zVersion()[0] != myVersion[0]) {
961 fprintf(stderr, "incompatible zlib version\n");
962 exit(1);
963
964 } else if (strcmp(zVersion(), PREFIX2(VERSION)) != 0) {
965 fprintf(stderr, "warning: different zlib version\n");
966 }
967
968 printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n",
969 ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)());
970
971 compr = (unsigned char*)calloc((unsigned int)comprLen, 1);
972 uncompr = (unsigned char*)calloc((unsigned int)uncomprLen, 1);
973 /* compr and uncompr are cleared to avoid reading uninitialized
974 * data and to ensure that uncompr compresses well.
975 */
976 if (compr == NULL || uncompr == NULL)
977 error("out of memory\n");
978
979 test_compress(compr, comprLen, uncompr, uncomprLen);
980
981 test_gzio((argc > 1 ? argv[1] : TESTFILE),
982 uncompr, uncomprLen);
983
984 test_deflate(compr, comprLen);
985 test_inflate(compr, comprLen, uncompr, uncomprLen);
986
987 test_large_deflate(compr, comprLen, uncompr, uncomprLen, 0);
988 test_large_inflate(compr, comprLen, uncompr, uncomprLen);
989
990 #ifndef ZLIB_COMPAT
991 test_large_deflate(compr, comprLen, uncompr, uncomprLen, 1);
992 test_large_inflate(compr, comprLen, uncompr, uncomprLen);
993 #endif
994
995 test_flush(compr, &comprLen);
996 test_sync(compr, comprLen, uncompr, uncomprLen);
997 comprLen = uncomprLen;
998
999 test_dict_deflate(compr, comprLen);
1000 test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
1001
1002 test_deflate_bound();
1003 test_deflate_copy(compr, comprLen);
1004 test_deflate_get_dict(compr, comprLen);
1005 test_deflate_set_header(compr, comprLen);
1006 test_deflate_tune(compr, comprLen);
1007 test_deflate_pending(compr, comprLen);
1008 test_deflate_prime(compr, comprLen, uncompr, uncomprLen);
1009
1010 free(compr);
1011 free(uncompr);
1012
1013 return 0;
1014 }
1015