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
20 #include "wincodecs_private.h"
23 IWICComponentFactory IWICComponentFactory_iface
;
27 static inline ComponentFactory
*impl_from_IWICComponentFactory(IWICComponentFactory
*iface
)
29 return CONTAINING_RECORD(iface
, ComponentFactory
, IWICComponentFactory_iface
);
32 static HRESULT WINAPI
ComponentFactory_QueryInterface(IWICComponentFactory
*iface
, REFIID iid
,
35 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
36 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
38 if (!ppv
) return E_INVALIDARG
;
40 if (IsEqualIID(&IID_IUnknown
, iid
) ||
41 IsEqualIID(&IID_IWICImagingFactory
, iid
) ||
42 IsEqualIID(&IID_IWICComponentFactory
, iid
))
44 *ppv
= &This
->IWICComponentFactory_iface
;
52 IUnknown_AddRef((IUnknown
*)*ppv
);
56 static ULONG WINAPI
ComponentFactory_AddRef(IWICComponentFactory
*iface
)
58 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
59 ULONG ref
= InterlockedIncrement(&This
->ref
);
61 TRACE("(%p) refcount=%u\n", iface
, ref
);
66 static ULONG WINAPI
ComponentFactory_Release(IWICComponentFactory
*iface
)
68 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
69 ULONG ref
= InterlockedDecrement(&This
->ref
);
71 TRACE("(%p) refcount=%u\n", iface
, ref
);
74 HeapFree(GetProcessHeap(), 0, This
);
79 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromFilename(
80 IWICComponentFactory
*iface
, LPCWSTR wzFilename
, const GUID
*pguidVendor
,
81 DWORD dwDesiredAccess
, WICDecodeOptions metadataOptions
,
82 IWICBitmapDecoder
**ppIDecoder
)
87 TRACE("(%p,%s,%s,%u,%u,%p)\n", iface
, debugstr_w(wzFilename
),
88 debugstr_guid(pguidVendor
), dwDesiredAccess
, metadataOptions
, ppIDecoder
);
90 hr
= StreamImpl_Create(&stream
);
93 hr
= IWICStream_InitializeFromFilename(stream
, wzFilename
, dwDesiredAccess
);
97 hr
= IWICComponentFactory_CreateDecoderFromStream(iface
, (IStream
*)stream
,
98 pguidVendor
, metadataOptions
, ppIDecoder
);
101 IWICStream_Release(stream
);
107 static IWICBitmapDecoder
*find_decoder(IStream
*pIStream
, const GUID
*pguidVendor
,
108 WICDecodeOptions metadataOptions
)
110 IEnumUnknown
*enumdecoders
;
111 IUnknown
*unkdecoderinfo
;
112 IWICBitmapDecoderInfo
*decoderinfo
;
113 IWICBitmapDecoder
*decoder
= NULL
;
119 res
= CreateComponentEnumerator(WICDecoder
, WICComponentEnumerateDefault
, &enumdecoders
);
120 if (FAILED(res
)) return NULL
;
124 res
= IEnumUnknown_Next(enumdecoders
, 1, &unkdecoderinfo
, &num_fetched
);
128 res
= IUnknown_QueryInterface(unkdecoderinfo
, &IID_IWICBitmapDecoderInfo
, (void**)&decoderinfo
);
134 res
= IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo
, &vendor
);
135 if (FAILED(res
) || !IsEqualIID(&vendor
, pguidVendor
))
137 IWICBitmapDecoderInfo_Release(decoderinfo
);
138 IUnknown_Release(unkdecoderinfo
);
143 res
= IWICBitmapDecoderInfo_MatchesPattern(decoderinfo
, pIStream
, &matches
);
145 if (SUCCEEDED(res
) && matches
)
147 res
= IWICBitmapDecoderInfo_CreateInstance(decoderinfo
, &decoder
);
149 /* FIXME: should use QueryCapability to choose a decoder */
153 res
= IWICBitmapDecoder_Initialize(decoder
, pIStream
, metadataOptions
);
157 IWICBitmapDecoder_Release(decoder
);
163 IWICBitmapDecoderInfo_Release(decoderinfo
);
166 IUnknown_Release(unkdecoderinfo
);
172 IEnumUnknown_Release(enumdecoders
);
177 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromStream(
178 IWICComponentFactory
*iface
, IStream
*pIStream
, const GUID
*pguidVendor
,
179 WICDecodeOptions metadataOptions
, IWICBitmapDecoder
**ppIDecoder
)
182 IWICBitmapDecoder
*decoder
= NULL
;
184 TRACE("(%p,%p,%s,%u,%p)\n", iface
, pIStream
, debugstr_guid(pguidVendor
),
185 metadataOptions
, ppIDecoder
);
188 decoder
= find_decoder(pIStream
, pguidVendor
, metadataOptions
);
190 decoder
= find_decoder(pIStream
, NULL
, metadataOptions
);
194 *ppIDecoder
= decoder
;
199 if (WARN_ON(wincodecs
))
205 WARN("failed to load from a stream\n");
208 res
= IStream_Seek(pIStream
, seek
, STREAM_SEEK_SET
, NULL
);
210 res
= IStream_Read(pIStream
, data
, 4, &bytesread
);
212 WARN("first %i bytes of stream=%x %x %x %x\n", bytesread
, data
[0], data
[1], data
[2], data
[3]);
215 return WINCODEC_ERR_COMPONENTNOTFOUND
;
219 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromFileHandle(
220 IWICComponentFactory
*iface
, ULONG_PTR hFile
, const GUID
*pguidVendor
,
221 WICDecodeOptions metadataOptions
, IWICBitmapDecoder
**ppIDecoder
)
226 TRACE("(%p,%lx,%s,%u,%p)\n", iface
, hFile
, debugstr_guid(pguidVendor
),
227 metadataOptions
, ppIDecoder
);
229 hr
= StreamImpl_Create(&stream
);
232 hr
= stream_initialize_from_filehandle(stream
, (HANDLE
)hFile
);
235 hr
= IWICComponentFactory_CreateDecoderFromStream(iface
, (IStream
*)stream
,
236 pguidVendor
, metadataOptions
, ppIDecoder
);
238 IWICStream_Release(stream
);
243 static HRESULT WINAPI
ComponentFactory_CreateComponentInfo(IWICComponentFactory
*iface
,
244 REFCLSID clsidComponent
, IWICComponentInfo
**ppIInfo
)
246 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(clsidComponent
), ppIInfo
);
247 return CreateComponentInfo(clsidComponent
, ppIInfo
);
250 static HRESULT WINAPI
ComponentFactory_CreateDecoder(IWICComponentFactory
*iface
,
251 REFGUID guidContainerFormat
, const GUID
*pguidVendor
,
252 IWICBitmapDecoder
**ppIDecoder
)
254 IEnumUnknown
*enumdecoders
;
255 IUnknown
*unkdecoderinfo
;
256 IWICBitmapDecoderInfo
*decoderinfo
;
257 IWICBitmapDecoder
*decoder
= NULL
, *preferred_decoder
= NULL
;
262 TRACE("(%p,%s,%s,%p)\n", iface
, debugstr_guid(guidContainerFormat
),
263 debugstr_guid(pguidVendor
), ppIDecoder
);
265 if (!guidContainerFormat
|| !ppIDecoder
) return E_INVALIDARG
;
267 res
= CreateComponentEnumerator(WICDecoder
, WICComponentEnumerateDefault
, &enumdecoders
);
268 if (FAILED(res
)) return res
;
270 while (!preferred_decoder
)
272 res
= IEnumUnknown_Next(enumdecoders
, 1, &unkdecoderinfo
, &num_fetched
);
273 if (res
!= S_OK
) break;
275 res
= IUnknown_QueryInterface(unkdecoderinfo
, &IID_IWICBitmapDecoderInfo
, (void **)&decoderinfo
);
280 res
= IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo
, &container_guid
);
281 if (SUCCEEDED(res
) && IsEqualIID(&container_guid
, guidContainerFormat
))
283 IWICBitmapDecoder
*new_decoder
;
285 res
= IWICBitmapDecoderInfo_CreateInstance(decoderinfo
, &new_decoder
);
290 res
= IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo
, &vendor
);
291 if (SUCCEEDED(res
) && IsEqualIID(&vendor
, pguidVendor
))
293 preferred_decoder
= new_decoder
;
298 if (new_decoder
&& !decoder
)
300 decoder
= new_decoder
;
304 if (new_decoder
) IWICBitmapDecoder_Release(new_decoder
);
308 IWICBitmapDecoderInfo_Release(decoderinfo
);
311 IUnknown_Release(unkdecoderinfo
);
314 IEnumUnknown_Release(enumdecoders
);
316 if (preferred_decoder
)
318 *ppIDecoder
= preferred_decoder
;
319 if (decoder
) IWICBitmapDecoder_Release(decoder
);
325 *ppIDecoder
= decoder
;
330 return WINCODEC_ERR_COMPONENTNOTFOUND
;
333 static HRESULT WINAPI
ComponentFactory_CreateEncoder(IWICComponentFactory
*iface
,
334 REFGUID guidContainerFormat
, const GUID
*pguidVendor
,
335 IWICBitmapEncoder
**ppIEncoder
)
338 IEnumUnknown
*enumencoders
;
339 IUnknown
*unkencoderinfo
;
340 IWICBitmapEncoderInfo
*encoderinfo
;
341 IWICBitmapEncoder
*encoder
=NULL
;
344 GUID actual_containerformat
;
346 TRACE("(%p,%s,%s,%p)\n", iface
, debugstr_guid(guidContainerFormat
),
347 debugstr_guid(pguidVendor
), ppIEncoder
);
349 if (pguidVendor
&& !fixme
++)
350 FIXME("ignoring vendor GUID\n");
352 res
= CreateComponentEnumerator(WICEncoder
, WICComponentEnumerateDefault
, &enumencoders
);
353 if (FAILED(res
)) return res
;
357 res
= IEnumUnknown_Next(enumencoders
, 1, &unkencoderinfo
, &num_fetched
);
361 res
= IUnknown_QueryInterface(unkencoderinfo
, &IID_IWICBitmapEncoderInfo
, (void**)&encoderinfo
);
365 res
= IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo
, &actual_containerformat
);
367 if (SUCCEEDED(res
) && IsEqualGUID(guidContainerFormat
, &actual_containerformat
))
369 res
= IWICBitmapEncoderInfo_CreateInstance(encoderinfo
, &encoder
);
374 IWICBitmapEncoderInfo_Release(encoderinfo
);
377 IUnknown_Release(unkencoderinfo
);
383 IEnumUnknown_Release(enumencoders
);
387 *ppIEncoder
= encoder
;
392 WARN("failed to create encoder\n");
394 return WINCODEC_ERR_COMPONENTNOTFOUND
;
398 static HRESULT WINAPI
ComponentFactory_CreatePalette(IWICComponentFactory
*iface
,
399 IWICPalette
**ppIPalette
)
401 TRACE("(%p,%p)\n", iface
, ppIPalette
);
402 return PaletteImpl_Create(ppIPalette
);
405 static HRESULT WINAPI
ComponentFactory_CreateFormatConverter(IWICComponentFactory
*iface
,
406 IWICFormatConverter
**ppIFormatConverter
)
408 return FormatConverter_CreateInstance(&IID_IWICFormatConverter
, (void**)ppIFormatConverter
);
411 static HRESULT WINAPI
ComponentFactory_CreateBitmapScaler(IWICComponentFactory
*iface
,
412 IWICBitmapScaler
**ppIBitmapScaler
)
414 TRACE("(%p,%p)\n", iface
, ppIBitmapScaler
);
416 return BitmapScaler_Create(ppIBitmapScaler
);
419 static HRESULT WINAPI
ComponentFactory_CreateBitmapClipper(IWICComponentFactory
*iface
,
420 IWICBitmapClipper
**ppIBitmapClipper
)
422 TRACE("(%p,%p)\n", iface
, ppIBitmapClipper
);
423 return BitmapClipper_Create(ppIBitmapClipper
);
426 static HRESULT WINAPI
ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory
*iface
,
427 IWICBitmapFlipRotator
**ppIBitmapFlipRotator
)
429 TRACE("(%p,%p)\n", iface
, ppIBitmapFlipRotator
);
430 return FlipRotator_Create(ppIBitmapFlipRotator
);
433 static HRESULT WINAPI
ComponentFactory_CreateStream(IWICComponentFactory
*iface
,
434 IWICStream
**ppIWICStream
)
436 TRACE("(%p,%p)\n", iface
, ppIWICStream
);
437 return StreamImpl_Create(ppIWICStream
);
440 static HRESULT WINAPI
ComponentFactory_CreateColorContext(IWICComponentFactory
*iface
,
441 IWICColorContext
**ppIColorContext
)
443 TRACE("(%p,%p)\n", iface
, ppIColorContext
);
444 return ColorContext_Create(ppIColorContext
);
447 static HRESULT WINAPI
ComponentFactory_CreateColorTransformer(IWICComponentFactory
*iface
,
448 IWICColorTransform
**ppIColorTransform
)
450 TRACE("(%p,%p)\n", iface
, ppIColorTransform
);
451 return ColorTransform_Create(ppIColorTransform
);
454 static HRESULT WINAPI
ComponentFactory_CreateBitmap(IWICComponentFactory
*iface
,
455 UINT uiWidth
, UINT uiHeight
, REFWICPixelFormatGUID pixelFormat
,
456 WICBitmapCreateCacheOption option
, IWICBitmap
**ppIBitmap
)
458 TRACE("(%p,%u,%u,%s,%u,%p)\n", iface
, uiWidth
, uiHeight
,
459 debugstr_guid(pixelFormat
), option
, ppIBitmap
);
460 return BitmapImpl_Create(uiWidth
, uiHeight
, 0, 0, NULL
, pixelFormat
, option
, ppIBitmap
);
463 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromSource(IWICComponentFactory
*iface
,
464 IWICBitmapSource
*piBitmapSource
, WICBitmapCreateCacheOption option
,
465 IWICBitmap
**ppIBitmap
)
468 IWICBitmapLock
*lock
;
469 IWICPalette
*palette
;
471 WICPixelFormatGUID pixelformat
= {0};
475 IWICComponentInfo
*info
;
476 IWICPixelFormatInfo2
*formatinfo
;
477 WICPixelFormatNumericRepresentation format_type
;
479 TRACE("(%p,%p,%u,%p)\n", iface
, piBitmapSource
, option
, ppIBitmap
);
481 if (!piBitmapSource
|| !ppIBitmap
)
484 hr
= IWICBitmapSource_GetSize(piBitmapSource
, &width
, &height
);
487 hr
= IWICBitmapSource_GetPixelFormat(piBitmapSource
, &pixelformat
);
490 hr
= CreateComponentInfo(&pixelformat
, &info
);
494 hr
= IWICComponentInfo_QueryInterface(info
, &IID_IWICPixelFormatInfo2
, (void**)&formatinfo
);
498 hr
= IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo
, &format_type
);
500 IWICPixelFormatInfo2_Release(formatinfo
);
503 IWICComponentInfo_Release(info
);
507 hr
= BitmapImpl_Create(width
, height
, 0, 0, NULL
, &pixelformat
, option
, &result
);
511 hr
= IWICBitmap_Lock(result
, NULL
, WICBitmapLockWrite
, &lock
);
514 UINT stride
, buffersize
;
520 hr
= IWICBitmapLock_GetStride(lock
, &stride
);
523 hr
= IWICBitmapLock_GetDataPointer(lock
, &buffersize
, &buffer
);
526 hr
= IWICBitmapSource_CopyPixels(piBitmapSource
, &rc
, stride
,
529 IWICBitmapLock_Release(lock
);
533 hr
= PaletteImpl_Create(&palette
);
535 if (SUCCEEDED(hr
) && (format_type
== WICPixelFormatNumericRepresentationUnspecified
||
536 format_type
== WICPixelFormatNumericRepresentationIndexed
))
538 hr
= IWICBitmapSource_CopyPalette(piBitmapSource
, palette
);
541 hr
= IWICBitmap_SetPalette(result
, palette
);
545 IWICPalette_Release(palette
);
550 hr
= IWICBitmapSource_GetResolution(piBitmapSource
, &dpix
, &dpiy
);
553 hr
= IWICBitmap_SetResolution(result
, dpix
, dpiy
);
561 IWICBitmap_Release(result
);
567 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory
*iface
,
568 IWICBitmapSource
*piBitmapSource
, UINT x
, UINT y
, UINT width
, UINT height
,
569 IWICBitmap
**ppIBitmap
)
571 FIXME("(%p,%p,%u,%u,%u,%u,%p): stub\n", iface
, piBitmapSource
, x
, y
, width
,
576 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory
*iface
,
577 UINT width
, UINT height
, REFWICPixelFormatGUID format
, UINT stride
,
578 UINT size
, BYTE
*buffer
, IWICBitmap
**bitmap
)
580 TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface
, width
, height
,
581 debugstr_guid(format
), stride
, size
, buffer
, bitmap
);
583 if (!stride
|| !size
|| !buffer
|| !bitmap
) return E_INVALIDARG
;
585 return BitmapImpl_Create(width
, height
, stride
, size
, buffer
, format
, WICBitmapCacheOnLoad
, bitmap
);
588 static BOOL
get_16bpp_format(HBITMAP hbm
, WICPixelFormatGUID
*format
)
594 hdc
= CreateCompatibleDC(0);
596 memset(&bmh
, 0, sizeof(bmh
));
597 bmh
.bV4Size
= sizeof(bmh
);
600 bmh
.bV4V4Compression
= BI_BITFIELDS
;
601 bmh
.bV4BitCount
= 16;
603 GetDIBits(hdc
, hbm
, 0, 0, NULL
, (BITMAPINFO
*)&bmh
, DIB_RGB_COLORS
);
605 if (bmh
.bV4RedMask
== 0x7c00 &&
606 bmh
.bV4GreenMask
== 0x3e0 &&
607 bmh
.bV4BlueMask
== 0x1f)
609 *format
= GUID_WICPixelFormat16bppBGR555
;
611 else if (bmh
.bV4RedMask
== 0xf800 &&
612 bmh
.bV4GreenMask
== 0x7e0 &&
613 bmh
.bV4BlueMask
== 0x1f)
615 *format
= GUID_WICPixelFormat16bppBGR565
;
619 FIXME("unrecognized bitfields %x,%x,%x\n", bmh
.bV4RedMask
,
620 bmh
.bV4GreenMask
, bmh
.bV4BlueMask
);
628 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory
*iface
,
629 HBITMAP hbm
, HPALETTE hpal
, WICBitmapAlphaChannelOption option
, IWICBitmap
**bitmap
)
633 WICPixelFormatGUID format
;
634 IWICBitmapLock
*lock
;
635 UINT size
, num_palette_entries
= 0;
636 PALETTEENTRY entry
[256];
638 TRACE("(%p,%p,%p,%u,%p)\n", iface
, hbm
, hpal
, option
, bitmap
);
640 if (!bitmap
) return E_INVALIDARG
;
642 if (GetObjectW(hbm
, sizeof(bm
), &bm
) != sizeof(bm
))
643 return WINCODEC_ERR_WIN32ERROR
;
647 num_palette_entries
= GetPaletteEntries(hpal
, 0, 256, entry
);
648 if (!num_palette_entries
)
649 return WINCODEC_ERR_WIN32ERROR
;
652 /* TODO: Figure out the correct format for 16, 32, 64 bpp */
653 switch(bm
.bmBitsPixel
)
656 format
= GUID_WICPixelFormat1bppIndexed
;
659 format
= GUID_WICPixelFormat4bppIndexed
;
662 format
= GUID_WICPixelFormat8bppIndexed
;
665 if (!get_16bpp_format(hbm
, &format
))
669 format
= GUID_WICPixelFormat24bppBGR
;
674 case WICBitmapUseAlpha
:
675 format
= GUID_WICPixelFormat32bppBGRA
;
677 case WICBitmapUsePremultipliedAlpha
:
678 format
= GUID_WICPixelFormat32bppPBGRA
;
680 case WICBitmapIgnoreAlpha
:
681 format
= GUID_WICPixelFormat32bppBGR
;
688 format
= GUID_WICPixelFormat48bppRGB
;
691 FIXME("unsupported %d bpp\n", bm
.bmBitsPixel
);
695 hr
= BitmapImpl_Create(bm
.bmWidth
, bm
.bmHeight
, bm
.bmWidthBytes
, 0, NULL
, &format
, option
, bitmap
);
696 if (hr
!= S_OK
) return hr
;
698 hr
= IWICBitmap_Lock(*bitmap
, NULL
, WICBitmapLockWrite
, &lock
);
703 char bmibuf
[FIELD_OFFSET(BITMAPINFO
, bmiColors
) + 256 * sizeof(RGBQUAD
)];
704 BITMAPINFO
*bmi
= (BITMAPINFO
*)bmibuf
;
706 IWICBitmapLock_GetDataPointer(lock
, &size
, &buffer
);
708 hdc
= CreateCompatibleDC(0);
710 bmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
711 bmi
->bmiHeader
.biBitCount
= 0;
712 GetDIBits(hdc
, hbm
, 0, 0, NULL
, bmi
, DIB_RGB_COLORS
);
713 bmi
->bmiHeader
.biHeight
= -bm
.bmHeight
;
714 GetDIBits(hdc
, hbm
, 0, bm
.bmHeight
, buffer
, bmi
, DIB_RGB_COLORS
);
717 IWICBitmapLock_Release(lock
);
719 if (num_palette_entries
)
721 IWICPalette
*palette
;
722 WICColor colors
[256];
725 hr
= PaletteImpl_Create(&palette
);
728 for (i
= 0; i
< num_palette_entries
; i
++)
729 colors
[i
] = 0xff000000 | entry
[i
].peRed
<< 16 |
730 entry
[i
].peGreen
<< 8 | entry
[i
].peBlue
;
732 hr
= IWICPalette_InitializeCustom(palette
, colors
, num_palette_entries
);
734 hr
= IWICBitmap_SetPalette(*bitmap
, palette
);
736 IWICPalette_Release(palette
);
743 IWICBitmap_Release(*bitmap
);
750 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory
*iface
,
751 HICON hicon
, IWICBitmap
**bitmap
)
753 IWICBitmapLock
*lock
;
756 int width
, height
, x
, y
;
765 TRACE("(%p,%p,%p)\n", iface
, hicon
, bitmap
);
767 if (!bitmap
) return E_INVALIDARG
;
769 if (!GetIconInfo(hicon
, &info
))
770 return HRESULT_FROM_WIN32(GetLastError());
772 GetObjectW(info
.hbmColor
? info
.hbmColor
: info
.hbmMask
, sizeof(bm
), &bm
);
775 height
= info
.hbmColor
? abs(bm
.bmHeight
) : abs(bm
.bmHeight
) / 2;
777 size
= stride
* height
;
779 hr
= BitmapImpl_Create(width
, height
, stride
, size
, NULL
,
780 &GUID_WICPixelFormat32bppBGRA
, WICBitmapCacheOnLoad
, bitmap
);
781 if (hr
!= S_OK
) goto failed
;
783 hr
= IWICBitmap_Lock(*bitmap
, NULL
, WICBitmapLockWrite
, &lock
);
786 IWICBitmap_Release(*bitmap
);
789 IWICBitmapLock_GetDataPointer(lock
, &size
, &buffer
);
791 hdc
= CreateCompatibleDC(0);
793 memset(&bi
, 0, sizeof(bi
));
794 bi
.bmiHeader
.biSize
= sizeof(bi
.bmiHeader
);
795 bi
.bmiHeader
.biWidth
= width
;
796 bi
.bmiHeader
.biHeight
= info
.hbmColor
? -height
: -height
* 2;
797 bi
.bmiHeader
.biPlanes
= 1;
798 bi
.bmiHeader
.biBitCount
= 32;
799 bi
.bmiHeader
.biCompression
= BI_RGB
;
805 GetDIBits(hdc
, info
.hbmColor
, 0, height
, buffer
, &bi
, DIB_RGB_COLORS
);
807 if (bm
.bmBitsPixel
== 32)
809 /* If any pixel has a non-zero alpha, ignore hbmMask */
810 bits
= (DWORD
*)buffer
;
811 for (x
= 0; x
< width
&& !has_alpha
; x
++, bits
++)
813 for (y
= 0; y
< height
; y
++)
815 if (*bits
& 0xff000000)
825 GetDIBits(hdc
, info
.hbmMask
, 0, height
, buffer
, &bi
, DIB_RGB_COLORS
);
835 mask
= HeapAlloc(GetProcessHeap(), 0, size
);
838 IWICBitmapLock_Release(lock
);
839 IWICBitmap_Release(*bitmap
);
845 /* read alpha data from the mask */
846 GetDIBits(hdc
, info
.hbmMask
, info
.hbmColor
? 0 : height
, height
, mask
, &bi
, DIB_RGB_COLORS
);
848 for (y
= 0; y
< height
; y
++)
850 rgba
= (DWORD
*)(buffer
+ y
* stride
);
851 bits
= (DWORD
*)(mask
+ y
* stride
);
853 for (x
= 0; x
< width
; x
++, rgba
++, bits
++)
862 HeapFree(GetProcessHeap(), 0, mask
);
866 /* set constant alpha of 255 */
867 for (y
= 0; y
< height
; y
++)
869 rgba
= (DWORD
*)(buffer
+ y
* stride
);
870 for (x
= 0; x
< width
; x
++, rgba
++)
877 IWICBitmapLock_Release(lock
);
881 DeleteObject(info
.hbmColor
);
882 DeleteObject(info
.hbmMask
);
887 static HRESULT WINAPI
ComponentFactory_CreateComponentEnumerator(IWICComponentFactory
*iface
,
888 DWORD componentTypes
, DWORD options
, IEnumUnknown
**ppIEnumUnknown
)
890 TRACE("(%p,%u,%u,%p)\n", iface
, componentTypes
, options
, ppIEnumUnknown
);
891 return CreateComponentEnumerator(componentTypes
, options
, ppIEnumUnknown
);
894 static HRESULT WINAPI
ComponentFactory_CreateFastMetadataEncoderFromDecoder(
895 IWICComponentFactory
*iface
, IWICBitmapDecoder
*pIDecoder
,
896 IWICFastMetadataEncoder
**ppIFastEncoder
)
898 FIXME("(%p,%p,%p): stub\n", iface
, pIDecoder
, ppIFastEncoder
);
902 static HRESULT WINAPI
ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(
903 IWICComponentFactory
*iface
, IWICBitmapFrameDecode
*pIFrameDecoder
,
904 IWICFastMetadataEncoder
**ppIFastEncoder
)
906 FIXME("(%p,%p,%p): stub\n", iface
, pIFrameDecoder
, ppIFastEncoder
);
910 static HRESULT WINAPI
ComponentFactory_CreateQueryWriter(IWICComponentFactory
*iface
,
911 REFGUID guidMetadataFormat
, const GUID
*pguidVendor
,
912 IWICMetadataQueryWriter
**ppIQueryWriter
)
914 FIXME("(%p,%s,%s,%p): stub\n", iface
, debugstr_guid(guidMetadataFormat
),
915 debugstr_guid(pguidVendor
), ppIQueryWriter
);
919 static HRESULT WINAPI
ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory
*iface
,
920 IWICMetadataQueryReader
*pIQueryReader
, const GUID
*pguidVendor
,
921 IWICMetadataQueryWriter
**ppIQueryWriter
)
923 FIXME("(%p,%p,%s,%p): stub\n", iface
, pIQueryReader
, debugstr_guid(pguidVendor
),
928 static HRESULT WINAPI
ComponentFactory_CreateMetadataReader(IWICComponentFactory
*iface
,
929 REFGUID format
, const GUID
*vendor
, DWORD options
, IStream
*stream
, IWICMetadataReader
**reader
)
931 FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
),
932 options
, stream
, reader
);
936 static HRESULT WINAPI
ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory
*iface
,
937 REFGUID format
, const GUID
*vendor
, DWORD options
, IStream
*stream
, IWICMetadataReader
**reader
)
939 FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
),
940 options
, stream
, reader
);
944 static HRESULT WINAPI
ComponentFactory_CreateMetadataWriter(IWICComponentFactory
*iface
,
945 REFGUID format
, const GUID
*vendor
, DWORD options
, IWICMetadataWriter
**writer
)
947 FIXME("%p,%s,%s,%x,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
), options
, writer
);
951 static HRESULT WINAPI
ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory
*iface
,
952 IWICMetadataReader
*reader
, const GUID
*vendor
, IWICMetadataWriter
**writer
)
954 FIXME("%p,%p,%s,%p: stub\n", iface
, reader
, debugstr_guid(vendor
), writer
);
958 static HRESULT WINAPI
ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory
*iface
,
959 IWICMetadataBlockReader
*block_reader
, IWICMetadataQueryReader
**query_reader
)
961 FIXME("%p,%p,%p: stub\n", iface
, block_reader
, query_reader
);
965 static HRESULT WINAPI
ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory
*iface
,
966 IWICMetadataBlockWriter
*block_writer
, IWICMetadataQueryWriter
**query_writer
)
968 FIXME("%p,%p,%p: stub\n", iface
, block_writer
, query_writer
);
972 static HRESULT WINAPI
ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory
*iface
,
973 PROPBAG2
*options
, UINT count
, IPropertyBag2
**property
)
975 TRACE("(%p,%p,%u,%p)\n", iface
, options
, count
, property
);
976 return CreatePropertyBag2(options
, count
, property
);
979 static const IWICComponentFactoryVtbl ComponentFactory_Vtbl
= {
980 ComponentFactory_QueryInterface
,
981 ComponentFactory_AddRef
,
982 ComponentFactory_Release
,
983 ComponentFactory_CreateDecoderFromFilename
,
984 ComponentFactory_CreateDecoderFromStream
,
985 ComponentFactory_CreateDecoderFromFileHandle
,
986 ComponentFactory_CreateComponentInfo
,
987 ComponentFactory_CreateDecoder
,
988 ComponentFactory_CreateEncoder
,
989 ComponentFactory_CreatePalette
,
990 ComponentFactory_CreateFormatConverter
,
991 ComponentFactory_CreateBitmapScaler
,
992 ComponentFactory_CreateBitmapClipper
,
993 ComponentFactory_CreateBitmapFlipRotator
,
994 ComponentFactory_CreateStream
,
995 ComponentFactory_CreateColorContext
,
996 ComponentFactory_CreateColorTransformer
,
997 ComponentFactory_CreateBitmap
,
998 ComponentFactory_CreateBitmapFromSource
,
999 ComponentFactory_CreateBitmapFromSourceRect
,
1000 ComponentFactory_CreateBitmapFromMemory
,
1001 ComponentFactory_CreateBitmapFromHBITMAP
,
1002 ComponentFactory_CreateBitmapFromHICON
,
1003 ComponentFactory_CreateComponentEnumerator
,
1004 ComponentFactory_CreateFastMetadataEncoderFromDecoder
,
1005 ComponentFactory_CreateFastMetadataEncoderFromFrameDecode
,
1006 ComponentFactory_CreateQueryWriter
,
1007 ComponentFactory_CreateQueryWriterFromReader
,
1008 ComponentFactory_CreateMetadataReader
,
1009 ComponentFactory_CreateMetadataReaderFromContainer
,
1010 ComponentFactory_CreateMetadataWriter
,
1011 ComponentFactory_CreateMetadataWriterFromReader
,
1012 ComponentFactory_CreateQueryReaderFromBlockReader
,
1013 ComponentFactory_CreateQueryWriterFromBlockWriter
,
1014 ComponentFactory_CreateEncoderPropertyBag
1017 HRESULT
ComponentFactory_CreateInstance(REFIID iid
, void** ppv
)
1019 ComponentFactory
*This
;
1022 TRACE("(%s,%p)\n", debugstr_guid(iid
), ppv
);
1026 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentFactory
));
1027 if (!This
) return E_OUTOFMEMORY
;
1029 This
->IWICComponentFactory_iface
.lpVtbl
= &ComponentFactory_Vtbl
;
1032 ret
= IWICComponentFactory_QueryInterface(&This
->IWICComponentFactory_iface
, iid
, ppv
);
1033 IWICComponentFactory_Release(&This
->IWICComponentFactory_iface
);