Decompress with gz* functions succeeded but failed with inflate* functions using zlib

☆樱花仙子☆ 提交于 2019-12-12 05:18:15

问题


I have a gzip file sample, with standard gzip header 1F 8B 08 00 ..., when I inflate it with inflate* functions in zlib, the output is only 11 bytes(in fact the output should be about 4KB), but when I decompress it with gz* functions, it produce the correct output, the code:

  1. using gz* (this can produce correct output):

    #define CHUNK 10240
    int gz_decompress(const char *path) {
        gzFile f = gzopen(path, "rb");
        if(!f)
            return -1;
    
        unsigned char result[CHUNK];
        int bytes_read = gzread(f, result, CHUNK);
        if(bytes_read < CHUNK)
            if(!gzeof(f))
                return -2;
        gzclose (f);
        return 0;
    }
    
  2. using inflate* (output is only 11 bytes):

    #define CHUNK 10240
    int inf(FILE *source)
    {
        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 = inflateInit(&strm);
        ret = inflateInit2(&strm, 16 + 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 (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);
                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);
                    return ret;
                }
                have = CHUNK - strm.avail_out;
            } while (strm.avail_out == 0);
    
            /* done when inflate() says it's done */
        } while (ret != Z_STREAM_END);
    
        /* clean up and return */
        (void)inflateEnd(&strm);
        return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
    }
    

In fact, the second snippet comes from the official zlib usage example zpipe.c, I changed only the invocation of inflateInit(&strm); to inflateInit2(&strm, 16 + 15); according to this zlib gzip discussion, but now I have no idea why it fails, anyone could help?


回答1:


Per your comment, inf() is returning Z_OK, which means that the gzip stream is being successfully decompressed and verified.

What do you mean "output is only 11 bytes"? Your inf() function can produce no output at all.



来源:https://stackoverflow.com/questions/17872152/decompress-with-gz-functions-succeeded-but-failed-with-inflate-functions-using

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!