ZLIBを使用して.FLAファイルを膨張(圧縮解除)して、その内容をすべて抽出しようとしています。 FLAファイルはZIP形式を使用しているので、ローカルファイルヘッダ(https://en.wikipedia.org/wiki/Zip_(file_format))を読み込み、その内部の情報を使用してファイルを解凍することができます。ZLIBライブラリを使用したPNGファイルの膨張(C)
普通のテキストベースのファイルではうまくいくようですが、バイナリ(PNGとDATファイルを試しただけです)では、圧縮解除に失敗して "Z_DATA_ERROR"を返します。
FLAファイル内のセントラルディレクトリファイルのヘッダーが通常のzipファイルとわずかに異なるため、ZLIB内でミニライブラリライブラリを使用することができません。私は、単一のPNGファイルをビュンして、それを試してみましたextracing
void DecompressBuffer(char* compressedBuffer, unsigned int compressedSize, std::string& out_decompressedBuffer)
{
// init the 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 the starting point and total data size to be 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)
{
// only store the data we have left in the 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); // This is what it reaches when trying to inflate a PNG or DAT file
break;
}
// store the readbuffer in the stream
strStream << readBuffer;
}
free(readBuffer);
}
out_decompressedBuffer = strStream.str();
inflateEnd(&stream);
}
:
は、ここで私は、データのチャンクを解凍するために使用するコードです。これは、Inflate()からのエラーは返しませんが、PNGも正しく膨張させることはなく、対応する唯一の値が最初の数に見えます。
元のファイル(左)と(右)コードファイルを経由して圧縮されていない:
Hex editor versions of both PNGs
私はそれが理にかなっています。代わりにベクトルを使用するように変更し、PNGファイルを解凍できるようになりました。私はそれが.DATでも機能するかどうかをテストするとすぐにあなたの答えを受け入れます。 –