diff --git a/Common/Render/TextureAtlas.cpp b/Common/Render/TextureAtlas.cpp index 285f766892..c23cb33646 100644 --- a/Common/Render/TextureAtlas.cpp +++ b/Common/Render/TextureAtlas.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "Common/Render/TextureAtlas.h" @@ -22,10 +23,19 @@ public: } template - T *ReadMultipleAlloc(size_t count) { + T *ReadMultipleAlloc(size_t count, bool compressed) { T *t = new T[count]; - memcpy(t, data_ + offset_, sizeof(T) * count); - offset_ += sizeof(T) * count; + if (!compressed) { + memcpy(t, data_ + offset_, sizeof(T) * count); + offset_ += sizeof(T) * count; + } else { + uint32_t compressed_size = 0; + memcpy(&compressed_size, data_ + offset_, sizeof(uint32_t)); + offset_ += sizeof(uint32_t); + + ZSTD_decompress(t, sizeof(T) * count, data_ + offset_, compressed_size); + offset_ += compressed_size; + } return t; } @@ -45,7 +55,8 @@ bool Atlas::Load(const uint8_t *data, size_t data_size) { return false; } - images = reader.ReadMultipleAlloc(num_images); + images = reader.ReadMultipleAlloc(num_images, header.version >= 1); + fonts = new AtlasFont[num_fonts]; for (int i = 0; i < num_fonts; i++) { AtlasFontHeader font_header = reader.Read(); @@ -55,8 +66,8 @@ bool Atlas::Load(const uint8_t *data, size_t data_size) { fonts[i].distslope = font_header.distslope; fonts[i].numRanges = font_header.numRanges; fonts[i].numChars = font_header.numChars; - fonts[i].ranges = reader.ReadMultipleAlloc(font_header.numRanges); - fonts[i].charData = reader.ReadMultipleAlloc(font_header.numChars); + fonts[i].ranges = reader.ReadMultipleAlloc(font_header.numRanges, header.version >= 1); + fonts[i].charData = reader.ReadMultipleAlloc(font_header.numChars, header.version >= 1); memcpy(fonts[i].name, font_header.name, sizeof(font_header.name)); } return true; diff --git a/ext/native/tools/atlastool.cpp b/ext/native/tools/atlastool.cpp index d3bcf498c1..e745736640 100644 --- a/ext/native/tools/atlastool.cpp +++ b/ext/native/tools/atlastool.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "Common/Render/TextureAtlas.h" @@ -853,6 +854,30 @@ void GetLocales(const char *locales, std::vector &ranges) std::sort(ranges.begin(), ranges.end()); } +static bool WriteCompressed(const void *src, size_t sz, size_t num, FILE *fp) { + size_t src_size = sz * num; + size_t compressed_size = ZSTD_compressBound(src_size); + uint8_t *compressed = new uint8_t[compressed_size]; + compressed_size = ZSTD_compress(compressed, compressed_size, src, src_size, 22); + if (ZSTD_isError(compressed_size)) { + delete[] compressed; + return false; + } + + uint32_t write_size = (uint32_t)compressed_size; + if (fwrite(&write_size, sizeof(uint32_t), 1, fp) != 1) { + delete[] compressed; + return false; + } + if (fwrite(compressed, 1, compressed_size, fp) != compressed_size) { + delete[] compressed; + return false; + } + + delete[] compressed; + return true; +} + int main(int argc, char **argv) { // initProgram(&argc, const_cast(&argv)); // /usr/share/fonts/truetype/msttcorefonts/Arial_Black.ttf @@ -981,15 +1006,16 @@ int main(int argc, char **argv) { FILE *meta = fopen(meta_name.c_str(), "wb"); AtlasHeader header; header.magic = ATLAS_MAGIC; - header.version = 0; + header.version = 1; header.numFonts = (int)fonts.size(); header.numImages = (int)images.size(); fwrite(&header, 1, sizeof(header), meta); // For each image + AtlasImage *atalas_images = new AtlasImage[images.size()]; for (int i = 0; i < (int)images.size(); i++) { - AtlasImage atlas_image = images[i].ToAtlasImage((float)dest.width(), (float)dest.height(), results); - fwrite(&atlas_image, 1, sizeof(atlas_image), meta); + atalas_images[i] = images[i].ToAtlasImage((float)dest.width(), (float)dest.height(), results); } + WriteCompressed(atalas_images, sizeof(AtlasImage), images.size(), meta); // For each font for (int i = 0; i < (int)fonts.size(); i++) { auto &font = fonts[i]; @@ -997,9 +1023,9 @@ int main(int argc, char **argv) { AtlasFontHeader font_header = font.GetHeader(); fwrite(&font_header, 1, sizeof(font_header), meta); auto ranges = font.GetRanges(); - fwrite(ranges.data(), sizeof(AtlasCharRange), ranges.size(), meta); + WriteCompressed(ranges.data(), sizeof(AtlasCharRange), ranges.size(), meta); auto chars = font.GetChars((float)dest.width(), (float)dest.height(), results); - fwrite(chars.data(), sizeof(AtlasChar), chars.size(), meta); + WriteCompressed(chars.data(), sizeof(AtlasChar), chars.size(), meta); } fclose(meta); } diff --git a/ext/native/tools/atlastool/atlastool.vcxproj b/ext/native/tools/atlastool/atlastool.vcxproj index 560b47bc34..65b315ebdc 100644 --- a/ext/native/tools/atlastool/atlastool.vcxproj +++ b/ext/native/tools/atlastool/atlastool.vcxproj @@ -95,7 +95,7 @@ true _CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ../../../../;../../ext;../../;../../../../ext;../prebuilt + ../../../../;../../ext;../../;../../../../ext;../prebuilt;../../../../ext/zstd/lib MultiThreaded false