I have the following C++ code which uses zlib to compress a memory buffer into a gzip encoded stream:
void compress(const std::vector<char>& src)
{
static constexpr int DEFAULT_WINDOW_BITS = 15;
static constexpr int GZIP_WINDOW_BITS = DEFAULT_WINDOW_BITS + 16;
static constexpr int GZIP_MEM_LEVEL = 8;
z_stream stream;
const auto srcData = reinterpret_cast<unsigned char*>(const_cast<char*>(src.data()));
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.next_in = srcData;
stream.avail_in = src.size();
auto result = deflateInit2(&stream,
Z_DEFAULT_COMPRESSION,
Z_DEFLATED,
GZIP_WINDOW_BITS,
GZIP_MEM_LEVEL,
Z_DEFAULT_STRATEGY);
if (result == Z_OK)
{
std::vector<char> dest(deflateBound(&stream, stream.avail_in));
const auto destData = reinterpret_cast<unsigned char*>(dest.data());
stream.next_out = destData;
stream.avail_out = dest.size();
result = deflate(&stream, Z_FINISH);
if (result == Z_STREAM_END)
{
std::cout << "Original: " << src.size() << "; compressed: " << dest.size() << std::endl;
}
else
{
std::cerr << "Error when compressing: code " << std::to_string(result);
}
result = deflateEnd(&stream);
if (result != Z_OK)
{
std::cerr << "Error: Cannot destroy deflate stream: code " << std::to_string(result) << std::endl;
}
}
else
{
std::cerr << "Error: Cannot initialize deflate stream: code " << std::to_string(result) << std::endl;
}
}
While the function finishes successfully, I'm getting no compression at all. In fact, for a 3MB file consisting of just the character 'a' repeated multiple times, I get the following:
Original: 3205841; compressed: 3206843
Am I doing something wrong?
(Notice that this is a simplified version of the original code; in practice, I'd be using RAII and exceptions for resource and error handling).
dest.size()instead ofstream.total_out? - Eljay