home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / zlib / example.c < prev    next >
C/C++ Source or Header  |  2002-04-25  |  16KB  |  557 lines

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