Распаковка данных zlib из файла .tmx (Tiled) - PullRequest
1 голос
/ 26 февраля 2011

Я пытаюсь написать загрузчик .tmx, который будет загружать данные карты Tiled прямо в мою игру. Я уже написал декодер Base64 и расшифровал строку.

Однако я не получаю вывод после распаковки данных. Я расскажу вам пример, чтобы вы могли увидеть проблему.

Файл .tmx, точнее строка кода, с которой я пытаюсь работать, выглядит следующим образом:

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

Во-первых, у меня есть сжатая zlib строка данных в кодировке Base64 из файла .tmx:

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 Ответ

1 голос
/ 10 марта 2011

Попробуйте это:

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