Decompressing zlib data from .tmx (Tiled) file
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_i开发者_开发技巧n = 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.
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);
精彩评论