2 * Copyright 2012 Vincent Povirk for CodeWeavers
3 * Copyright 2016 Dmitry Timoshkov
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wincodecs_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
39 /* WARNING: .NET Media Integration Layer (MIL) directly dereferences
40 * BitmapImpl members and depends on its exact layout.
42 typedef struct BitmapImpl
{
43 IMILUnknown1 IMILUnknown1_iface
;
45 IMILBitmap IMILBitmap_iface
;
46 IWICBitmap IWICBitmap_iface
;
47 IMILUnknown2 IMILUnknown2_iface
;
50 LONG lock
; /* 0 if not locked, -1 if locked for writing, count if locked for reading */
52 void *view
; /* used if data is a section created by an application */
53 UINT offset
; /* offset into view */
57 WICPixelFormatGUID pixelformat
;
62 typedef struct BitmapLockImpl
{
63 IWICBitmapLock IWICBitmapLock_iface
;
70 static inline BitmapImpl
*impl_from_IWICBitmap(IWICBitmap
*iface
)
72 return CONTAINING_RECORD(iface
, BitmapImpl
, IWICBitmap_iface
);
75 static inline BitmapImpl
*impl_from_IMILBitmap(IMILBitmap
*iface
)
77 return CONTAINING_RECORD(iface
, BitmapImpl
, IMILBitmap_iface
);
80 static inline BitmapImpl
*impl_from_IMILUnknown1(IMILUnknown1
*iface
)
82 return CONTAINING_RECORD(iface
, BitmapImpl
, IMILUnknown1_iface
);
85 static inline BitmapImpl
*impl_from_IMILUnknown2(IMILUnknown2
*iface
)
87 return CONTAINING_RECORD(iface
, BitmapImpl
, IMILUnknown2_iface
);
90 static inline BitmapLockImpl
*impl_from_IWICBitmapLock(IWICBitmapLock
*iface
)
92 return CONTAINING_RECORD(iface
, BitmapLockImpl
, IWICBitmapLock_iface
);
95 static BOOL
BitmapImpl_AcquireLock(BitmapImpl
*This
, int write
)
99 return 0 == InterlockedCompareExchange(&This
->lock
, -1, 0);
105 LONG prev_val
= This
->lock
;
108 if (prev_val
== InterlockedCompareExchange(&This
->lock
, prev_val
+1, prev_val
))
114 static void BitmapImpl_ReleaseLock(BitmapImpl
*This
)
118 LONG prev_val
= This
->lock
, new_val
;
122 new_val
= prev_val
- 1;
123 if (prev_val
== InterlockedCompareExchange(&This
->lock
, new_val
, prev_val
))
129 static HRESULT WINAPI
BitmapLockImpl_QueryInterface(IWICBitmapLock
*iface
, REFIID iid
,
132 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
133 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
135 if (!ppv
) return E_INVALIDARG
;
137 if (IsEqualIID(&IID_IUnknown
, iid
) ||
138 IsEqualIID(&IID_IWICBitmapLock
, iid
))
140 *ppv
= &This
->IWICBitmapLock_iface
;
144 FIXME("unknown interface %s\n", debugstr_guid(iid
));
146 return E_NOINTERFACE
;
149 IUnknown_AddRef((IUnknown
*)*ppv
);
153 static ULONG WINAPI
BitmapLockImpl_AddRef(IWICBitmapLock
*iface
)
155 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
156 ULONG ref
= InterlockedIncrement(&This
->ref
);
158 TRACE("(%p) refcount=%u\n", iface
, ref
);
163 static ULONG WINAPI
BitmapLockImpl_Release(IWICBitmapLock
*iface
)
165 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
166 ULONG ref
= InterlockedDecrement(&This
->ref
);
168 TRACE("(%p) refcount=%u\n", iface
, ref
);
172 BitmapImpl_ReleaseLock(This
->parent
);
173 IWICBitmap_Release(&This
->parent
->IWICBitmap_iface
);
174 HeapFree(GetProcessHeap(), 0, This
);
180 static HRESULT WINAPI
BitmapLockImpl_GetSize(IWICBitmapLock
*iface
,
181 UINT
*puiWidth
, UINT
*puiHeight
)
183 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
184 TRACE("(%p,%p,%p)\n", iface
, puiWidth
, puiHeight
);
186 if (!puiWidth
|| !puiHeight
)
189 *puiWidth
= This
->width
;
190 *puiHeight
= This
->height
;
195 static HRESULT WINAPI
BitmapLockImpl_GetStride(IWICBitmapLock
*iface
,
198 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
199 TRACE("(%p,%p)\n", iface
, pcbStride
);
204 *pcbStride
= This
->parent
->stride
;
209 static HRESULT WINAPI
BitmapLockImpl_GetDataPointer(IWICBitmapLock
*iface
,
210 UINT
*pcbBufferSize
, BYTE
**ppbData
)
212 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
213 TRACE("(%p,%p,%p)\n", iface
, pcbBufferSize
, ppbData
);
215 if (!pcbBufferSize
|| !ppbData
)
218 *pcbBufferSize
= This
->parent
->stride
* (This
->height
- 1) +
219 ((This
->parent
->bpp
* This
->width
) + 7)/8;
220 *ppbData
= This
->data
;
225 static HRESULT WINAPI
BitmapLockImpl_GetPixelFormat(IWICBitmapLock
*iface
,
226 WICPixelFormatGUID
*pPixelFormat
)
228 BitmapLockImpl
*This
= impl_from_IWICBitmapLock(iface
);
229 TRACE("(%p,%p)\n", iface
, pPixelFormat
);
231 return IWICBitmap_GetPixelFormat(&This
->parent
->IWICBitmap_iface
, pPixelFormat
);
234 static const IWICBitmapLockVtbl BitmapLockImpl_Vtbl
= {
235 BitmapLockImpl_QueryInterface
,
236 BitmapLockImpl_AddRef
,
237 BitmapLockImpl_Release
,
238 BitmapLockImpl_GetSize
,
239 BitmapLockImpl_GetStride
,
240 BitmapLockImpl_GetDataPointer
,
241 BitmapLockImpl_GetPixelFormat
244 static HRESULT WINAPI
BitmapImpl_QueryInterface(IWICBitmap
*iface
, REFIID iid
,
247 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
248 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
250 if (!ppv
) return E_INVALIDARG
;
252 if (IsEqualIID(&IID_IUnknown
, iid
) ||
253 IsEqualIID(&IID_IWICBitmapSource
, iid
) ||
254 IsEqualIID(&IID_IWICBitmap
, iid
))
256 *ppv
= &This
->IWICBitmap_iface
;
258 else if (IsEqualIID(&IID_IMILBitmap
, iid
) ||
259 IsEqualIID(&IID_IMILBitmapSource
, iid
))
261 *ppv
= &This
->IMILBitmap_iface
;
265 FIXME("unknown interface %s\n", debugstr_guid(iid
));
267 return E_NOINTERFACE
;
270 IUnknown_AddRef((IUnknown
*)*ppv
);
274 static ULONG WINAPI
BitmapImpl_AddRef(IWICBitmap
*iface
)
276 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
277 ULONG ref
= InterlockedIncrement(&This
->ref
);
279 TRACE("(%p) refcount=%u\n", iface
, ref
);
284 static ULONG WINAPI
BitmapImpl_Release(IWICBitmap
*iface
)
286 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
287 ULONG ref
= InterlockedDecrement(&This
->ref
);
289 TRACE("(%p) refcount=%u\n", iface
, ref
);
293 if (This
->palette
) IWICPalette_Release(This
->palette
);
294 This
->cs
.DebugInfo
->Spare
[0] = 0;
295 DeleteCriticalSection(&This
->cs
);
297 UnmapViewOfFile(This
->view
);
299 HeapFree(GetProcessHeap(), 0, This
->data
);
300 HeapFree(GetProcessHeap(), 0, This
);
306 static HRESULT WINAPI
BitmapImpl_GetSize(IWICBitmap
*iface
,
307 UINT
*puiWidth
, UINT
*puiHeight
)
309 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
310 TRACE("(%p,%p,%p)\n", iface
, puiWidth
, puiHeight
);
312 if (!puiWidth
|| !puiHeight
)
315 *puiWidth
= This
->width
;
316 *puiHeight
= This
->height
;
321 static HRESULT WINAPI
BitmapImpl_GetPixelFormat(IWICBitmap
*iface
,
322 WICPixelFormatGUID
*pPixelFormat
)
324 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
325 TRACE("(%p,%p)\n", iface
, pPixelFormat
);
330 memcpy(pPixelFormat
, &This
->pixelformat
, sizeof(GUID
));
335 static HRESULT WINAPI
BitmapImpl_GetResolution(IWICBitmap
*iface
,
336 double *pDpiX
, double *pDpiY
)
338 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
339 TRACE("(%p,%p,%p)\n", iface
, pDpiX
, pDpiY
);
341 if (!pDpiX
|| !pDpiY
)
344 EnterCriticalSection(&This
->cs
);
347 LeaveCriticalSection(&This
->cs
);
352 static HRESULT WINAPI
BitmapImpl_CopyPalette(IWICBitmap
*iface
,
353 IWICPalette
*pIPalette
)
355 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
356 TRACE("(%p,%p)\n", iface
, pIPalette
);
358 if (!This
->palette_set
)
359 return WINCODEC_ERR_PALETTEUNAVAILABLE
;
361 return IWICPalette_InitializeFromPalette(pIPalette
, This
->palette
);
364 static HRESULT WINAPI
BitmapImpl_CopyPixels(IWICBitmap
*iface
,
365 const WICRect
*prc
, UINT cbStride
, UINT cbBufferSize
, BYTE
*pbBuffer
)
367 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
368 TRACE("(%p,%s,%u,%u,%p)\n", iface
, debug_wic_rect(prc
), cbStride
, cbBufferSize
, pbBuffer
);
370 return copy_pixels(This
->bpp
, This
->data
, This
->width
, This
->height
,
371 This
->stride
, prc
, cbStride
, cbBufferSize
, pbBuffer
);
374 static HRESULT WINAPI
BitmapImpl_Lock(IWICBitmap
*iface
, const WICRect
*prcLock
,
375 DWORD flags
, IWICBitmapLock
**ppILock
)
377 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
378 BitmapLockImpl
*result
;
381 TRACE("(%p,%s,%x,%p)\n", iface
, debug_wic_rect(prcLock
), flags
, ppILock
);
383 if (!(flags
& (WICBitmapLockRead
|WICBitmapLockWrite
)) || !ppILock
)
389 rc
.Width
= This
->width
;
390 rc
.Height
= This
->height
;
393 else if (prcLock
->X
>= This
->width
|| prcLock
->Y
>= This
->height
||
394 prcLock
->X
+ prcLock
->Width
> This
->width
||
395 prcLock
->Y
+ prcLock
->Height
> This
->height
||
396 prcLock
->Width
<= 0 || prcLock
->Height
<= 0)
398 else if (((prcLock
->X
* This
->bpp
) % 8) != 0)
400 FIXME("Cannot lock at an X coordinate not at a full byte\n");
404 result
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapLockImpl
));
406 return E_OUTOFMEMORY
;
408 if (!BitmapImpl_AcquireLock(This
, flags
& WICBitmapLockWrite
))
410 HeapFree(GetProcessHeap(), 0, result
);
411 return WINCODEC_ERR_ALREADYLOCKED
;
414 result
->IWICBitmapLock_iface
.lpVtbl
= &BitmapLockImpl_Vtbl
;
416 result
->parent
= This
;
417 result
->width
= prcLock
->Width
;
418 result
->height
= prcLock
->Height
;
419 result
->data
= This
->data
+ This
->stride
* prcLock
->Y
+
420 (This
->bpp
* prcLock
->X
)/8;
422 IWICBitmap_AddRef(&This
->IWICBitmap_iface
);
423 *ppILock
= &result
->IWICBitmapLock_iface
;
428 static HRESULT WINAPI
BitmapImpl_SetPalette(IWICBitmap
*iface
, IWICPalette
*pIPalette
)
430 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
433 TRACE("(%p,%p)\n", iface
, pIPalette
);
437 IWICPalette
*new_palette
;
438 hr
= PaletteImpl_Create(&new_palette
);
440 if (FAILED(hr
)) return hr
;
442 if (InterlockedCompareExchangePointer((void**)&This
->palette
, new_palette
, NULL
))
444 /* someone beat us to it */
445 IWICPalette_Release(new_palette
);
449 hr
= IWICPalette_InitializeFromPalette(This
->palette
, pIPalette
);
452 This
->palette_set
= 1;
457 static HRESULT WINAPI
BitmapImpl_SetResolution(IWICBitmap
*iface
,
458 double dpiX
, double dpiY
)
460 BitmapImpl
*This
= impl_from_IWICBitmap(iface
);
461 TRACE("(%p,%f,%f)\n", iface
, dpiX
, dpiY
);
463 EnterCriticalSection(&This
->cs
);
466 LeaveCriticalSection(&This
->cs
);
471 static const IWICBitmapVtbl BitmapImpl_Vtbl
= {
472 BitmapImpl_QueryInterface
,
476 BitmapImpl_GetPixelFormat
,
477 BitmapImpl_GetResolution
,
478 BitmapImpl_CopyPalette
,
479 BitmapImpl_CopyPixels
,
481 BitmapImpl_SetPalette
,
482 BitmapImpl_SetResolution
485 static HRESULT WINAPI
IMILBitmapImpl_QueryInterface(IMILBitmap
*iface
, REFIID iid
,
488 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
489 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
490 return IWICBitmap_QueryInterface(&This
->IWICBitmap_iface
, iid
, ppv
);
493 static ULONG WINAPI
IMILBitmapImpl_AddRef(IMILBitmap
*iface
)
495 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
496 return IWICBitmap_AddRef(&This
->IWICBitmap_iface
);
499 static ULONG WINAPI
IMILBitmapImpl_Release(IMILBitmap
*iface
)
501 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
502 return IWICBitmap_Release(&This
->IWICBitmap_iface
);
505 static HRESULT WINAPI
IMILBitmapImpl_GetSize(IMILBitmap
*iface
,
506 UINT
*width
, UINT
*height
)
508 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
509 TRACE("(%p,%p,%p)\n", iface
, width
, height
);
510 return IWICBitmap_GetSize(&This
->IWICBitmap_iface
, width
, height
);
515 const GUID
*WIC_format
;
519 { &GUID_WICPixelFormatDontCare
, 0 },
520 { &GUID_WICPixelFormat1bppIndexed
, 1 },
521 { &GUID_WICPixelFormat2bppIndexed
, 2 },
522 { &GUID_WICPixelFormat4bppIndexed
, 3 },
523 { &GUID_WICPixelFormat8bppIndexed
, 4 },
524 { &GUID_WICPixelFormatBlackWhite
, 5 },
525 { &GUID_WICPixelFormat2bppGray
, 6 },
526 { &GUID_WICPixelFormat4bppGray
, 7 },
527 { &GUID_WICPixelFormat8bppGray
, 8 },
528 { &GUID_WICPixelFormat16bppBGR555
, 9 },
529 { &GUID_WICPixelFormat16bppBGR565
, 0x0a },
530 { &GUID_WICPixelFormat16bppGray
, 0x0b },
531 { &GUID_WICPixelFormat24bppBGR
, 0x0c },
532 { &GUID_WICPixelFormat24bppRGB
, 0x0d },
533 { &GUID_WICPixelFormat32bppBGR
, 0x0e },
534 { &GUID_WICPixelFormat32bppBGRA
, 0x0f },
535 { &GUID_WICPixelFormat32bppPBGRA
, 0x10 },
536 { &GUID_WICPixelFormat48bppRGB
, 0x15 },
537 { &GUID_WICPixelFormat64bppRGBA
, 0x16 },
538 { &GUID_WICPixelFormat64bppPRGBA
, 0x17 },
539 { &GUID_WICPixelFormat32bppCMYK
, 0x1c }
542 static HRESULT WINAPI
IMILBitmapImpl_GetPixelFormat(IMILBitmap
*iface
,
545 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
548 TRACE("(%p,%p)\n", iface
, format
);
550 if (!format
) return E_INVALIDARG
;
554 for (i
= 0; i
< ARRAY_SIZE(pixel_fmt_map
); i
++)
556 if (IsEqualGUID(pixel_fmt_map
[i
].WIC_format
, &This
->pixelformat
))
558 *format
= pixel_fmt_map
[i
].enum_format
;
563 TRACE("=> %u\n", *format
);
567 static HRESULT WINAPI
IMILBitmapImpl_GetResolution(IMILBitmap
*iface
,
568 double *dpix
, double *dpiy
)
570 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
571 TRACE("(%p,%p,%p)\n", iface
, dpix
, dpiy
);
572 return IWICBitmap_GetResolution(&This
->IWICBitmap_iface
, dpix
, dpiy
);
575 static HRESULT WINAPI
IMILBitmapImpl_CopyPalette(IMILBitmap
*iface
,
576 IWICPalette
*palette
)
578 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
579 TRACE("(%p,%p)\n", iface
, palette
);
580 return IWICBitmap_CopyPalette(&This
->IWICBitmap_iface
, palette
);
583 static HRESULT WINAPI
IMILBitmapImpl_CopyPixels(IMILBitmap
*iface
,
584 const WICRect
*rc
, UINT stride
, UINT size
, BYTE
*buffer
)
586 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
587 TRACE("(%p,%p,%u,%u,%p)\n", iface
, rc
, stride
, size
, buffer
);
588 return IWICBitmap_CopyPixels(&This
->IWICBitmap_iface
, rc
, stride
, size
, buffer
);
591 static HRESULT WINAPI
IMILBitmapImpl_unknown1(IMILBitmap
*iface
, void **ppv
)
593 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
595 TRACE("(%p,%p)\n", iface
, ppv
);
597 if (!ppv
) return E_INVALIDARG
;
599 /* reference count is not incremented here */
600 *ppv
= &This
->IMILUnknown1_iface
;
605 static HRESULT WINAPI
IMILBitmapImpl_Lock(IMILBitmap
*iface
, const WICRect
*rc
, DWORD flags
, IWICBitmapLock
**lock
)
607 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
608 TRACE("(%p,%p,%08x,%p)\n", iface
, rc
, flags
, lock
);
609 return IWICBitmap_Lock(&This
->IWICBitmap_iface
, rc
, flags
, lock
);
612 static HRESULT WINAPI
IMILBitmapImpl_Unlock(IMILBitmap
*iface
, IWICBitmapLock
*lock
)
614 TRACE("(%p,%p)\n", iface
, lock
);
615 IWICBitmapLock_Release(lock
);
619 static HRESULT WINAPI
IMILBitmapImpl_SetPalette(IMILBitmap
*iface
, IWICPalette
*palette
)
621 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
622 TRACE("(%p,%p)\n", iface
, palette
);
623 return IWICBitmap_SetPalette(&This
->IWICBitmap_iface
, palette
);
626 static HRESULT WINAPI
IMILBitmapImpl_SetResolution(IMILBitmap
*iface
, double dpix
, double dpiy
)
628 BitmapImpl
*This
= impl_from_IMILBitmap(iface
);
629 TRACE("(%p,%f,%f)\n", iface
, dpix
, dpiy
);
630 return IWICBitmap_SetResolution(&This
->IWICBitmap_iface
, dpix
, dpiy
);
633 static HRESULT WINAPI
IMILBitmapImpl_AddDirtyRect(IMILBitmap
*iface
, const WICRect
*rc
)
635 FIXME("(%p,%p): stub\n", iface
, rc
);
639 static const IMILBitmapVtbl IMILBitmapImpl_Vtbl
=
641 IMILBitmapImpl_QueryInterface
,
642 IMILBitmapImpl_AddRef
,
643 IMILBitmapImpl_Release
,
644 IMILBitmapImpl_GetSize
,
645 IMILBitmapImpl_GetPixelFormat
,
646 IMILBitmapImpl_GetResolution
,
647 IMILBitmapImpl_CopyPalette
,
648 IMILBitmapImpl_CopyPixels
,
649 IMILBitmapImpl_unknown1
,
651 IMILBitmapImpl_Unlock
,
652 IMILBitmapImpl_SetPalette
,
653 IMILBitmapImpl_SetResolution
,
654 IMILBitmapImpl_AddDirtyRect
657 static HRESULT WINAPI
IMILUnknown1Impl_QueryInterface(IMILUnknown1
*iface
, REFIID iid
,
660 /* It's not clear what interface should be returned here */
661 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_guid(iid
), ppv
);
663 return E_NOINTERFACE
;
666 static ULONG WINAPI
IMILUnknown1Impl_AddRef(IMILUnknown1
*iface
)
668 BitmapImpl
*This
= impl_from_IMILUnknown1(iface
);
669 return IWICBitmap_AddRef(&This
->IWICBitmap_iface
);
672 static ULONG WINAPI
IMILUnknown1Impl_Release(IMILUnknown1
*iface
)
674 BitmapImpl
*This
= impl_from_IMILUnknown1(iface
);
675 return IWICBitmap_Release(&This
->IWICBitmap_iface
);
678 DECLSPEC_HIDDEN
void WINAPI
IMILUnknown1Impl_unknown1(IMILUnknown1
*iface
, void *arg
)
680 FIXME("(%p,%p): stub\n", iface
, arg
);
683 static HRESULT WINAPI
IMILUnknown1Impl_unknown2(IMILUnknown1
*iface
, void *arg1
, void *arg2
)
685 FIXME("(%p,%p,%p): stub\n", iface
, arg1
, arg2
);
689 DECLSPEC_HIDDEN HRESULT WINAPI
IMILUnknown1Impl_unknown3(IMILUnknown1
*iface
, void *arg
)
691 FIXME("(%p,%p): stub\n", iface
, arg
);
695 static HRESULT WINAPI
IMILUnknown1Impl_unknown4(IMILUnknown1
*iface
, void *arg
)
697 FIXME("(%p,%p): stub\n", iface
, arg
);
701 static HRESULT WINAPI
IMILUnknown1Impl_unknown5(IMILUnknown1
*iface
, void *arg
)
703 FIXME("(%p,%p): stub\n", iface
, arg
);
707 static HRESULT WINAPI
IMILUnknown1Impl_unknown6(IMILUnknown1
*iface
, DWORD64 arg
)
709 FIXME("(%p,%s): stub\n", iface
, wine_dbgstr_longlong(arg
));
713 static HRESULT WINAPI
IMILUnknown1Impl_unknown7(IMILUnknown1
*iface
, void *arg
)
715 FIXME("(%p,%p): stub\n", iface
, arg
);
719 DECLSPEC_HIDDEN HRESULT WINAPI
IMILUnknown1Impl_unknown8(IMILUnknown1
*iface
)
721 FIXME("(%p): stub\n", iface
);
725 DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown1
, 8)
726 DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown3
, 8)
727 DEFINE_THISCALL_WRAPPER(IMILUnknown1Impl_unknown8
, 4)
729 static const IMILUnknown1Vtbl IMILUnknown1Impl_Vtbl
=
731 IMILUnknown1Impl_QueryInterface
,
732 IMILUnknown1Impl_AddRef
,
733 IMILUnknown1Impl_Release
,
734 THISCALL(IMILUnknown1Impl_unknown1
),
735 IMILUnknown1Impl_unknown2
,
736 THISCALL(IMILUnknown1Impl_unknown3
),
737 IMILUnknown1Impl_unknown4
,
738 IMILUnknown1Impl_unknown5
,
739 IMILUnknown1Impl_unknown6
,
740 IMILUnknown1Impl_unknown7
,
741 THISCALL(IMILUnknown1Impl_unknown8
)
744 static HRESULT WINAPI
IMILUnknown2Impl_QueryInterface(IMILUnknown2
*iface
, REFIID iid
,
747 FIXME("(%p,%s,%p): stub\n", iface
, debugstr_guid(iid
), ppv
);
749 return E_NOINTERFACE
;
752 static ULONG WINAPI
IMILUnknown2Impl_AddRef(IMILUnknown2
*iface
)
754 FIXME("(%p): stub\n", iface
);
758 static ULONG WINAPI
IMILUnknown2Impl_Release(IMILUnknown2
*iface
)
760 FIXME("(%p): stub\n", iface
);
764 static HRESULT WINAPI
IMILUnknown2Impl_unknown1(IMILUnknown2
*iface
, void *arg1
, void **arg2
)
766 FIXME("(%p,%p,%p): stub\n", iface
, arg1
, arg2
);
767 if (arg2
) *arg2
= NULL
;
771 static HRESULT WINAPI
IMILUnknown2Impl_unknown2(IMILUnknown2
*iface
, void *arg1
, void *arg2
)
773 FIXME("(%p,%p,%p): stub\n", iface
, arg1
, arg2
);
777 static HRESULT WINAPI
IMILUnknown2Impl_unknown3(IMILUnknown2
*iface
, void *arg1
)
779 FIXME("(%p,%p): stub\n", iface
, arg1
);
783 static const IMILUnknown2Vtbl IMILUnknown2Impl_Vtbl
=
785 IMILUnknown2Impl_QueryInterface
,
786 IMILUnknown2Impl_AddRef
,
787 IMILUnknown2Impl_Release
,
788 IMILUnknown2Impl_unknown1
,
789 IMILUnknown2Impl_unknown2
,
790 IMILUnknown2Impl_unknown3
793 HRESULT
BitmapImpl_Create(UINT uiWidth
, UINT uiHeight
, UINT stride
, UINT datasize
, void *view
,
794 UINT offset
, REFWICPixelFormatGUID pixelFormat
, WICBitmapCreateCacheOption option
,
795 IWICBitmap
**ppIBitmap
)
802 hr
= get_pixelformat_bpp(pixelFormat
, &bpp
);
803 if (FAILED(hr
)) return hr
;
805 if (!stride
) stride
= (((bpp
*uiWidth
)+31)/32)*4;
806 if (!datasize
) datasize
= stride
* uiHeight
;
808 if (datasize
< stride
* uiHeight
) return WINCODEC_ERR_INSUFFICIENTBUFFER
;
809 if (stride
< ((bpp
*uiWidth
)+7)/8) return E_INVALIDARG
;
811 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapImpl
));
812 if (!This
) return E_OUTOFMEMORY
;
814 if (view
) data
= (BYTE
*)view
+ offset
;
815 else if (!(data
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, datasize
)))
817 HeapFree(GetProcessHeap(), 0, This
);
818 return E_OUTOFMEMORY
;
821 This
->IWICBitmap_iface
.lpVtbl
= &BitmapImpl_Vtbl
;
822 This
->IMILBitmap_iface
.lpVtbl
= &IMILBitmapImpl_Vtbl
;
823 This
->IMILUnknown1_iface
.lpVtbl
= &IMILUnknown1Impl_Vtbl
;
824 This
->IMILUnknown2_iface
.lpVtbl
= &IMILUnknown2Impl_Vtbl
;
826 This
->palette
= NULL
;
827 This
->palette_set
= 0;
831 This
->offset
= offset
;
832 This
->width
= uiWidth
;
833 This
->height
= uiHeight
;
834 This
->stride
= stride
;
836 memcpy(&This
->pixelformat
, pixelFormat
, sizeof(GUID
));
837 This
->dpix
= This
->dpiy
= 0.0;
838 InitializeCriticalSection(&This
->cs
);
839 This
->cs
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": BitmapImpl.lock");
841 *ppIBitmap
= &This
->IWICBitmap_iface
;