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