从 .tmx(平铺)文件中解压 zlib 数据

发布于 2024-10-19 21:40:13 字数 1974 浏览 4 评论 0原文

我正在尝试编写一个 .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);

一些注释:我已经删除了错误检查(示例代码和我的代码有)。足够)为了简洁起见,我在运行过程中没有收到任何错误消息。但是,输出文件是空的,我不知道为什么。

I'm trying to write a .tmx loader that will load the Tiled map data directly into my game. I've already written the Base64 decoder and decoded the string.

However, I receive no output after decompressing the data. I'll walk you through an example so you can see the problem.

The .tmx file, or rather the line of code I'm trying to work with, looks like this:

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

First, I have the Base64 encoded, zlib compressed data string from the .tmx file:

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

I run my Base64 decoder like so:

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

and get

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

I can only assume that this is correct. I've tried my decoder on Wikipedia examples and it gave me the correct output. Therefore, I am not assuming that my Base64 decoder is wrong. After all, I have output which should at least return some kind of crap after I decompress it, or a stream error.

I am using the zlib library and a copy-paste version of the decompression sample in zpipe.c (the function called int inf(FILE *source, FIle *dest). For this example, I quickly copied the output (the decoded tmx string) to file. This is the code for the decompression (again, mostly copy-paste)

#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);

Some notes: I have removed the error checking (the example code and my code had plenty) for brevity. I did not receive any error messages during the run. However, the output file is empty, and I don't know why.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月亮邮递员 2024-10-26 21:40:13

试试这个:

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);

Try this:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文