Ke.
Ke.

Reputation: 2586

zlib c++ char size of buffer for compression

I'm using this function for zlib compression and wondering whether the outbuffer variable should be set to a specific size? Is it limiting the char array to whatever I put in here? Is there a limit to the length I can put in here? Would it make sense to just convert it to std::string, since Im compiling in c++?

 /** Compress a STL string using zlib with given compression level and return
     * the binary data. */
    std::string compress_string(const std::string& str, int compressionlevel = 9)
    {
        z_stream zs;                        // z_stream is zlib's control structure
        memset(&zs, 0, sizeof(zs));

        if (deflateInit(&zs, compressionlevel) != Z_OK)
            throw(std::runtime_error("deflateInit failed while compressing."));

        // For the compress
        deflateInit2(&zs, compressionlevel, Z_DEFLATED,MOD_GZIP_ZLIB_WINDOWSIZE + 16,MOD_GZIP_ZLIB_CFACTOR,Z_DEFAULT_STRATEGY) != Z_OK;

        zs.next_in = (Bytef*)str.data();
        zs.avail_in = str.size();           // set the z_stream's input

        int ret;
        char outbuffer[3222768];
        std::string outstring;

        // retrieve the compressed bytes blockwise
        do {
            zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
            zs.avail_out = sizeof(outbuffer);

            ret = deflate(&zs, Z_FINISH);

            if (outstring.size() < zs.total_out) {
                // append the block to the output string
                outstring.append(outbuffer,zs.total_out - outstring.size());
            }
        }
        while (ret == Z_OK);

        deflateEnd(&zs);

        if (ret != Z_STREAM_END) {          // an error occurred that was not EOF
            std::ostringstream oss;
            oss << "Exception during zlib compression: (" << ret << ") " << zs.msg;
            throw(std::runtime_error(oss.str()));
        }

        return outstring;
    }

Upvotes: 0

Views: 1621

Answers (1)

Mark Adler
Mark Adler

Reputation: 112374

That is what deflateBound() is for. After your deflateInit2(), you can call it with the input size and it will give you a bound on the possible expansion when compressing incompressible data.

By the way, calling deflateInit/deflateInit2 twice on the same structure will result in a large memory leak. Just call one of them once.

You should read the zlib documentation in its entirety.

Upvotes: 1

Related Questions