Deflate and inflate (zlib.h) in C

I am trying to implement 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 have something wrong identified?

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); 
+6
source share
3 answers

You cannot print deflated output as follows. It is not canceled. You also cannot stretch it.

Since your input is a string, although you probably only want to pass the contents of the string, including the null terminator. Therefore set avail_in to strlen (a) + 1.

You need to examine the next_out and avail_out fields after calling deflate to find out how much data has been written to the output buffer.

See the documentation here under the deflot call.

Here is your modified code. Note that if you are compressing something that is not a string, you will need to change this, as well as with strings that you can compress without a zero ending and add it after unpacking.

 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); 
+6
source

zlib already has a simple inflation / deflation function that 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); 

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

+21
source

The zpipe example (http://zlib.net/zpipe.c) covers it pretty much, just delete the ops file (prefix function f) and you will replace the in and out memory buffers, although this may be enough to replace in or save buffers as is depending on your use. Just keep in mind that you will need to resize your account buffer to decompress arbitrary size data if you plan to have unknown dimensional chunks

+2
source

Source: https://habr.com/ru/post/897975/


All Articles