deflate and inflate (zlib.h) in C

后端 未结 3 611
南方客
南方客 2020-12-28 09:53

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

相关标签:
3条回答
  • 2020-12-28 10:49

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

    0 讨论(0)
  • 2020-12-28 10:52

    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);
    
    0 讨论(0)
  • 2020-12-28 10:54

    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

    0 讨论(0)
提交回复
热议问题