Re: zlib.h



Mark Adler <madler@xxxxxxxxxxxxxxxxxx> writes:

[...]

Thanks a lot for your advices, it was very useful.
Well in my case by design we know that we can do everything in one pass.
I was thinking that it could be useful to have also an example like
on zlib.net or in the examples code.

In fact is not hard at all but zlib was not thought to be used I guess
and in the beginning it might be confusing.

I also hate code duplication so (trying to follow your advices) I ended
up with something as below.

Do I still need the (deflate|inflate)Init right?

And another thing, to implement the adaptive compression, I had also a
nasty idea.
Check inside this module if the resulting data is really smaller and if
it's not just return the original data.

But then in decompression phase I should:
- try to decompress
- if I get an error that it was not compressed

It's quite dirty and I probably won't use that, but could that work?

I think it would not work ONLY if I am so unlucky to have in my data the
same header that zlib would expect, which is I guess quite unlikely to
happen.
Or is there something else?

--8<---------------cut here---------------start------------->8---
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "../shared/structs.h"
#include "zlib.h"

#include "util.h"

#define LEVEL Z_BEST_COMPRESSION
#define COMPRESS 0
#define DECOMPRESS 1

static z_stream strm;

/**
* Initialize the stream to default values
* Used in same way by compression and decompression
*
* @param strm zstream to initialize
*/
void _reset_zstream(z_stream *strm) {
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
}

/**
* Setup the stream for compression and decompression
*
* @param strm
* @param data
* @param result
*/
void _setup_zstream(z_stream *strm, const payload_t *data, payload_t *result) {
// setup the correct values in the stream
_reset_zstream(strm);
strm->avail_in = data->len;
strm->avail_out = result->len;
strm->next_in = (unsigned char *) data->stream;
strm->next_out = (unsigned char *) result->stream;
}

void print_gained(streamlen_t before, streamlen_t after) {
LOG_INFO("Compressed data is %.5f%% of original size.", ((float) after / before) * 100);
}

int _zlib_manage(int mode, const payload_t data, payload_t *result) {
int ret;
_setup_zstream(&strm, &data, result);
switch (mode) {
case COMPRESS:
deflateInit(&strm, LEVEL);
ret = deflate(&strm, Z_FINISH);
break;
case DECOMPRESS:
inflateInit(&strm);
ret = inflate(&strm, Z_FINISH);
break;
}
assert(ret == Z_STREAM_END);
result->len = (result->len - strm.avail_out);
return Z_OK;
}

int payload_compress(const payload_t data, payload_t *result) {
return _zlib_manage(COMPRESS, data, result);
}

int payload_decompress(const payload_t data, payload_t *result) {
return _zlib_manage(DECOMPRESS, data, result);
}
--8<---------------cut here---------------end--------------->8---
.