Main Page | Report this Page
 
   
Science Forum Index  »  Compression Forum  »  zlib with gzip file
Page 1 of 1    
Author Message
Guest
Posted: Tue Apr 15, 2008 11:37 am
Hi all,

I am trying to decompress gzip files using zlib. I know that the
format of headers required by zlib and gzip is different, and to fix
it inflateInit2 must be called. I call inflateInit2 with a negative
value to eat the headers, still I get no success. I picked the code
available at zlib.net and modified it a little that demonstrates my
problem. here is the code
-
#include <stdio.h>
#include <zlib.h>
#include <fcntl.h>
#define CHUNK 1024*16
#include <assert.h>


int inf(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];

/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -15);
if (ret != Z_OK)
return ret;

/* decompress until deflate stream ends or end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
printf("fread %d\n", ret);
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;

/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
// ret = inflate(&strm, Z_NO_FLUSH);
ret = inflate(&strm, Z_SYNC_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
printf("inflate %d\n", ret);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);

/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);

/* clean up and return */
(void)inflateEnd(&strm);
printf("%d\n", ret);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}

int main(int argc, char** argv)
{
FILE *fp1, *fp2;
if ( argc < 3 )
{
printf("wrong\n");
exit(1);
}

fp1 = fopen(argv[1], "r");
if (!fp1) {
fprintf(stdout, "open 1\n");
return 1;
}
fp2 = fopen(argv[2], "w");
if (!fp2) {
fprintf(stdout, "open 2\n");
return 1;
}
if (inf(fp1, fp2) == Z_OK) {
fprintf(stdout, "sucees\n");
} else {
fprintf(stdout, "failure\n");
}
return 0;
}

Anything wrong there? Is it the version of my libz (1.1.4) that's the
issue?

Thanks ..
Guest
Posted: Tue Apr 15, 2008 12:14 pm
On Apr 15, 2:37 pm, km_jr_use...@yahoo.com wrote:
Quote:
Hi all,

I am trying to decompress gzip files using zlib. I know that the
format of headers required by zlib and gzip is different, and to fix
it inflateInit2 must be called. I call inflateInit2 with a negative
value to eat the headers, still I get no success. I picked the code
available at zlib.net and modified it a little that demonstrates my
problem. here is the code

I read that older versions of zlib need some additional bytes in the
compressed stream. Here is the quote from gzio.c --
/* windowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy"
byte
* after the compressed stream in order to complete
decompression and
* return Z_STREAM_END. Here the gzip CRC32 ensures that 4
bytes are
* present after the compressed stream.
*/

Does that mean I insert an extra byte in the buffer containing the
compressed stream?

Thanks ..
Mark Adler
Posted: Tue Apr 15, 2008 12:23 pm
Guest
On Apr 15, 2:37 pm, km_jr_use...@yahoo.com wrote:
Quote:
    ret = inflateInit2(&strm, -15);

That does raw inflation, not gzip decoding. For background, a zlib
stream is header - deflate data - trailer, and a gzip stream is
different header - deflate data - different trailer. In either case,
you can use inflateInit2() with -15 for windowBits to inflate the
deflate data, but it's up to you to find the deflate data by decoding
the formats. (Documented in RFC 1950 for zlib, RFC 1952 for gzip.)

Or if you use +15 for windowBits or just use inflateInit(), then zlib
will decode the zlib header and trailer for you. But in that case, it
won't decode a gzip header and trailer.

Quote:
Anything wrong there? Is it the version of my libz (1.1.4) that's the issue?

Version 1.1.4 of zlib will do what I said above, and nothing else.
You can still decode gzip streams, but you'd have to roll your own
gzip header and trailer processing. It's not hard, but you have to
read and understand the RFC.

Version 1.2.x of zlib will do more. You can give inflateInit2() a
windowBits parameter of 31 or 47 to decode the gzip format or to
automatically detect and decode the zlib or gzip format, respectively.

Mark
Guest
Posted: Tue Apr 15, 2008 2:37 pm
On Apr 15, 3:23 pm, Mark Adler <mad...@alumni.caltech.edu> wrote:
Quote:
On Apr 15, 2:37 pm, km_jr_use...@yahoo.com wrote:
Anything wrong there? Is it the version of my libz (1.1.4) that's the issue?

Version 1.1.4 of zlib will do what I said above, and nothing else.
You can still decode gzip streams, but you'd have to roll your own
gzip header and trailer processing. It's not hard, but you have to
read and understand the RFC.

Thanks Mark. I know you maintain zlib and so could you tell me if I
could borrow the relevant code from the current zlib source code to
get the desired functionality? If yes, then could you point me to
which files I should look at.

Thanks again ..
Mark Adler
Posted: Tue Apr 15, 2008 2:44 pm
Guest
On Apr 15, 5:37 pm, km_jr_use...@yahoo.com wrote:
Quote:
Thanks Mark. I know you maintain zlib and so could you tell me if I
could borrow the relevant code from the current zlib source code to
get the desired functionality? If yes, then could you point me to
which files I should look at.

You can find the latest release at http://zlib.net/ . The file with
the gzip format decoding (and a lot of other stuff) is inflate.c. The
code within the #ifdef GUNZIP blocks has the actual code. It may not
be easy to lift from zlib, but at least you can see what it does. It
is relatively straightforward.

Mark
 
Page 1 of 1       All times are GMT - 5 Hours
The time now is Tue Oct 14, 2008 5:41 am