#include "NativeRendererSupport.h" #include namespace XCEngine::UI::Editor::Host { using namespace NativeRendererSupport; bool NativeRenderer::DecodeTextureFile( const std::filesystem::path& path, NativeTextureResource& outTexture, std::string& outError) { outError.clear(); if (!EnsureWicFactory(outError)) { return false; } const std::wstring widePath = path.wstring(); Microsoft::WRL::ComPtr decoder; HRESULT hr = m_wicFactory->CreateDecoderFromFilename( widePath.c_str(), nullptr, GENERIC_READ, WICDecodeMetadataCacheOnLoad, decoder.ReleaseAndGetAddressOf()); if (FAILED(hr) || !decoder) { outError = HrToString("IWICImagingFactory::CreateDecoderFromFilename", hr); return false; } Microsoft::WRL::ComPtr frame; hr = decoder->GetFrame(0u, frame.ReleaseAndGetAddressOf()); if (FAILED(hr) || !frame) { outError = HrToString("IWICBitmapDecoder::GetFrame", hr); return false; } return DecodeTextureFrame(*frame.Get(), outTexture, outError); } bool NativeRenderer::DecodeTextureMemory( const std::uint8_t* data, std::size_t size, NativeTextureResource& outTexture, std::string& outError) { outError.clear(); if (data == nullptr || size == 0u) { outError = "DecodeTextureMemory rejected an empty image payload."; return false; } if (size > static_cast((std::numeric_limits::max)())) { outError = "DecodeTextureMemory payload exceeds WIC stream limits."; return false; } if (!EnsureWicFactory(outError)) { return false; } Microsoft::WRL::ComPtr stream; HRESULT hr = m_wicFactory->CreateStream(stream.ReleaseAndGetAddressOf()); if (FAILED(hr) || !stream) { outError = HrToString("IWICImagingFactory::CreateStream", hr); return false; } hr = stream->InitializeFromMemory( const_cast(reinterpret_cast(data)), static_cast(size)); if (FAILED(hr)) { outError = HrToString("IWICStream::InitializeFromMemory", hr); return false; } Microsoft::WRL::ComPtr decoder; hr = m_wicFactory->CreateDecoderFromStream( stream.Get(), nullptr, WICDecodeMetadataCacheOnLoad, decoder.ReleaseAndGetAddressOf()); if (FAILED(hr) || !decoder) { outError = HrToString("IWICImagingFactory::CreateDecoderFromStream", hr); return false; } Microsoft::WRL::ComPtr frame; hr = decoder->GetFrame(0u, frame.ReleaseAndGetAddressOf()); if (FAILED(hr) || !frame) { outError = HrToString("IWICBitmapDecoder::GetFrame", hr); return false; } return DecodeTextureFrame(*frame.Get(), outTexture, outError); } bool NativeRenderer::DecodeTextureFrame( IWICBitmapSource& source, NativeTextureResource& outTexture, std::string& outError) { outError.clear(); Microsoft::WRL::ComPtr converter; HRESULT hr = m_wicFactory->CreateFormatConverter(converter.ReleaseAndGetAddressOf()); if (FAILED(hr) || !converter) { outError = HrToString("IWICImagingFactory::CreateFormatConverter", hr); return false; } hr = converter->Initialize( &source, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0f, WICBitmapPaletteTypeCustom); if (FAILED(hr)) { outError = HrToString("IWICFormatConverter::Initialize", hr); return false; } UINT width = 0u; UINT height = 0u; hr = converter->GetSize(&width, &height); if (FAILED(hr) || width == 0u || height == 0u) { outError = HrToString("IWICBitmapSource::GetSize", hr); return false; } std::vector pixels( static_cast(width) * static_cast(height) * 4u); hr = converter->CopyPixels( nullptr, width * 4u, static_cast(pixels.size()), pixels.data()); if (FAILED(hr)) { outError = HrToString("IWICBitmapSource::CopyPixels", hr); return false; } outTexture.pixels = std::move(pixels); outTexture.width = width; outTexture.height = height; outTexture.cachedBitmap.Reset(); outTexture.cachedTarget = nullptr; return true; } } // namespace XCEngine::UI::Editor::Host