diff options
Diffstat (limited to 'source/core/slang-deflate-compression-system.cpp')
| -rw-r--r-- | source/core/slang-deflate-compression-system.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/source/core/slang-deflate-compression-system.cpp b/source/core/slang-deflate-compression-system.cpp new file mode 100644 index 000000000..a316be122 --- /dev/null +++ b/source/core/slang-deflate-compression-system.cpp @@ -0,0 +1,89 @@ +#include "slang-deflate-compression-system.h" + +#include "../../slang-com-helper.h" +#include "../../slang-com-ptr.h" + +// We don't want compress #define to clash +#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES 1 + +#include "../../external/miniz/miniz.h" +#include "../../external/miniz/miniz_common.h" +#include "../../external/miniz/miniz_tdef.h" +#include "../../external/miniz/miniz_tinfl.h" + +#include "slang-blob.h" + +namespace Slang +{ + +// Allocate static const storage for the various interface IDs that the Slang API needs to expose +static const Guid IID_ISlangUnknown = SLANG_UUID_ISlangUnknown; +static const Guid IID_ICompressionSystem = SLANG_UUID_ICompressionSystem; + +class DeflateCompressionSystemImpl : public RefObject, public ICompressionSystem +{ +public: + // ISlangUnknown + // override ref counting, as singleton + SLANG_IUNKNOWN_QUERY_INTERFACE + + SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; } + SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; } + + // ICompressionSystem + virtual SLANG_NO_THROW CompressionSystemType SLANG_MCALL getSystemType() SLANG_OVERRIDE { return CompressionSystemType::Deflate; } + virtual SLANG_NO_THROW SlangResult SLANG_MCALL compress(const CompressionStyle* style, const void* src, size_t srcSizeInBytes, ISlangBlob** outBlob) SLANG_OVERRIDE; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL decompress(const void* compressed, size_t compressedSizeInBytes, size_t decompressedSizeInBytes, void* outDecompressed) SLANG_OVERRIDE; + +protected: + + ICompressionSystem* getInterface(const Guid& guid); +}; + +ICompressionSystem* DeflateCompressionSystemImpl::getInterface(const Guid& guid) +{ + return (guid == IID_ISlangUnknown || guid == IID_ICompressionSystem) ? static_cast<ICompressionSystem*>(this) : nullptr; +} + +SlangResult DeflateCompressionSystemImpl::compress(const CompressionStyle* style, const void* src, size_t srcSizeInBytes, ISlangBlob** outBlob) +{ + SLANG_UNUSED(style); + + size_t compressedSizeInBytes; + + const int flags = 0; + void* compressed = tdefl_compress_mem_to_heap(src, srcSizeInBytes, &compressedSizeInBytes, 0); + + if (!compressed) + { + return SLANG_FAIL; + } + + ScopedAllocation alloc; + alloc.attach(compressed, compressedSizeInBytes); + + auto blob = RawBlob::moveCreate(alloc); + *outBlob = blob.detach(); + return SLANG_OK; +} + +SlangResult DeflateCompressionSystemImpl::decompress(const void* compressed, size_t compressedSizeInBytes, size_t decompressedSizeInBytes, void* outDecompressed) +{ + const int flags = TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + + size_t size = tinfl_decompress_mem_to_mem(outDecompressed, decompressedSizeInBytes, compressed ,compressedSizeInBytes, flags); + if (size == TINFL_DECOMPRESS_MEM_TO_MEM_FAILED) + { + return SLANG_FAIL; + } + + return SLANG_OK; +} + +/* static */ICompressionSystem* DeflateCompressionSystem::getSingleton() +{ + static DeflateCompressionSystemImpl impl; + return &impl; +} + +} // namespace Slang |
