Can I read a zlib compressed file in memory without actually extracting it to disk? It would be nice if you could provide a snippet.
-
10have you tried anything yourself yet? just a tip: "please provide the code" is a bad way to ask for help. nobody wants to do your work for you for free, but people do want to help you solve a problem you can't figure out yourself. word your question that way to get better results. – Mike Atlas Feb 04 '11 at 19:00
-
5You'll receive more help if you make an attempt and then show us where you're getting stuck. If you are stuck on where to begin, you could indicate that in your question with some ideas that you are considering. – Tim Post Feb 04 '11 at 19:00
-
7It would be nice to be paid for doing the job instead of you ;) – Felice Pollano Feb 04 '11 at 19:03
-
http://www.zlib.net/zlib_how.html – Yippie-Ki-Yay Feb 04 '11 at 18:59
2 Answers
Here's a zLib inflate routine that takes a buffer in memory and decompresses into the provided output buffer. This is a 'one-shot' function, in that it attempts to inflate the entire input buffer all at once, and assumes you've given it enough space to fit it all. It is also possible to write a multi-shot function that dynamically grows the destination buffer as needed.
int inflate(const void *src, int srcLen, void *dst, int dstLen) {
z_stream strm = {0};
strm.total_in = strm.avail_in = srcLen;
strm.total_out = strm.avail_out = dstLen;
strm.next_in = (Bytef *) src;
strm.next_out = (Bytef *) dst;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int err = -1;
int ret = -1;
err = inflateInit2(&strm, (15 + 32)); //15 window bits, and the +32 tells zlib to to detect if using gzip or zlib
if (err == Z_OK) {
err = inflate(&strm, Z_FINISH);
if (err == Z_STREAM_END) {
ret = strm.total_out;
}
else {
inflateEnd(&strm);
return err;
}
}
else {
inflateEnd(&strm);
return err;
}
inflateEnd(&strm);
return ret;
}
Explanation:
src: the source buffer containing the compressed (gzip or zlib) data
srcLen: the length of the source buffer
dst: the destination buffer, into which the output will be written
dstLen: the length of the destination buffer
Return values:
Z_BUF_ERROR: if dstLen is not large enough to fit the inflated data
Z_MEM_ERROR: if there's insufficient memory to perform the decompression
Z_DATA_ERROR: if the input data was corrupt
Otherwise, the return value is the number of bytes written to dst.

- 4,143
- 2
- 18
- 9
-
4zlib api provide uncompress((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen) function for 'one-shot' inflate. – velkyel Jul 09 '15 at 17:05
-
Hi, Perhaps you can elaborate some more about how to convert this function to multi-shot based, and dynamically allocate the memory for the decompressed function. a code example would be best :-) thanks – Jan 22 '19 at 11:34
Solution provided by Raj Advani does not work for multistream zlib buffer. Solution for gzip data:
void decompress(Bytef *src, int src_len, Bytef *dst, int dst_len)
{
z_stream strm = {0};
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
while (src_len > 0)
{
strm.total_in = strm.avail_in = src_len;
strm.total_out = strm.avail_out = dst_len;
strm.next_in = src;
strm.next_out = (Bytef *) dst;
assert(inflateInit2(&strm, (MAX_WBITS + 16)) == Z_OK);
decompress_block(&strm, dst);
unsigned int processed = src_len - strm.avail_in;
src_len -= processed;
src += processed;
}
}
int decompress_block(z_stream *strm, void *dst)
{
int ret;
do
{
ret = inflate(strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR && ret != Z_NEED_DICT && ret != Z_MEM_ERROR && ret != Z_DATA_ERROR);
assert(strm->avail_out > 0);
}
while (ret != Z_STREAM_END);
inflateEnd(strm);
assert(write(1, dst, strm->total_out) == strm->total_out);
return 0;
}

- 1,047
- 8
- 21