2 * Copyright 2012 Vincent Povirk 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 "wincodecs_private.h"
21 /* WARNING: .NET Media Integration Layer (MIL) directly dereferences
22 * BitmapImpl members and depends on its exact layout.
24 typedef struct BitmapImpl
{
25 IMILUnknown1 IMILUnknown1_iface
;
27 IMILBitmapSource IMILBitmapSource_iface
;
28 IWICBitmap IWICBitmap_iface
;
29 IMILUnknown2 IMILUnknown2_iface
;
32 LONG lock
; /* 0 if not locked, -1 if locked for writing, count if locked for reading */
34 BOOL is_section
; /* TRUE if data is a section created by an application */
38 WICPixelFormatGUID pixelformat
;
43 typedef struct BitmapLockImpl
{
44 IWICBitmapLock IWICBitmapLock_iface
;
51 static inline BitmapImpl
*impl_from_IWICBitmap(IWICBitmap
*iface
)
53 return CONTAINING_RECORD(iface
, BitmapImpl
, IWICBitmap_iface
);
56 static inline BitmapImpl
*impl_from_IMILBitmapSource(IMILBitmapSource
*iface
)
58 return CONTAINING_RECORD(iface
, BitmapImpl
, IMILBitmapSource_iface
);
61 static inline BitmapImpl
*impl_from_IMILUnknown1(IMILUnknown1
*iface
)
63 return CONTAINING_RECORD(iface
, BitmapImpl
, IMILUnknown1_iface
);
67 /* This is currently unused */
68 static inline BitmapImpl
*impl_from_IMILUnknown2(IMILUnknown2
*iface
)
70 return CONTAINING_RECORD(iface
, BitmapImpl
, IMILUnknown2_iface
);
74 static inline BitmapLockImpl
*impl_from_IWICBitmapLock(IWICBitmapLock
*iface
)
76 return CONTAINING_RECORD(iface
, BitmapLockImpl
, IWICBitmapLock_iface
);
79 static BOOL
BitmapImpl_AcquireLock(BitmapImpl
*This
, int write
)
83 return 0 == InterlockedCompareExchange(&This
->lock
, -1, 0);
89 LONG prev_val
= This
->lock
;
92 if (prev_val
== InterlockedCompareExchange(&This
->lock
, prev_val
+1, prev_val
))
98 static void BitmapImpl_ReleaseLock(BitmapImpl
*This
)
102 LONG prev_val
= This
->lock
, new_val
;
106 new_val
= prev_val
- 1;
107 if (prev_val
== InterlockedCompareExchange(&This
->lock
, new_val
, prev_val
))
113 static HRESULT WINAPI
BitmapLockImpl_QueryInterface(IWICBitmapLock
*iface
, REFIID iid
,
116 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
117 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
119 if (!ppv
) return E_INVALIDARG
;
121 if (IsEqualIID(&IID_IUnknown
, iid
) ||
122 IsEqualIID(&IID_IWICBitmapLock
, iid
))
124 *ppv
= &This
->IWICBitmapLock_iface
;
128 FIXME("unknown interface %s\n", debugstr_guid(iid
));
130 return E_NOINTERFACE
;
133 IUnknown_AddRef((IUnknown
*)*ppv
);
137 static ULONG WINAPI
BitmapLockImpl_AddRef(IWICBitmapLock
*iface
)
139 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
140 ULONG ref
= InterlockedIncrement(&This
->ref
);
142 TRACE("(%p) refcount=%u\n", iface
, ref
);
147 static ULONG WINAPI
BitmapLockImpl_Release(IWICBitmapLock
*iface
)
149 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
150 ULONG ref
= InterlockedDecrement(&This
->ref
);
152 TRACE("(%p) refcount=%u\n", iface
, ref
);
156 BitmapImpl_ReleaseLock(This
->parent
);
157 IWICBitmap_Release(&This
->parent
->IWICBitmap_iface
);
158 HeapFree(GetProcessHeap(), 0, This
);
164 static HRESULT WINAPI
BitmapLockImpl_GetSize(IWICBitmapLock
*iface
,
165 UINT
*puiWidth
, UINT
*puiHeight
)
167 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
168 TRACE("(%p,%p,%p)\n", iface
, puiWidth
, puiHeight
);
170 if (!puiWidth
|| !puiHeight
)
173 *puiWidth
= This
->width
;
174 *puiHeight
= This
->height
;
179 static HRESULT WINAPI
BitmapLockImpl_GetStride(IWICBitmapLock
*iface
,
182 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
183 TRACE("(%p,%p)\n", iface
, pcbStride
);
188 *pcbStride
= This
->parent
->stride
;
193 static HRESULT WINAPI
BitmapLockImpl_GetDataPointer(IWICBitmapLock
*iface
,
194 UINT
*pcbBufferSize
, BYTE
**ppbData
)
196 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
197 TRACE("(%p,%p,%p)\n", iface
, pcbBufferSize
, ppbData
);
199 if (!pcbBufferSize
|| !ppbData
)
202 *pcbBufferSize
= This
->parent
->stride
* (This
->height
- 1) +
203 ((This
->parent
->bpp
* This
->width
) + 7)/8;
204 *ppbData
= This
->data
;
209 static HRESULT WINAPI
BitmapLockImpl_GetPixelFormat(IWICBitmapLock
*iface
,
210 WICPixelFormatGUID
*pPixelFormat
)
212 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
213 TRACE("(%p,%p)\n", iface
, pPixelFormat
);
215 return IWICBitmap_GetPixelFormat(&This
->parent
->IWICBitmap_iface
, pPixelFormat
);
218 static const IWICBitmapLockVtbl BitmapLockImpl_Vtbl
= {
219 BitmapLockImpl_QueryInterface
,
220 BitmapLockImpl_AddRef
,
221 BitmapLockImpl_Release
,
222 BitmapLockImpl_GetSize
,
223 BitmapLockImpl_GetStride
,
224 BitmapLockImpl_GetDataPointer
,
225 BitmapLockImpl_GetPixelFormat
228 static HRESULT WINAPI
BitmapImpl_QueryInterface(IWICBitmap
*iface
, REFIID iid
,
231 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
232 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
234 if (!ppv
) return E_INVALIDARG
;
236 if (IsEqualIID(&IID_IUnknown
, iid
) ||
237 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
238 IsEqualIID(&IID_IWICBitmap
, iid
))
240 *ppv
= &This
->IWICBitmap_iface
;
242 else if (IsEqualIID(&IID_IMILBitmap
, iid
) ||
243 IsEqualIID(&IID_IMILBitmapSource
, iid
))
245 *ppv
= &This
->IMILBitmapSource_iface
;
249 FIXME("unknown interface %s\n", debugstr_guid(iid
));
251 return E_NOINTERFACE
;
254 IUnknown_AddRef((IUnknown
*)*ppv
);
258 static ULONG WINAPI
BitmapImpl_AddRef(IWICBitmap
*iface
)
260 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
261 ULONG ref
= InterlockedIncrement(&This
->ref
);
263 TRACE("(%p) refcount=%u\n", iface
, ref
);
268 static ULONG WINAPI
BitmapImpl_Release(IWICBitmap
*iface
)
270 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
271 ULONG ref
= InterlockedDecrement(&This
->ref
);
273 TRACE("(%p) refcount=%u\n", iface
, ref
);
277 if (This
->palette
) IWICPalette_Release(This
->palette
);
278 This
->cs
.DebugInfo
->Spare
[0] = 0;
279 DeleteCriticalSection(&This
->cs
);
280 if (This
->is_section
)
281 UnmapViewOfFile(This
->data
);
283 HeapFree(GetProcessHeap(), 0, This
->data
);
284 HeapFree(GetProcessHeap(), 0, This
);
290 static HRESULT WINAPI
BitmapImpl_GetSize(IWICBitmap
*iface
,
291 UINT
*puiWidth
, UINT
*puiHeight
)
293 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
294 TRACE("(%p,%p,%p)\n", iface
, puiWidth
, puiHeight
);
296 if (!puiWidth
|| !puiHeight
)
299 *puiWidth
= This
->width
;
300 *puiHeight
= This
->height
;
305 static HRESULT WINAPI
BitmapImpl_GetPixelFormat(IWICBitmap
*iface
,
306 WICPixelFormatGUID
*pPixelFormat
)
308 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
309 TRACE("(%p,%p)\n", iface
, pPixelFormat
);
314 memcpy(pPixelFormat
, &This
->pixelformat
, sizeof(GUID
));
319 static HRESULT WINAPI
BitmapImpl_GetResolution(IWICBitmap
*iface
,
320 double *pDpiX
, double *pDpiY
)
322 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
323 TRACE("(%p,%p,%p)\n", iface
, pDpiX
, pDpiY
);
325 if (!pDpiX
|| !pDpiY
)
328 EnterCriticalSection(&This
->cs
);
331 LeaveCriticalSection(&This
->cs
);
336 static HRESULT WINAPI
BitmapImpl_CopyPalette(IWICBitmap
*iface
,
337 IWICPalette
*pIPalette
)
339 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
340 TRACE("(%p,%p)\n", iface
, pIPalette
);
342 if (!This
->palette_set
)
343 return WINCODEC_ERR_PALETTEUNAVAILABLE
;
345 return IWICPalette_InitializeFromPalette(pIPalette
, This
->palette
);
348 static HRESULT WINAPI
BitmapImpl_CopyPixels(IWICBitmap
*iface
,
349 const WICRect
*prc
, UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
)
351 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
352 TRACE("(%p,%p,%u,%u,%p)\n", iface
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
354 return copy_pixels(This
->bpp
, This
->data
, This
->width
, This
->height
,
355 This
->stride
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
358 static HRESULT WINAPI
BitmapImpl_Lock(IWICBitmap
*iface
, const WICRect
*prcLock
,
359 DWORD flags
, IWICBitmapLock
**ppILock
)
361 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
362 BitmapLockImpl
*result
;
365 TRACE("(%p,%p,%x,%p)\n", iface
, prcLock
, flags
, ppILock
);
367 if (!(flags
& (WICBitmapLockRead
|WICBitmapLockWrite
)) || !ppILock
)
373 rc
.Width
= This
->width
;
374 rc
.Height
= This
->height
;
377 else if (prcLock
->X
>= This
->width
|| prcLock
->Y
>= This
->height
||
378 prcLock
->X
+ prcLock
->Width
> This
->width
||
379 prcLock
->Y
+ prcLock
->Height
> This
->height
||
380 prcLock
->Width
<= 0 || prcLock
->Height
<= 0)
382 else if (((prcLock
->X
* This
->bpp
) % 8) != 0)
384 FIXME("Cannot lock at an X coordinate not at a full byte\n");
388 result
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapLockImpl
));
390 return E_OUTOFMEMORY
;
392 if (!BitmapImpl_AcquireLock(This
, flags
& WICBitmapLockWrite
))
394 HeapFree(GetProcessHeap(), 0, result
);
395 return WINCODEC_ERR_ALREADYLOCKED
;
398 result
->IWICBitmapLock_iface
.lpVtbl
= &BitmapLockImpl_Vtbl
;
400 result
->parent
= This
;
401 result
->width
= prcLock
->Width
;
402 result
->height
= prcLock
->Height
;
403 result
->data
= This
->data
+ This
->stride
* prcLock
->Y
+
404 (This
->bpp
* prcLock
->X
)/8;
406 IWICBitmap_AddRef(&This
->IWICBitmap_iface
);
407 *ppILock
= &result
->IWICBitmapLock_iface
;
412 static HRESULT WINAPI
BitmapImpl_SetPalette(IWICBitmap
*iface
, IWICPalette
*pIPalette
)
414 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
417 TRACE("(%p,%p)\n", iface
, pIPalette
);
421 IWICPalette
*new_palette
;
422 hr
= PaletteImpl_Create(&new_palette
);
424 if (FAILED(hr
)) return hr
;
426 if (InterlockedCompareExchangePointer((void**)&This
->palette
, new_palette
, NULL
))
428 /* someone beat us to it */
429 IWICPalette_Release(new_palette
);
433 hr
= IWICPalette_InitializeFromPalette(This
->palette
, pIPalette
);
436 This
->palette_set
= 1;
441 static HRESULT WINAPI
BitmapImpl_SetResolution(IWICBitmap
*iface
,
442 double dpiX
, double dpiY
)
444 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
445 TRACE("(%p,%f,%f)\n", iface
, dpiX
, dpiY
);
447 EnterCriticalSection(&This
->cs
);
450 LeaveCriticalSection(&This
->cs
);
455 static const IWICBitmapVtbl BitmapImpl_Vtbl
= {
456 BitmapImpl_QueryInterface
,
460 BitmapImpl_GetPixelFormat
,
461 BitmapImpl_GetResolution
,
462 BitmapImpl_CopyPalette
,
463 BitmapImpl_CopyPixels
,
465 BitmapImpl_SetPalette
,
466 BitmapImpl_SetResolution
469 static HRESULT WINAPI
IMILBitmapImpl_QueryInterface(IMILBitmapSource
*iface
, REFIID iid
,
472 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
473 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
475 if (!ppv
) return E_INVALIDARG
;
477 if (IsEqualIID(&IID_IUnknown
, iid
) ||
478 IsEqualIID(&IID_IMILBitmap
, iid
) ||
479 IsEqualIID(&IID_IMILBitmapSource
, iid
))
481 IUnknown_AddRef(&This
->IMILBitmapSource_iface
);
482 *ppv
= &This
->IMILBitmapSource_iface
;
485 else if (IsEqualIID(&IID_IWICBitmap
, iid
) ||
486 IsEqualIID(&IID_IWICBitmapSource
, iid
))
488 IUnknown_AddRef(&This
->IWICBitmap_iface
);
489 *ppv
= &This
->IWICBitmap_iface
;
493 FIXME("unknown interface %s\n", debugstr_guid(iid
));
495 return E_NOINTERFACE
;
498 static ULONG WINAPI
IMILBitmapImpl_AddRef(IMILBitmapSource
*iface
)
500 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
501 return IWICBitmap_AddRef(&This
->IWICBitmap_iface
);
504 static ULONG WINAPI
IMILBitmapImpl_Release(IMILBitmapSource
*iface
)
506 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
507 return IWICBitmap_Release(&This
->IWICBitmap_iface
);
510 static HRESULT WINAPI
IMILBitmapImpl_GetSize(IMILBitmapSource
*iface
,
511 UINT
*width
, UINT
*height
)
513 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
514 TRACE("(%p,%p,%p)\n", iface
, width
, height
);
515 return IWICBitmap_GetSize(&This
->IWICBitmap_iface
, width
, height
);
520 const GUID
*WIC_format
;
524 { &GUID_WICPixelFormatDontCare
, 0 },
525 { &GUID_WICPixelFormat1bppIndexed
, 1 },
526 { &GUID_WICPixelFormat2bppIndexed
, 2 },
527 { &GUID_WICPixelFormat4bppIndexed
, 3 },
528 { &GUID_WICPixelFormat8bppIndexed
, 4 },
529 { &GUID_WICPixelFormatBlackWhite
, 5 },
530 { &GUID_WICPixelFormat2bppGray
, 6 },
531 { &GUID_WICPixelFormat4bppGray
, 7 },
532 { &GUID_WICPixelFormat8bppGray
, 8 },
533 { &GUID_WICPixelFormat16bppBGR555
, 9 },
534 { &GUID_WICPixelFormat16bppBGR565
, 0x0a },
535 { &GUID_WICPixelFormat16bppGray
, 0x0b },
536 { &GUID_WICPixelFormat24bppBGR
, 0x0c },
537 { &GUID_WICPixelFormat24bppRGB
, 0x0d },
538 { &GUID_WICPixelFormat32bppBGR
, 0x0e },
539 { &GUID_WICPixelFormat32bppBGRA
, 0x0f },
540 { &GUID_WICPixelFormat32bppPBGRA
, 0x10 },
541 { &GUID_WICPixelFormat48bppRGB
, 0x15 },
542 { &GUID_WICPixelFormat64bppRGBA
, 0x16 },
543 { &GUID_WICPixelFormat64bppPRGBA
, 0x17 },
544 { &GUID_WICPixelFormat32bppCMYK
, 0x1c }
547 static HRESULT WINAPI
IMILBitmapImpl_GetPixelFormat(IMILBitmapSource
*iface
,
550 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
553 TRACE("(%p,%p)\n", iface
, format
);
555 if (!format
) return E_INVALIDARG
;
559 for (i
= 0; i
< sizeof(pixel_fmt_map
)/sizeof(pixel_fmt_map
[0]); i
++)
561 if (IsEqualGUID(pixel_fmt_map
[i
].WIC_format
, &This
->pixelformat
))
563 *format
= pixel_fmt_map
[i
].enum_format
;
568 TRACE("=> %u\n", *format
);
572 static HRESULT WINAPI
IMILBitmapImpl_GetResolution(IMILBitmapSource
*iface
,
573 double *dpix
, double *dpiy
)
575 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
576 TRACE("(%p,%p,%p)\n", iface
, dpix
, dpiy
);
577 return IWICBitmap_GetResolution(&This
->IWICBitmap_iface
, dpix
, dpiy
);
580 static HRESULT WINAPI
IMILBitmapImpl_CopyPalette(IMILBitmapSource
*iface
,
581 IWICPalette
*palette
)
583 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
584 TRACE("(%p,%p)\n", iface
, palette
);
585 return IWICBitmap_CopyPalette(&This
->IWICBitmap_iface
, palette
);
588 static HRESULT WINAPI
IMILBitmapImpl_CopyPixels(IMILBitmapSource
*iface
,
589 const WICRect
*rc
, UINT stride
, UINT size
, BYTE
*buffer
)
591 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
592 TRACE("(%p,%p,%u,%u,%p)\n", iface
, rc
, stride
, size
, buffer
);
593 return IWICBitmap_CopyPixels(&This
->IWICBitmap_iface
, rc
, stride
, size
, buffer
);
596 static HRESULT WINAPI
IMILBitmapImpl_unknown1(IMILBitmapSource
*iface
, void **ppv
)
598 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
600 TRACE("(%p,%p)\n", iface
, ppv
);
602 if (!ppv
) return E_INVALIDARG
;
604 /* reference count is not incremented here */
605 *ppv
= &This
->IMILUnknown1_iface
;
610 static HRESULT WINAPI
IMILBitmapImpl_Lock(IMILBitmapSource
*iface
, const WICRect
*rc
, DWORD flags
, IWICBitmapLock
**lock
)
612 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
613 TRACE("(%p,%p,%08x,%p)\n", iface
, rc
, flags
, lock
);
614 return IWICBitmap_Lock(&This
->IWICBitmap_iface
, rc
, flags
, lock
);
617 static HRESULT WINAPI
IMILBitmapImpl_Unlock(IMILBitmapSource
*iface
, IWICBitmapLock
*lock
)
619 TRACE("(%p,%p)\n", iface
, lock
);
620 IWICBitmapLock_Release(lock
);
624 static HRESULT WINAPI
IMILBitmapImpl_SetPalette(IMILBitmapSource
*iface
, IWICPalette
*palette
)
626 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
627 TRACE("(%p,%p)\n", iface
, palette
);
628 return IWICBitmap_SetPalette(&This
->IWICBitmap_iface
, palette
);
631 static HRESULT WINAPI
IMILBitmapImpl_SetResolution(IMILBitmapSource
*iface
, double dpix
, double dpiy
)
633 BitmapImpl
*This
= impl_from_IMILBitmapSource(iface
);
634 TRACE("(%p,%f,%f)\n", iface
, dpix
, dpiy
);
635 return IWICBitmap_SetResolution(&This
->IWICBitmap_iface
, dpix
, dpiy
);
638 static HRESULT WINAPI
IMILBitmapImpl_AddDirtyRect(IMILBitmapSource
*iface
, const WICRect
*rc
)
640 FIXME("(%p,%p): stub\n", iface
, rc
);
644 static const IMILBitmapSourceVtbl IMILBitmapImpl_Vtbl
=
646 IMILBitmapImpl_QueryInterface
,
647 IMILBitmapImpl_AddRef
,
648 IMILBitmapImpl_Release
,
649 IMILBitmapImpl_GetSize
,
650 IMILBitmapImpl_GetPixelFormat
,
651 IMILBitmapImpl_GetResolution
,
652 IMILBitmapImpl_CopyPalette
,
653 IMILBitmapImpl_CopyPixels
,
654 IMILBitmapImpl_unknown1
,
656 IMILBitmapImpl_Unlock
,
657 IMILBitmapImpl_SetPalette
,
658 IMILBitmapImpl_SetResolution
,
659 IMILBitmapImpl_AddDirtyRect
662 static HRESULT WINAPI
IMILUnknown1Impl_QueryInterface(IMILUnknown1
*iface
, REFIID iid
,
665 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_guid(iid
), ppv
);
667 return E_NOINTERFACE
;
670 static ULONG WINAPI
IMILUnknown1Impl_AddRef(IMILUnknown1
*iface
)
672 BitmapImpl
*This
= impl_from_IMILUnknown1(iface
);
673 return IWICBitmap_AddRef(&This
->IWICBitmap_iface
);
676 static ULONG WINAPI
IMILUnknown1Impl_Release(IMILUnknown1
*iface
)
678 BitmapImpl
*This
= impl_from_IMILUnknown1(iface
);
679 return IWICBitmap_Release(&This
->IWICBitmap_iface
);
682 DECLSPEC_HIDDEN
void WINAPI
IMILUnknown1Impl_unknown1(IMILUnknown1
*iface
, void *arg
)
684 FIXME("(%p,%p): stub\n", iface
, arg
);
687 static HRESULT WINAPI
IMILUnknown1Impl_unknown2(IMILUnknown1
*iface
, void *arg1
, void *arg2
)
689 FIXME("(%p,%p,%p): stub\n", iface
, arg1
, arg2
);
693 DECLSPEC_HIDDEN HRESULT WINAPI
IMILUnknown1Impl_unknown3(IMILUnknown1
*iface
, void *arg
)
695 FIXME("(%p,%p): stub\n", iface
, arg
);
699 static HRESULT WINAPI
IMILUnknown1Impl_unknown4(IMILUnknown1
*iface
, void *arg
)
701 FIXME("(%p,%p): stub\n", iface
, arg
);
705 static HRESULT WINAPI
IMILUnknown1Impl_unknown5(IMILUnknown1
*iface
, void *arg
)
707 FIXME("(%p,%p): stub\n", iface
, arg
);
711 static HRESULT WINAPI
IMILUnknown1Impl_unknown6(IMILUnknown1
*iface
, DWORD64 arg
)
713 FIXME("(%p,%s): stub\n", iface
, wine_dbgstr_longlong(arg
));
717 static HRESULT WINAPI
IMILUnknown1Impl_unknown7(IMILUnknown1
*iface
, void *arg
)
719 FIXME("(%p,%p): stub\n", iface
, arg
);
723 DECLSPEC_HIDDEN HRESULT WINAPI
IMILUnknown1Impl_unknown8(IMILUnknown1
*iface
)
725 FIXME("(%p): stub\n", iface
);
729 DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown1
, 8)
730 DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown3
, 8)
731 DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown8
, 4)
733 static const IMILUnknown1Vtbl IMILUnknown1Impl_Vtbl
=
735 IMILUnknown1Impl_QueryInterface
,
736 IMILUnknown1Impl_AddRef
,
737 IMILUnknown1Impl_Release
,
738 THISCALL(IMILUnknown1Impl_unknown1
),
739 IMILUnknown1Impl_unknown2
,
740 THISCALL(IMILUnknown1Impl_unknown3
),
741 IMILUnknown1Impl_unknown4
,
742 IMILUnknown1Impl_unknown5
,
743 IMILUnknown1Impl_unknown6
,
744 IMILUnknown1Impl_unknown7
,
745 THISCALL(IMILUnknown1Impl_unknown8
)
748 static HRESULT WINAPI
IMILUnknown2Impl_QueryInterface(IMILUnknown2
*iface
, REFIID iid
,
751 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_guid(iid
), ppv
);
753 return E_NOINTERFACE
;
756 static ULONG WINAPI
IMILUnknown2Impl_AddRef(IMILUnknown2
*iface
)
758 FIXME("(%p): stub\n", iface
);
762 static ULONG WINAPI
IMILUnknown2Impl_Release(IMILUnknown2
*iface
)
764 FIXME("(%p): stub\n", iface
);
768 static HRESULT WINAPI
IMILUnknown2Impl_unknown1(IMILUnknown2
*iface
, void *arg1
, void **arg2
)
770 FIXME("(%p,%p,%p): stub\n", iface
, arg1
, arg2
);
771 if (arg2
) *arg2
= NULL
;
775 static HRESULT WINAPI
IMILUnknown2Impl_unknown2(IMILUnknown2
*iface
, void *arg1
, void *arg2
)
777 FIXME("(%p,%p,%p): stub\n", iface
, arg1
, arg2
);
781 static HRESULT WINAPI
IMILUnknown2Impl_unknown3(IMILUnknown2
*iface
, void *arg1
)
783 FIXME("(%p,%p): stub\n", iface
, arg1
);
787 static const IMILUnknown2Vtbl IMILUnknown2Impl_Vtbl
=
789 IMILUnknown2Impl_QueryInterface
,
790 IMILUnknown2Impl_AddRef
,
791 IMILUnknown2Impl_Release
,
792 IMILUnknown2Impl_unknown1
,
793 IMILUnknown2Impl_unknown2
,
794 IMILUnknown2Impl_unknown3
797 HRESULT
BitmapImpl_Create(UINT uiWidth
, UINT uiHeight
,
798 UINT stride
, UINT datasize
, BYTE
*data
,
799 REFWICPixelFormatGUID pixelFormat
, WICBitmapCreateCacheOption option
,
800 IWICBitmap
**ppIBitmap
)
806 hr
= get_pixelformat_bpp(pixelFormat
, &bpp
);
807 if (FAILED(hr
)) return hr
;
809 if (!stride
) stride
= (((bpp
*uiWidth
)+31)/32)*4;
810 if (!datasize
) datasize
= stride
* uiHeight
;
812 if (datasize
< stride
* uiHeight
) return WINCODEC_ERR_INSUFFICIENTBUFFER
;
813 if (stride
< ((bpp
*uiWidth
)+7)/8) return E_INVALIDARG
;
815 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl
));
816 if (!This
) return E_OUTOFMEMORY
;
820 data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, datasize
);
823 HeapFree(GetProcessHeap(), 0, This
);
824 return E_OUTOFMEMORY
;
826 This
->is_section
= FALSE
;
829 This
->is_section
= TRUE
;
831 This
->IWICBitmap_iface
.lpVtbl
= &BitmapImpl_Vtbl
;
832 This
->IMILBitmapSource_iface
.lpVtbl
= &IMILBitmapImpl_Vtbl
;
833 This
->IMILUnknown1_iface
.lpVtbl
= &IMILUnknown1Impl_Vtbl
;
834 This
->IMILUnknown2_iface
.lpVtbl
= &IMILUnknown2Impl_Vtbl
;
836 This
->palette
= NULL
;
837 This
->palette_set
= 0;
840 This
->width
= uiWidth
;
841 This
->height
= uiHeight
;
842 This
->stride
= stride
;
844 memcpy(&This
->pixelformat
, pixelFormat
, sizeof(GUID
));
845 This
->dpix
= This
->dpiy
= 0.0;
846 InitializeCriticalSection(&This
->cs
);
847 This
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BitmapImpl.lock");
849 *ppIBitmap
= &This
->IWICBitmap_iface
;