// SPDX-License-Identifier: GPL-3.0-or-later // WarcraftXL 1.1 BLP transform extension. #include "engine/assets/shared/textures/blp/BlpTranscode.hpp" #include "wxl/ModernBlpApi.h" #include "wxl/PluginApi.h" #include "wxl/StorageApi.h" #include #include #include #include namespace { const WXL_Api* g_api = nullptr; constexpr uint32_t kMaxTextureEdge = 1024; int __cdecl Transcode(const char* name, const uint8_t* raw, uint32_t rawLen, const WXL_ByteSink* sink) { if (!raw || !sink || !sink->Write) return 0; namespace blp = wxl::modern::assets::textures::blp; const std::span input(raw, rawLen); std::vector capped; const bool didCap = blp::CapBlpMips(input, capped, kMaxTextureEdge); const std::span source = didCap ? std::span(capped.data(), capped.size()) : input; std::vector transcoded; if (blp::TranscodeBlp(source, transcoded)) { sink->Write(sink->ctx, transcoded.data(), static_cast(transcoded.size())); if (g_api && g_api->Log) g_api->Log(WXL_LOG_DEBUG, "wxl-modern-blp", "%s%s BGRA->DXT5", name ? name : "?", didCap ? " capped" : ""); return 1; } if (!didCap) return 0; sink->Write(sink->ctx, capped.data(), static_cast(capped.size())); return 1; } const WXL_ModernBlpApi g_blpApi = { sizeof(WXL_ModernBlpApi), WXL_MODERN_BLP_API_VERSION, &Transcode, }; } const WXL_PluginInfo* __cdecl WXL_Query(void) { static const WXL_PluginInfo info = { sizeof(WXL_PluginInfo), WXL_API_VERSION, "wxl-modern-blp", 1, WXL_CLIENT_BUILD, }; return &info; } int __cdecl WXL_Load(const WXL_Api* api) { if (!api || api->apiVersion != WXL_API_VERSION) return 0; g_api = api; auto* storage = static_cast( api->GetInterface("wxl.storage", WXL_STORAGE_API_VERSION)); if (!storage || storage->apiVersion != WXL_STORAGE_API_VERSION || !storage->RegisterClientTransform) { api->Log(WXL_LOG_ERROR, "wxl-modern-blp", "wxl.storage v1 is unavailable"); return 0; } storage->RegisterClientTransform(".blp", &Transcode); api->PublishInterface("wxl.modern-blp", WXL_MODERN_BLP_API_VERSION, const_cast(&g_blpApi)); api->Log(WXL_LOG_INFO, "wxl-modern-blp", "BLP transcode and mip cap active"); return 1; }