From: Zhiyi Zhang zzhang@codeweavers.com
--- dlls/d2d1/wic_render_target.c | 94 ++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 8 deletions(-)
diff --git a/dlls/d2d1/wic_render_target.c b/dlls/d2d1/wic_render_target.c index f6e7b14ed3f..618766ab52b 100644 --- a/dlls/d2d1/wic_render_target.c +++ b/dlls/d2d1/wic_render_target.c @@ -149,15 +149,101 @@ static const struct d2d_device_context_ops d2d_wic_render_target_ops = d2d_wic_render_target_present, };
+static HRESULT check_invalid_formats(const WICPixelFormatGUID *bitmap_format, + const D2D1_PIXEL_FORMAT *pixel_format) +{ + unsigned int i; + + static const struct + { + const WICPixelFormatGUID *wic_format; + D2D1_PIXEL_FORMAT pixel_format; + } + supported_formats[] = + { + {&GUID_WICPixelFormat8bppAlpha, {DXGI_FORMAT_A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat8bppAlpha, {DXGI_FORMAT_A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT}}, + {&GUID_WICPixelFormat32bppBGR, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE}}, + {&GUID_WICPixelFormat32bppBGR, {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D2D1_ALPHA_MODE_IGNORE}}, + {&GUID_WICPixelFormat32bppPBGRA, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat32bppPBGRA, {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat32bppRGB, {DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_IGNORE}}, + {&GUID_WICPixelFormat32bppRGB, {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D2D1_ALPHA_MODE_IGNORE}}, + {&GUID_WICPixelFormat32bppPRGBA, {DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat32bppPRGBA, {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat64bppRGB, {DXGI_FORMAT_R16G16B16A16_UNORM, D2D1_ALPHA_MODE_IGNORE}}, + {&GUID_WICPixelFormat64bppPRGBA, {DXGI_FORMAT_R16G16B16A16_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat128bppPRGBAFloat, {DXGI_FORMAT_R32G32B32A32_FLOAT, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat128bppRGBFloat, {DXGI_FORMAT_R32G32B32A32_FLOAT, D2D1_ALPHA_MODE_IGNORE}}, + {&GUID_WICPixelFormat64bppPRGBAHalf, {DXGI_FORMAT_R16G16B16A16_FLOAT, D2D1_ALPHA_MODE_PREMULTIPLIED}}, + {&GUID_WICPixelFormat64bppRGBHalf, {DXGI_FORMAT_R16G16B16A16_FLOAT, D2D1_ALPHA_MODE_IGNORE}}, + }; + + for (i = 0; i < ARRAY_SIZE(supported_formats); ++i) + { + if (IsEqualGUID(bitmap_format, supported_formats[i].wic_format) + && (pixel_format->format == DXGI_FORMAT_UNKNOWN + || pixel_format->format == supported_formats[i].pixel_format.format) + && (pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || pixel_format->alphaMode == supported_formats[i].pixel_format.alphaMode)) + return TRUE; + } + + if (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat8bppAlpha) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppBGR) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppPBGRA) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppRGB) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppPRGBA) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat64bppRGB) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat64bppPRGBA) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat128bppPRGBAFloat) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat128bppRGBFloat) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat64bppPRGBAHalf) + || IsEqualGUID(bitmap_format, &GUID_WICPixelFormat64bppRGBHalf) + || (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat32bppRGBA1010102) + && !((pixel_format->format == DXGI_FORMAT_UNKNOWN + || pixel_format->format == DXGI_FORMAT_R10G10B10A2_UNORM) + && (pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || pixel_format->alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED))) + || (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat8bppY) + && !((pixel_format->format == DXGI_FORMAT_UNKNOWN + || pixel_format->format == DXGI_FORMAT_R8_UNORM) + && (pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || pixel_format->alphaMode == D2D1_ALPHA_MODE_IGNORE))) + || (IsEqualGUID(bitmap_format, &GUID_WICPixelFormat16bppCbCr) + && !((pixel_format->format == DXGI_FORMAT_UNKNOWN + || pixel_format->format == DXGI_FORMAT_R8G8_UNORM) + && (pixel_format->alphaMode == D2D1_ALPHA_MODE_UNKNOWN + || pixel_format->alphaMode == D2D1_ALPHA_MODE_IGNORE)))) + return E_INVALIDARG; + + return D2DERR_UNSUPPORTED_PIXEL_FORMAT; +} + HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, ID2D1Factory1 *factory, ID3D10Device1 *d3d_device, IWICBitmap *bitmap, const D2D1_RENDER_TARGET_PROPERTIES *desc) { D3D10_TEXTURE2D_DESC texture_desc; + WICPixelFormatGUID bitmap_format; ID3D10Texture2D *texture; IDXGIDevice *dxgi_device; ID2D1Device *device; HRESULT hr;
+ if (FAILED(hr = IWICBitmap_GetPixelFormat(bitmap, &bitmap_format))) + { + WARN("Failed to get bitmap format, hr %#lx.\n", hr); + return hr; + } + + if (FAILED(hr = check_invalid_formats(&bitmap_format, &desc->pixelFormat))) + { + WARN("Invalid WIC bitmap format %s pixel format %#x alpha %u.\n", + debugstr_guid(&bitmap_format), desc->pixelFormat.format, + desc->pixelFormat.alphaMode); + return hr; + } + render_target->IUnknown_iface.lpVtbl = &d2d_wic_render_target_vtbl;
if (FAILED(hr = IWICBitmap_GetSize(bitmap, &render_target->width, &render_target->height))) @@ -174,14 +260,6 @@ HRESULT d2d_wic_render_target_init(struct d2d_wic_render_target *render_target, texture_desc.Format = desc->pixelFormat.format; if (texture_desc.Format == DXGI_FORMAT_UNKNOWN) { - WICPixelFormatGUID bitmap_format; - - if (FAILED(hr = IWICBitmap_GetPixelFormat(bitmap, &bitmap_format))) - { - WARN("Failed to get bitmap format, hr %#lx.\n", hr); - return hr; - } - if (IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppPBGRA) || IsEqualGUID(&bitmap_format, &GUID_WICPixelFormat32bppBGR)) {