Using zlib to create a gzip file using zpipe.c exa

2019-04-11 06:16发布

问题:

All,

I am just trying to get the zpipe demo working using dev-c++ where I have all the zlib code imported and using the zpipe.c as an example. Everything compiles and runs. If I try to create a gzip file using the commented out call to deflateInit2 it creates with now errors, but is corrupted when unzipping with 7zip. If I use the standard zlib headers to create the file, when I use the corresponding call to inflate it give me a return of -3/Z_DATA_ERROR indicating my defalte data is corrupted. Everything points to something being wrong in the def unction, but its pretty much exactly the example.

Any ideas?? Thanks so much in advance!

int main(int argc, char **argv)
{
     int ret;
     FILE *source;
     FILE *zip;
     FILE *zipped;
     FILE *back;

     source = fopen ("C:\\Users\\schmoudm\\Pictures\\caela.jpg", "r");
     zip = fopen ("C:\\Core\\RD\\test.gz", "w");

     printf ("calling def \n");
     ret = def(source, zip, Z_DEFAULT_COMPRESSION);
     printf("def return: %i \n", ret);
     fclose(source);
     fclose(zip);

     if (ret == 0) {
        printf ("setting up inf \n");
        zipped = fopen ("C:\\Core\\RD\\test.gz", "r"); 
        back = fopen ("C:\\Core\\RD\\zlibout.txt", "w"); 
        printf ("calling inf \n");
        ret = inf(zipped, back); 
        printf("inf return: %i \n", ret);  
        zerr(ret);
     }

    fclose(source);
    fclose(zip);

    printf("DONE!");
    system("PAUSE");
    return 0;
}

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

    /* allocate deflate state */
    strm.zalloc = Z_NULL;
    strm.zfree = Z_NULL;
    strm.opaque = Z_NULL;

    ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
    //ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8,       Z_DEFAULT_STRATEGY);
    if (ret != Z_OK)
        return ret;

    /* compress until end of file */
    do {
        strm.avail_in = fread(in, 1, CHUNK, source);
        printf("available in: %u \n", strm.avail_in);  
        if (ferror(source)) {
            (void)deflateEnd(&strm);
            return Z_ERRNO;
        }
        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
        strm.next_in = in;

        /* run deflate() on input until output buffer not full, finish
           compression if all of source has been read in */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = deflate(&strm, flush);    /* no bad return value */
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            have = CHUNK - strm.avail_out;
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                (void)deflateEnd(&strm);
                return Z_ERRNO;
            }
        } while (strm.avail_out == 0);
        assert(strm.avail_in == 0);     /* all input will be used */

        /* done when last data in file processed */
    } while (flush != Z_FINISH);
    assert(ret == Z_STREAM_END);        /* stream will be complete */

    /* clean up and return */
    (void)deflateEnd(&strm);
    return Z_OK;
}

回答1:

but its pretty much exactly the example.

Alas, you left out a critical portion from zpipe.c.

#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
#  include <fcntl.h>
#  include <io.h>
#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
#  define SET_BINARY_MODE(file)
#endif

and

/* avoid end-of-line conversions */
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);

So in your code you need to do SET_BINARY_MODE(source) and SET_BINARY_MODE(zip).

Or you need to use the "b" option in both fopen()'s.



标签: c gzip zlib