root/lib/zlib/example.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_compress
  2. test_gzio
  3. test_deflate
  4. test_inflate
  5. test_large_deflate
  6. test_large_inflate
  7. test_flush
  8. test_sync
  9. test_dict_deflate
  10. test_dict_inflate
  11. main

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

/* [<][>][^][v][top][bottom][index][help] */