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