Inflate (decompress) PNG file using ZLIB library C++ -


i'm trying use zlib inflate (decompress) .fla files, extracting contents. since fla files use zip format, able read local file headers(https://en.wikipedia.org/wiki/zip_(file_format)) it, , use info inside decompress files.

it seems work fine regular text-based files, when comes binary (i've tried png , dat files), fails decompress them, returning "z_data_error".

i'm unable use minilib library inside zlib, since central directory file header inside fla files differs normal zip files (which why im reading local files header manually).

here's code use decompress chunk of data:

void decompressbuffer(char* compressedbuffer, unsigned int compressedsize, std::string& out_decompressedbuffer) {     // init decompression stream     z_stream 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);         return;     }      // set starting point , total data size read     stream.avail_in = compressedsize;     stream.next_in  = (bytef*)&compressedbuffer[0];      std::stringstream strstream;      // 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)          {             // store data have left in stream             size_t length = max_read_buffer_size - stream.avail_out;             std::string str((char*)readbuffer);             str = str.substr(0, length);             strstream << str;             break;         }         else         {                    if (ret != z_ok)             {                 printf("error: inflate %d\n", ret); // reaches when trying inflate png or dat file                 break;             }              // store readbuffer in stream             strstream << readbuffer;         }          free(readbuffer);     }      out_decompressedbuffer = strstream.str();      inflateend(&stream); } 

i have tried zipping single png file , extracing that. doesn't return errors inflate(), doesn't correctly inflate png either, , corresponding values seem first few.

the original file (left) , uncompressed via code file (right):

hex editor versions of both pngs

you things rely on data being text , strings, not binary data.

for example

std::string str((char*)readbuffer); 

if contents of readbuffer raw binary data might contain 1 or more 0 bytes in middle of it. when use c-style string first 0 act string terminator character.

i suggest try generalize it, , remove dependency of strings. instead suggest use e.g. std::vector<int8_t>.

meanwhile, during transition more generalized way, can e.g.

std::string str(readbuffer, length); 

this create string of specified length, , contents not checked terminators.


Comments

Popular posts from this blog

asynchronous - C# WinSCP .NET assembly: How to upload multiple files asynchronously -

aws api gateway - SerializationException in posting new Records via Dynamodb Proxy Service in API -

asp.net - Problems sending emails from forum -