从.tmx(Tiled)文件解压缩zlib数据

时间:2011-02-26 17:52:20

标签: c++ base64 zlib tmx

我正在尝试编写一个.tmx加载程序,它会将Tiled地图数据直接加载到我的游戏中。我已经编写了Base64解码器并解码了字符串。

但是,解压缩数据后我没有收到任何输出。我将向您介绍一个示例,以便您可以看到问题。

.tmx文件,或者更确切地说是我正在尝试使用的代码行,如下所示:

<data encoding="base64" compression="zlib">
    eJzt1UEKwCAMBMBUsPXi/7+rH9CjSp2BPeWyEEgiAIA/yT3PIO/GXrdKPXUyY63ZPljPPs7iXp2lxPiffxt7AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAtGh4aAGc=
</data>

首先,我有来自.tmx文件的Base64编码的zlib压缩数据字符串:

std::string TmxSample = "eJzt1UEKwCAMBMBUsPXi/7+rH9CjSp2BPeWyEEgiAIA/yT3PIO/GXrdKPXUyY63ZPljPPs7iXp2lxPiffxt7AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAtGh4aAGc=";

我像这样运行我的Base64解码器:

std::string DecodedTmxSample = Base64::decode(TmxSample);

并获取

xœíÕA
À ÀT°õâÿ¿«Ð£J=å²H"

我只能假设这是正确的。我在维基百科的例子上尝试了我的解码器,它给了我正确的输出。因此,我不认为我的Base64解码器是错误的。毕竟,我有输出,它应该至少在我解压缩之后返回某种废话,或者流错误。

我正在使用zlib库和zpipe.c中的解压缩示例的复制粘贴版本(名为int inf(FILE *source, FIle *dest)的函数。对于此示例,我快速复制了输出(解码的tmx字符串)这是解压缩的代码(再次,主要是复制粘贴)

#define CHUNK 16384
int           ret;
unsigned      have;
z_stream      strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];

strm.zalloc   = Z_NULL;
strm.zfree    = Z_NULL;
strm.opaque   = Z_NULL;
strm.avail_in = 0;
strm.next_in  = Z_NULL;
ret           = inflateInit(&strm);

FILE *file;
// Contains decoded data.
file = fopen("testFile", "r");

FILE *dest;
// We write decompressed data to this file.
dest = fopen("testOutFile", "w");

do 
{
    strm.avail_in = fread(in, 1, CHUNK, file);
    strm.next_in  = in;

    do
    {
        strm.avail_out = CHUNK;
        strm.next_out  = out;
        ret            = inflate(&strm, Z_NO_FLUSH);
        have           = CHUNK - strm.avail_out;

    } while (strm.avail_out == 0);

} while (ret != Z_STREAM_END);

一些注意事项:为了简洁,我删除了错误检查(示例代码和我的代码有很多)。我在运行期间没有收到任何错误消息。但是,输出文件是空的,我不知道为什么。

1 个答案:

答案 0 :(得分:1)

试试这个:

do 
{
    if ( strm.avail_in == 0 ){
       strm.avail_in = fread(in, 1, CHUNK, file);
       strm.next_in  = in;
    }
    strm.avail_out = CHUNK;
    strm.next_out  = out;

    ret            = inflate(&strm, Z_SYNC_FLUSH);
    have           = CHUNK - strm.avail_out;

    fwrite ( out, 1, have, dest ); //you forgot this step

} while (ret != Z_STREAM_END);