deflate and inflate (zlib.h) in C

Posted on

deflate and inflate (zlib.h) in C

I am trying to implement the zlib.h deflate and inflate functions to compress and decompress a char array (not a file).

I would like to know if the following syntax is correct ? Am I missing something or defined something incorrectly ?

char a[50] = "Hello World!";
char b[50];
char c[50];

// deflate
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)sizeof(a); // size of input
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

deflateInit(&defstream, Z_DEFAULT_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);

printf("Deflate:n%lun%sn", strlen(b), b);

// inflate
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = (uInt)sizeof(b); // size of input
infstream.next_in = (Bytef *)b; // input char array
infstream.avail_out = (uInt)sizeof(c); // size of output
infstream.next_out = (Bytef *)c; // output char array

inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);

printf("Inflate:n%lun%sn", strlen(c), c);

zlib already has a simple inflate/deflate function you can use.

char a[50] = "Hello, world!";
char b[50];
char c[50];

uLong ucompSize = strlen(a)+1; // "Hello, world!" + NULL delimiter.
uLong compSize = compressBound(ucompSize);

// Deflate
compress((Bytef *)b, &compSize, (Bytef *)a, ucompSize);

// Inflate
uncompress((Bytef *)c, &ucompSize, (Bytef *)b, compSize);

When in doubt, check out the zlib manual.
My code is crappy, sorry =/

You can’t printf the deflated output like this. It’s not null terminated. You can’t strlen it either.

Since your input is a string though you probably do want to only pass the content of the string including the null terminator. So set avail_in to strlen(a) + 1.

You need to examine the next_out and avail_out fields after you call deflate to see how much data was written to the output buffer.

See documentation here under the deflate call.

Here’s your modified code. Note if you’re compressing something that is not a string you’ll need to change this and also with strings you may compress without the terminating zero and add it back after decompressing.

char a[50] = "Hello World!";
char b[50];
char c[50];

// deflate
// zlib struct
z_stream defstream;
defstream.zalloc = Z_NULL;
defstream.zfree = Z_NULL;
defstream.opaque = Z_NULL;
defstream.avail_in = (uInt)strlen(a)+1; // size of input, string + terminator
defstream.next_in = (Bytef *)a; // input char array
defstream.avail_out = (uInt)sizeof(b); // size of output
defstream.next_out = (Bytef *)b; // output char array

deflateInit(&defstream, Z_DEFAULT_COMPRESSION);
deflate(&defstream, Z_FINISH);
deflateEnd(&defstream);

// This is one way of getting the size of the output
printf("Deflated size is: %lun", (char*)defstream.next_out - b);

// inflate
// zlib struct
z_stream infstream;
infstream.zalloc = Z_NULL;
infstream.zfree = Z_NULL;
infstream.opaque = Z_NULL;
infstream.avail_in = (uInt)((char*)defstream.next_out - b); // size of input
infstream.next_in = (Bytef *)b; // input char array
infstream.avail_out = (uInt)sizeof(c); // size of output
infstream.next_out = (Bytef *)c; // output char array

inflateInit(&infstream);
inflate(&infstream, Z_NO_FLUSH);
inflateEnd(&infstream);

printf("Inflate:n%lun%sn", strlen(c), c);

The zpipe example (http://zlib.net/zpipe.c) pretty much covers it, just remove the file ops(the f prefixed function), and you replace in and out with your in-memory buffers, though it may be enough to only replace in or keep the buffers as-is depending on you usage. Just note that you will need to make your out buffer resizeable to account for decompression of arbitrarily sized data, if you are planning on having unknown sized chunks

Leave a Reply

Your email address will not be published. Required fields are marked *