mirror of
https://github.com/ScrelliCopter/tmx2gba.git
synced 2025-02-21 03:29:25 +11:00
refactor tmxmap
This commit is contained in:
@@ -37,32 +37,39 @@ enum class Compression { NONE, GZIP, ZLIB, ZSTD, INVALID };
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]] static bool Decompress(Compression compression, std::span<uint32_t> out, const std::string_view decoded)
|
||||
[[nodiscard]] static bool DecodeBase64(
|
||||
std::vector<uint32_t>& out, size_t numTiles,
|
||||
const std::string_view base64, Compression compression)
|
||||
{
|
||||
//FIXME: lmao what is big endian
|
||||
auto decoded = base64_decode(TrimWhitespace(base64));
|
||||
if (decoded.empty()) { return false; }
|
||||
const std::span source(reinterpret_cast<const uint8_t*>(decoded.data()), decoded.size());
|
||||
std::span destination(reinterpret_cast<uint8_t*>(out.data()), sizeof(uint32_t) * out.size());
|
||||
|
||||
//FIXME: lmao what is big endian
|
||||
switch (compression)
|
||||
{
|
||||
case Compression::GZIP:
|
||||
#ifndef USE_ZLIB
|
||||
{
|
||||
out.resize(numTiles);
|
||||
GZipReader reader;
|
||||
if (!reader.OpenMemory(source) || !reader.Read(destination) || !reader.Check())
|
||||
if (!reader.OpenMemory(source) ||
|
||||
!reader.Read({ reinterpret_cast<uint8_t*>(out.data()), sizeof(uint32_t) * numTiles }) ||
|
||||
!reader.Check())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
case Compression::ZLIB:
|
||||
{
|
||||
out.resize(numTiles);
|
||||
// Decompress gzip/zlib data with zlib/zlib data miniz
|
||||
z_stream s =
|
||||
{
|
||||
.next_in = const_cast<Bytef*>(source.data()),
|
||||
.avail_in = static_cast<unsigned int>(source.size()),
|
||||
.next_out = static_cast<Bytef*>(destination.data()),
|
||||
.avail_out = static_cast<unsigned int>(destination.size()),
|
||||
.next_out = reinterpret_cast<Bytef*>(out.data()),
|
||||
.avail_out = static_cast<unsigned int>(sizeof(uint32_t) * numTiles),
|
||||
.zalloc = nullptr, .zfree = nullptr, .opaque = nullptr
|
||||
};
|
||||
#ifdef USE_ZLIB
|
||||
@@ -78,16 +85,29 @@ enum class Compression { NONE, GZIP, ZLIB, ZSTD, INVALID };
|
||||
}
|
||||
case Compression::ZSTD:
|
||||
{
|
||||
out.resize(numTiles);
|
||||
auto res = ZSTD_decompress(
|
||||
destination.data(), destination.size(),
|
||||
reinterpret_cast<void*>(out.data()),
|
||||
sizeof(uint32_t) * numTiles,
|
||||
source.data(), source.size());
|
||||
return !ZSTD_isError(res);
|
||||
}
|
||||
// Define all labels to shut up linters
|
||||
case Compression::NONE:
|
||||
{
|
||||
out.reserve(numTiles);
|
||||
const auto end = source.end();
|
||||
for (auto it = source.begin(); it < end - 3;)
|
||||
{
|
||||
uint32_t tile = *it++;
|
||||
tile |= static_cast<uint32_t>(*it++) << 8u;
|
||||
tile |= static_cast<uint32_t>(*it++) << 16u;
|
||||
tile |= static_cast<uint32_t>(*it++) << 24u;
|
||||
out.emplace_back(tile);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Compression::INVALID:
|
||||
//default:
|
||||
return false;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,32 +143,13 @@ void TmxMap::ReadLayer(const pugi::xml_node& xNode)
|
||||
auto encoding = EncodingFromStr(xData.attribute("encoding").value());
|
||||
if (encoding == Encoding::BASE64)
|
||||
{
|
||||
// Decode base64 string
|
||||
auto decoded = base64_decode(TrimWhitespace(xData.child_value()));
|
||||
if (decoded.empty())
|
||||
const std::string_view base64(xData.child_value());
|
||||
if (base64.empty())
|
||||
return;
|
||||
|
||||
auto compression = CompressionFromStr(xData.attribute("compression").value());
|
||||
if (compression == Compression::GZIP || compression == Compression::ZLIB || compression == Compression::ZSTD)
|
||||
{
|
||||
tileDat.resize(numTiles);
|
||||
if (!Decompress(compression, tileDat, decoded))
|
||||
return;
|
||||
}
|
||||
else if (compression == Compression::NONE)
|
||||
{
|
||||
tileDat.reserve(numTiles);
|
||||
const auto end = decoded.end();
|
||||
for (auto it = decoded.begin(); it < end - 3;)
|
||||
{
|
||||
uint32_t tile = static_cast<uint32_t>(static_cast<uint8_t>(*it++));
|
||||
tile |= static_cast<uint32_t>(static_cast<uint8_t>(*it++)) << 8u;
|
||||
tile |= static_cast<uint32_t>(static_cast<uint8_t>(*it++)) << 16u;
|
||||
tile |= static_cast<uint32_t>(static_cast<uint8_t>(*it++)) << 24u;
|
||||
tileDat.emplace_back(tile);
|
||||
}
|
||||
}
|
||||
else { return; }
|
||||
const auto compression = CompressionFromStr(xData.attribute("compression").value());
|
||||
if (compression == Compression::INVALID || !DecodeBase64(tileDat, numTiles, base64, compression))
|
||||
return;
|
||||
}
|
||||
else if (encoding == Encoding::XML)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user