diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c678b169588d..227297bd55c95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ if(NOT VERBOSE) set(CMAKE_REQUIRED_QUIET ON) endif() +set(TEXTUREPACKER_COMPRESSION_METHOD "zstd" CACHE STRING "TexturePacker compression method [none|lzo|zstd]") + # Includes include(cmake/modules/extra/ECMEnableSanitizers.cmake) include(cmake/scripts/common/GeneratorSetup.cmake) @@ -187,6 +189,7 @@ set(required_deps ASS TagLib TinyXML ZLIB + ZSTD ${PLATFORM_REQUIRED_DEPS}) # Optional dependencies. Keep in alphabetical order please diff --git a/cmake/modules/FindZSTD.cmake b/cmake/modules/FindZSTD.cmake new file mode 100644 index 0000000000000..3506c50c2058f --- /dev/null +++ b/cmake/modules/FindZSTD.cmake @@ -0,0 +1,35 @@ +#.rst: +# FindZSTD +# -------- +# Finds the ZSTD library +# +# This will define the following variables:: +# +# ZSTD_FOUND - system has ZSTD +# ZSTD_INCLUDE_DIRS - the ZSTD include directory +# ZSTD_LIBRARIES - the ZSTD libraries +# + +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_LIBZSTD libzstd QUIET) +endif() + +find_path(ZSTD_INCLUDE_DIR NAMES zstd.h + PATHS ${PC_LIBZSTD_INCLUDEDIR}) + +find_library(ZSTD_LIBRARY NAMES zstd libzstd + PATHS ${PC_LIBZSTD_LIBDIR}) + +set(ZSTD_VERSION ${PC_LIBZSTD_VERSION}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ZSTD + REQUIRED_VARS ZSTD_LIBRARY ZSTD_INCLUDE_DIR + VERSION_VAR ZSTD_VERSION) + +if(ZSTD_FOUND) + set(ZSTD_LIBRARIES ${ZSTD_LIBRARY}) + set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR}) +endif() + +mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY) diff --git a/cmake/scripts/common/ProjectMacros.cmake b/cmake/scripts/common/ProjectMacros.cmake index 3a1910caa6f9c..3ae642865f1a9 100644 --- a/cmake/scripts/common/ProjectMacros.cmake +++ b/cmake/scripts/common/ProjectMacros.cmake @@ -15,6 +15,7 @@ function(pack_xbt input output) ARGS -input ${input} -output ${output} -dupecheck + -compression-method ${TEXTUREPACKER_COMPRESSION_METHOD} DEPENDS ${MEDIA_FILES}) list(APPEND XBT_FILES ${output}) set(XBT_FILES ${XBT_FILES} PARENT_SCOPE) diff --git a/tools/depends/native/Makefile b/tools/depends/native/Makefile index 28ce21e84ef59..60bb75fdac734 100644 --- a/tools/depends/native/Makefile +++ b/tools/depends/native/Makefile @@ -30,7 +30,8 @@ NATIVE= \ python3 \ swig \ TexturePacker \ - zlib + zlib \ + zstd ifneq ($(NATIVE_OS),osx) NATIVE += libffi @@ -80,7 +81,7 @@ pugixml: cmake python3: $(EXPAT) $(LIBFFI) pkg-config zlib openssl autoconf-archive swig: pcre tar: xz automake -TexturePacker: automake pkg-config libpng liblzo2 giflib libjpeg-turbo +TexturePacker: automake pkg-config libpng liblzo2 giflib libjpeg-turbo zstd wayland-scanner: expat pkg-config waylandpp-scanner: cmake pugixml diff --git a/tools/depends/native/TexturePacker/CMakeLists.txt b/tools/depends/native/TexturePacker/CMakeLists.txt index 97dc1d324494d..d01d69f20f3d1 100644 --- a/tools/depends/native/TexturePacker/CMakeLists.txt +++ b/tools/depends/native/TexturePacker/CMakeLists.txt @@ -8,6 +8,7 @@ find_package(Lzo2 REQUIRED) find_package(PNG REQUIRED) find_package(GIF REQUIRED) find_package(JPEG REQUIRED) +find_package(ZSTD REQUIRED) if(GIF_VERSION LESS 4) message(FATAL_ERROR "giflib < 4 not supported") @@ -42,6 +43,7 @@ target_include_directories(TexturePacker PRIVATE ${PNG_INCLUDE_DIRS} ${JPEG_INCLUDE_DIR} ${GIF_INCLUDE_DIR} + ${ZSTD_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/xbmc ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src/decoder) @@ -50,5 +52,6 @@ target_link_libraries(TexturePacker ${GIF_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} + ${ZSTD_LIBRARIES} ${LZO2_LIBRARIES}) target_compile_options(TexturePacker PRIVATE ${ARCH_DEFINES} ${SYSTEM_DEFINES}) diff --git a/tools/depends/native/TexturePacker/src/TexturePacker.cpp b/tools/depends/native/TexturePacker/src/TexturePacker.cpp index 99ceeaa96bbcc..13df608c2b6ce 100644 --- a/tools/depends/native/TexturePacker/src/TexturePacker.cpp +++ b/tools/depends/native/TexturePacker/src/TexturePacker.cpp @@ -27,30 +27,29 @@ #include #define platform_stricmp strcasecmp #endif -#include -#include -#include - +#include "DecoderManager.h" +#include "XBTFWriter.h" +#include "cmdlineargs.h" #include "guilib/XBTF.h" #include "guilib/XBTFReader.h" +#include "md5.h" -#include "DecoderManager.h" +#include +#include -#include "XBTFWriter.h" -#include "md5.h" -#include "cmdlineargs.h" +#include +#include #ifdef TARGET_WINDOWS #define strncasecmp _strnicmp #endif +#include #include #include #include -#define FLAGS_USE_LZO 1 - #define DIR_SEPARATOR '/' namespace @@ -91,10 +90,11 @@ bool HasAlpha(unsigned char* argb, unsigned int width, unsigned int height) void Usage() { puts("Usage:"); - puts(" -help Show this screen."); - puts(" -input Input directory. Default: current dir"); - puts(" -output Output directory/filename. Default: Textures.xbt"); - puts(" -dupecheck Enable duplicate file detection. Reduces output file size. Default: off"); + puts(" -help Show this screen."); + puts(" -input Input directory. Default: current dir"); + puts(" -output Output directory/filename. Default: Textures.xbt"); + puts(" -dupecheck Enable duplicate file detection. Reduces output file size. Default: off"); + puts(" -compression-method Compression method to use. [lzo|none] Default: lzo"); } } // namespace @@ -111,7 +111,10 @@ class TexturePacker int createBundle(const std::string& InputDir, const std::string& OutputFile); - void SetFlags(unsigned int flags) { m_flags = flags; } + void SetCompressionMethod(XBTFCompressionMethod compressionMethod) + { + m_compressionMethod = compressionMethod; + } private: void CreateSkeletonHeader(CXBTFWriter& xbtfWriter, @@ -128,7 +131,7 @@ class TexturePacker std::vector m_dupes; bool m_dupecheck{false}; - unsigned int m_flags{0}; + XBTFCompressionMethod m_compressionMethod = XBTFCompressionMethod::NONE; }; void TexturePacker::CreateSkeletonHeader(CXBTFWriter& xbtfWriter, @@ -203,9 +206,9 @@ CXBTFFrame TexturePacker::CreateXBTFFrame(DecodedFrame& decodedFrame, CXBTFWrite const bool hasAlpha = HasAlpha(data, width, height); CXBTFFrame frame; - lzo_uint packedSize = size; + uint64_t packedSize = size; - if ((m_flags & FLAGS_USE_LZO) == FLAGS_USE_LZO) + if (m_compressionMethod == XBTFCompressionMethod::LZO) { // grab a temporary buffer for unpacking into packedSize = size + size / 16 + 64 + 3; // see simple.c in lzo @@ -222,6 +225,8 @@ CXBTFFrame TexturePacker::CreateXBTFFrame(DecodedFrame& decodedFrame, CXBTFWrite // compression failed, or compressed size is bigger than uncompressed, so store as uncompressed packedSize = size; writer.AppendContent(data, size); + + frame.SetCompressionMethod(XBTFCompressionMethod::NONE); } else { // success @@ -231,16 +236,47 @@ CXBTFFrame TexturePacker::CreateXBTFFrame(DecodedFrame& decodedFrame, CXBTFWrite { //optimisation failed packedSize = size; writer.AppendContent(data, size); + + frame.SetCompressionMethod(XBTFCompressionMethod::NONE); } else { // success writer.AppendContent(packed.data(), packedSize); + + frame.SetCompressionMethod(XBTFCompressionMethod::LZO); } } } + else if (m_compressionMethod == XBTFCompressionMethod::ZSTD) + { + packedSize = ZSTD_compressBound(size); + + std::vector packed(packedSize); + + packedSize = ZSTD_compress(packed.data(), packed.size(), data, size, ZSTD_CLEVEL_DEFAULT); + + if (ZSTD_isError(packedSize) == 1) + { + fprintf(stderr, "ztd error: %s\n", ZSTD_getErrorName(packedSize)); + + packedSize = size; + writer.AppendContent(data, size); + + frame.SetCompressionMethod(XBTFCompressionMethod::NONE); + } + else + { + packed.resize(packedSize); + writer.AppendContent(packed.data(), packed.size()); + + frame.SetCompressionMethod(XBTFCompressionMethod::ZSTD); + } + } else { writer.AppendContent(data, size); + + frame.SetCompressionMethod(XBTFCompressionMethod::NONE); } frame.SetPackedSize(packedSize); frame.SetUnpackedSize(size); @@ -291,6 +327,8 @@ int TexturePacker::createBundle(const std::string& InputDir, const std::string& std::vector files = writer.GetFiles(); m_dupes.resize(files.size()); + const auto start = std::chrono::steady_clock::now(); + for (size_t i = 0; i < files.size(); i++) { struct MD5Context ctx; @@ -340,10 +378,11 @@ int TexturePacker::createBundle(const std::string& InputDir, const std::string& CXBTFFrame frame = CreateXBTFFrame(frames.frameList[j], writer); file.GetFrames().push_back(frame); printf(" frame %4i (delay:%4i) %s%c (%d,%d @ %" PRIu64 - " bytes)\n", + " -> %" PRIu64 " bytes, compression: %s)\n", j, frame.GetDuration(), GetFormatString(frame.GetFormat()), frame.HasAlpha() ? ' ' : '*', frame.GetWidth(), frame.GetHeight(), - frame.GetUnpackedSize()); + frame.GetUnpackedSize(), frame.GetPackedSize(), + XBTFCompressionMethodMap.at(frame.GetCompressionMethod()).data()); } } file.SetLoop(0); @@ -351,6 +390,15 @@ int TexturePacker::createBundle(const std::string& InputDir, const std::string& writer.UpdateFile(file); } + const auto end = std::chrono::steady_clock::now(); + + const auto diff = + std::chrono::duration_cast>(end - start); + + printf( + "TexturePacker: processed %lu files in %.3f ms using %s\n", files.size(), diff.count(), + XBTFCompressionMethodMap.at(files.front().GetFrames().front().GetCompressionMethod()).data()); + if (!writer.UpdateHeader(m_dupes)) { fprintf(stderr, "Error writing header to file\n"); @@ -385,7 +433,7 @@ int main(int argc, char* argv[]) TexturePacker texturePacker; - texturePacker.SetFlags(FLAGS_USE_LZO); + texturePacker.SetCompressionMethod(XBTFCompressionMethod::LZO); for (unsigned int i = 1; i < args.size(); ++i) { @@ -407,6 +455,25 @@ int main(int argc, char* argv[]) { texturePacker.EnableVerboseOutput(); } + else if (!strcmp(args[i], "-compression-method")) + { + std::string compressionMethod = args[++i]; + + if (compressionMethod == "lzo") + { + texturePacker.SetCompressionMethod(XBTFCompressionMethod::LZO); + } + + if (compressionMethod == "zstd") + { + texturePacker.SetCompressionMethod(XBTFCompressionMethod::ZSTD); + } + + if (compressionMethod == "none") + { + texturePacker.SetCompressionMethod(XBTFCompressionMethod::NONE); + } + } else if (!platform_stricmp(args[i], "-output") || !platform_stricmp(args[i], "-o")) { OutputFilename = args[++i]; diff --git a/tools/depends/native/TexturePacker/src/XBTFWriter.cpp b/tools/depends/native/TexturePacker/src/XBTFWriter.cpp index bb7f40ea20527..f09ac7841d8aa 100644 --- a/tools/depends/native/TexturePacker/src/XBTFWriter.cpp +++ b/tools/depends/native/TexturePacker/src/XBTFWriter.cpp @@ -131,6 +131,7 @@ bool CXBTFWriter::UpdateHeader(const std::vector& dupes) WRITE_U64(frame.GetUnpackedSize(), m_file); WRITE_U32(frame.GetDuration(), m_file); WRITE_U64(frame.GetOffset(), m_file); + WRITE_U32(static_cast(frame.GetCompressionMethod()), m_file); } } diff --git a/tools/depends/native/TexturePacker/src/cmdlineargs.h b/tools/depends/native/TexturePacker/src/cmdlineargs.h index d0b9d03d3451f..06ecd179eedff 100644 --- a/tools/depends/native/TexturePacker/src/cmdlineargs.h +++ b/tools/depends/native/TexturePacker/src/cmdlineargs.h @@ -26,8 +26,9 @@ char* GetCommandLine(); #else #include #endif -#include +#include #include +#include class CmdLineArgs : public std::vector { diff --git a/tools/depends/native/TexturePacker/src/configure.ac b/tools/depends/native/TexturePacker/src/configure.ac index 4b83b5e0336c8..d9ccfd6213a2c 100644 --- a/tools/depends/native/TexturePacker/src/configure.ac +++ b/tools/depends/native/TexturePacker/src/configure.ac @@ -33,6 +33,9 @@ AC_CHECK_HEADER([jpeglib.h],, AC_MSG_ERROR("jpeglib.h not found")) AC_CHECK_LIB([jpeg],[main],, AC_MSG_ERROR("libjpeg not found")) AC_CHECK_HEADER([lzo/lzo1x.h],, AC_MSG_ERROR("lzo/lzo1x.h not found")) AC_CHECK_LIB([lzo2],[main],, AC_MSG_ERROR("liblzo2 not found")) +AC_CHECK_HEADER([zstd.h],, AC_MSG_ERROR("zstd.h not found")) +AC_CHECK_LIB([zstd],[main],, AC_MSG_ERROR("libzstd not found")) + AC_SUBST(KODI_SRC_DIR) AC_SUBST(STATIC_FLAG) diff --git a/tools/depends/native/zstd/Makefile b/tools/depends/native/zstd/Makefile new file mode 100644 index 0000000000000..674a0d0358d92 --- /dev/null +++ b/tools/depends/native/zstd/Makefile @@ -0,0 +1,30 @@ +include ../../Makefile.include +PREFIX=$(NATIVEPREFIX) +PLATFORM=$(NATIVEPLATFORM) +DEPS = ../../Makefile.include Makefile ../../download-files.include + +LIBNAME=zstd +VERSION=1.5.5 +SOURCE=$(LIBNAME)-$(VERSION) +ARCHIVE=$(SOURCE).tar.gz +SHA512=99109ec0e07fa65c2101c9cb36be56b672bbd0ee69d265f924718e61f9192ae8385c8d9e4d0c318be9edfa6d849fd3d60e5f164fa120961449429ea3c5dab6b6 +include ../../download-files.include + +all: .installed-$(PLATFORM) + +$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE) + rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM) + cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + +.installed-$(PLATFORM): $(PLATFORM) + $(MAKE) -C $(PLATFORM)/lib libzstd.a PREFIX=$(PREFIX) + $(MAKE) -C $(PLATFORM)/lib install-pc install-static install-includes PREFIX=$(PREFIX) + touch $@ + +clean: + $(MAKE) -C $(PLATFORM) clean + rm -f .installed-$(PLATFORM) + +distclean:: + rm -rf $(PLATFORM) .installed-$(PLATFORM) + diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile index 93f769ae5c2e2..56ee9db686f06 100644 --- a/tools/depends/target/Makefile +++ b/tools/depends/target/Makefile @@ -48,7 +48,8 @@ DEPENDS = \ sqlite3 \ tinyxml \ udfread \ - xz + xz \ + zstd ifeq ($(ENABLE_GPLV3),yes) DEPENDS+=samba-gplv3 libcdio-gplv3 diff --git a/tools/depends/target/gnutls/Makefile b/tools/depends/target/gnutls/Makefile index 335667d32a0e9..66103c041690d 100644 --- a/tools/depends/target/gnutls/Makefile +++ b/tools/depends/target/gnutls/Makefile @@ -23,6 +23,7 @@ CONFIGURE_OPTIONS+= ac_cv_func_malloc_0_nonnull=yes \ CONFIGURE=./configure --prefix=$(PREFIX) \ --disable-shared \ --without-p11-kit \ + --without-zstd \ --disable-nls \ --with-included-unistring \ --with-included-libtasn1 \ diff --git a/tools/depends/target/zstd/Makefile b/tools/depends/target/zstd/Makefile new file mode 100644 index 0000000000000..d9bd369e809b1 --- /dev/null +++ b/tools/depends/target/zstd/Makefile @@ -0,0 +1,28 @@ +include ../../Makefile.include +DEPS = ../../Makefile.include Makefile ../../download-files.include + +LIBNAME=zstd +VERSION=1.5.5 +SOURCE=$(LIBNAME)-$(VERSION) +ARCHIVE=$(SOURCE).tar.gz +SHA512=99109ec0e07fa65c2101c9cb36be56b672bbd0ee69d265f924718e61f9192ae8385c8d9e4d0c318be9edfa6d849fd3d60e5f164fa120961449429ea3c5dab6b6 +include ../../download-files.include + +all: .installed-$(PLATFORM) + +$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE) + rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM) + cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE) + +.installed-$(PLATFORM): $(PLATFORM) + $(MAKE) -C $(PLATFORM)/lib libzstd.a PREFIX=$(PREFIX) CFLAGS="$(CFLAGS)" CPPFLAGS="$(CPPFLAGS)" + $(MAKE) -C $(PLATFORM)/lib install-pc install-static install-includes PREFIX=$(PREFIX) + touch $@ + +clean: + $(MAKE) -C $(PLATFORM) clean + rm -f .installed-$(PLATFORM) + +distclean:: + rm -rf $(PLATFORM) .installed-$(PLATFORM) + diff --git a/xbmc/guilib/TextureBundleXBT.cpp b/xbmc/guilib/TextureBundleXBT.cpp index 981ddad82588f..3f612854e3368 100644 --- a/xbmc/guilib/TextureBundleXBT.cpp +++ b/xbmc/guilib/TextureBundleXBT.cpp @@ -30,7 +30,7 @@ #include #include - +#include #ifdef TARGET_WINDOWS_DESKTOP #ifdef NDEBUG @@ -225,18 +225,44 @@ bool CTextureBundleXBT::ConvertFrameToTexture(const std::string& name, } // check if it's packed with lzo - if (frame.IsPacked()) - { // unpack - std::vector unpacked(static_cast(frame.GetUnpackedSize())); - lzo_uint s = (lzo_uint)frame.GetUnpackedSize(); - if (lzo1x_decompress_safe(buffer.data(), static_cast(buffer.size()), unpacked.data(), - &s, NULL) != LZO_E_OK || - s != frame.GetUnpackedSize()) + switch (frame.GetCompressionMethod()) + { + case XBTFCompressionMethod::LZO: + { // unpack + std::vector unpacked(static_cast(frame.GetUnpackedSize())); + lzo_uint s = (lzo_uint)frame.GetUnpackedSize(); + if (lzo1x_decompress_safe(buffer.data(), static_cast(buffer.size()), + unpacked.data(), &s, NULL) != LZO_E_OK || + s != frame.GetUnpackedSize()) + { + CLog::Log(LOGERROR, "Error loading texture: {}: Decompression error", name); + return false; + } + + buffer = std::move(unpacked); + + break; + } + case XBTFCompressionMethod::ZSTD: { - CLog::Log(LOGERROR, "Error loading texture: {}: Decompression error", name); - return false; + std::vector unpacked(static_cast(frame.GetUnpackedSize())); + + const size_t unpackedSize = + ZSTD_decompress(unpacked.data(), unpacked.size(), buffer.data(), buffer.size()); + + if (ZSTD_isError(unpackedSize) == 1) + { + CLog::Log(LOGERROR, "Error loading texture: {}: zstd error: {}", name, + ZSTD_getErrorName(unpackedSize)); + return false; + } + + buffer = std::move(unpacked); + break; } - buffer = std::move(unpacked); + case XBTFCompressionMethod::NONE: + default: + break; } // create an xbmc texture @@ -275,27 +301,52 @@ std::vector CTextureBundleXBT::UnpackFrame(const CXBTFReader& reader, } // if the frame isn't packed there's nothing else to be done - if (!frame.IsPacked()) - return packedBuffer; - - // make sure lzo is initialized - if (lzo_init() != LZO_E_OK) + switch (frame.GetCompressionMethod()) { - CLog::Log(LOGERROR, "CTextureBundleXBT: failed to initialize lzo"); - return {}; - } + case XBTFCompressionMethod::NONE: + default: + { + return packedBuffer; + } + case XBTFCompressionMethod::LZO: + { + // make sure lzo is initialized + if (lzo_init() != LZO_E_OK) + { + CLog::Log(LOGERROR, "CTextureBundleXBT: failed to initialize lzo"); + return {}; + } + + lzo_uint size = static_cast(frame.GetUnpackedSize()); + std::vector unpackedBuffer(static_cast(frame.GetUnpackedSize())); + if (lzo1x_decompress_safe(packedBuffer.data(), static_cast(packedBuffer.size()), + unpackedBuffer.data(), &size, nullptr) != LZO_E_OK || + size != frame.GetUnpackedSize()) + { + CLog::Log( + LOGERROR, + "CTextureBundleXBT: failed to decompress frame with {} unpacked bytes to {} bytes", + frame.GetPackedSize(), frame.GetUnpackedSize()); + return {}; + } + + return unpackedBuffer; + } + case XBTFCompressionMethod::ZSTD: + { + std::vector unpackedBuffer(static_cast(frame.GetUnpackedSize())); - lzo_uint size = static_cast(frame.GetUnpackedSize()); - std::vector unpackedBuffer(static_cast(frame.GetUnpackedSize())); - if (lzo1x_decompress_safe(packedBuffer.data(), static_cast(packedBuffer.size()), - unpackedBuffer.data(), &size, nullptr) != LZO_E_OK || - size != frame.GetUnpackedSize()) - { - CLog::Log(LOGERROR, - "CTextureBundleXBT: failed to decompress frame with {} unpacked bytes to {} bytes", - frame.GetPackedSize(), frame.GetUnpackedSize()); - return {}; - } + const size_t unpackedSize = ZSTD_decompress(unpackedBuffer.data(), unpackedBuffer.size(), + packedBuffer.data(), packedBuffer.size()); + + if (ZSTD_isError(unpackedSize) == 1) + { + CLog::Log(LOGERROR, "CTextureBundleXBT: failed to decompress frame - zstd error: {}", + ZSTD_getErrorName(unpackedSize)); + return {}; + } - return unpackedBuffer; + return unpackedBuffer; + } + } } diff --git a/xbmc/guilib/TextureManager.cpp b/xbmc/guilib/TextureManager.cpp index ddf2e77e7f99a..65a945e1a667e 100644 --- a/xbmc/guilib/TextureManager.cpp +++ b/xbmc/guilib/TextureManager.cpp @@ -24,6 +24,8 @@ #include +#define _DEBUG_TEXTURES + #ifdef _DEBUG_TEXTURES #include "utils/TimeUtils.h" #endif diff --git a/xbmc/guilib/XBTF.cpp b/xbmc/guilib/XBTF.cpp index aa095ccb5f5ed..e0c26e6895098 100644 --- a/xbmc/guilib/XBTF.cpp +++ b/xbmc/guilib/XBTF.cpp @@ -52,9 +52,14 @@ void CXBTFFrame::SetPackedSize(uint64_t size) m_packedSize = size; } -bool CXBTFFrame::IsPacked() const +XBTFCompressionMethod CXBTFFrame::GetCompressionMethod() const { - return m_unpackedSize != m_packedSize; + return m_compressionMethod; +} + +void CXBTFFrame::SetCompressionMethod(XBTFCompressionMethod compressionMethod) +{ + m_compressionMethod = compressionMethod; } bool CXBTFFrame::HasAlpha() const @@ -111,7 +116,8 @@ uint64_t CXBTFFrame::GetHeaderSize() const sizeof(m_packedSize) + sizeof(m_unpackedSize) + sizeof(m_offset) + - sizeof(m_duration); + sizeof(m_duration) + + sizeof(m_compressionMethod); return result; } diff --git a/xbmc/guilib/XBTF.h b/xbmc/guilib/XBTF.h index 382943902b576..2f5c9aadba2c8 100644 --- a/xbmc/guilib/XBTF.h +++ b/xbmc/guilib/XBTF.h @@ -8,18 +8,32 @@ #pragma once +#include "utils/Map.h" + #include #include +#include #include #include -#include - static const std::string XBTF_MAGIC = "XBTF"; -static const std::string XBTF_VERSION = "2"; +static const std::string XBTF_VERSION = "3"; #include "TextureFormats.h" +enum class XBTFCompressionMethod : uint32_t +{ + NONE, + LZO, + ZSTD, +}; + +constexpr auto XBTFCompressionMethodMap = make_map({ + {XBTFCompressionMethod::NONE, "none"}, + {XBTFCompressionMethod::LZO, "lzo"}, + {XBTFCompressionMethod::ZSTD, "zstd"}, +}); + class CXBTFFrame { public: @@ -48,7 +62,9 @@ class CXBTFFrame uint32_t GetDuration() const; void SetDuration(uint32_t duration); - bool IsPacked() const; + XBTFCompressionMethod GetCompressionMethod() const; + void SetCompressionMethod(XBTFCompressionMethod compressionMethod); + bool HasAlpha() const; private: @@ -59,6 +75,7 @@ class CXBTFFrame uint64_t m_unpackedSize; uint64_t m_offset; uint32_t m_duration; + XBTFCompressionMethod m_compressionMethod = XBTFCompressionMethod::NONE; }; class CXBTFFile diff --git a/xbmc/guilib/XBTFReader.cpp b/xbmc/guilib/XBTFReader.cpp index cca8e834c1afb..f235ceb93aaa3 100644 --- a/xbmc/guilib/XBTFReader.cpp +++ b/xbmc/guilib/XBTFReader.cpp @@ -152,6 +152,10 @@ bool CXBTFReader::Open(const std::string& path) return false; frame.SetOffset(u64); + if (!ReadUInt32(m_file, u32)) + return false; + frame.SetCompressionMethod(static_cast(u32)); + xbtfFile.GetFrames().push_back(frame); }