deflate and inflate (zlib.h) in C

只愿长相守 提交于 2019-12-03 19:07:05

问题


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%lu\n%s\n", 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%lu\n%s\n", strlen(c), c);

回答1:


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: %lu\n", (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%lu\n%s\n", strlen(c), c);



回答2:


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 =/




回答3:


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



来源:https://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!