]>
git.saurik.com Git - wxWidgets.git/blob - src/zlib/example.c
073ce76b3300d3a209fd3bedcbace737f4a0d312
   1 /* example.c -- usage example of the zlib compression library 
   2  * Copyright (C) 1995-1998 Jean-loup Gailly. 
   3  * For conditions of distribution and use, see copyright notice in zlib.h  
  15    extern void exit  
OF((int)); 
  18 #define CHECK_ERR(err, msg) { \ 
  20         fprintf(stderr, "%s error: %d\n", msg, err); \ 
  25 const char hello
[] = "hello, hello!"; 
  26 /* "hello world" would be more standard, but the repeated "hello" 
  27  * stresses the compression code better, sorry... 
  30 const char dictionary
[] = "hello"; 
  31 uLong dictId
; /* Adler32 value of the dictionary */ 
  33 void test_compress      
OF((Byte 
*compr
, uLong comprLen
, 
  34                             Byte 
*uncompr
, uLong uncomprLen
)); 
  35 void test_gzio          
OF((const char *out
, const char *in
,  
  36                             Byte 
*uncompr
, int uncomprLen
)); 
  37 void test_deflate       
OF((Byte 
*compr
, uLong comprLen
)); 
  38 void test_inflate       
OF((Byte 
*compr
, uLong comprLen
, 
  39                             Byte 
*uncompr
, uLong uncomprLen
)); 
  40 void test_large_deflate 
OF((Byte 
*compr
, uLong comprLen
, 
  41                             Byte 
*uncompr
, uLong uncomprLen
)); 
  42 void test_large_inflate 
OF((Byte 
*compr
, uLong comprLen
, 
  43                             Byte 
*uncompr
, uLong uncomprLen
)); 
  44 void test_flush         
OF((Byte 
*compr
, uLong 
*comprLen
)); 
  45 void test_sync          
OF((Byte 
*compr
, uLong comprLen
, 
  46                             Byte 
*uncompr
, uLong uncomprLen
)); 
  47 void test_dict_deflate  
OF((Byte 
*compr
, uLong comprLen
)); 
  48 void test_dict_inflate  
OF((Byte 
*compr
, uLong comprLen
, 
  49                             Byte 
*uncompr
, uLong uncomprLen
)); 
  50 int  main               
OF((int argc
, char *argv
[])); 
  52 /* =========================================================================== 
  53  * Test compress() and uncompress() 
  55 void test_compress(compr
, comprLen
, uncompr
, uncomprLen
) 
  56     Byte 
*compr
, *uncompr
; 
  57     uLong comprLen
, uncomprLen
; 
  60     uLong len 
= strlen(hello
)+1; 
  62     err 
= compress(compr
, &comprLen
, (const Bytef
*)hello
, len
); 
  63     CHECK_ERR(err
, "compress"); 
  65     strcpy((char*)uncompr
, "garbage"); 
  67     err 
= uncompress(uncompr
, &uncomprLen
, compr
, comprLen
); 
  68     CHECK_ERR(err
, "uncompress"); 
  70     if (strcmp((char*)uncompr
, hello
)) { 
  71         fprintf(stderr
, "bad uncompress\n"); 
  74         printf("uncompress(): %s\n", (char *)uncompr
); 
  78 /* =========================================================================== 
  79  * Test read/write of .gz files 
  81 void test_gzio(out
, in
, uncompr
, uncomprLen
) 
  82     const char *out
; /* output file */ 
  83     const char *in
;  /* input file */ 
  88     int len 
= strlen(hello
)+1; 
  92     file 
