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