2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2012 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"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
39 IWICComponentFactory IWICComponentFactory_iface
;
43 static inline ComponentFactory
*impl_from_IWICComponentFactory(IWICComponentFactory
*iface
)
45 return CONTAINING_RECORD(iface
, ComponentFactory
, IWICComponentFactory_iface
);
48 static HRESULT WINAPI
ComponentFactory_QueryInterface(IWICComponentFactory
*iface
, REFIID iid
,
51 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
52 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
54 if (!ppv
) return E_INVALIDARG
;
56 if (IsEqualIID(&IID_IUnknown
, iid
) ||
57 IsEqualIID(&IID_IWICImagingFactory
, iid
) ||
58 IsEqualIID(&IID_IWICComponentFactory
, iid
))
60 *ppv
= &This
->IWICComponentFactory_iface
;
68 IUnknown_AddRef((IUnknown
*)*ppv
);
72 static ULONG WINAPI
ComponentFactory_AddRef(IWICComponentFactory
*iface
)
74 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
75 ULONG ref
= InterlockedIncrement(&This
->ref
);
77 TRACE("(%p) refcount=%u\n", iface
, ref
);
82 static ULONG WINAPI
ComponentFactory_Release(IWICComponentFactory
*iface
)
84 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
85 ULONG ref
= InterlockedDecrement(&This
->ref
);
87 TRACE("(%p) refcount=%u\n", iface
, ref
);
90 HeapFree(GetProcessHeap(), 0, This
);
95 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromFilename(
96 IWICComponentFactory
*iface
, LPCWSTR wzFilename
, const GUID
*pguidVendor
,
97 DWORD dwDesiredAccess
, WICDecodeOptions metadataOptions
,
98 IWICBitmapDecoder
**ppIDecoder
)
103 TRACE("(%p,%s,%s,%u,%u,%p)\n", iface
, debugstr_w(wzFilename
),
104 debugstr_guid(pguidVendor
), dwDesiredAccess
, metadataOptions
, ppIDecoder
);
106 hr
= StreamImpl_Create(&stream
);
109 hr
= IWICStream_InitializeFromFilename(stream
, wzFilename
, dwDesiredAccess
);
113 hr
= IWICComponentFactory_CreateDecoderFromStream(iface
, (IStream
*)stream
,
114 pguidVendor
, metadataOptions
, ppIDecoder
);
117 IWICStream_Release(stream
);
123 static IWICBitmapDecoder
*find_decoder(IStream
*pIStream
, const GUID
*pguidVendor
,
124 WICDecodeOptions metadataOptions
)
126 IEnumUnknown
*enumdecoders
;
127 IUnknown
*unkdecoderinfo
;
128 IWICBitmapDecoderInfo
*decoderinfo
;
129 IWICBitmapDecoder
*decoder
= NULL
;
135 res
= CreateComponentEnumerator(WICDecoder
, WICComponentEnumerateDefault
, &enumdecoders
);
136 if (FAILED(res
)) return NULL
;
140 res
= IEnumUnknown_Next(enumdecoders
, 1, &unkdecoderinfo
, &num_fetched
);
144 res
= IUnknown_QueryInterface(unkdecoderinfo
, &IID_IWICBitmapDecoderInfo
, (void**)&decoderinfo
);
150 res
= IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo
, &vendor
);
151 if (FAILED(res
) || !IsEqualIID(&vendor
, pguidVendor
))
153 IWICBitmapDecoderInfo_Release(decoderinfo
);
154 IUnknown_Release(unkdecoderinfo
);
159 res
= IWICBitmapDecoderInfo_MatchesPattern(decoderinfo
, pIStream
, &matches
);
161 if (SUCCEEDED(res
) && matches
)
163 res
= IWICBitmapDecoderInfo_CreateInstance(decoderinfo
, &decoder
);
165 /* FIXME: should use QueryCapability to choose a decoder */
169 res
= IWICBitmapDecoder_Initialize(decoder
, pIStream
, metadataOptions
);
173 IWICBitmapDecoder_Release(decoder
);
179 IWICBitmapDecoderInfo_Release(decoderinfo
);
182 IUnknown_Release(unkdecoderinfo
);
188 IEnumUnknown_Release(enumdecoders
);
193 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromStream(
194 IWICComponentFactory
*iface
, IStream
*pIStream
, const GUID
*pguidVendor
,
195 WICDecodeOptions metadataOptions
, IWICBitmapDecoder
**ppIDecoder
)
198 IWICBitmapDecoder
*decoder
= NULL
;
200 TRACE("(%p,%p,%s,%u,%p)\n", iface
, pIStream
, debugstr_guid(pguidVendor
),
201 metadataOptions
, ppIDecoder
);
204 decoder
= find_decoder(pIStream
, pguidVendor
, metadataOptions
);
206 decoder
= find_decoder(pIStream
, NULL
, metadataOptions
);
210 *ppIDecoder
= decoder
;
215 if (WARN_ON(wincodecs
))
221 WARN("failed to load from a stream\n");
224 res
= IStream_Seek(pIStream
, seek
, STREAM_SEEK_SET
, NULL
);
226 res
= IStream_Read(pIStream
, data
, 4, &bytesread
);
228 WARN("first %i bytes of stream=%x %x %x %x\n", bytesread
, data
[0], data
[1], data
[2], data
[3]);
231 return WINCODEC_ERR_COMPONENTNOTFOUND
;
235 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromFileHandle(
236 IWICComponentFactory
*iface
, ULONG_PTR hFile
, const GUID
*pguidVendor
,
237 WICDecodeOptions metadataOptions
, IWICBitmapDecoder
**ppIDecoder
)
242 TRACE("(%p,%lx,%s,%u,%p)\n", iface
, hFile
, debugstr_guid(pguidVendor
),
243 metadataOptions
, ppIDecoder
);
245 hr
= StreamImpl_Create(&stream
);
248 hr
= stream_initialize_from_filehandle(stream
, (HANDLE
)hFile
);
251 hr
= IWICComponentFactory_CreateDecoderFromStream(iface
, (IStream
*)stream
,
252 pguidVendor
, metadataOptions
, ppIDecoder
);
254 IWICStream_Release(stream
);
259 static HRESULT WINAPI
ComponentFactory_CreateComponentInfo(IWICComponentFactory
*iface
,
260 REFCLSID clsidComponent
, IWICComponentInfo
**ppIInfo
)
262 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(clsidComponent
), ppIInfo
);
263 return CreateComponentInfo(clsidComponent
, ppIInfo
);
266 static HRESULT WINAPI
ComponentFactory_CreateDecoder(IWICComponentFactory
*iface
,
267 REFGUID guidContainerFormat
, const GUID
*pguidVendor
,
268 IWICBitmapDecoder
**ppIDecoder
)
270 IEnumUnknown
*enumdecoders
;
271 IUnknown
*unkdecoderinfo
;
272 IWICBitmapDecoderInfo
*decoderinfo
;
273 IWICBitmapDecoder
*decoder
= NULL
, *preferred_decoder
= NULL
;
278 TRACE("(%p,%s,%s,%p)\n", iface
, debugstr_guid(guidContainerFormat
),
279 debugstr_guid(pguidVendor
), ppIDecoder
);
281 if (!guidContainerFormat
|| !ppIDecoder
) return E_INVALIDARG
;
283 res
= CreateComponentEnumerator(WICDecoder
, WICComponentEnumerateDefault
, &enumdecoders
);
284 if (FAILED(res
)) return res
;
286 while (!preferred_decoder
)
288 res
= IEnumUnknown_Next(enumdecoders
, 1, &unkdecoderinfo
, &num_fetched
);
289 if (res
!= S_OK
) break;
291 res
= IUnknown_QueryInterface(unkdecoderinfo
, &IID_IWICBitmapDecoderInfo
, (void **)&decoderinfo
);
296 res
= IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo
, &container_guid
);
297 if (SUCCEEDED(res
) && IsEqualIID(&container_guid
, guidContainerFormat
))
299 IWICBitmapDecoder
*new_decoder
;
301 res
= IWICBitmapDecoderInfo_CreateInstance(decoderinfo
, &new_decoder
);
306 res
= IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo
, &vendor
);
307 if (SUCCEEDED(res
) && IsEqualIID(&vendor
, pguidVendor
))
309 preferred_decoder
= new_decoder
;
314 if (new_decoder
&& !decoder
)
316 decoder
= new_decoder
;
320 if (new_decoder
) IWICBitmapDecoder_Release(new_decoder
);
324 IWICBitmapDecoderInfo_Release(decoderinfo
);
327 IUnknown_Release(unkdecoderinfo
);
330 IEnumUnknown_Release(enumdecoders
);
332 if (preferred_decoder
)
334 *ppIDecoder
= preferred_decoder
;
335 if (decoder
) IWICBitmapDecoder_Release(decoder
);
341 *ppIDecoder
= decoder
;
346 return WINCODEC_ERR_COMPONENTNOTFOUND
;
349 static HRESULT WINAPI
ComponentFactory_CreateEncoder(IWICComponentFactory
*iface
,
350 REFGUID guidContainerFormat
, const GUID
*pguidVendor
,
351 IWICBitmapEncoder
**ppIEncoder
)
354 IEnumUnknown
*enumencoders
;
355 IUnknown
*unkencoderinfo
;
356 IWICBitmapEncoderInfo
*encoderinfo
;
357 IWICBitmapEncoder
*encoder
=NULL
;
360 GUID actual_containerformat
;
362 TRACE("(%p,%s,%s,%p)\n", iface
, debugstr_guid(guidContainerFormat
),
363 debugstr_guid(pguidVendor
), ppIEncoder
);
365 if (pguidVendor
&& !fixme
++)
366 FIXME("ignoring vendor GUID\n");
368 res
= CreateComponentEnumerator(WICEncoder
, WICComponentEnumerateDefault
, &enumencoders
);
369 if (FAILED(res
)) return res
;
373 res
= IEnumUnknown_Next(enumencoders
, 1, &unkencoderinfo
, &num_fetched
);
377 res
= IUnknown_QueryInterface(unkencoderinfo
, &IID_IWICBitmapEncoderInfo
, (void**)&encoderinfo
);
381 res
= IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo
, &actual_containerformat
);
383 if (SUCCEEDED(res
) && IsEqualGUID(guidContainerFormat
, &actual_containerformat
))
385 res
= IWICBitmapEncoderInfo_CreateInstance(encoderinfo
, &encoder
);
390 IWICBitmapEncoderInfo_Release(encoderinfo
);
393 IUnknown_Release(unkencoderinfo
);
399 IEnumUnknown_Release(enumencoders
);
403 *ppIEncoder
= encoder
;
408 WARN("failed to create encoder\n");
410 return WINCODEC_ERR_COMPONENTNOTFOUND
;
414 static HRESULT WINAPI
ComponentFactory_CreatePalette(IWICComponentFactory
*iface
,
415 IWICPalette
**ppIPalette
)
417 TRACE("(%p,%p)\n", iface
, ppIPalette
);
418 return PaletteImpl_Create(ppIPalette
);
421 static HRESULT WINAPI
ComponentFactory_CreateFormatConverter(IWICComponentFactory
*iface
,
422 IWICFormatConverter
**ppIFormatConverter
)
424 return FormatConverter_CreateInstance(&IID_IWICFormatConverter
, (void**)ppIFormatConverter
);
427 static HRESULT WINAPI
ComponentFactory_CreateBitmapScaler(IWICComponentFactory
*iface
,
428 IWICBitmapScaler
**ppIBitmapScaler
)
430 TRACE("(%p,%p)\n", iface
, ppIBitmapScaler
);
432 return BitmapScaler_Create(ppIBitmapScaler
);
435 static HRESULT WINAPI
ComponentFactory_CreateBitmapClipper(IWICComponentFactory
*iface
,
436 IWICBitmapClipper
**ppIBitmapClipper
)
438 TRACE("(%p,%p)\n", iface
, ppIBitmapClipper
);
439 return BitmapClipper_Create(ppIBitmapClipper
);
442 static HRESULT WINAPI
ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory
*iface
,
443 IWICBitmapFlipRotator
**ppIBitmapFlipRotator
)
445 TRACE("(%p,%p)\n", iface
, ppIBitmapFlipRotator
);
446 return FlipRotator_Create(ppIBitmapFlipRotator
);
449 static HRESULT WINAPI
ComponentFactory_CreateStream(IWICComponentFactory
*iface
,
450 IWICStream
**ppIWICStream
)
452 TRACE("(%p,%p)\n", iface
, ppIWICStream
);
453 return StreamImpl_Create(ppIWICStream
);
456 static HRESULT WINAPI
ComponentFactory_CreateColorContext(IWICComponentFactory
*iface
,
457 IWICColorContext
**ppIColorContext
)
459 TRACE("(%p,%p)\n", iface
, ppIColorContext
);
460 return ColorContext_Create(ppIColorContext
);
463 static HRESULT WINAPI
ComponentFactory_CreateColorTransformer(IWICComponentFactory
*iface
,
464 IWICColorTransform
**ppIColorTransform
)
466 TRACE("(%p,%p)\n", iface
, ppIColorTransform
);
467 return ColorTransform_Create(ppIColorTransform
);
470 static HRESULT WINAPI
ComponentFactory_CreateBitmap(IWICComponentFactory
*iface
,
471 UINT uiWidth
, UINT uiHeight
, REFWICPixelFormatGUID pixelFormat
,
472 WICBitmapCreateCacheOption option
, IWICBitmap
**ppIBitmap
)
474 TRACE("(%p,%u,%u,%s,%u,%p)\n", iface
, uiWidth
, uiHeight
,
475 debugstr_guid(pixelFormat
), option
, ppIBitmap
);
476 return BitmapImpl_Create(uiWidth
, uiHeight
, 0, 0, NULL
, 0, pixelFormat
, option
, ppIBitmap
);
479 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromSource(IWICComponentFactory
*iface
,
480 IWICBitmapSource
*piBitmapSource
, WICBitmapCreateCacheOption option
,
481 IWICBitmap
**ppIBitmap
)
484 IWICBitmapLock
*lock
;
485 IWICPalette
*palette
;
487 WICPixelFormatGUID pixelformat
= {0};
491 IWICComponentInfo
*info
;
492 IWICPixelFormatInfo2
*formatinfo
;
493 WICPixelFormatNumericRepresentation format_type
;
495 TRACE("(%p,%p,%u,%p)\n", iface
, piBitmapSource
, option
, ppIBitmap
);
497 if (!piBitmapSource
|| !ppIBitmap
)
500 hr
= IWICBitmapSource_GetSize(piBitmapSource
, &width
, &height
);
503 hr
= IWICBitmapSource_GetPixelFormat(piBitmapSource
, &pixelformat
);
506 hr
= CreateComponentInfo(&pixelformat
, &info
);
510 hr
= IWICComponentInfo_QueryInterface(info
, &IID_IWICPixelFormatInfo2
, (void**)&formatinfo
);
514 hr
= IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo
, &format_type
);
516 IWICPixelFormatInfo2_Release(formatinfo
);
519 IWICComponentInfo_Release(info
);
523 hr
= BitmapImpl_Create(width
, height
, 0, 0, NULL
, 0, &pixelformat
, option
, &result
);
527 hr
= IWICBitmap_Lock(result
, NULL
, WICBitmapLockWrite
, &lock
);
530 UINT stride
, buffersize
;
536 hr
= IWICBitmapLock_GetStride(lock
, &stride
);
539 hr
= IWICBitmapLock_GetDataPointer(lock
, &buffersize
, &buffer
);
542 hr
= IWICBitmapSource_CopyPixels(piBitmapSource
, &rc
, stride
,
545 IWICBitmapLock_Release(lock
);
548 if (SUCCEEDED(hr
) && (format_type
== WICPixelFormatNumericRepresentationUnspecified
||
549 format_type
== WICPixelFormatNumericRepresentationIndexed
))
551 hr
= PaletteImpl_Create(&palette
);
555 hr
= IWICBitmapSource_CopyPalette(piBitmapSource
, palette
);
558 hr
= IWICBitmap_SetPalette(result
, palette
);
562 IWICPalette_Release(palette
);
568 hr
= IWICBitmapSource_GetResolution(piBitmapSource
, &dpix
, &dpiy
);
571 hr
= IWICBitmap_SetResolution(result
, dpix
, dpiy
);
579 IWICBitmap_Release(result
);
585 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory
*iface
,
586 IWICBitmapSource
*piBitmapSource
, UINT x
, UINT y
, UINT width
, UINT height
,
587 IWICBitmap
**ppIBitmap
)
589 FIXME("(%p,%p,%u,%u,%u,%u,%p): stub\n", iface
, piBitmapSource
, x
, y
, width
,
594 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory
*iface
,
595 UINT width
, UINT height
, REFWICPixelFormatGUID format
, UINT stride
,
596 UINT size
, BYTE
*buffer
, IWICBitmap
**bitmap
)
600 TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface
, width
, height
,
601 debugstr_guid(format
), stride
, size
, buffer
, bitmap
);
603 if (!stride
|| !size
|| !buffer
|| !bitmap
) return E_INVALIDARG
;
605 hr
= BitmapImpl_Create(width
, height
, stride
, size
, NULL
, 0, format
, WICBitmapCacheOnLoad
, bitmap
);
608 IWICBitmapLock
*lock
;
610 hr
= IWICBitmap_Lock(*bitmap
, NULL
, WICBitmapLockWrite
, &lock
);
616 IWICBitmapLock_GetDataPointer(lock
, &buffersize
, &data
);
617 memcpy(data
, buffer
, buffersize
);
619 IWICBitmapLock_Release(lock
);
623 IWICBitmap_Release(*bitmap
);
630 static BOOL
get_16bpp_format(HBITMAP hbm
, WICPixelFormatGUID
*format
)
636 hdc
= CreateCompatibleDC(0);
638 memset(&bmh
, 0, sizeof(bmh
));
639 bmh
.bV4Size
= sizeof(bmh
);
642 bmh
.bV4V4Compression
= BI_BITFIELDS
;
643 bmh
.bV4BitCount
= 16;
645 GetDIBits(hdc
, hbm
, 0, 0, NULL
, (BITMAPINFO
*)&bmh
, DIB_RGB_COLORS
);
647 if (bmh
.bV4RedMask
== 0x7c00 &&
648 bmh
.bV4GreenMask
== 0x3e0 &&
649 bmh
.bV4BlueMask
== 0x1f)
651 *format
= GUID_WICPixelFormat16bppBGR555
;
653 else if (bmh
.bV4RedMask
== 0xf800 &&
654 bmh
.bV4GreenMask
== 0x7e0 &&
655 bmh
.bV4BlueMask
== 0x1f)
657 *format
= GUID_WICPixelFormat16bppBGR565
;
661 FIXME("unrecognized bitfields %x,%x,%x\n", bmh
.bV4RedMask
,
662 bmh
.bV4GreenMask
, bmh
.bV4BlueMask
);
670 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory
*iface
,
671 HBITMAP hbm
, HPALETTE hpal
, WICBitmapAlphaChannelOption option
, IWICBitmap
**bitmap
)
675 WICPixelFormatGUID format
;
676 IWICBitmapLock
*lock
;
677 UINT size
, num_palette_entries
= 0;
678 PALETTEENTRY entry
[256];
680 TRACE("(%p,%p,%p,%u,%p)\n", iface
, hbm
, hpal
, option
, bitmap
);
682 if (!bitmap
) return E_INVALIDARG
;
684 if (GetObjectW(hbm
, sizeof(bm
), &bm
) != sizeof(bm
))
685 return WINCODEC_ERR_WIN32ERROR
;
689 num_palette_entries
= GetPaletteEntries(hpal
, 0, 256, entry
);
690 if (!num_palette_entries
)
691 return WINCODEC_ERR_WIN32ERROR
;
694 /* TODO: Figure out the correct format for 16, 32, 64 bpp */
695 switch(bm
.bmBitsPixel
)
698 format
= GUID_WICPixelFormat1bppIndexed
;
701 format
= GUID_WICPixelFormat4bppIndexed
;
704 format
= GUID_WICPixelFormat8bppIndexed
;
707 if (!get_16bpp_format(hbm
, &format
))
711 format
= GUID_WICPixelFormat24bppBGR
;
716 case WICBitmapUseAlpha
:
717 format
= GUID_WICPixelFormat32bppBGRA
;
719 case WICBitmapUsePremultipliedAlpha
:
720 format
= GUID_WICPixelFormat32bppPBGRA
;
722 case WICBitmapIgnoreAlpha
:
723 format
= GUID_WICPixelFormat32bppBGR
;
730 format
= GUID_WICPixelFormat48bppRGB
;
733 FIXME("unsupported %d bpp\n", bm
.bmBitsPixel
);
737 hr
= BitmapImpl_Create(bm
.bmWidth
, bm
.bmHeight
, bm
.bmWidthBytes
, 0, NULL
, 0, &format
,
738 WICBitmapCacheOnLoad
, bitmap
);
739 if (hr
!= S_OK
) return hr
;
741 hr
= IWICBitmap_Lock(*bitmap
, NULL
, WICBitmapLockWrite
, &lock
);
746 char bmibuf
[FIELD_OFFSET(BITMAPINFO
, bmiColors
[256])];
747 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmibuf
;
749 IWICBitmapLock_GetDataPointer(lock
, &size
, &buffer
);
751 hdc
= CreateCompatibleDC(0);
753 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
754 bmi
->bmiHeader
.biBitCount
= 0;
755 GetDIBits(hdc
, hbm
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
756 bmi
->bmiHeader
.biHeight
= -bm
.bmHeight
;
757 GetDIBits(hdc
, hbm
, 0, bm
.bmHeight
, buffer
, bmi
, DIB_RGB_COLORS
);
760 IWICBitmapLock_Release(lock
);
762 if (num_palette_entries
)
764 IWICPalette
*palette
;
765 WICColor colors
[256];
768 hr
= PaletteImpl_Create(&palette
);
771 for (i
= 0; i
< num_palette_entries
; i
++)
772 colors
[i
] = 0xff000000 | entry
[i
].peRed
<< 16 |
773 entry
[i
].peGreen
<< 8 | entry
[i
].peBlue
;
775 hr
= IWICPalette_InitializeCustom(palette
, colors
, num_palette_entries
);
777 hr
= IWICBitmap_SetPalette(*bitmap
, palette
);
779 IWICPalette_Release(palette
);
786 IWICBitmap_Release(*bitmap
);
793 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory
*iface
,
794 HICON hicon
, IWICBitmap
**bitmap
)
796 IWICBitmapLock
*lock
;
799 int width
, height
, x
, y
;
808 TRACE("(%p,%p,%p)\n", iface
, hicon
, bitmap
);
810 if (!bitmap
) return E_INVALIDARG
;
812 if (!GetIconInfo(hicon
, &info
))
813 return HRESULT_FROM_WIN32(GetLastError());
815 GetObjectW(info
.hbmColor
? info
.hbmColor
: info
.hbmMask
, sizeof(bm
), &bm
);
818 height
= info
.hbmColor
? abs(bm
.bmHeight
) : abs(bm
.bmHeight
) / 2;
820 size
= stride
* height
;
822 hr
= BitmapImpl_Create(width
, height
, stride
, size
, NULL
, 0,
823 &GUID_WICPixelFormat32bppBGRA
, WICBitmapCacheOnLoad
, bitmap
);
824 if (hr
!= S_OK
) goto failed
;
826 hr
= IWICBitmap_Lock(*bitmap
, NULL
, WICBitmapLockWrite
, &lock
);
829 IWICBitmap_Release(*bitmap
);
832 IWICBitmapLock_GetDataPointer(lock
, &size
, &buffer
);
834 hdc
= CreateCompatibleDC(0);
836 memset(&bi
, 0, sizeof(bi
));
837 bi
.bmiHeader
.biSize
= sizeof(bi
.bmiHeader
);
838 bi
.bmiHeader
.biWidth
= width
;
839 bi
.bmiHeader
.biHeight
= info
.hbmColor
? -height
: -height
* 2;
840 bi
.bmiHeader
.biPlanes
= 1;
841 bi
.bmiHeader
.biBitCount
= 32;
842 bi
.bmiHeader
.biCompression
= BI_RGB
;
848 GetDIBits(hdc
, info
.hbmColor
, 0, height
, buffer
, &bi
, DIB_RGB_COLORS
);
850 if (bm
.bmBitsPixel
== 32)
852 /* If any pixel has a non-zero alpha, ignore hbmMask */
853 bits
= (DWORD
*)buffer
;
854 for (x
= 0; x
< width
&& !has_alpha
; x
++, bits
++)
856 for (y
= 0; y
< height
; y
++)
858 if (*bits
& 0xff000000)
868 GetDIBits(hdc
, info
.hbmMask
, 0, height
, buffer
, &bi
, DIB_RGB_COLORS
);
878 mask
= HeapAlloc(GetProcessHeap(), 0, size
);
881 IWICBitmapLock_Release(lock
);
882 IWICBitmap_Release(*bitmap
);
888 /* read alpha data from the mask */
889 GetDIBits(hdc
, info
.hbmMask
, info
.hbmColor
? 0 : height
, height
, mask
, &bi
, DIB_RGB_COLORS
);
891 for (y
= 0; y
< height
; y
++)
893 rgba
= (DWORD
*)(buffer
+ y
* stride
);
894 bits
= (DWORD
*)(mask
+ y
* stride
);
896 for (x
= 0; x
< width
; x
++, rgba
++, bits
++)
905 HeapFree(GetProcessHeap(), 0, mask
);
909 /* set constant alpha of 255 */
910 for (y
= 0; y
< height
; y
++)
912 rgba
= (DWORD
*)(buffer
+ y
* stride
);
913 for (x
= 0; x
< width
; x
++, rgba
++)
920 IWICBitmapLock_Release(lock
);
924 DeleteObject(info
.hbmColor
);
925 DeleteObject(info
.hbmMask
);
930 static HRESULT WINAPI
ComponentFactory_CreateComponentEnumerator(IWICComponentFactory
*iface
,
931 DWORD componentTypes
, DWORD options
, IEnumUnknown
**ppIEnumUnknown
)
933 TRACE("(%p,%u,%u,%p)\n", iface
, componentTypes
, options
, ppIEnumUnknown
);
934 return CreateComponentEnumerator(componentTypes
, options
, ppIEnumUnknown
);
937 static HRESULT WINAPI
ComponentFactory_CreateFastMetadataEncoderFromDecoder(
938 IWICComponentFactory
*iface
, IWICBitmapDecoder
*pIDecoder
,
939 IWICFastMetadataEncoder
**ppIFastEncoder
)
941 FIXME("(%p,%p,%p): stub\n", iface
, pIDecoder
, ppIFastEncoder
);
945 static HRESULT WINAPI
ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(
946 IWICComponentFactory
*iface
, IWICBitmapFrameDecode
*pIFrameDecoder
,
947 IWICFastMetadataEncoder
**ppIFastEncoder
)
949 FIXME("(%p,%p,%p): stub\n", iface
, pIFrameDecoder
, ppIFastEncoder
);
953 static HRESULT WINAPI
ComponentFactory_CreateQueryWriter(IWICComponentFactory
*iface
,
954 REFGUID guidMetadataFormat
, const GUID
*pguidVendor
,
955 IWICMetadataQueryWriter
**ppIQueryWriter
)
957 FIXME("(%p,%s,%s,%p): stub\n", iface
, debugstr_guid(guidMetadataFormat
),
958 debugstr_guid(pguidVendor
), ppIQueryWriter
);
962 static HRESULT WINAPI
ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory
*iface
,
963 IWICMetadataQueryReader
*pIQueryReader
, const GUID
*pguidVendor
,
964 IWICMetadataQueryWriter
**ppIQueryWriter
)
966 FIXME("(%p,%p,%s,%p): stub\n", iface
, pIQueryReader
, debugstr_guid(pguidVendor
),
971 static HRESULT WINAPI
ComponentFactory_CreateMetadataReader(IWICComponentFactory
*iface
,
972 REFGUID format
, const GUID
*vendor
, DWORD options
, IStream
*stream
, IWICMetadataReader
**reader
)
974 FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
),
975 options
, stream
, reader
);
979 static HRESULT WINAPI
ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory
*iface
,
980 REFGUID format
, const GUID
*vendor
, DWORD options
, IStream
*stream
, IWICMetadataReader
**reader
)
983 IEnumUnknown
*enumreaders
;
984 IUnknown
*unkreaderinfo
;
985 IWICMetadataReaderInfo
*readerinfo
;
986 IWICPersistStream
*wicpersiststream
;
992 TRACE("%p,%s,%s,%x,%p,%p\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
),
993 options
, stream
, reader
);
995 if (!format
|| !stream
|| !reader
)
1000 hr
= CreateComponentEnumerator(WICMetadataReader
, WICComponentEnumerateDefault
, &enumreaders
);
1001 if (FAILED(hr
)) return hr
;
1008 hr
= IEnumUnknown_Next(enumreaders
, 1, &unkreaderinfo
, &num_fetched
);
1012 hr
= IUnknown_QueryInterface(unkreaderinfo
, &IID_IWICMetadataReaderInfo
, (void**)&readerinfo
);
1018 hr
= IWICMetadataReaderInfo_GetVendorGUID(readerinfo
, &decoder_vendor
);
1020 if (FAILED(hr
) || !IsEqualIID(vendor
, &decoder_vendor
))
1022 IWICMetadataReaderInfo_Release(readerinfo
);
1023 IUnknown_Release(unkreaderinfo
);
1028 hr
= IWICMetadataReaderInfo_MatchesPattern(readerinfo
, format
, stream
, &matches
);
1030 if (SUCCEEDED(hr
) && matches
)
1032 hr
= IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
1035 hr
= IWICMetadataReaderInfo_CreateInstance(readerinfo
, reader
);
1039 hr
= IWICMetadataReader_QueryInterface(*reader
, &IID_IWICPersistStream
, (void**)&wicpersiststream
);
1043 hr
= IWICPersistStream_LoadEx(wicpersiststream
,
1044 stream
, vendor
, options
& WICPersistOptionMask
);
1046 IWICPersistStream_Release(wicpersiststream
);
1051 IWICMetadataReader_Release(*reader
);
1057 IUnknown_Release(readerinfo
);
1060 IUnknown_Release(unkreaderinfo
);
1066 if (!*reader
&& vendor
)
1069 IEnumUnknown_Reset(enumreaders
);
1073 IEnumUnknown_Release(enumreaders
);
1075 if (!*reader
&& !(options
& WICMetadataCreationFailUnknown
))
1077 hr
= IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
1080 hr
= UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader
, (void**)reader
);
1084 hr
= IWICMetadataReader_QueryInterface(*reader
, &IID_IWICPersistStream
, (void**)&wicpersiststream
);
1088 hr
= IWICPersistStream_LoadEx(wicpersiststream
, stream
, NULL
, options
& WICPersistOptionMask
);
1090 IWICPersistStream_Release(wicpersiststream
);
1095 IWICMetadataReader_Release(*reader
);
1104 return WINCODEC_ERR_COMPONENTNOTFOUND
;
1107 static HRESULT WINAPI
ComponentFactory_CreateMetadataWriter(IWICComponentFactory
*iface
,
1108 REFGUID format
, const GUID
*vendor
, DWORD options
, IWICMetadataWriter
**writer
)
1110 FIXME("%p,%s,%s,%x,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
), options
, writer
);
1114 static HRESULT WINAPI
ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory
*iface
,
1115 IWICMetadataReader
*reader
, const GUID
*vendor
, IWICMetadataWriter
**writer
)
1117 FIXME("%p,%p,%s,%p: stub\n", iface
, reader
, debugstr_guid(vendor
), writer
);
1121 static HRESULT WINAPI
ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory
*iface
,
1122 IWICMetadataBlockReader
*block_reader
, IWICMetadataQueryReader
**query_reader
)
1124 TRACE("%p,%p,%p\n", iface
, block_reader
, query_reader
);
1126 if (!block_reader
|| !query_reader
)
1127 return E_INVALIDARG
;
1129 return MetadataQueryReader_CreateInstance(block_reader
, NULL
, query_reader
);
1132 static HRESULT WINAPI
ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory
*iface
,
1133 IWICMetadataBlockWriter
*block_writer
, IWICMetadataQueryWriter
**query_writer
)
1135 FIXME("%p,%p,%p: stub\n", iface
, block_writer
, query_writer
);
1139 static HRESULT WINAPI
ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory
*iface
,
1140 PROPBAG2
*options
, UINT count
, IPropertyBag2
**property
)
1142 TRACE("(%p,%p,%u,%p)\n", iface
, options
, count
, property
);
1143 return CreatePropertyBag2(options
, count
, property
);
1146 static const IWICComponentFactoryVtbl ComponentFactory_Vtbl
= {
1147 ComponentFactory_QueryInterface
,
1148 ComponentFactory_AddRef
,
1149 ComponentFactory_Release
,
1150 ComponentFactory_CreateDecoderFromFilename
,
1151 ComponentFactory_CreateDecoderFromStream
,
1152 ComponentFactory_CreateDecoderFromFileHandle
,
1153 ComponentFactory_CreateComponentInfo
,
1154 ComponentFactory_CreateDecoder
,
1155 ComponentFactory_CreateEncoder
,
1156 ComponentFactory_CreatePalette
,
1157 ComponentFactory_CreateFormatConverter
,
1158 ComponentFactory_CreateBitmapScaler
,
1159 ComponentFactory_CreateBitmapClipper
,
1160 ComponentFactory_CreateBitmapFlipRotator
,
1161 ComponentFactory_CreateStream
,
1162 ComponentFactory_CreateColorContext
,
1163 ComponentFactory_CreateColorTransformer
,
1164 ComponentFactory_CreateBitmap
,
1165 ComponentFactory_CreateBitmapFromSource
,
1166 ComponentFactory_CreateBitmapFromSourceRect
,
1167 ComponentFactory_CreateBitmapFromMemory
,
1168 ComponentFactory_CreateBitmapFromHBITMAP
,
1169 ComponentFactory_CreateBitmapFromHICON
,
1170 ComponentFactory_CreateComponentEnumerator
,
1171 ComponentFactory_CreateFastMetadataEncoderFromDecoder
,
1172 ComponentFactory_CreateFastMetadataEncoderFromFrameDecode
,
1173 ComponentFactory_CreateQueryWriter
,
1174 ComponentFactory_CreateQueryWriterFromReader
,
1175 ComponentFactory_CreateMetadataReader
,
1176 ComponentFactory_CreateMetadataReaderFromContainer
,
1177 ComponentFactory_CreateMetadataWriter
,
1178 ComponentFactory_CreateMetadataWriterFromReader
,
1179 ComponentFactory_CreateQueryReaderFromBlockReader
,
1180 ComponentFactory_CreateQueryWriterFromBlockWriter
,
1181 ComponentFactory_CreateEncoderPropertyBag
1184 HRESULT
ComponentFactory_CreateInstance(REFIID iid
, void** ppv
)
1186 ComponentFactory
*This
;
1189 TRACE("(%s,%p)\n", debugstr_guid(iid
), ppv
);
1193 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentFactory
));
1194 if (!This
) return E_OUTOFMEMORY
;
1196 This
->IWICComponentFactory_iface
.lpVtbl
= &ComponentFactory_Vtbl
;
1199 ret
= IWICComponentFactory_QueryInterface(&This
->IWICComponentFactory_iface
, iid
, ppv
);
1200 IWICComponentFactory_Release(&This
->IWICComponentFactory_iface
);
1205 HRESULT WINAPI
WICCreateBitmapFromSectionEx(UINT width
, UINT height
,
1206 REFWICPixelFormatGUID format
, HANDLE section
, UINT stride
,
1207 UINT offset
, WICSectionAccessLevel wicaccess
, IWICBitmap
**bitmap
)
1209 SYSTEM_INFO sysinfo
;
1210 UINT bpp
, access
, size
, view_offset
, view_size
;
1214 TRACE("%u,%u,%s,%p,%u,%u,%#x,%p\n", width
, height
, debugstr_guid(format
),
1215 section
, stride
, offset
, wicaccess
, bitmap
);
1217 if (!width
|| !height
|| !section
|| !bitmap
) return E_INVALIDARG
;
1219 hr
= get_pixelformat_bpp(format
, &bpp
);
1220 if (FAILED(hr
)) return hr
;
1224 case WICSectionAccessLevelReadWrite
:
1225 access
= FILE_MAP_READ
| FILE_MAP_WRITE
;
1228 case WICSectionAccessLevelRead
:
1229 access
= FILE_MAP_READ
;
1233 FIXME("unsupported access %#x\n", wicaccess
);
1234 return E_INVALIDARG
;
1237 if (!stride
) stride
= (((bpp
* width
) + 31) / 32) * 4;
1238 size
= stride
* height
;
1239 if (size
/ height
!= stride
) return E_INVALIDARG
;
1241 GetSystemInfo(&sysinfo
);
1242 view_offset
= offset
- (offset
% sysinfo
.dwAllocationGranularity
);
1243 view_size
= size
+ (offset
- view_offset
);
1245 view
= MapViewOfFile(section
, access
, 0, view_offset
, view_size
);
1246 if (!view
) return HRESULT_FROM_WIN32(GetLastError());
1248 offset
-= view_offset
;
1249 hr
= BitmapImpl_Create(width
, height
, stride
, 0, view
, offset
, format
, WICBitmapCacheOnLoad
, bitmap
);
1250 if (FAILED(hr
)) UnmapViewOfFile(view
);
1254 HRESULT WINAPI
WICCreateBitmapFromSection(UINT width
, UINT height
,
1255 REFWICPixelFormatGUID format
, HANDLE section
,
1256 UINT stride
, UINT offset
, IWICBitmap
**bitmap
)
1258 TRACE("%u,%u,%s,%p,%u,%u,%p\n", width
, height
, debugstr_guid(format
),
1259 section
, stride
, offset
, bitmap
);
1261 return WICCreateBitmapFromSectionEx(width
, height
, format
, section
,
1262 stride
, offset
, WICSectionAccessLevelRead
, bitmap
);