aboutsummaryrefslogtreecommitdiff
path: root/src/win/graphics/direct/ImageFactory.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-02-01 18:49:55 +0800
committercrupest <crupest@outlook.com>2022-02-01 18:49:55 +0800
commitd1c14725443399f7145e314d79597ec35b639eeb (patch)
tree50c6743d6766cdc6fd04921d305380143b42d3dc /src/win/graphics/direct/ImageFactory.cpp
parentb9a553d4acc15ec981636b30db537be280d593e5 (diff)
downloadcru-d1c14725443399f7145e314d79597ec35b639eeb.tar.gz
cru-d1c14725443399f7145e314d79597ec35b639eeb.tar.bz2
cru-d1c14725443399f7145e314d79597ec35b639eeb.zip
...
Diffstat (limited to 'src/win/graphics/direct/ImageFactory.cpp')
-rw-r--r--src/win/graphics/direct/ImageFactory.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/win/graphics/direct/ImageFactory.cpp b/src/win/graphics/direct/ImageFactory.cpp
new file mode 100644
index 00000000..dc43a9b9
--- /dev/null
+++ b/src/win/graphics/direct/ImageFactory.cpp
@@ -0,0 +1,52 @@
+#include "cru/win/graphics/direct/ImageFactory.hpp"
+#include "cru/win/graphics/direct/Exception.hpp"
+#include "cru/win/graphics/direct/Factory.hpp"
+#include "cru/win/graphics/direct/Image.hpp"
+
+#include <wincodec.h>
+
+namespace cru::platform::graphics::win::direct {
+WinImageFactory::WinImageFactory(DirectGraphicsFactory* graphics_factory)
+ : DirectGraphicsResource(graphics_factory) {
+ HRESULT hr =
+ CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
+ IID_PPV_ARGS(&wic_imaging_factory_));
+ ThrowIfFailed(hr);
+}
+
+WinImageFactory::~WinImageFactory() {}
+
+std::unique_ptr<IImage> WinImageFactory::DecodeFromStream(io::Stream* stream) {
+ // TODO: The correct way to do this is to implement a IStream wrapper.
+
+ auto buffer = stream->ReadAll();
+
+ HRESULT hr;
+
+ Microsoft::WRL::ComPtr<IWICStream> wic_stream;
+ hr = wic_imaging_factory_->CreateStream(&wic_stream);
+ ThrowIfFailed(hr);
+
+ hr = wic_stream->InitializeFromMemory(
+ reinterpret_cast<unsigned char*>(buffer.data()), buffer.size());
+ ThrowIfFailed(hr);
+
+ Microsoft::WRL::ComPtr<IWICBitmapDecoder> wic_bitmap_decoder;
+ hr = wic_imaging_factory_->CreateDecoderFromStream(
+ wic_stream.Get(), NULL, WICDecodeMetadataCacheOnDemand,
+ &wic_bitmap_decoder);
+ ThrowIfFailed(hr);
+
+ Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> wic_bitmap_frame_decode;
+ hr = wic_bitmap_decoder->GetFrame(0, &wic_bitmap_frame_decode);
+ ThrowIfFailed(hr);
+
+ auto d2d_context = graphics_factory_->GetDefaultD2D1DeviceContext();
+
+ ID2D1Bitmap* d2d_image;
+ d2d_context->CreateBitmapFromWicBitmap(wic_bitmap_frame_decode.Get(), NULL,
+ &d2d_image);
+
+ return std::make_unique<Direct2DImage>(graphics_factory_, d2d_image, true);
+}
+} // namespace cru::platform::graphics::win::direct