PageRenderTime 39ms CodeModel.GetById 2ms app.highlight 32ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/ZLib/example.c

https://bitbucket.org/cabalistic/ogredeps/
C | 565 lines | 416 code | 98 blank | 51 comment | 75 complexity | f78aede7da3d66b0f8dfae491fec0565 MD5 | raw file
  1/* example.c -- usage example of the zlib compression library
  2 * Copyright (C) 1995-2006 Jean-loup Gailly.
  3 * For conditions of distribution and use, see copyright notice in zlib.h
  4 */
  5
  6/* @(#) $Id: example.c,v 1.5 2010/04/21 20:36:23 drolon Exp $ */
  7
  8#include "zlib.h"
  9#include <stdio.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
 29const char hello[] = "hello, hello!";
 30/* "hello world" would be more standard, but the repeated "hello"
 31 * stresses the compression code better, sorry...
 32 */
 33
 34const char dictionary[] = "hello";
 35uLong dictId; /* Adler32 value of the dictionary */
 36
 37void test_compress      OF((Byte *compr, uLong comprLen,
 38                            Byte *uncompr, uLong uncomprLen));
 39void test_gzio          OF((const char *fname,
 40                            Byte *uncompr, uLong uncomprLen));
 41void test_deflate       OF((Byte *compr, uLong comprLen));
 42void test_inflate       OF((Byte *compr, uLong comprLen,
 43                            Byte *uncompr, uLong uncomprLen));
 44void test_large_deflate OF((Byte *compr, uLong comprLen,
 45                            Byte *uncompr, uLong uncomprLen));
 46void test_large_inflate OF((Byte *compr, uLong comprLen,
 47                            Byte *uncompr, uLong uncomprLen));
 48void test_flush         OF((Byte *compr, uLong *comprLen));
 49void test_sync          OF((Byte *compr, uLong comprLen,
 50                            Byte *uncompr, uLong uncomprLen));
 51void test_dict_deflate  OF((Byte *compr, uLong comprLen));
 52void test_dict_inflate  OF((Byte *compr, uLong comprLen,
 53                            Byte *uncompr, uLong uncomprLen));
 54int  main               OF((int argc, char *argv[]));
 55
 56/* ===========================================================================
 57 * Test compress() and uncompress()
 58 */
 59void test_compress(compr, comprLen, uncompr, uncomprLen)
 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 */
 85void test_gzio(fname, uncompr, uncomprLen)
 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 */
169void test_deflate(compr, comprLen)
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 */
207void test_inflate(compr, comprLen, uncompr, uncomprLen)
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 */
248void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
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 */
303void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
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 */
344void test_flush(compr, comprLen)
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 */
382void test_sync(compr, comprLen, uncompr, uncomprLen)
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 */
426void test_dict_deflate(compr, comprLen)
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 */
463void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
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
514int main(argc, argv)
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}