winemac: Don't bring a window onto the screen in SetFocus().
[wine] / dlls / windowscodecs / imgfactory.c
1 /*
2  * Copyright 2009 Vincent Povirk for CodeWeavers
3  * Copyright 2012 Dmitry Timoshkov
4  *
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.
9  *
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.
14  *
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
18  */
19
20 #include "config.h"
21
22 #include <stdarg.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "objbase.h"
30 #include "shellapi.h"
31 #include "wincodec.h"
32 #include "wincodecsdk.h"
33
34 #include "wincodecs_private.h"
35
36 #include "wine/debug.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
39
40 typedef struct {
41     IWICComponentFactory IWICComponentFactory_iface;
42     LONG ref;
43 } ComponentFactory;
44
45 static inline ComponentFactory *impl_from_IWICComponentFactory(IWICComponentFactory *iface)
46 {
47     return CONTAINING_RECORD(iface, ComponentFactory, IWICComponentFactory_iface);
48 }
49
50 static HRESULT WINAPI ComponentFactory_QueryInterface(IWICComponentFactory *iface, REFIID iid,
51     void **ppv)
52 {
53     ComponentFactory *This = impl_from_IWICComponentFactory(iface);
54     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
55
56     if (!ppv) return E_INVALIDARG;
57
58     if (IsEqualIID(&IID_IUnknown, iid) ||
59         IsEqualIID(&IID_IWICImagingFactory, iid) ||
60         IsEqualIID(&IID_IWICComponentFactory, iid))
61     {
62         *ppv = &This->IWICComponentFactory_iface;
63     }
64     else
65     {
66         *ppv = NULL;
67         return E_NOINTERFACE;
68     }
69
70     IUnknown_AddRef((IUnknown*)*ppv);
71     return S_OK;
72 }
73
74 static ULONG WINAPI ComponentFactory_AddRef(IWICComponentFactory *iface)
75 {
76     ComponentFactory *This = impl_from_IWICComponentFactory(iface);
77     ULONG ref = InterlockedIncrement(&This->ref);
78
79     TRACE("(%p) refcount=%u\n", iface, ref);
80
81     return ref;
82 }
83
84 static ULONG WINAPI ComponentFactory_Release(IWICComponentFactory *iface)
85 {
86     ComponentFactory *This = impl_from_IWICComponentFactory(iface);
87     ULONG ref = InterlockedDecrement(&This->ref);
88
89     TRACE("(%p) refcount=%u\n", iface, ref);
90
91     if (ref == 0)
92         HeapFree(GetProcessHeap(), 0, This);
93
94     return ref;
95 }
96
97 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename(
98     IWICComponentFactory *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
99     DWORD dwDesiredAccess, WICDecodeOptions metadataOptions,
100     IWICBitmapDecoder **ppIDecoder)
101 {
102     IWICStream *stream;
103     HRESULT hr;
104
105     TRACE("(%p,%s,%s,%u,%u,%p)\n", iface, debugstr_w(wzFilename),
106         debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder);
107
108     hr = StreamImpl_Create(&stream);
109     if (SUCCEEDED(hr))
110     {
111         hr = IWICStream_InitializeFromFilename(stream, wzFilename, dwDesiredAccess);
112
113         if (SUCCEEDED(hr))
114         {
115             hr = IWICComponentFactory_CreateDecoderFromStream(iface, (IStream*)stream,
116                 pguidVendor, metadataOptions, ppIDecoder);
117         }
118
119         IWICStream_Release(stream);
120     }
121
122     return hr;
123 }
124
125 static IWICBitmapDecoder *find_decoder(IStream *pIStream, const GUID *pguidVendor,
126                                        WICDecodeOptions metadataOptions)
127 {
128     IEnumUnknown *enumdecoders;
129     IUnknown *unkdecoderinfo;
130     IWICBitmapDecoderInfo *decoderinfo;
131     IWICBitmapDecoder *decoder = NULL;
132     GUID vendor;
133     HRESULT res;
134     ULONG num_fetched;
135     BOOL matches;
136
137     res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
138     if (FAILED(res)) return NULL;
139
140     while (!decoder)
141     {
142         res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
143
144         if (res == S_OK)
145         {
146             res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo);
147
148             if (SUCCEEDED(res))
149             {
150                 if (pguidVendor)
151                 {
152                     res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
153                     if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor))
154                     {
155                         IWICBitmapDecoderInfo_Release(decoderinfo);
156                         IUnknown_Release(unkdecoderinfo);
157                         continue;
158                     }
159                 }
160
161                 res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches);
162
163                 if (SUCCEEDED(res) && matches)
164                 {
165                     res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &decoder);
166
167                     /* FIXME: should use QueryCapability to choose a decoder */
168
169                     if (SUCCEEDED(res))
170                     {
171                         res = IWICBitmapDecoder_Initialize(decoder, pIStream, metadataOptions);
172
173                         if (FAILED(res))
174                         {
175                             IWICBitmapDecoder_Release(decoder);
176                             decoder = NULL;
177                         }
178                     }
179                 }
180
181                 IWICBitmapDecoderInfo_Release(decoderinfo);
182             }
183
184             IUnknown_Release(unkdecoderinfo);
185         }
186         else
187             break;
188     }
189
190     IEnumUnknown_Release(enumdecoders);
191
192     return decoder;
193 }
194
195 static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(
196     IWICComponentFactory *iface, IStream *pIStream, const GUID *pguidVendor,
197     WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
198 {
199     HRESULT res;
200     IWICBitmapDecoder *decoder = NULL;
201
202     TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
203         metadataOptions, ppIDecoder);
204
205     if (pguidVendor)
206         decoder = find_decoder(pIStream, pguidVendor, metadataOptions);
207     if (!decoder)
208         decoder = find_decoder(pIStream, NULL, metadataOptions);
209
210     if (decoder)
211     {
212         *ppIDecoder = decoder;
213         return S_OK;
214     }
215     else
216     {
217         if (WARN_ON(wincodecs))
218         {
219             LARGE_INTEGER seek;
220             BYTE data[4];
221             ULONG bytesread;
222
223             WARN("failed to load from a stream\n");
224
225             seek.QuadPart = 0;
226             res = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
227             if (SUCCEEDED(res))
228                 res = IStream_Read(pIStream, data, 4, &bytesread);
229             if (SUCCEEDED(res))
230                 WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
231         }
232         *ppIDecoder = NULL;
233         return WINCODEC_ERR_COMPONENTNOTFOUND;
234     }
235 }
236
237 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFileHandle(
238     IWICComponentFactory *iface, ULONG_PTR hFile, const GUID *pguidVendor,
239     WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
240 {
241     IWICStream *stream;
242     HRESULT hr;
243
244     TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor),
245         metadataOptions, ppIDecoder);
246
247     hr = StreamImpl_Create(&stream);
248     if (SUCCEEDED(hr))
249     {
250         hr = stream_initialize_from_filehandle(stream, (HANDLE)hFile);
251         if (SUCCEEDED(hr))
252         {
253             hr = IWICComponentFactory_CreateDecoderFromStream(iface, (IStream*)stream,
254                 pguidVendor, metadataOptions, ppIDecoder);
255         }
256         IWICStream_Release(stream);
257     }
258     return hr;
259 }
260
261 static HRESULT WINAPI ComponentFactory_CreateComponentInfo(IWICComponentFactory *iface,
262     REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
263 {
264     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo);
265     return CreateComponentInfo(clsidComponent, ppIInfo);
266 }
267
268 static HRESULT WINAPI ComponentFactory_CreateDecoder(IWICComponentFactory *iface,
269     REFGUID guidContainerFormat, const GUID *pguidVendor,
270     IWICBitmapDecoder **ppIDecoder)
271 {
272     IEnumUnknown *enumdecoders;
273     IUnknown *unkdecoderinfo;
274     IWICBitmapDecoderInfo *decoderinfo;
275     IWICBitmapDecoder *decoder = NULL, *preferred_decoder = NULL;
276     GUID vendor;
277     HRESULT res;
278     ULONG num_fetched;
279
280     TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
281         debugstr_guid(pguidVendor), ppIDecoder);
282
283     if (!guidContainerFormat || !ppIDecoder) return E_INVALIDARG;
284
285     res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
286     if (FAILED(res)) return res;
287
288     while (!preferred_decoder)
289     {
290         res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
291         if (res != S_OK) break;
292
293         res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void **)&decoderinfo);
294         if (SUCCEEDED(res))
295         {
296             GUID container_guid;
297
298             res = IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo, &container_guid);
299             if (SUCCEEDED(res) && IsEqualIID(&container_guid, guidContainerFormat))
300             {
301                 IWICBitmapDecoder *new_decoder;
302
303                 res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &new_decoder);
304                 if (SUCCEEDED(res))
305                 {
306                     if (pguidVendor)
307                     {
308                         res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
309                         if (SUCCEEDED(res) && IsEqualIID(&vendor, pguidVendor))
310                         {
311                             preferred_decoder = new_decoder;
312                             new_decoder = NULL;
313                         }
314                     }
315
316                     if (new_decoder && !decoder)
317                     {
318                         decoder = new_decoder;
319                         new_decoder = NULL;
320                     }
321
322                     if (new_decoder) IWICBitmapDecoder_Release(new_decoder);
323                 }
324             }
325
326             IWICBitmapDecoderInfo_Release(decoderinfo);
327         }
328
329         IUnknown_Release(unkdecoderinfo);
330     }
331
332     IEnumUnknown_Release(enumdecoders);
333
334     if (preferred_decoder)
335     {
336         *ppIDecoder = preferred_decoder;
337         if (decoder) IWICBitmapDecoder_Release(decoder);
338         return S_OK;
339     }
340
341     if (decoder)
342     {
343         *ppIDecoder = decoder;
344         return S_OK;
345     }
346
347     *ppIDecoder = NULL;
348     return WINCODEC_ERR_COMPONENTNOTFOUND;
349 }
350
351 static HRESULT WINAPI ComponentFactory_CreateEncoder(IWICComponentFactory *iface,
352     REFGUID guidContainerFormat, const GUID *pguidVendor,
353     IWICBitmapEncoder **ppIEncoder)
354 {
355     static int fixme=0;
356     IEnumUnknown *enumencoders;
357     IUnknown *unkencoderinfo;
358     IWICBitmapEncoderInfo *encoderinfo;
359     IWICBitmapEncoder *encoder=NULL;
360     HRESULT res=S_OK;
361     ULONG num_fetched;
362     GUID actual_containerformat;
363
364     TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
365         debugstr_guid(pguidVendor), ppIEncoder);
366
367     if (pguidVendor && !fixme++)
368         FIXME("ignoring vendor GUID\n");
369
370     res = CreateComponentEnumerator(WICEncoder, WICComponentEnumerateDefault, &enumencoders);
371     if (FAILED(res)) return res;
372
373     while (!encoder)
374     {
375         res = IEnumUnknown_Next(enumencoders, 1, &unkencoderinfo, &num_fetched);
376
377         if (res == S_OK)
378         {
379             res = IUnknown_QueryInterface(unkencoderinfo, &IID_IWICBitmapEncoderInfo, (void**)&encoderinfo);
380
381             if (SUCCEEDED(res))
382             {
383                 res = IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo, &actual_containerformat);
384
385                 if (SUCCEEDED(res) && IsEqualGUID(guidContainerFormat, &actual_containerformat))
386                 {
387                     res = IWICBitmapEncoderInfo_CreateInstance(encoderinfo, &encoder);
388                     if (FAILED(res))
389                         encoder = NULL;
390                 }
391
392                 IWICBitmapEncoderInfo_Release(encoderinfo);
393             }
394
395             IUnknown_Release(unkencoderinfo);
396         }
397         else
398             break;
399     }
400
401     IEnumUnknown_Release(enumencoders);
402
403     if (encoder)
404     {
405         *ppIEncoder = encoder;
406         return S_OK;
407     }
408     else
409     {
410         WARN("failed to create encoder\n");
411         *ppIEncoder = NULL;
412         return WINCODEC_ERR_COMPONENTNOTFOUND;
413     }
414 }
415
416 static HRESULT WINAPI ComponentFactory_CreatePalette(IWICComponentFactory *iface,
417     IWICPalette **ppIPalette)
418 {
419     TRACE("(%p,%p)\n", iface, ppIPalette);
420     return PaletteImpl_Create(ppIPalette);
421 }
422
423 static HRESULT WINAPI ComponentFactory_CreateFormatConverter(IWICComponentFactory *iface,
424     IWICFormatConverter **ppIFormatConverter)
425 {
426     return FormatConverter_CreateInstance(NULL, &IID_IWICFormatConverter, (void**)ppIFormatConverter);
427 }
428
429 static HRESULT WINAPI ComponentFactory_CreateBitmapScaler(IWICComponentFactory *iface,
430     IWICBitmapScaler **ppIBitmapScaler)
431 {
432     TRACE("(%p,%p)\n", iface, ppIBitmapScaler);
433
434     return BitmapScaler_Create(ppIBitmapScaler);
435 }
436
437 static HRESULT WINAPI ComponentFactory_CreateBitmapClipper(IWICComponentFactory *iface,
438     IWICBitmapClipper **ppIBitmapClipper)
439 {
440     FIXME("(%p,%p): stub\n", iface, ppIBitmapClipper);
441     return E_NOTIMPL;
442 }
443
444 static HRESULT WINAPI ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory *iface,
445     IWICBitmapFlipRotator **ppIBitmapFlipRotator)
446 {
447     TRACE("(%p,%p)\n", iface, ppIBitmapFlipRotator);
448     return FlipRotator_Create(ppIBitmapFlipRotator);
449 }
450
451 static HRESULT WINAPI ComponentFactory_CreateStream(IWICComponentFactory *iface,
452     IWICStream **ppIWICStream)
453 {
454     TRACE("(%p,%p)\n", iface, ppIWICStream);
455     return StreamImpl_Create(ppIWICStream);
456 }
457
458 static HRESULT WINAPI ComponentFactory_CreateColorContext(IWICComponentFactory *iface,
459     IWICColorContext **ppIColorContext)
460 {
461     TRACE("(%p,%p)\n", iface, ppIColorContext);
462     return ColorContext_Create(ppIColorContext);
463 }
464
465 static HRESULT WINAPI ComponentFactory_CreateColorTransformer(IWICComponentFactory *iface,
466     IWICColorTransform **ppIColorTransform)
467 {
468     TRACE("(%p,%p)\n", iface, ppIColorTransform);
469     return ColorTransform_Create(ppIColorTransform);
470 }
471
472 static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface,
473     UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
474     WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
475 {
476     TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight,
477         debugstr_guid(pixelFormat), option, ppIBitmap);
478     return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, pixelFormat, option, ppIBitmap);
479 }
480
481 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface,
482     IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
483     IWICBitmap **ppIBitmap)
484 {
485     IWICBitmap *result;
486     IWICBitmapLock *lock;
487     IWICPalette *palette;
488     UINT width, height;
489     WICPixelFormatGUID pixelformat = {0};
490     HRESULT hr;
491     WICRect rc;
492     double dpix, dpiy;
493     IWICComponentInfo *info;
494     IWICPixelFormatInfo2 *formatinfo;
495     WICPixelFormatNumericRepresentation format_type;
496
497     TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap);
498
499     if (!piBitmapSource || !ppIBitmap)
500         return E_INVALIDARG;
501
502     hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height);
503
504     if (SUCCEEDED(hr))
505         hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat);
506
507     if (SUCCEEDED(hr))
508         hr = CreateComponentInfo(&pixelformat, &info);
509
510     if (SUCCEEDED(hr))
511     {
512         hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo);
513
514         if (SUCCEEDED(hr))
515         {
516             hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type);
517
518             IWICPixelFormatInfo2_Release(formatinfo);
519         }
520
521         IWICComponentInfo_Release(info);
522     }
523
524     if (SUCCEEDED(hr))
525         hr = BitmapImpl_Create(width, height, 0, 0, NULL, &pixelformat, option, &result);
526
527     if (SUCCEEDED(hr))
528     {
529         hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock);
530         if (SUCCEEDED(hr))
531         {
532             UINT stride, buffersize;
533             BYTE *buffer;
534             rc.X = rc.Y = 0;
535             rc.Width = width;
536             rc.Height = height;
537
538             hr = IWICBitmapLock_GetStride(lock, &stride);
539
540             if (SUCCEEDED(hr))
541                 hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer);
542
543             if (SUCCEEDED(hr))
544                 hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride,
545                     buffersize, buffer);
546
547             IWICBitmapLock_Release(lock);
548         }
549
550         if (SUCCEEDED(hr))
551             hr = PaletteImpl_Create(&palette);
552
553         if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified ||
554                               format_type == WICPixelFormatNumericRepresentationIndexed))
555         {
556             hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette);
557
558             if (SUCCEEDED(hr))
559                 hr = IWICBitmap_SetPalette(result, palette);
560             else
561                 hr = S_OK;
562
563             IWICPalette_Release(palette);
564         }
565
566         if (SUCCEEDED(hr))
567         {
568             hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy);
569
570             if (SUCCEEDED(hr))
571                 hr = IWICBitmap_SetResolution(result, dpix, dpiy);
572             else
573                 hr = S_OK;
574         }
575
576         if (SUCCEEDED(hr))
577             *ppIBitmap = result;
578         else
579             IWICBitmap_Release(result);
580     }
581
582     return hr;
583 }
584
585 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory *iface,
586     IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height,
587     IWICBitmap **ppIBitmap)
588 {
589     FIXME("(%p,%p,%u,%u,%u,%u,%p): stub\n", iface, piBitmapSource, x, y, width,
590         height, ppIBitmap);
591     return E_NOTIMPL;
592 }
593
594 static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface,
595     UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride,
596     UINT size, BYTE *buffer, IWICBitmap **bitmap)
597 {
598     TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height,
599         debugstr_guid(format), stride, size, buffer, bitmap);
600
601     if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;
602
603     return BitmapImpl_Create(width, height, stride, size, buffer, format, WICBitmapCacheOnLoad, bitmap);
604 }
605
606 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface,
607     HBITMAP hBitmap, HPALETTE hPalette, WICBitmapAlphaChannelOption options,
608     IWICBitmap **ppIBitmap)
609 {
610     FIXME("(%p,%p,%p,%u,%p): stub\n", iface, hBitmap, hPalette, options, ppIBitmap);
611     return E_NOTIMPL;
612 }
613
614 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface,
615     HICON hicon, IWICBitmap **bitmap)
616 {
617     IWICBitmapLock *lock;
618     ICONINFO info;
619     BITMAP bm;
620     int width, height, x, y;
621     UINT stride, size;
622     BYTE *buffer;
623     DWORD *bits;
624     BITMAPINFO bi;
625     HDC hdc;
626     BOOL has_alpha;
627     HRESULT hr;
628
629     TRACE("(%p,%p,%p)\n", iface, hicon, bitmap);
630
631     if (!bitmap) return E_INVALIDARG;
632
633     if (!GetIconInfo(hicon, &info))
634         return HRESULT_FROM_WIN32(GetLastError());
635
636     GetObjectW(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm);
637
638     width = bm.bmWidth;
639     height = info.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2;
640     stride = width * 4;
641     size = stride * height;
642
643     hr = BitmapImpl_Create(width, height, stride, size, NULL,
644                            &GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad, bitmap);
645     if (hr != S_OK) goto failed;
646
647     hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
648     if (hr != S_OK)
649     {
650         IWICBitmap_Release(*bitmap);
651         goto failed;
652     }
653     IWICBitmapLock_GetDataPointer(lock, &size, &buffer);
654
655     hdc = CreateCompatibleDC(0);
656
657     memset(&bi, 0, sizeof(bi));
658     bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
659     bi.bmiHeader.biWidth = width;
660     bi.bmiHeader.biHeight = info.hbmColor ? -height: -height * 2;
661     bi.bmiHeader.biPlanes = 1;
662     bi.bmiHeader.biBitCount = 32;
663     bi.bmiHeader.biCompression = BI_RGB;
664
665     has_alpha = FALSE;
666
667     if (info.hbmColor)
668     {
669         GetDIBits(hdc, info.hbmColor, 0, height, buffer, &bi, DIB_RGB_COLORS);
670
671         if (bm.bmBitsPixel == 32)
672         {
673             /* If any pixel has a non-zero alpha, ignore hbmMask */
674             bits = (DWORD *)buffer;
675             for (x = 0; x < width && !has_alpha; x++, bits++)
676             {
677                 for (y = 0; y < height; y++)
678                 {
679                     if (*bits & 0xff000000)
680                     {
681                         has_alpha = TRUE;
682                         break;
683                     }
684                 }
685             }
686         }
687     }
688     else
689         GetDIBits(hdc, info.hbmMask, 0, height, buffer, &bi, DIB_RGB_COLORS);
690
691     if (!has_alpha)
692     {
693         DWORD *rgba;
694
695         if (info.hbmMask)
696         {
697             BYTE *mask;
698
699             mask = HeapAlloc(GetProcessHeap(), 0, size);
700             if (!mask)
701             {
702                 IWICBitmapLock_Release(lock);
703                 IWICBitmap_Release(*bitmap);
704                 DeleteDC(hdc);
705                 hr = E_OUTOFMEMORY;
706                 goto failed;
707             }
708
709             /* read alpha data from the mask */
710             GetDIBits(hdc, info.hbmMask, info.hbmColor ? 0 : height, height, mask, &bi, DIB_RGB_COLORS);
711
712             for (y = 0; y < height; y++)
713             {
714                 rgba = (DWORD *)(buffer + y * stride);
715                 bits = (DWORD *)(mask + y * stride);
716
717                 for (x = 0; x < width; x++, rgba++, bits++)
718                 {
719                     if (*bits)
720                         *rgba = 0;
721                     else
722                         *rgba |= 0xff000000;
723                 }
724             }
725
726             HeapFree(GetProcessHeap(), 0, mask);
727         }
728         else
729         {
730             /* set constant alpha of 255 */
731             for (y = 0; y < height; y++)
732             {
733                 rgba = (DWORD *)(buffer + y * stride);
734                 for (x = 0; x < width; x++, rgba++)
735                     *rgba |= 0xff000000;
736             }
737         }
738
739     }
740
741     IWICBitmapLock_Release(lock);
742     DeleteDC(hdc);
743
744 failed:
745     DeleteObject(info.hbmColor);
746     DeleteObject(info.hbmMask);
747
748     return hr;
749 }
750
751 static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *iface,
752     DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
753 {
754     TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown);
755     return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown);
756 }
757
758 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromDecoder(
759     IWICComponentFactory *iface, IWICBitmapDecoder *pIDecoder,
760     IWICFastMetadataEncoder **ppIFastEncoder)
761 {
762     FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder);
763     return E_NOTIMPL;
764 }
765
766 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(
767     IWICComponentFactory *iface, IWICBitmapFrameDecode *pIFrameDecoder,
768     IWICFastMetadataEncoder **ppIFastEncoder)
769 {
770     FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder);
771     return E_NOTIMPL;
772 }
773
774 static HRESULT WINAPI ComponentFactory_CreateQueryWriter(IWICComponentFactory *iface,
775     REFGUID guidMetadataFormat, const GUID *pguidVendor,
776     IWICMetadataQueryWriter **ppIQueryWriter)
777 {
778     FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat),
779         debugstr_guid(pguidVendor), ppIQueryWriter);
780     return E_NOTIMPL;
781 }
782
783 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory *iface,
784     IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor,
785     IWICMetadataQueryWriter **ppIQueryWriter)
786 {
787     FIXME("(%p,%p,%s,%p): stub\n", iface, pIQueryReader, debugstr_guid(pguidVendor),
788         ppIQueryWriter);
789     return E_NOTIMPL;
790 }
791
792 static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface,
793         REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
794 {
795     FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor),
796         options, stream, reader);
797     return E_NOTIMPL;
798 }
799
800 static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface,
801         REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
802 {
803     FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor),
804         options, stream, reader);
805     return E_NOTIMPL;
806 }
807
808 static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface,
809         REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer)
810 {
811     FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer);
812     return E_NOTIMPL;
813 }
814
815 static HRESULT WINAPI ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory *iface,
816         IWICMetadataReader *reader, const GUID *vendor, IWICMetadataWriter **writer)
817 {
818     FIXME("%p,%p,%s,%p: stub\n", iface, reader, debugstr_guid(vendor), writer);
819     return E_NOTIMPL;
820 }
821
822 static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory *iface,
823         IWICMetadataBlockReader *block_reader, IWICMetadataQueryReader **query_reader)
824 {
825     FIXME("%p,%p,%p: stub\n", iface, block_reader, query_reader);
826     return E_NOTIMPL;
827 }
828
829 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface,
830         IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer)
831 {
832     FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer);
833     return E_NOTIMPL;
834 }
835
836 static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface,
837         PROPBAG2 *options, UINT count, IPropertyBag2 **property)
838 {
839     TRACE("(%p,%p,%u,%p)\n", iface, options, count, property);
840     return CreatePropertyBag2(options, count, property);
841 }
842
843 static const IWICComponentFactoryVtbl ComponentFactory_Vtbl = {
844     ComponentFactory_QueryInterface,
845     ComponentFactory_AddRef,
846     ComponentFactory_Release,
847     ComponentFactory_CreateDecoderFromFilename,
848     ComponentFactory_CreateDecoderFromStream,
849     ComponentFactory_CreateDecoderFromFileHandle,
850     ComponentFactory_CreateComponentInfo,
851     ComponentFactory_CreateDecoder,
852     ComponentFactory_CreateEncoder,
853     ComponentFactory_CreatePalette,
854     ComponentFactory_CreateFormatConverter,
855     ComponentFactory_CreateBitmapScaler,
856     ComponentFactory_CreateBitmapClipper,
857     ComponentFactory_CreateBitmapFlipRotator,
858     ComponentFactory_CreateStream,
859     ComponentFactory_CreateColorContext,
860     ComponentFactory_CreateColorTransformer,
861     ComponentFactory_CreateBitmap,
862     ComponentFactory_CreateBitmapFromSource,
863     ComponentFactory_CreateBitmapFromSourceRect,
864     ComponentFactory_CreateBitmapFromMemory,
865     ComponentFactory_CreateBitmapFromHBITMAP,
866     ComponentFactory_CreateBitmapFromHICON,
867     ComponentFactory_CreateComponentEnumerator,
868     ComponentFactory_CreateFastMetadataEncoderFromDecoder,
869     ComponentFactory_CreateFastMetadataEncoderFromFrameDecode,
870     ComponentFactory_CreateQueryWriter,
871     ComponentFactory_CreateQueryWriterFromReader,
872     ComponentFactory_CreateMetadataReader,
873     ComponentFactory_CreateMetadataReaderFromContainer,
874     ComponentFactory_CreateMetadataWriter,
875     ComponentFactory_CreateMetadataWriterFromReader,
876     ComponentFactory_CreateQueryReaderFromBlockReader,
877     ComponentFactory_CreateQueryWriterFromBlockWriter,
878     ComponentFactory_CreateEncoderPropertyBag
879 };
880
881 HRESULT ComponentFactory_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
882 {
883     ComponentFactory *This;
884     HRESULT ret;
885
886     TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv);
887
888     *ppv = NULL;
889
890     if (pUnkOuter) return CLASS_E_NOAGGREGATION;
891
892     This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentFactory));
893     if (!This) return E_OUTOFMEMORY;
894
895     This->IWICComponentFactory_iface.lpVtbl = &ComponentFactory_Vtbl;
896     This->ref = 1;
897
898     ret = IWICComponentFactory_QueryInterface(&This->IWICComponentFactory_iface, iid, ppv);
899     IWICComponentFactory_Release(&This->IWICComponentFactory_iface);
900
901     return ret;
902 }