= gzopen(out
, "wb"); 
  94         fprintf(stderr
, "gzopen error\n"); 
  98     if (gzputs(file
, "ello") != 4) { 
  99         fprintf(stderr
, "gzputs err: %s\n", gzerror(file
, &err
)); 
 102     if (gzprintf(file
, ", %s!", "hello") != 8) { 
 103         fprintf(stderr
, "gzprintf err: %s\n", gzerror(file
, &err
)); 
 106     gzseek(file
, 1L, SEEK_CUR
); /* add one zero byte */ 
 109     file 
= gzopen(in
, "rb"); 
 111         fprintf(stderr
, "gzopen error\n"); 
 113     strcpy((char*)uncompr
, "garbage"); 
 115     uncomprLen 
= gzread(file
, uncompr
, (unsigned)uncomprLen
); 
 116     if (uncomprLen 
!= len
) { 
 117         fprintf(stderr
, "gzread err: %s\n", gzerror(file
, &err
)); 
 120     if (strcmp((char*)uncompr
, hello
)) { 
 121         fprintf(stderr
, "bad gzread: %s\n", (char*)uncompr
); 
 124         printf("gzread(): %s\n", (char *)uncompr
); 
 127     pos 
= gzseek(file
, -8L, SEEK_CUR
); 
 128     if (pos 
!= 6 || gztell(file
) != pos
) { 
 129         fprintf(stderr
, "gzseek error, pos=%ld, gztell=%ld\n", 
 130                 (long)pos
, (long)gztell(file
)); 
 134     if (gzgetc(file
) != ' ') { 
 135         fprintf(stderr
, "gzgetc error\n"); 
 139     gzgets(file
, (char*)uncompr
, uncomprLen
); 
 140     uncomprLen 
= strlen((char*)uncompr
); 
 141     if (uncomprLen 
!= 6) { /* "hello!" */ 
 142         fprintf(stderr
, "gzgets err after gzseek: %s\n", gzerror(file
, &err
)); 
 145     if (strcmp((char*)uncompr
, hello
+7)) { 
 146         fprintf(stderr
, "bad gzgets after gzseek\n"); 
 149         printf("gzgets() after gzseek: %s\n", (char *)uncompr
); 
 155 /* =========================================================================== 
 156  * Test deflate() with small buffers 
 158 void test_deflate(compr
, comprLen
) 
 162     z_stream c_stream
; /* compression stream */ 
 164     int len 
= strlen(hello
)+1; 
 166     c_stream
.zalloc 
= (alloc_func
)0; 
 167     c_stream
.zfree 
= (free_func
)0; 
 168     c_stream
.opaque 
= (voidpf
)0; 
 170     err 
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
); 
 171     CHECK_ERR(err
, "deflateInit"); 
 173     c_stream
.next_in  
= (Bytef
*)hello
; 
 174     c_stream
.next_out 
= compr
; 
 176     while (c_stream
.total_in 
!= (uLong
)len 
&& c_stream
.total_out 
< comprLen
) { 
 177         c_stream
.avail_in 
= c_stream
.avail_out 
= 1; /* force small buffers */ 
 178         err 
= deflate(&c_stream
, Z_NO_FLUSH
); 
 179         CHECK_ERR(err
, "deflate"); 
 181     /* Finish the stream, still forcing small buffers: */ 
 183         c_stream
.avail_out 
= 1; 
 184         err 
= deflate(&c_stream
, Z_FINISH
); 
 185         if (err 
== Z_STREAM_END
) break; 
 186         CHECK_ERR(err
, "deflate"); 
 189     err 
= deflateEnd(&c_stream
); 
 190     CHECK_ERR(err
, "deflateEnd"); 
 193 /* =========================================================================== 
 194  * Test inflate() with small buffers 
 196 void test_inflate(compr
, comprLen
, uncompr
, uncomprLen
) 
 197     Byte 
*compr
, *uncompr
; 
 198     uLong comprLen
, uncomprLen
; 
 201     z_stream d_stream
; /* decompression stream */ 
 203     strcpy((char*)uncompr
, "garbage"); 
 205     d_stream
.zalloc 
= (alloc_func
)0; 
 206     d_stream
.zfree 
= (free_func
)0; 
 207     d_stream
.opaque 
= (voidpf
)0; 
 209     d_stream
.next_in  
= compr
; 
 210     d_stream
.avail_in 
= 0; 
 211     d_stream
.next_out 
= uncompr
; 
 213     err 
= inflateInit(&d_stream
); 
 214     CHECK_ERR(err
, "inflateInit"); 
 216     while (d_stream
.total_out 
< uncomprLen 
&& d_stream
.total_in 
< comprLen
) { 
 217         d_stream
.avail_in 
= d_stream
.avail_out 
= 1; /* force small buffers */ 
 218         err 
= inflate(&d_stream
, Z_NO_FLUSH
); 
 219         if (err 
== Z_STREAM_END
) break; 
 220         CHECK_ERR(err
, "inflate"); 
 223     err 
= inflateEnd(&d_stream
); 
 224     CHECK_ERR(err
, "inflateEnd"); 
 226     if (strcmp((char*)uncompr
, hello
)) { 
 227         fprintf(stderr
, "bad inflate\n"); 
 230         printf("inflate(): %s\n", (char *)uncompr
); 
 234 /* =========================================================================== 
 235  * Test deflate() with large buffers and dynamic change of compression level 
 237 void test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
) 
 238     Byte 
*compr
, *uncompr
; 
 239     uLong comprLen
, uncomprLen
; 
 241     z_stream c_stream
; /* compression stream */ 
 244     c_stream
.zalloc 
= (alloc_func
)0; 
 245     c_stream
.zfree 
= (free_func
)0; 
 246     c_stream
.opaque 
= (voidpf
)0; 
 248     err 
= deflateInit(&c_stream
, Z_BEST_SPEED
); 
 249     CHECK_ERR(err
, "deflateInit"); 
 251     c_stream
.next_out 
= compr
; 
 252     c_stream
.avail_out 
= (uInt
)comprLen
; 
 254     /* At this point, uncompr is still mostly zeroes, so it should compress 
 257     c_stream
.next_in 
= uncompr
; 
 258     c_stream
.avail_in 
= (uInt
)uncomprLen
; 
 259     err 
= deflate(&c_stream
, Z_NO_FLUSH
); 
 260     CHECK_ERR(err
, "deflate"); 
 261     if (c_stream
.avail_in 
!= 0) { 
 262         fprintf(stderr
, "deflate not greedy\n"); 
 266     /* Feed in already compressed data and switch to no compression: */ 
 267     deflateParams(&c_stream
, Z_NO_COMPRESSION
, Z_DEFAULT_STRATEGY
); 
 268     c_stream
.next_in 
= compr
; 
 269     c_stream
.avail_in 
= (uInt
)comprLen
/2; 
 270     err 
= deflate(&c_stream
, Z_NO_FLUSH
); 
 271     CHECK_ERR(err
, "deflate"); 
 273     /* Switch back to compressing mode: */ 
 274     deflateParams(&c_stream
, Z_BEST_COMPRESSION
, Z_FILTERED
); 
 275     c_stream
.next_in 
= uncompr
; 
 276     c_stream
.avail_in 
= (uInt
)uncomprLen
; 
 277     err 
= deflate(&c_stream
, Z_NO_FLUSH
); 
 278     CHECK_ERR(err
, "deflate"); 
 280     err 
= deflate(&c_stream
, Z_FINISH
); 
 281     if (err 
!= Z_STREAM_END
) { 
 282         fprintf(stderr
, "deflate should report Z_STREAM_END\n"); 
 285     err 
= deflateEnd(&c_stream
); 
 286     CHECK_ERR(err
, "deflateEnd"); 
 289 /* =========================================================================== 
 290  * Test inflate() with large buffers 
 292 void test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
) 
 293     Byte 
*compr
, *uncompr
; 
 294     uLong comprLen
, uncomprLen
; 
 297     z_stream d_stream
; /* decompression stream */ 
 299     strcpy((char*)uncompr
, "garbage"); 
 301     d_stream
.zalloc 
= (alloc_func
)0; 
 302     d_stream
.zfree 
= (free_func
)0; 
 303     d_stream
.opaque 
= (voidpf
)0; 
 305     d_stream
.next_in  
= compr
; 
 306     d_stream
.avail_in 
= (uInt
)comprLen
; 
 308     err 
= inflateInit(&d_stream
); 
 309     CHECK_ERR(err
, "inflateInit"); 
 312         d_stream
.next_out 
= uncompr
;            /* discard the output */ 
 313         d_stream
.avail_out 
= (uInt
)uncomprLen
; 
 314         err 
= inflate(&d_stream
, Z_NO_FLUSH
); 
 315         if (err 
== Z_STREAM_END
) break; 
 316         CHECK_ERR(err
, "large inflate"); 
 319     err 
= inflateEnd(&d_stream
); 
 320     CHECK_ERR(err
, "inflateEnd"); 
 322     if (d_stream
.total_out 
!= 2*uncomprLen 
+ comprLen
/2) { 
 323         fprintf(stderr
, "bad large inflate: %ld\n", d_stream
.total_out
); 
 326         printf("large_inflate(): OK\n"); 
 330 /* =========================================================================== 
 331  * Test deflate() with full flush 
 333 void test_flush(compr
, comprLen
) 
 337     z_stream c_stream
; /* compression stream */ 
 339     int len 
= strlen(hello
)+1; 
 341     c_stream
.zalloc 
= (alloc_func
)0; 
 342     c_stream
.zfree 
= (free_func
)0; 
 343     c_stream
.opaque 
= (voidpf
)0; 
 345     err 
= deflateInit(&c_stream
, Z_DEFAULT_COMPRESSION
); 
 346     CHECK_ERR(err
, "deflateInit"); 
 348     c_stream
.next_in  
= (Bytef
*)hello
; 
 349     c_stream
.next_out 
= compr
; 
 350     c_stream
.avail_in 
= 3; 
 351     c_stream
.avail_out 
= (uInt
)*comprLen
; 
 352     err 
= deflate(&c_stream
, Z_FULL_FLUSH
); 
 353     CHECK_ERR(err
, "deflate"); 
 355     compr
[3]++; /* force an error in first compressed block */ 
 356     c_stream
.avail_in 
= len 
- 3; 
 358     err 
= deflate(&c_stream
, Z_FINISH
); 
 359     if (err 
!= Z_STREAM_END
) { 
 360         CHECK_ERR(err
, "deflate"); 
 362     err 
= deflateEnd(&c_stream
); 
 363     CHECK_ERR(err
, "deflateEnd"); 
 365     *comprLen 
= c_stream
.total_out
; 
 368 /* =========================================================================== 
 371 void test_sync(compr
, comprLen
, uncompr
, uncomprLen
) 
 372     Byte 
*compr
, *uncompr
; 
 373     uLong comprLen
, uncomprLen
; 
 376     z_stream d_stream
; /* decompression stream */ 
 378     strcpy((char*)uncompr
, "garbage"); 
 380     d_stream
.zalloc 
= (alloc_func
)0; 
 381     d_stream
.zfree 
= (free_func
)0; 
 382     d_stream
.opaque 
= (voidpf
)0; 
 384     d_stream
.next_in  
= compr
; 
 385     d_stream
.avail_in 
= 2; /* just read the zlib header */ 
 387     err 
= inflateInit(&d_stream
); 
 388     CHECK_ERR(err
, "inflateInit"); 
 390     d_stream
.next_out 
= uncompr
; 
 391     d_stream
.avail_out 
= (uInt
)uncomprLen
; 
 393     inflate(&d_stream
, Z_NO_FLUSH
); 
 394     CHECK_ERR(err
, "inflate"); 
 396     d_stream
.avail_in 
= (uInt
)comprLen
-2;   /* read all compressed data */ 
 397     err 
= inflateSync(&d_stream
);           /* but skip the damaged part */ 
 398     CHECK_ERR(err
, "inflateSync"); 
 400     err 
= inflate(&d_stream
, Z_FINISH
); 
 401     if (err 
!= Z_DATA_ERROR
) { 
 402         fprintf(stderr
, "inflate should report DATA_ERROR\n"); 
 403         /* Because of incorrect adler32 */ 
 406     err 
= inflateEnd(&d_stream
); 
 407     CHECK_ERR(err
, "inflateEnd"); 
 409     printf("after inflateSync(): hel%s\n", (char *)uncompr
); 
 412 /* =========================================================================== 
 413  * Test deflate() with preset dictionary 
 415 void test_dict_deflate(compr
, comprLen
) 
 419     z_stream c_stream
; /* compression stream */ 
 422     c_stream
.zalloc 
= (alloc_func
)0; 
 423     c_stream
.zfree 
= (free_func
)0; 
 424     c_stream
.opaque 
= (voidpf
)0; 
 426     err 
= deflateInit(&c_stream
, Z_BEST_COMPRESSION
); 
 427     CHECK_ERR(err
, "deflateInit"); 
 429     err 
= deflateSetDictionary(&c_stream
, 
 430                                (const Bytef
*)dictionary
, sizeof(dictionary
)); 
 431     CHECK_ERR(err
, "deflateSetDictionary"); 
 433     dictId 
= c_stream
.adler
; 
 434     c_stream
.next_out 
= compr
; 
 435     c_stream
.avail_out 
= (uInt
)comprLen
; 
 437     c_stream
.next_in 
= (Bytef
*)hello
; 
 438     c_stream
.avail_in 
= (uInt
)strlen(hello
)+1; 
 440     err 
= deflate(&c_stream
, Z_FINISH
); 
 441     if (err 
!= Z_STREAM_END
) { 
 442         fprintf(stderr
, "deflate should report Z_STREAM_END\n"); 
 445     err 
= deflateEnd(&c_stream
); 
 446     CHECK_ERR(err
, "deflateEnd"); 
 449 /* =========================================================================== 
 450  * Test inflate() with a preset dictionary 
 452 void test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
) 
 453     Byte 
*compr
, *uncompr
; 
 454     uLong comprLen
, uncomprLen
; 
 457     z_stream d_stream
; /* decompression stream */ 
 459     strcpy((char*)uncompr
, "garbage"); 
 461     d_stream
.zalloc 
= (alloc_func
)0; 
 462     d_stream
.zfree 
= (free_func
)0; 
 463     d_stream
.opaque 
= (voidpf
)0; 
 465     d_stream
.next_in  
= compr
; 
 466     d_stream
.avail_in 
= (uInt
)comprLen
; 
 468     err 
= inflateInit(&d_stream
); 
 469     CHECK_ERR(err
, "inflateInit"); 
 471     d_stream
.next_out 
= uncompr
; 
 472     d_stream
.avail_out 
= (uInt
)uncomprLen
; 
 475         err 
= inflate(&d_stream
, Z_NO_FLUSH
); 
 476         if (err 
== Z_STREAM_END
) break; 
 477         if (err 
== Z_NEED_DICT
) { 
 478             if (d_stream
.adler 
!= dictId
) { 
 479                 fprintf(stderr
, "unexpected dictionary"); 
 482             err 
= inflateSetDictionary(&d_stream
, (const Bytef
*)dictionary
, 
 485         CHECK_ERR(err
, "inflate with dict"); 
 488     err 
= inflateEnd(&d_stream
); 
 489     CHECK_ERR(err
, "inflateEnd"); 
 491     if (strcmp((char*)uncompr
, hello
)) { 
 492         fprintf(stderr
, "bad inflate with dict\n"); 
 495         printf("inflate with dictionary: %s\n", (char *)uncompr
); 
 499 /* =========================================================================== 
 500  * Usage:  example [output.gz  [input.gz]] 
 507     Byte 
*compr
, *uncompr
; 
 508     uLong comprLen 
= 10000*sizeof(int); /* don't overflow on MSDOS */ 
 509     uLong uncomprLen 
= comprLen
; 
 510     static const char* myVersion 
= ZLIB_VERSION
; 
 512     if (zlibVersion()[0] != myVersion
[0]) { 
 513         fprintf(stderr
, "incompatible zlib version\n"); 
 516     } else if (strcmp(zlibVersion(), ZLIB_VERSION
) != 0) { 
 517         fprintf(stderr
, "warning: different zlib version\n"); 
 520     compr    
= (Byte
*)calloc((uInt
)comprLen
, 1); 
 521     uncompr  
= (Byte
*)calloc((uInt
)uncomprLen
, 1); 
 522     /* compr and uncompr are cleared to avoid reading uninitialized 
 523      * data and to ensure that uncompr compresses well. 
 525     if (compr 
== Z_NULL 
|| uncompr 
== Z_NULL
) { 
 526         printf("out of memory\n"); 
 529     test_compress(compr
, comprLen
, uncompr
, uncomprLen
); 
 531     test_gzio((argc 
> 1 ? argv
[1] : "foo.gz"), 
 532               (argc 
> 2 ? argv
[2] : "foo.gz"), 
 533               uncompr
, (int)uncomprLen
); 
 535     test_deflate(compr
, comprLen
); 
 536     test_inflate(compr
, comprLen
, uncompr
, uncomprLen
); 
 538     test_large_deflate(compr
, comprLen
, uncompr
, uncomprLen
); 
 539     test_large_inflate(compr
, comprLen
, uncompr
, uncomprLen
); 
 541     test_flush(compr
, &comprLen
); 
 542     test_sync(compr
, comprLen
, uncompr
, uncomprLen
); 
 543     comprLen 
= uncomprLen
; 
 545     test_dict_deflate(compr
, comprLen
); 
 546     test_dict_inflate(compr
, comprLen
, uncompr
, uncomprLen
); 
 549     return 0; /* to avoid warning */