2 * Copyright 2014 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "d2d1_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(d2d
);
24 static inline struct d2d_bitmap
*impl_from_ID2D1Bitmap1(ID2D1Bitmap1
*iface
)
26 return CONTAINING_RECORD(iface
, struct d2d_bitmap
, ID2D1Bitmap1_iface
);
29 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_QueryInterface(ID2D1Bitmap1
*iface
, REFIID iid
, void **out
)
31 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
33 if (IsEqualGUID(iid
, &IID_ID2D1Bitmap1
)
34 || IsEqualGUID(iid
, &IID_ID2D1Bitmap
)
35 || IsEqualGUID(iid
, &IID_ID2D1Image
)
36 || IsEqualGUID(iid
, &IID_ID2D1Resource
)
37 || IsEqualGUID(iid
, &IID_IUnknown
))
39 ID2D1Bitmap1_AddRef(iface
);
44 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
50 static ULONG STDMETHODCALLTYPE
d2d_bitmap_AddRef(ID2D1Bitmap1
*iface
)
52 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
53 ULONG refcount
= InterlockedIncrement(&bitmap
->refcount
);
55 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
60 static ULONG STDMETHODCALLTYPE
d2d_bitmap_Release(ID2D1Bitmap1
*iface
)
62 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
63 ULONG refcount
= InterlockedDecrement(&bitmap
->refcount
);
65 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
70 ID3D10ShaderResourceView_Release(bitmap
->srv
);
72 ID3D10RenderTargetView_Release(bitmap
->rtv
);
74 IDXGISurface_Release(bitmap
->surface
);
75 ID3D10Resource_Release(bitmap
->resource
);
76 ID2D1Factory_Release(bitmap
->factory
);
83 static void STDMETHODCALLTYPE
d2d_bitmap_GetFactory(ID2D1Bitmap1
*iface
, ID2D1Factory
**factory
)
85 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
87 TRACE("iface %p, factory %p.\n", iface
, factory
);
89 ID2D1Factory_AddRef(*factory
= bitmap
->factory
);
92 static D2D1_SIZE_F
* STDMETHODCALLTYPE
d2d_bitmap_GetSize(ID2D1Bitmap1
*iface
, D2D1_SIZE_F
*size
)
94 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
96 TRACE("iface %p, size %p.\n", iface
, size
);
98 size
->width
= bitmap
->pixel_size
.width
/ (bitmap
->dpi_x
/ 96.0f
);
99 size
->height
= bitmap
->pixel_size
.height
/ (bitmap
->dpi_y
/ 96.0f
);
103 static D2D1_SIZE_U
* STDMETHODCALLTYPE
d2d_bitmap_GetPixelSize(ID2D1Bitmap1
*iface
, D2D1_SIZE_U
*pixel_size
)
105 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
107 TRACE("iface %p, pixel_size %p.\n", iface
, pixel_size
);
109 *pixel_size
= bitmap
->pixel_size
;
113 static D2D1_PIXEL_FORMAT
* STDMETHODCALLTYPE
d2d_bitmap_GetPixelFormat(ID2D1Bitmap1
*iface
, D2D1_PIXEL_FORMAT
*format
)
115 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
117 TRACE("iface %p, format %p.\n", iface
, format
);
119 *format
= bitmap
->format
;
123 static void STDMETHODCALLTYPE
d2d_bitmap_GetDpi(ID2D1Bitmap1
*iface
, float *dpi_x
, float *dpi_y
)
125 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
127 TRACE("iface %p, dpi_x %p, dpi_y %p.\n", iface
, dpi_x
, dpi_y
);
129 *dpi_x
= bitmap
->dpi_x
;
130 *dpi_y
= bitmap
->dpi_y
;
133 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_CopyFromBitmap(ID2D1Bitmap1
*iface
,
134 const D2D1_POINT_2U
*dst_point
, ID2D1Bitmap
*bitmap
, const D2D1_RECT_U
*src_rect
)
136 FIXME("iface %p, dst_point %p, bitmap %p, src_rect %p stub!\n", iface
, dst_point
, bitmap
, src_rect
);
141 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_CopyFromRenderTarget(ID2D1Bitmap1
*iface
,
142 const D2D1_POINT_2U
*dst_point
, ID2D1RenderTarget
*render_target
, const D2D1_RECT_U
*src_rect
)
144 FIXME("iface %p, dst_point %p, render_target %p, src_rect %p stub!\n", iface
, dst_point
, render_target
, src_rect
);
149 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_CopyFromMemory(ID2D1Bitmap1
*iface
,
150 const D2D1_RECT_U
*dst_rect
, const void *src_data
, UINT32 pitch
)
152 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
153 ID3D10Device
*device
;
156 TRACE("iface %p, dst_rect %p, src_data %p, pitch %u.\n", iface
, dst_rect
, src_data
, pitch
);
160 box
.left
= dst_rect
->left
;
161 box
.top
= dst_rect
->top
;
163 box
.right
= dst_rect
->right
;
164 box
.bottom
= dst_rect
->bottom
;
168 ID3D10Resource_GetDevice(bitmap
->resource
, &device
);
169 ID3D10Device_UpdateSubresource(device
, bitmap
->resource
, 0, dst_rect
? &box
: NULL
, src_data
, pitch
, 0);
170 ID3D10Device_Release(device
);
175 static void STDMETHODCALLTYPE
d2d_bitmap_GetColorContext(ID2D1Bitmap1
*iface
, ID2D1ColorContext
**context
)
177 FIXME("iface %p, context %p stub!\n", iface
, context
);
180 static D2D1_BITMAP_OPTIONS STDMETHODCALLTYPE
d2d_bitmap_GetOptions(ID2D1Bitmap1
*iface
)
182 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
184 TRACE("iface %p.\n", iface
);
186 return bitmap
->options
;
189 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_GetSurface(ID2D1Bitmap1
*iface
, IDXGISurface
**surface
)
191 struct d2d_bitmap
*bitmap
= impl_from_ID2D1Bitmap1(iface
);
193 TRACE("iface %p, surface %p.\n", iface
, surface
);
195 *surface
= bitmap
->surface
;
197 IDXGISurface_AddRef(*surface
);
199 return *surface
? S_OK
: D2DERR_INVALID_CALL
;
202 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_Map(ID2D1Bitmap1
*iface
, D2D1_MAP_OPTIONS options
,
203 D2D1_MAPPED_RECT
*mapped_rect
)
205 FIXME("iface %p, options %#x, mapped_rect %p stub!\n", iface
, options
, mapped_rect
);
210 static HRESULT STDMETHODCALLTYPE
d2d_bitmap_Unmap(ID2D1Bitmap1
*iface
)
212 FIXME("iface %p stub!\n", iface
);
217 static const struct ID2D1Bitmap1Vtbl d2d_bitmap_vtbl
=
219 d2d_bitmap_QueryInterface
,
222 d2d_bitmap_GetFactory
,
224 d2d_bitmap_GetPixelSize
,
225 d2d_bitmap_GetPixelFormat
,
227 d2d_bitmap_CopyFromBitmap
,
228 d2d_bitmap_CopyFromRenderTarget
,
229 d2d_bitmap_CopyFromMemory
,
230 d2d_bitmap_GetColorContext
,
231 d2d_bitmap_GetOptions
,
232 d2d_bitmap_GetSurface
,
237 static BOOL
format_supported(const D2D1_PIXEL_FORMAT
*format
)
241 static const D2D1_PIXEL_FORMAT supported_formats
[] =
243 {DXGI_FORMAT_R32G32B32A32_FLOAT
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
244 {DXGI_FORMAT_R32G32B32A32_FLOAT
, D2D1_ALPHA_MODE_IGNORE
},
245 {DXGI_FORMAT_R16G16B16A16_FLOAT
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
246 {DXGI_FORMAT_R16G16B16A16_FLOAT
, D2D1_ALPHA_MODE_IGNORE
},
247 {DXGI_FORMAT_R16G16B16A16_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
248 {DXGI_FORMAT_R16G16B16A16_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
249 {DXGI_FORMAT_R8G8B8A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
250 {DXGI_FORMAT_R8G8B8A8_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
251 {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
252 {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_IGNORE
},
253 {DXGI_FORMAT_A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
254 {DXGI_FORMAT_A8_UNORM
, D2D1_ALPHA_MODE_STRAIGHT
},
255 {DXGI_FORMAT_B8G8R8A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
256 {DXGI_FORMAT_B8G8R8A8_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
257 {DXGI_FORMAT_B8G8R8X8_UNORM
, D2D1_ALPHA_MODE_IGNORE
},
258 {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_PREMULTIPLIED
},
259 {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
, D2D1_ALPHA_MODE_IGNORE
},
262 for (i
= 0; i
< ARRAY_SIZE(supported_formats
); ++i
)
264 if (supported_formats
[i
].format
== format
->format
265 && supported_formats
[i
].alphaMode
== format
->alphaMode
)
272 static void d2d_bitmap_init(struct d2d_bitmap
*bitmap
, struct d2d_device_context
*context
,
273 ID3D10Resource
*resource
, D2D1_SIZE_U size
, const D2D1_BITMAP_PROPERTIES1
*desc
)
275 ID3D10Device
*d3d_device
;
278 bitmap
->ID2D1Bitmap1_iface
.lpVtbl
= &d2d_bitmap_vtbl
;
279 bitmap
->refcount
= 1;
280 ID2D1Factory_AddRef(bitmap
->factory
= context
->factory
);
281 ID3D10Resource_AddRef(bitmap
->resource
= resource
);
282 bitmap
->pixel_size
= size
;
283 bitmap
->format
= desc
->pixelFormat
;
284 bitmap
->dpi_x
= desc
->dpiX
;
285 bitmap
->dpi_y
= desc
->dpiY
;
286 bitmap
->options
= desc
->bitmapOptions
;
288 if (d2d_device_context_is_dxgi_target(context
))
289 ID3D10Resource_QueryInterface(resource
, &IID_IDXGISurface
, (void **)&bitmap
->surface
);
291 ID3D10Resource_GetDevice(resource
, &d3d_device
);
292 if (bitmap
->options
& D2D1_BITMAP_OPTIONS_TARGET
)
294 if (FAILED(hr
= ID3D10Device_CreateRenderTargetView(d3d_device
, resource
, NULL
, &bitmap
->rtv
)))
295 WARN("Failed to create RTV, hr %#x.\n", hr
);
298 if (!(bitmap
->options
& D2D1_BITMAP_OPTIONS_CANNOT_DRAW
))
300 if (FAILED(hr
= ID3D10Device_CreateShaderResourceView(d3d_device
, resource
, NULL
, &bitmap
->srv
)))
301 WARN("Failed to create SRV, hr %#x.\n", hr
);
303 ID3D10Device_Release(d3d_device
);
305 if (bitmap
->dpi_x
== 0.0f
&& bitmap
->dpi_y
== 0.0f
)
307 bitmap
->dpi_x
= 96.0f
;
308 bitmap
->dpi_y
= 96.0f
;
312 HRESULT
d2d_bitmap_create(struct d2d_device_context
*context
, D2D1_SIZE_U size
, const void *src_data
,
313 UINT32 pitch
, const D2D1_BITMAP_PROPERTIES1
*desc
, struct d2d_bitmap
**bitmap
)
315 D3D10_SUBRESOURCE_DATA resource_data
;
316 D2D1_BITMAP_PROPERTIES1 bitmap_desc
;
317 D3D10_TEXTURE2D_DESC texture_desc
;
318 ID3D10Texture2D
*texture
;
321 if (!format_supported(&desc
->pixelFormat
))
323 WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n",
324 desc
->pixelFormat
.format
, desc
->pixelFormat
.alphaMode
);
325 return D2DERR_UNSUPPORTED_PIXEL_FORMAT
;
328 if (desc
->dpiX
== 0.0f
&& desc
->dpiY
== 0.0f
)
331 bitmap_desc
.dpiX
= context
->desc
.dpiX
;
332 bitmap_desc
.dpiY
= context
->desc
.dpiY
;
335 else if (desc
->dpiX
<= 0.0f
|| desc
->dpiY
<= 0.0f
)
340 texture_desc
.Width
= size
.width
;
341 texture_desc
.Height
= size
.height
;
342 if (!texture_desc
.Width
|| !texture_desc
.Height
)
343 texture_desc
.Width
= texture_desc
.Height
= 1;
344 texture_desc
.MipLevels
= 1;
345 texture_desc
.ArraySize
= 1;
346 texture_desc
.Format
= desc
->pixelFormat
.format
;
347 texture_desc
.SampleDesc
.Count
= 1;
348 texture_desc
.SampleDesc
.Quality
= 0;
349 texture_desc
.Usage
= D3D10_USAGE_DEFAULT
;
350 texture_desc
.BindFlags
= 0;
351 if (desc
->bitmapOptions
& D2D1_BITMAP_OPTIONS_TARGET
)
352 texture_desc
.BindFlags
|= D3D10_BIND_RENDER_TARGET
;
353 if (!(desc
->bitmapOptions
& D2D1_BITMAP_OPTIONS_CANNOT_DRAW
))
354 texture_desc
.BindFlags
|= D3D10_BIND_SHADER_RESOURCE
;
355 texture_desc
.CPUAccessFlags
= 0;
356 texture_desc
.MiscFlags
= 0;
357 if (desc
->bitmapOptions
& D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE
)
358 texture_desc
.MiscFlags
|= D3D10_RESOURCE_MISC_GDI_COMPATIBLE
;
360 resource_data
.pSysMem
= src_data
;
361 resource_data
.SysMemPitch
= pitch
;
363 if (FAILED(hr
= ID3D10Device_CreateTexture2D(context
->d3d_device
, &texture_desc
,
364 src_data
? &resource_data
: NULL
, &texture
)))
366 ERR("Failed to create texture, hr %#x.\n", hr
);
370 if ((*bitmap
= heap_alloc_zero(sizeof(**bitmap
))))
372 d2d_bitmap_init(*bitmap
, context
, (ID3D10Resource
*)texture
, size
, desc
);
373 TRACE("Created bitmap %p.\n", *bitmap
);
375 ID3D10Texture2D_Release(texture
);
377 return *bitmap
? S_OK
: E_OUTOFMEMORY
;
380 HRESULT
d2d_bitmap_create_shared(struct d2d_device_context
*context
, REFIID iid
, void *data
,
381 const D2D1_BITMAP_PROPERTIES1
*desc
, struct d2d_bitmap
**bitmap
)
383 D2D1_BITMAP_PROPERTIES1 d
;
385 if (IsEqualGUID(iid
, &IID_ID2D1Bitmap
))
387 struct d2d_bitmap
*src_impl
= unsafe_impl_from_ID2D1Bitmap(data
);
388 ID3D10Device
*device
;
391 if (src_impl
->factory
!= context
->factory
)
393 hr
= D2DERR_WRONG_FACTORY
;
397 ID3D10Resource_GetDevice(src_impl
->resource
, &device
);
398 ID3D10Device_Release(device
);
399 if (device
!= context
->d3d_device
)
401 hr
= D2DERR_UNSUPPORTED_OPERATION
;
407 d
.pixelFormat
= src_impl
->format
;
408 d
.dpiX
= src_impl
->dpi_x
;
409 d
.dpiY
= src_impl
->dpi_y
;
410 d
.bitmapOptions
= src_impl
->options
;
411 d
.colorContext
= NULL
;
415 if (!format_supported(&desc
->pixelFormat
))
417 WARN("Tried to create bitmap with unsupported format {%#x / %#x}.\n",
418 desc
->pixelFormat
.format
, desc
->pixelFormat
.alphaMode
);
419 hr
= D2DERR_UNSUPPORTED_PIXEL_FORMAT
;
423 if (!(*bitmap
= heap_alloc_zero(sizeof(**bitmap
))))
429 d2d_bitmap_init(*bitmap
, context
, src_impl
->resource
, src_impl
->pixel_size
, desc
);
430 TRACE("Created bitmap %p.\n", *bitmap
);
436 if (IsEqualGUID(iid
, &IID_IDXGISurface
) || IsEqualGUID(iid
, &IID_IDXGISurface1
))
438 DXGI_SURFACE_DESC surface_desc
;
439 IDXGISurface
*surface
= data
;
440 ID3D10Resource
*resource
;
441 D2D1_SIZE_U pixel_size
;
442 ID3D10Device
*device
;
445 if (FAILED(IDXGISurface_QueryInterface(surface
, &IID_ID3D10Resource
, (void **)&resource
)))
447 WARN("Failed to get d3d resource from dxgi surface.\n");
451 ID3D10Resource_GetDevice(resource
, &device
);
452 ID3D10Device_Release(device
);
453 if (device
!= context
->d3d_device
)
455 ID3D10Resource_Release(resource
);
456 return D2DERR_UNSUPPORTED_OPERATION
;
459 if (!(*bitmap
= heap_alloc_zero(sizeof(**bitmap
))))
461 ID3D10Resource_Release(resource
);
462 return E_OUTOFMEMORY
;
466 if (FAILED(hr
= IDXGISurface_GetDesc(surface
, &surface_desc
)))
468 WARN("Failed to get surface desc, hr %#x.\n", hr
);
469 ID3D10Resource_Release(resource
);
475 memset(&d
, 0, sizeof(d
));
476 d
.pixelFormat
.format
= surface_desc
.Format
;
481 if (d
.pixelFormat
.format
== DXGI_FORMAT_UNKNOWN
)
482 d
.pixelFormat
.format
= surface_desc
.Format
;
485 if (d
.dpiX
== 0.0f
|| d
.dpiY
== 0.0f
)
488 d
.dpiX
= context
->desc
.dpiX
;
490 d
.dpiY
= context
->desc
.dpiY
;
493 pixel_size
.width
= surface_desc
.Width
;
494 pixel_size
.height
= surface_desc
.Height
;
496 d2d_bitmap_init(*bitmap
, context
, resource
, pixel_size
, &d
);
497 ID3D10Resource_Release(resource
);
498 TRACE("Created bitmap %p.\n", *bitmap
);
503 WARN("Unhandled interface %s.\n", debugstr_guid(iid
));
508 HRESULT
d2d_bitmap_create_from_wic_bitmap(struct d2d_device_context
*context
, IWICBitmapSource
*bitmap_source
,
509 const D2D1_BITMAP_PROPERTIES1
*desc
, struct d2d_bitmap
**bitmap
)
511 const D2D1_PIXEL_FORMAT
*d2d_format
;
512 D2D1_BITMAP_PROPERTIES1 bitmap_desc
;
513 WICPixelFormatGUID wic_format
;
514 unsigned int bpp
, data_size
;
524 const WICPixelFormatGUID
*wic
;
525 D2D1_PIXEL_FORMAT d2d
;
529 {&GUID_WICPixelFormat32bppPBGRA
, {DXGI_FORMAT_B8G8R8A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
}},
530 {&GUID_WICPixelFormat32bppPRGBA
, {DXGI_FORMAT_R8G8B8A8_UNORM
, D2D1_ALPHA_MODE_PREMULTIPLIED
}},
531 {&GUID_WICPixelFormat32bppBGR
, {DXGI_FORMAT_B8G8R8A8_UNORM
, D2D1_ALPHA_MODE_IGNORE
}},
534 if (FAILED(hr
= IWICBitmapSource_GetSize(bitmap_source
, &size
.width
, &size
.height
)))
536 WARN("Failed to get bitmap size, hr %#x.\n", hr
);
542 bitmap_desc
.pixelFormat
.format
= DXGI_FORMAT_UNKNOWN
;
543 bitmap_desc
.pixelFormat
.alphaMode
= D2D1_ALPHA_MODE_UNKNOWN
;
544 bitmap_desc
.dpiX
= 0.0f
;
545 bitmap_desc
.dpiY
= 0.0f
;
546 bitmap_desc
.bitmapOptions
= 0;
547 bitmap_desc
.colorContext
= NULL
;
554 if (FAILED(hr
= IWICBitmapSource_GetPixelFormat(bitmap_source
, &wic_format
)))
556 WARN("Failed to get bitmap format, hr %#x.\n", hr
);
560 for (i
= 0, d2d_format
= NULL
; i
< ARRAY_SIZE(format_lookup
); ++i
)
562 if (IsEqualGUID(&wic_format
, format_lookup
[i
].wic
))
564 d2d_format
= &format_lookup
[i
].d2d
;
571 WARN("Unsupported WIC bitmap format %s.\n", debugstr_guid(&wic_format
));
572 return D2DERR_UNSUPPORTED_PIXEL_FORMAT
;
575 if (bitmap_desc
.pixelFormat
.format
== DXGI_FORMAT_UNKNOWN
)
576 bitmap_desc
.pixelFormat
.format
= d2d_format
->format
;
577 if (bitmap_desc
.pixelFormat
.alphaMode
== D2D1_ALPHA_MODE_UNKNOWN
)
578 bitmap_desc
.pixelFormat
.alphaMode
= d2d_format
->alphaMode
;
580 switch (bitmap_desc
.pixelFormat
.format
)
582 case DXGI_FORMAT_B8G8R8A8_UNORM
:
583 case DXGI_FORMAT_R8G8B8A8_UNORM
:
588 FIXME("Unhandled format %#x.\n", bitmap_desc
.pixelFormat
.format
);
589 return D2DERR_UNSUPPORTED_PIXEL_FORMAT
;
592 pitch
= ((bpp
* size
.width
) + 15) & ~15;
593 if (pitch
/ bpp
< size
.width
)
594 return E_OUTOFMEMORY
;
595 if (!(data
= heap_calloc(size
.height
, pitch
)))
596 return E_OUTOFMEMORY
;
597 data_size
= size
.height
* pitch
;
601 rect
.Width
= size
.width
;
602 rect
.Height
= size
.height
;
603 if (FAILED(hr
= IWICBitmapSource_CopyPixels(bitmap_source
, &rect
, pitch
, data_size
, data
)))
605 WARN("Failed to copy bitmap pixels, hr %#x.\n", hr
);
610 hr
= d2d_bitmap_create(context
, size
, data
, pitch
, &bitmap_desc
, bitmap
);
617 struct d2d_bitmap
*unsafe_impl_from_ID2D1Bitmap(ID2D1Bitmap
*iface
)
621 assert(iface
->lpVtbl
== (ID2D1BitmapVtbl
*)&d2d_bitmap_vtbl
);
622 return CONTAINING_RECORD(iface
, struct d2d_bitmap
, ID2D1Bitmap1_iface
);