I'm trying to use ZLIB to inflate (decompress) .FLA files, thus extracting all its contents. Since FLA files use a ZIP format, I am able to read the local file headers(https://en.wikipedia.org/wiki/Zip_(file_format)) from it, and use the info inside to decompress the files.
It seems to work fine for regular text-based files, but when it comes to binary (I've only tried PNG and DAT files), it fails to decompress them, returning "Z_DATA_ERROR".
I'm unable to use the minilib library inside ZLIB, since the Central directory file header inside FLA files differs slightly from normal zip files (which is why im reading the local files header manually).
Here's the code I use to decompress a chunk of data:
void DecompressBuffer(char* compressedBuffer, unsigned int compressedSize, std::string& out_decompressedBuffer)
// init the decompression stream
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = 0;
stream.next_in = Z_NULL;
if (int err = inflateInit2(&stream, -MAX_WBITS) != Z_OK)
printf("Error: inflateInit %d\n", err);
// Set the starting point and total data size to be read
stream.avail_in = compressedSize;
stream.next_in = (Bytef*)&compressedBuffer;
// Start decompressing
while (stream.avail_in != 0)
unsigned char* readBuffer = (unsigned char*)malloc(MAX_READ_BUFFER_SIZE + 1);
readBuffer[MAX_READ_BUFFER_SIZE] = '\0';
stream.next_out = readBuffer;
stream.avail_out = MAX_READ_BUFFER_SIZE;
int ret = inflate(&stream, Z_NO_FLUSH);
if (ret == Z_STREAM_END)
// only store the data we have left in the stream
size_t length = MAX_READ_BUFFER_SIZE - stream.avail_out;
str = str.substr(0, length);
strStream << str;
if (ret != Z_OK)
printf("Error: inflate %d\n", ret); // This is what it reaches when trying to inflate a PNG or DAT file
// store the readbuffer in the stream
strStream << readBuffer;
out_decompressedBuffer = strStream.str();
You do things that rely on the data being text and strings, not binary data.
If the contents of
readBuffer is raw binary data then it might contain one or more zero bytes in the middle of it. When you use it as a C-style string then the first zero will act as the string terminator character.
I suggest you try to generalize it, and remove the dependency of strings. Instead I suggest you use e.g.
Meanwhile, during your transition to a more generalized way, you can do e.g.
std::string str(readBuffer, length);
This will create a string of the specified length, and the contents will not be checked for terminators.