aboutsummaryrefslogtreecommitdiff
path: root/src/win/graphics/direct/ImageFactory.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-05-15 13:56:40 +0800
committercrupest <crupest@outlook.com>2022-05-15 13:56:40 +0800
commit9e0c9d3499bc50c3534b4dc500d8b5d0b5f22752 (patch)
tree7342f6991771fa31b16fd6a5ed892ff6025f3d05 /src/win/graphics/direct/ImageFactory.cpp
parent41de54bad2c0f857821fcc83f41af3334d068b6d (diff)
downloadcru-9e0c9d3499bc50c3534b4dc500d8b5d0b5f22752.tar.gz
cru-9e0c9d3499bc50c3534b4dc500d8b5d0b5f22752.tar.bz2
cru-9e0c9d3499bc50c3534b4dc500d8b5d0b5f22752.zip
...
Diffstat (limited to 'src/win/graphics/direct/ImageFactory.cpp')
-rw-r--r--src/win/graphics/direct/ImageFactory.cpp159
1 files changed, 0 insertions, 159 deletions
diff --git a/src/win/graphics/direct/ImageFactory.cpp b/src/win/graphics/direct/ImageFactory.cpp
deleted file mode 100644
index 0e8eb1b6..00000000
--- a/src/win/graphics/direct/ImageFactory.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-#include "cru/win/graphics/direct/ImageFactory.h"
-#include "cru/common/platform/win/Exception.h"
-#include "cru/common/platform/win/StreamConvert.h"
-#include "cru/platform/Check.h"
-#include "cru/win/graphics/direct/Exception.h"
-#include "cru/win/graphics/direct/Factory.h"
-#include "cru/win/graphics/direct/Image.h"
-
-#include <d2d1_1.h>
-#include <d2d1_1helper.h>
-#include <wincodec.h>
-#include <wrl/client.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) {
- auto graphics_factory = GetDirectFactory();
-
- HRESULT hr;
-
- Microsoft::WRL::ComPtr<IStream> com_stream(
- platform::win::ConvertStreamToComStream(stream));
-
- Microsoft::WRL::ComPtr<IWICBitmapDecoder> wic_bitmap_decoder;
- hr = wic_imaging_factory_->CreateDecoderFromStream(
- com_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();
-
- Microsoft::WRL::ComPtr<ID2D1Bitmap1> d2d_image;
- d2d_context->CreateBitmapFromWicBitmap(
- wic_bitmap_frame_decode.Get(),
- D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET,
- D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
- D2D1_ALPHA_MODE_PREMULTIPLIED)),
- &d2d_image);
-
- return std::make_unique<Direct2DImage>(graphics_factory,
- std::move(d2d_image));
-}
-
-GUID ConvertImageFormatToGUID(ImageFormat format) {
- GUID format_guid;
- switch (format) {
- case ImageFormat::Png:
- format_guid = GUID_ContainerFormatPng;
- break;
- case ImageFormat::Jpeg:
- format_guid = GUID_ContainerFormatJpeg;
- break;
- case ImageFormat::Gif:
- format_guid = GUID_ContainerFormatGif;
- break;
- default:
- throw Exception(u"Unknown image format");
- }
- return format_guid;
-}
-
-void WinImageFactory::EncodeToStream(IImage* image, io::Stream* stream,
- ImageFormat format, float quality) {
- auto direct_image = CheckPlatform<Direct2DImage>(image, GetPlatformId());
-
- Microsoft::WRL::ComPtr<IStream> com_stream(
- platform::win::ConvertStreamToComStream(stream));
-
- auto d2d_bitmap = direct_image->GetD2DBitmap();
- auto size = d2d_bitmap->GetPixelSize();
- FLOAT dpi_x, dpi_y;
- d2d_bitmap->GetDpi(&dpi_x, &dpi_y);
- auto pixel_format = d2d_bitmap->GetPixelFormat();
- Ensures(pixel_format.format == DXGI_FORMAT_B8G8R8A8_UNORM);
- Ensures(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED);
-
- Microsoft::WRL::ComPtr<ID2D1Bitmap1> cpu_bitmap;
- ThrowIfFailed(GetDirectFactory()->GetDefaultD2D1DeviceContext()->CreateBitmap(
- size, nullptr, 0,
- D2D1::BitmapProperties1(
- D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ,
- pixel_format, dpi_x, dpi_y),
- &cpu_bitmap));
-
- ThrowIfFailed(cpu_bitmap->CopyFromBitmap(nullptr, d2d_bitmap.Get(), nullptr));
-
- D2D1_MAPPED_RECT mapped_rect;
- ThrowIfFailed(cpu_bitmap->Map(D2D1_MAP_OPTIONS_READ, &mapped_rect));
-
- Microsoft::WRL::ComPtr<IWICBitmap> wic_bitmap;
- ThrowIfFailed(wic_imaging_factory_->CreateBitmapFromMemory(
- size.width, size.height, GUID_WICPixelFormat32bppPBGRA, mapped_rect.pitch,
- mapped_rect.pitch * size.height, mapped_rect.bits, &wic_bitmap));
-
- ThrowIfFailed(cpu_bitmap->Unmap());
-
- Microsoft::WRL::ComPtr<IWICBitmapEncoder> wic_bitmap_encoder;
-
- ThrowIfFailed(wic_imaging_factory_->CreateEncoder(
- ConvertImageFormatToGUID(format), nullptr, &wic_bitmap_encoder));
-
- ThrowIfFailed(wic_bitmap_encoder->Initialize(com_stream.Get(),
- WICBitmapEncoderNoCache));
-
- Microsoft::WRL::ComPtr<IWICBitmapFrameEncode> wic_bitmap_frame_encode;
- Microsoft::WRL::ComPtr<IPropertyBag2> property_bag;
- ThrowIfFailed(wic_bitmap_encoder->CreateNewFrame(&wic_bitmap_frame_encode,
- &property_bag));
-
- if (format == ImageFormat::Jpeg) {
- PROPBAG2 option = {0};
- option.pstrName = const_cast<wchar_t*>(L"ImageQuality");
- VARIANT varValue;
- VariantInit(&varValue);
- varValue.vt = VT_R4;
- varValue.fltVal = quality;
- ThrowIfFailed(property_bag->Write(1, &option, &varValue));
- }
-
- ThrowIfFailed(wic_bitmap_frame_encode->Initialize(property_bag.Get()));
- ThrowIfFailed(wic_bitmap_frame_encode->SetResolution(dpi_x, dpi_y));
- ThrowIfFailed(wic_bitmap_frame_encode->WriteSource(wic_bitmap.Get(), NULL));
- ThrowIfFailed(wic_bitmap_frame_encode->Commit());
-
- ThrowIfFailed(wic_bitmap_encoder->Commit());
-}
-
-std::unique_ptr<IImage> WinImageFactory::CreateBitmap(int width, int height) {
- if (width <= 0) throw Exception(u"Bitmap width must be greater than 0.");
- if (height <= 0) throw Exception(u"Bitmap height must be greater than 0.");
-
- auto graphics_factory = GetDirectFactory();
-
- Microsoft::WRL::ComPtr<ID2D1Bitmap1> bitmap;
-
- auto d2d_context = graphics_factory->GetDefaultD2D1DeviceContext();
- ThrowIfFailed(d2d_context->CreateBitmap(
- D2D1::SizeU(width, height), nullptr, 0,
- D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET,
- D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
- D2D1_ALPHA_MODE_PREMULTIPLIED)),
- &bitmap));
-
- return std::make_unique<Direct2DImage>(graphics_factory, std::move(bitmap));
-}
-} // namespace cru::platform::graphics::win::direct