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 <assert.h>
23 #include <stdarg.h>
24 
25 #define COBJMACROS
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winreg.h"
30 #include "objbase.h"
31 #include "shellapi.h"
32 
33 #include "wincodecs_private.h"
34 
35 #include "wine/debug.h"
36 
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
38 
39 typedef struct {
40     IWICImagingFactory2 IWICImagingFactory2_iface;
41     IWICComponentFactory IWICComponentFactory_iface;
42     LONG ref;
43 } ImagingFactory;
44 
impl_from_IWICComponentFactory(IWICComponentFactory * iface)45 static inline ImagingFactory *impl_from_IWICComponentFactory(IWICComponentFactory *iface)
46 {
47     return CONTAINING_RECORD(iface, ImagingFactory, IWICComponentFactory_iface);
48 }
49 
impl_from_IWICImagingFactory2(IWICImagingFactory2 * iface)50 static inline ImagingFactory *impl_from_IWICImagingFactory2(IWICImagingFactory2 *iface)
51 {
52     return CONTAINING_RECORD(iface, ImagingFactory, IWICImagingFactory2_iface);
53 }
54 
ImagingFactory_QueryInterface(IWICImagingFactory2 * iface,REFIID iid,void ** ppv)55 static HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory2 *iface, REFIID iid,
56     void **ppv)
57 {
58     ImagingFactory *This = impl_from_IWICImagingFactory2(iface);
59     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
60 
61     if (!ppv) return E_INVALIDARG;
62 
63     if (IsEqualIID(&IID_IUnknown, iid) ||
64         IsEqualIID(&IID_IWICImagingFactory, iid) ||
65         IsEqualIID(&IID_IWICComponentFactory, iid))
66     {
67         *ppv = &This->IWICComponentFactory_iface;
68     }
69     else if (IsEqualIID(&IID_IWICImagingFactory2, iid))
70     {
71         *ppv = &This->IWICImagingFactory2_iface;
72     }
73     else
74     {
75         *ppv = NULL;
76         return E_NOINTERFACE;
77     }
78 
79     IUnknown_AddRef((IUnknown*)*ppv);
80     return S_OK;
81 }
82 
ImagingFactory_AddRef(IWICImagingFactory2 * iface)83 static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory2 *iface)
84 {
85     ImagingFactory *This = impl_from_IWICImagingFactory2(iface);
86     ULONG ref = InterlockedIncrement(&This->ref);
87 
88     TRACE("(%p) refcount=%u\n", iface, ref);
89 
90     return ref;
91 }
92 
ImagingFactory_Release(IWICImagingFactory2 * iface)93 static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory2 *iface)
94 {
95     ImagingFactory *This = impl_from_IWICImagingFactory2(iface);
96     ULONG ref = InterlockedDecrement(&This->ref);
97 
98     TRACE("(%p) refcount=%u\n", iface, ref);
99 
100     if (ref == 0)
101         HeapFree(GetProcessHeap(), 0, This);
102 
103     return ref;
104 }
105 
ImagingFactory_CreateDecoderFromFilename(IWICImagingFactory2 * iface,LPCWSTR wzFilename,const GUID * pguidVendor,DWORD dwDesiredAccess,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** ppIDecoder)106 static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
107     IWICImagingFactory2 *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
108     DWORD dwDesiredAccess, WICDecodeOptions metadataOptions,
109     IWICBitmapDecoder **ppIDecoder)
110 {
111     IWICStream *stream;
112     HRESULT hr;
113 
114     TRACE("(%p,%s,%s,%u,%u,%p)\n", iface, debugstr_w(wzFilename),
115         debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder);
116 
117     hr = StreamImpl_Create(&stream);
118     if (SUCCEEDED(hr))
119     {
120         hr = IWICStream_InitializeFromFilename(stream, wzFilename, dwDesiredAccess);
121 
122         if (SUCCEEDED(hr))
123         {
124             hr = IWICImagingFactory2_CreateDecoderFromStream(iface, (IStream*)stream,
125                 pguidVendor, metadataOptions, ppIDecoder);
126         }
127 
128         IWICStream_Release(stream);
129     }
130 
131     return hr;
132 }
133 
find_decoder(IStream * pIStream,const GUID * pguidVendor,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** decoder)134 static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor,
135                             WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder)
136 {
137     IEnumUnknown *enumdecoders;
138     IUnknown *unkdecoderinfo;
139     IWICBitmapDecoderInfo *decoderinfo;
140     GUID vendor;
141     HRESULT res;
142     ULONG num_fetched;
143     BOOL matches;
144 
145     *decoder = NULL;
146 
147     res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
148     if (FAILED(res)) return res;
149 
150     while (!*decoder)
151     {
152         res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
153 
154         if (res == S_OK)
155         {
156             res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo);
157 
158             if (SUCCEEDED(res))
159             {
160                 if (pguidVendor)
161                 {
162                     res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
163                     if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor))
164                     {
165                         IWICBitmapDecoderInfo_Release(decoderinfo);
166                         IUnknown_Release(unkdecoderinfo);
167                         continue;
168                     }
169                 }
170 
171                 res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches);
172 
173                 if (SUCCEEDED(res) && matches)
174                 {
175                     res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder);
176 
177                     /* FIXME: should use QueryCapability to choose a decoder */
178 
179                     if (SUCCEEDED(res))
180                     {
181                         res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions);
182 
183                         if (FAILED(res))
184                         {
185                             IWICBitmapDecoder_Release(*decoder);
186                             IWICBitmapDecoderInfo_Release(decoderinfo);
187                             IUnknown_Release(unkdecoderinfo);
188                             IEnumUnknown_Release(enumdecoders);
189                             *decoder = NULL;
190                             return res;
191                         }
192                     }
193                 }
194 
195                 IWICBitmapDecoderInfo_Release(decoderinfo);
196             }
197 
198             IUnknown_Release(unkdecoderinfo);
199         }
200         else
201             break;
202     }
203 
204     IEnumUnknown_Release(enumdecoders);
205 
206     return WINCODEC_ERR_COMPONENTNOTFOUND;
207 }
208 
ImagingFactory_CreateDecoderFromStream(IWICImagingFactory2 * iface,IStream * pIStream,const GUID * pguidVendor,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** ppIDecoder)209 static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
210     IWICImagingFactory2 *iface, IStream *pIStream, const GUID *pguidVendor,
211     WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
212 {
213     HRESULT res;
214     IWICBitmapDecoder *decoder = NULL;
215 
216     TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
217         metadataOptions, ppIDecoder);
218 
219     if (pguidVendor)
220         res = find_decoder(pIStream, pguidVendor, metadataOptions, &decoder);
221     if (!decoder)
222         res = find_decoder(pIStream, NULL, metadataOptions, &decoder);
223 
224     if (decoder)
225     {
226         *ppIDecoder = decoder;
227         return S_OK;
228     }
229     else
230     {
231         if (WARN_ON(wincodecs))
232         {
233             LARGE_INTEGER seek;
234             BYTE data[4];
235             ULONG bytesread;
236 
237             WARN("failed to load from a stream %#x\n", res);
238 
239             seek.QuadPart = 0;
240             if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK)
241             {
242                 if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK)
243                     WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
244             }
245         }
246         *ppIDecoder = NULL;
247         return res;
248     }
249 }
250 
ImagingFactory_CreateDecoderFromFileHandle(IWICImagingFactory2 * iface,ULONG_PTR hFile,const GUID * pguidVendor,WICDecodeOptions metadataOptions,IWICBitmapDecoder ** ppIDecoder)251 static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle(
252     IWICImagingFactory2 *iface, ULONG_PTR hFile, const GUID *pguidVendor,
253     WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
254 {
255     IWICStream *stream;
256     HRESULT hr;
257 
258     TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor),
259         metadataOptions, ppIDecoder);
260 
261     hr = StreamImpl_Create(&stream);
262     if (SUCCEEDED(hr))
263     {
264         hr = stream_initialize_from_filehandle(stream, (HANDLE)hFile);
265         if (SUCCEEDED(hr))
266         {
267             hr = IWICImagingFactory2_CreateDecoderFromStream(iface, (IStream*)stream,
268                 pguidVendor, metadataOptions, ppIDecoder);
269         }
270         IWICStream_Release(stream);
271     }
272     return hr;
273 }
274 
ImagingFactory_CreateComponentInfo(IWICImagingFactory2 * iface,REFCLSID clsidComponent,IWICComponentInfo ** ppIInfo)275 static HRESULT WINAPI ImagingFactory_CreateComponentInfo(IWICImagingFactory2 *iface,
276     REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
277 {
278     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo);
279     return CreateComponentInfo(clsidComponent, ppIInfo);
280 }
281 
ImagingFactory_CreateDecoder(IWICImagingFactory2 * iface,REFGUID guidContainerFormat,const GUID * pguidVendor,IWICBitmapDecoder ** ppIDecoder)282 static HRESULT WINAPI ImagingFactory_CreateDecoder(IWICImagingFactory2 *iface,
283     REFGUID guidContainerFormat, const GUID *pguidVendor,
284     IWICBitmapDecoder **ppIDecoder)
285 {
286     IEnumUnknown *enumdecoders;
287     IUnknown *unkdecoderinfo;
288     IWICBitmapDecoderInfo *decoderinfo;
289     IWICBitmapDecoder *decoder = NULL, *preferred_decoder = NULL;
290     GUID vendor;
291     HRESULT res;
292     ULONG num_fetched;
293 
294     TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
295         debugstr_guid(pguidVendor), ppIDecoder);
296 
297     if (!guidContainerFormat || !ppIDecoder) return E_INVALIDARG;
298 
299     res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
300     if (FAILED(res)) return res;
301 
302     while (!preferred_decoder)
303     {
304         res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
305         if (res != S_OK) break;
306 
307         res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void **)&decoderinfo);
308         if (SUCCEEDED(res))
309         {
310             GUID container_guid;
311 
312             res = IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo, &container_guid);
313             if (SUCCEEDED(res) && IsEqualIID(&container_guid, guidContainerFormat))
314             {
315                 IWICBitmapDecoder *new_decoder;
316 
317                 res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &new_decoder);
318                 if (SUCCEEDED(res))
319                 {
320                     if (pguidVendor)
321                     {
322                         res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
323                         if (SUCCEEDED(res) && IsEqualIID(&vendor, pguidVendor))
324                         {
325                             preferred_decoder = new_decoder;
326                             new_decoder = NULL;
327                         }
328                     }
329 
330                     if (new_decoder && !decoder)
331                     {
332                         decoder = new_decoder;
333                         new_decoder = NULL;
334                     }
335 
336                     if (new_decoder) IWICBitmapDecoder_Release(new_decoder);
337                 }
338             }
339 
340             IWICBitmapDecoderInfo_Release(decoderinfo);
341         }
342 
343         IUnknown_Release(unkdecoderinfo);
344     }
345 
346     IEnumUnknown_Release(enumdecoders);
347 
348     if (preferred_decoder)
349     {
350         *ppIDecoder = preferred_decoder;
351         if (decoder) IWICBitmapDecoder_Release(decoder);
352         return S_OK;
353     }
354 
355     if (decoder)
356     {
357         *ppIDecoder = decoder;
358         return S_OK;
359     }
360 
361     *ppIDecoder = NULL;
362     return WINCODEC_ERR_COMPONENTNOTFOUND;
363 }
364 
ImagingFactory_CreateEncoder(IWICImagingFactory2 * iface,REFGUID guidContainerFormat,const GUID * pguidVendor,IWICBitmapEncoder ** ppIEncoder)365 static HRESULT WINAPI ImagingFactory_CreateEncoder(IWICImagingFactory2 *iface,
366     REFGUID guidContainerFormat, const GUID *pguidVendor,
367     IWICBitmapEncoder **ppIEncoder)
368 {
369     static int fixme=0;
370     IEnumUnknown *enumencoders;
371     IUnknown *unkencoderinfo;
372     IWICBitmapEncoderInfo *encoderinfo;
373     IWICBitmapEncoder *encoder=NULL;
374     HRESULT res=S_OK;
375     ULONG num_fetched;
376     GUID actual_containerformat;
377 
378     TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
379         debugstr_guid(pguidVendor), ppIEncoder);
380 
381     if (pguidVendor && !fixme++)
382         FIXME("ignoring vendor GUID\n");
383 
384     res = CreateComponentEnumerator(WICEncoder, WICComponentEnumerateDefault, &enumencoders);
385     if (FAILED(res)) return res;
386 
387     while (!encoder)
388     {
389         res = IEnumUnknown_Next(enumencoders, 1, &unkencoderinfo, &num_fetched);
390 
391         if (res == S_OK)
392         {
393             res = IUnknown_QueryInterface(unkencoderinfo, &IID_IWICBitmapEncoderInfo, (void**)&encoderinfo);
394 
395             if (SUCCEEDED(res))
396             {
397                 res = IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo, &actual_containerformat);
398 
399                 if (SUCCEEDED(res) && IsEqualGUID(guidContainerFormat, &actual_containerformat))
400                 {
401                     res = IWICBitmapEncoderInfo_CreateInstance(encoderinfo, &encoder);
402                     if (FAILED(res))
403                         encoder = NULL;
404                 }
405 
406                 IWICBitmapEncoderInfo_Release(encoderinfo);
407             }
408 
409             IUnknown_Release(unkencoderinfo);
410         }
411         else
412             break;
413     }
414 
415     IEnumUnknown_Release(enumencoders);
416 
417     if (encoder)
418     {
419         *ppIEncoder = encoder;
420         return S_OK;
421     }
422     else
423     {
424         WARN("failed to create encoder\n");
425         *ppIEncoder = NULL;
426         return WINCODEC_ERR_COMPONENTNOTFOUND;
427     }
428 }
429 
ImagingFactory_CreatePalette(IWICImagingFactory2 * iface,IWICPalette ** ppIPalette)430 static HRESULT WINAPI ImagingFactory_CreatePalette(IWICImagingFactory2 *iface,
431     IWICPalette **ppIPalette)
432 {
433     TRACE("(%p,%p)\n", iface, ppIPalette);
434     return PaletteImpl_Create(ppIPalette);
435 }
436 
ImagingFactory_CreateFormatConverter(IWICImagingFactory2 * iface,IWICFormatConverter ** ppIFormatConverter)437 static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory2 *iface,
438     IWICFormatConverter **ppIFormatConverter)
439 {
440     return FormatConverter_CreateInstance(&IID_IWICFormatConverter, (void**)ppIFormatConverter);
441 }
442 
ImagingFactory_CreateBitmapScaler(IWICImagingFactory2 * iface,IWICBitmapScaler ** ppIBitmapScaler)443 static HRESULT WINAPI ImagingFactory_CreateBitmapScaler(IWICImagingFactory2 *iface,
444     IWICBitmapScaler **ppIBitmapScaler)
445 {
446     TRACE("(%p,%p)\n", iface, ppIBitmapScaler);
447 
448     return BitmapScaler_Create(ppIBitmapScaler);
449 }
450 
ImagingFactory_CreateBitmapClipper(IWICImagingFactory2 * iface,IWICBitmapClipper ** ppIBitmapClipper)451 static HRESULT WINAPI ImagingFactory_CreateBitmapClipper(IWICImagingFactory2 *iface,
452     IWICBitmapClipper **ppIBitmapClipper)
453 {
454     TRACE("(%p,%p)\n", iface, ppIBitmapClipper);
455     return BitmapClipper_Create(ppIBitmapClipper);
456 }
457 
ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory2 * iface,IWICBitmapFlipRotator ** ppIBitmapFlipRotator)458 static HRESULT WINAPI ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory2 *iface,
459     IWICBitmapFlipRotator **ppIBitmapFlipRotator)
460 {
461     TRACE("(%p,%p)\n", iface, ppIBitmapFlipRotator);
462     return FlipRotator_Create(ppIBitmapFlipRotator);
463 }
464 
ImagingFactory_CreateStream(IWICImagingFactory2 * iface,IWICStream ** ppIWICStream)465 static HRESULT WINAPI ImagingFactory_CreateStream(IWICImagingFactory2 *iface,
466     IWICStream **ppIWICStream)
467 {
468     TRACE("(%p,%p)\n", iface, ppIWICStream);
469     return StreamImpl_Create(ppIWICStream);
470 }
471 
ImagingFactory_CreateColorContext(IWICImagingFactory2 * iface,IWICColorContext ** ppIColorContext)472 static HRESULT WINAPI ImagingFactory_CreateColorContext(IWICImagingFactory2 *iface,
473     IWICColorContext **ppIColorContext)
474 {
475     TRACE("(%p,%p)\n", iface, ppIColorContext);
476     return ColorContext_Create(ppIColorContext);
477 }
478 
ImagingFactory_CreateColorTransformer(IWICImagingFactory2 * iface,IWICColorTransform ** ppIColorTransform)479 static HRESULT WINAPI ImagingFactory_CreateColorTransformer(IWICImagingFactory2 *iface,
480     IWICColorTransform **ppIColorTransform)
481 {
482     TRACE("(%p,%p)\n", iface, ppIColorTransform);
483     return ColorTransform_Create(ppIColorTransform);
484 }
485 
ImagingFactory_CreateBitmap(IWICImagingFactory2 * iface,UINT uiWidth,UINT uiHeight,REFWICPixelFormatGUID pixelFormat,WICBitmapCreateCacheOption option,IWICBitmap ** ppIBitmap)486 static HRESULT WINAPI ImagingFactory_CreateBitmap(IWICImagingFactory2 *iface,
487     UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
488     WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
489 {
490     TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight,
491         debugstr_guid(pixelFormat), option, ppIBitmap);
492     return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, 0, pixelFormat, option, ppIBitmap);
493 }
494 
create_bitmap_from_source_rect(IWICBitmapSource * piBitmapSource,const WICRect * rect,WICBitmapCreateCacheOption option,IWICBitmap ** ppIBitmap)495 static HRESULT create_bitmap_from_source_rect(IWICBitmapSource *piBitmapSource, const WICRect *rect,
496     WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
497 {
498     IWICBitmap *result;
499     IWICBitmapLock *lock;
500     IWICPalette *palette;
501     UINT width, height;
502     WICPixelFormatGUID pixelformat = {0};
503     HRESULT hr;
504     WICRect rc;
505     double dpix, dpiy;
506     IWICComponentInfo *info;
507     IWICPixelFormatInfo2 *formatinfo;
508     WICPixelFormatNumericRepresentation format_type;
509 
510     assert(!rect || option == WICBitmapCacheOnLoad);
511 
512     if (!piBitmapSource || !ppIBitmap)
513         return E_INVALIDARG;
514 
515     if (option == WICBitmapNoCache && SUCCEEDED(IWICBitmapSource_QueryInterface(piBitmapSource,
516             &IID_IWICBitmap, (void **)&result)))
517     {
518         *ppIBitmap = result;
519         return S_OK;
520     }
521 
522     hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height);
523 
524     if (SUCCEEDED(hr) && rect)
525     {
526         if (rect->X >= width || rect->Y >= height || rect->Width == 0 || rect->Height == 0)
527             return E_INVALIDARG;
528 
529         width = min(width - rect->X, rect->Width);
530         height = min(height - rect->Y, rect->Height);
531     }
532 
533     if (SUCCEEDED(hr))
534         hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat);
535 
536     if (SUCCEEDED(hr))
537         hr = CreateComponentInfo(&pixelformat, &info);
538 
539     if (SUCCEEDED(hr))
540     {
541         hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo);
542 
543         if (SUCCEEDED(hr))
544         {
545             hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type);
546 
547             IWICPixelFormatInfo2_Release(formatinfo);
548         }
549 
550         IWICComponentInfo_Release(info);
551     }
552 
553     if (SUCCEEDED(hr))
554         hr = BitmapImpl_Create(width, height, 0, 0, NULL, 0, &pixelformat, option, &result);
555 
556     if (SUCCEEDED(hr))
557     {
558         hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock);
559         if (SUCCEEDED(hr))
560         {
561             UINT stride, buffersize;
562             BYTE *buffer;
563 
564             if (rect)
565             {
566                 rc.X = rect->X;
567                 rc.Y = rect->Y;
568             }
569             else
570                 rc.X = rc.Y = 0;
571             rc.Width = width;
572             rc.Height = height;
573 
574             hr = IWICBitmapLock_GetStride(lock, &stride);
575 
576             if (SUCCEEDED(hr))
577                 hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer);
578 
579             if (SUCCEEDED(hr))
580                 hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride,
581                     buffersize, buffer);
582 
583             IWICBitmapLock_Release(lock);
584         }
585 
586         if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified ||
587                               format_type == WICPixelFormatNumericRepresentationIndexed))
588         {
589             hr = PaletteImpl_Create(&palette);
590 
591             if (SUCCEEDED(hr))
592             {
593                 hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette);
594 
595                 if (SUCCEEDED(hr))
596                     hr = IWICBitmap_SetPalette(result, palette);
597                 else
598                     hr = S_OK;
599 
600                 IWICPalette_Release(palette);
601             }
602         }
603 
604         if (SUCCEEDED(hr))
605         {
606             hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy);
607 
608             if (SUCCEEDED(hr))
609                 hr = IWICBitmap_SetResolution(result, dpix, dpiy);
610             else
611                 hr = S_OK;
612         }
613 
614         if (SUCCEEDED(hr))
615             *ppIBitmap = result;
616         else
617             IWICBitmap_Release(result);
618     }
619 
620     return hr;
621 }
622 
ImagingFactory_CreateBitmapFromSource(IWICImagingFactory2 * iface,IWICBitmapSource * piBitmapSource,WICBitmapCreateCacheOption option,IWICBitmap ** ppIBitmap)623 static HRESULT WINAPI ImagingFactory_CreateBitmapFromSource(IWICImagingFactory2 *iface,
624     IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
625     IWICBitmap **ppIBitmap)
626 {
627     TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap);
628 
629     return create_bitmap_from_source_rect(piBitmapSource, NULL, option, ppIBitmap);
630 }
631 
ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory2 * iface,IWICBitmapSource * piBitmapSource,UINT x,UINT y,UINT width,UINT height,IWICBitmap ** ppIBitmap)632 static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory2 *iface,
633     IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height,
634     IWICBitmap **ppIBitmap)
635 {
636     WICRect rect;
637 
638     TRACE("(%p,%p,%u,%u,%u,%u,%p)\n", iface, piBitmapSource, x, y, width,
639         height, ppIBitmap);
640 
641     rect.X = x;
642     rect.Y = y;
643     rect.Width = width;
644     rect.Height = height;
645 
646     return create_bitmap_from_source_rect(piBitmapSource, &rect, WICBitmapCacheOnLoad, ppIBitmap);
647 }
648 
ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory2 * iface,UINT width,UINT height,REFWICPixelFormatGUID format,UINT stride,UINT size,BYTE * buffer,IWICBitmap ** bitmap)649 static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory2 *iface,
650     UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride,
651     UINT size, BYTE *buffer, IWICBitmap **bitmap)
652 {
653     HRESULT hr;
654 
655     TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height,
656         debugstr_guid(format), stride, size, buffer, bitmap);
657 
658     if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;
659 
660     hr = BitmapImpl_Create(width, height, stride, size, NULL, 0, format, WICBitmapCacheOnLoad, bitmap);
661     if (SUCCEEDED(hr))
662     {
663         IWICBitmapLock *lock;
664 
665         hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
666         if (SUCCEEDED(hr))
667         {
668             UINT buffersize;
669             BYTE *data;
670 
671             IWICBitmapLock_GetDataPointer(lock, &buffersize, &data);
672             memcpy(data, buffer, buffersize);
673 
674             IWICBitmapLock_Release(lock);
675         }
676         else
677         {
678             IWICBitmap_Release(*bitmap);
679             *bitmap = NULL;
680         }
681     }
682     return hr;
683 }
684 
get_16bpp_format(HBITMAP hbm,WICPixelFormatGUID * format)685 static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format)
686 {
687     BOOL ret = TRUE;
688     BITMAPV4HEADER bmh;
689     HDC hdc;
690 
691     hdc = CreateCompatibleDC(0);
692 
693     memset(&bmh, 0, sizeof(bmh));
694     bmh.bV4Size = sizeof(bmh);
695     bmh.bV4Width = 1;
696     bmh.bV4Height = 1;
697     bmh.bV4V4Compression = BI_BITFIELDS;
698     bmh.bV4BitCount = 16;
699 
700     GetDIBits(hdc, hbm, 0, 0, NULL, (BITMAPINFO *)&bmh, DIB_RGB_COLORS);
701 
702     if (bmh.bV4RedMask == 0x7c00 &&
703         bmh.bV4GreenMask == 0x3e0 &&
704         bmh.bV4BlueMask == 0x1f)
705     {
706         *format = GUID_WICPixelFormat16bppBGR555;
707     }
708     else if (bmh.bV4RedMask == 0xf800 &&
709         bmh.bV4GreenMask == 0x7e0 &&
710         bmh.bV4BlueMask == 0x1f)
711     {
712         *format = GUID_WICPixelFormat16bppBGR565;
713     }
714     else
715     {
716         FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask,
717             bmh.bV4GreenMask, bmh.bV4BlueMask);
718         ret = FALSE;
719     }
720 
721     DeleteDC(hdc);
722     return ret;
723 }
724 
ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory2 * iface,HBITMAP hbm,HPALETTE hpal,WICBitmapAlphaChannelOption option,IWICBitmap ** bitmap)725 static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory2 *iface,
726     HBITMAP hbm, HPALETTE hpal, WICBitmapAlphaChannelOption option, IWICBitmap **bitmap)
727 {
728     BITMAP bm;
729     HRESULT hr;
730     WICPixelFormatGUID format;
731     IWICBitmapLock *lock;
732     UINT size, num_palette_entries = 0;
733     PALETTEENTRY entry[256];
734 
735     TRACE("(%p,%p,%p,%u,%p)\n", iface, hbm, hpal, option, bitmap);
736 
737     if (!bitmap) return E_INVALIDARG;
738 
739     if (GetObjectW(hbm, sizeof(bm), &bm) != sizeof(bm))
740         return WINCODEC_ERR_WIN32ERROR;
741 
742     if (hpal)
743     {
744         num_palette_entries = GetPaletteEntries(hpal, 0, 256, entry);
745         if (!num_palette_entries)
746             return WINCODEC_ERR_WIN32ERROR;
747     }
748 
749     /* TODO: Figure out the correct format for 16, 32, 64 bpp */
750     switch(bm.bmBitsPixel)
751     {
752     case 1:
753         format = GUID_WICPixelFormat1bppIndexed;
754         break;
755     case 4:
756         format = GUID_WICPixelFormat4bppIndexed;
757         break;
758     case 8:
759         format = GUID_WICPixelFormat8bppIndexed;
760         break;
761     case 16:
762         if (!get_16bpp_format(hbm, &format))
763             return E_INVALIDARG;
764         break;
765     case 24:
766         format = GUID_WICPixelFormat24bppBGR;
767         break;
768     case 32:
769         switch (option)
770         {
771         case WICBitmapUseAlpha:
772             format = GUID_WICPixelFormat32bppBGRA;
773             break;
774         case WICBitmapUsePremultipliedAlpha:
775             format = GUID_WICPixelFormat32bppPBGRA;
776             break;
777         case WICBitmapIgnoreAlpha:
778             format = GUID_WICPixelFormat32bppBGR;
779             break;
780         default:
781             return E_INVALIDARG;
782         }
783         break;
784     case 48:
785         format = GUID_WICPixelFormat48bppRGB;
786         break;
787     default:
788         FIXME("unsupported %d bpp\n", bm.bmBitsPixel);
789         return E_INVALIDARG;
790     }
791 
792     hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, 0, &format,
793                            WICBitmapCacheOnLoad, bitmap);
794     if (hr != S_OK) return hr;
795 
796     hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
797     if (hr == S_OK)
798     {
799         BYTE *buffer;
800         HDC hdc;
801         char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD)];
802         BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
803 
804         IWICBitmapLock_GetDataPointer(lock, &size, &buffer);
805 
806         hdc = CreateCompatibleDC(0);
807 
808         bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
809         bmi->bmiHeader.biBitCount = 0;
810         GetDIBits(hdc, hbm, 0, 0, NULL, bmi, DIB_RGB_COLORS);
811         bmi->bmiHeader.biHeight = -bm.bmHeight;
812         GetDIBits(hdc, hbm, 0, bm.bmHeight, buffer, bmi, DIB_RGB_COLORS);
813 
814         DeleteDC(hdc);
815         IWICBitmapLock_Release(lock);
816 
817         if (num_palette_entries)
818         {
819             IWICPalette *palette;
820             WICColor colors[256];
821             UINT i;
822 
823             hr = PaletteImpl_Create(&palette);
824             if (hr == S_OK)
825             {
826                 for (i = 0; i < num_palette_entries; i++)
827                     colors[i] = 0xff000000 | entry[i].peRed << 16 |
828                                 entry[i].peGreen << 8 | entry[i].peBlue;
829 
830                 hr = IWICPalette_InitializeCustom(palette, colors, num_palette_entries);
831                 if (hr == S_OK)
832                     hr = IWICBitmap_SetPalette(*bitmap, palette);
833 
834                 IWICPalette_Release(palette);
835             }
836         }
837     }
838 
839     if (hr != S_OK)
840     {
841         IWICBitmap_Release(*bitmap);
842         *bitmap = NULL;
843     }
844 
845     return hr;
846 }
847 
ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 * iface,HICON hicon,IWICBitmap ** bitmap)848 static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 *iface,
849     HICON hicon, IWICBitmap **bitmap)
850 {
851     IWICBitmapLock *lock;
852     ICONINFO info;
853     BITMAP bm;
854     int width, height, x, y;
855     UINT stride, size;
856     BYTE *buffer;
857     DWORD *bits;
858     BITMAPINFO bi;
859     HDC hdc;
860     BOOL has_alpha;
861     HRESULT hr;
862 
863     TRACE("(%p,%p,%p)\n", iface, hicon, bitmap);
864 
865     if (!bitmap) return E_INVALIDARG;
866 
867     if (!GetIconInfo(hicon, &info))
868         return HRESULT_FROM_WIN32(GetLastError());
869 
870     GetObjectW(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm);
871 
872     width = bm.bmWidth;
873     height = info.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2;
874     stride = width * 4;
875     size = stride * height;
876 
877     hr = BitmapImpl_Create(width, height, stride, size, NULL, 0,
878                            &GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad, bitmap);
879     if (hr != S_OK) goto failed;
880 
881     hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
882     if (hr != S_OK)
883     {
884         IWICBitmap_Release(*bitmap);
885         goto failed;
886     }
887     IWICBitmapLock_GetDataPointer(lock, &size, &buffer);
888 
889     hdc = CreateCompatibleDC(0);
890 
891     memset(&bi, 0, sizeof(bi));
892     bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
893     bi.bmiHeader.biWidth = width;
894     bi.bmiHeader.biHeight = info.hbmColor ? -height: -height * 2;
895     bi.bmiHeader.biPlanes = 1;
896     bi.bmiHeader.biBitCount = 32;
897     bi.bmiHeader.biCompression = BI_RGB;
898 
899     has_alpha = FALSE;
900 
901     if (info.hbmColor)
902     {
903         GetDIBits(hdc, info.hbmColor, 0, height, buffer, &bi, DIB_RGB_COLORS);
904 
905         if (bm.bmBitsPixel == 32)
906         {
907             /* If any pixel has a non-zero alpha, ignore hbmMask */
908             bits = (DWORD *)buffer;
909             for (x = 0; x < width && !has_alpha; x++, bits++)
910             {
911                 for (y = 0; y < height; y++)
912                 {
913                     if (*bits & 0xff000000)
914                     {
915                         has_alpha = TRUE;
916                         break;
917                     }
918                 }
919             }
920         }
921     }
922     else
923         GetDIBits(hdc, info.hbmMask, 0, height, buffer, &bi, DIB_RGB_COLORS);
924 
925     if (!has_alpha)
926     {
927         DWORD *rgba;
928 
929         if (info.hbmMask)
930         {
931             BYTE *mask;
932 
933             mask = HeapAlloc(GetProcessHeap(), 0, size);
934             if (!mask)
935             {
936                 IWICBitmapLock_Release(lock);
937                 IWICBitmap_Release(*bitmap);
938                 DeleteDC(hdc);
939                 hr = E_OUTOFMEMORY;
940                 goto failed;
941             }
942 
943             /* read alpha data from the mask */
944             GetDIBits(hdc, info.hbmMask, info.hbmColor ? 0 : height, height, mask, &bi, DIB_RGB_COLORS);
945 
946             for (y = 0; y < height; y++)
947             {
948                 rgba = (DWORD *)(buffer + y * stride);
949                 bits = (DWORD *)(mask + y * stride);
950 
951                 for (x = 0; x < width; x++, rgba++, bits++)
952                 {
953                     if (*bits)
954                         *rgba = 0;
955                     else
956                         *rgba |= 0xff000000;
957                 }
958             }
959 
960             HeapFree(GetProcessHeap(), 0, mask);
961         }
962         else
963         {
964             /* set constant alpha of 255 */
965             for (y = 0; y < height; y++)
966             {
967                 rgba = (DWORD *)(buffer + y * stride);
968                 for (x = 0; x < width; x++, rgba++)
969                     *rgba |= 0xff000000;
970             }
971         }
972 
973     }
974 
975     IWICBitmapLock_Release(lock);
976     DeleteDC(hdc);
977 
978 failed:
979     DeleteObject(info.hbmColor);
980     DeleteObject(info.hbmMask);
981 
982     return hr;
983 }
984 
ImagingFactory_CreateComponentEnumerator(IWICImagingFactory2 * iface,DWORD componentTypes,DWORD options,IEnumUnknown ** ppIEnumUnknown)985 static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory2 *iface,
986     DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
987 {
988     TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown);
989     return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown);
990 }
991 
ImagingFactory_CreateFastMetadataEncoderFromDecoder(IWICImagingFactory2 * iface,IWICBitmapDecoder * pIDecoder,IWICFastMetadataEncoder ** ppIFastEncoder)992 static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromDecoder(
993     IWICImagingFactory2 *iface, IWICBitmapDecoder *pIDecoder,
994     IWICFastMetadataEncoder **ppIFastEncoder)
995 {
996     FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder);
997     return E_NOTIMPL;
998 }
999 
ImagingFactory_CreateFastMetadataEncoderFromFrameDecode(IWICImagingFactory2 * iface,IWICBitmapFrameDecode * pIFrameDecoder,IWICFastMetadataEncoder ** ppIFastEncoder)1000 static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode(
1001     IWICImagingFactory2 *iface, IWICBitmapFrameDecode *pIFrameDecoder,
1002     IWICFastMetadataEncoder **ppIFastEncoder)
1003 {
1004     FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder);
1005     return E_NOTIMPL;
1006 }
1007 
ImagingFactory_CreateQueryWriter(IWICImagingFactory2 * iface,REFGUID guidMetadataFormat,const GUID * pguidVendor,IWICMetadataQueryWriter ** ppIQueryWriter)1008 static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory2 *iface,
1009     REFGUID guidMetadataFormat, const GUID *pguidVendor,
1010     IWICMetadataQueryWriter **ppIQueryWriter)
1011 {
1012     FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat),
1013         debugstr_guid(pguidVendor), ppIQueryWriter);
1014     return E_NOTIMPL;
1015 }
1016 
ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory2 * iface,IWICMetadataQueryReader * pIQueryReader,const GUID * pguidVendor,IWICMetadataQueryWriter ** ppIQueryWriter)1017 static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory2 *iface,
1018     IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor,
1019     IWICMetadataQueryWriter **ppIQueryWriter)
1020 {
1021     FIXME("(%p,%p,%s,%p): stub\n", iface, pIQueryReader, debugstr_guid(pguidVendor),
1022         ppIQueryWriter);
1023     return E_NOTIMPL;
1024 }
1025 
1026 #ifndef __REACTOS__
ImagingFactory_CreateImageEncoder(IWICImagingFactory2 * iface,ID2D1Device * device,IWICImageEncoder ** encoder)1027 static HRESULT WINAPI ImagingFactory_CreateImageEncoder(IWICImagingFactory2 *iface, ID2D1Device *device, IWICImageEncoder **encoder)
1028 {
1029     FIXME("%p,%p,%p stub.\n", iface, device, encoder);
1030     return E_NOTIMPL;
1031 }
1032 #endif
1033 
1034 static const IWICImagingFactory2Vtbl ImagingFactory_Vtbl = {
1035     ImagingFactory_QueryInterface,
1036     ImagingFactory_AddRef,
1037     ImagingFactory_Release,
1038     ImagingFactory_CreateDecoderFromFilename,
1039     ImagingFactory_CreateDecoderFromStream,
1040     ImagingFactory_CreateDecoderFromFileHandle,
1041     ImagingFactory_CreateComponentInfo,
1042     ImagingFactory_CreateDecoder,
1043     ImagingFactory_CreateEncoder,
1044     ImagingFactory_CreatePalette,
1045     ImagingFactory_CreateFormatConverter,
1046     ImagingFactory_CreateBitmapScaler,
1047     ImagingFactory_CreateBitmapClipper,
1048     ImagingFactory_CreateBitmapFlipRotator,
1049     ImagingFactory_CreateStream,
1050     ImagingFactory_CreateColorContext,
1051     ImagingFactory_CreateColorTransformer,
1052     ImagingFactory_CreateBitmap,
1053     ImagingFactory_CreateBitmapFromSource,
1054     ImagingFactory_CreateBitmapFromSourceRect,
1055     ImagingFactory_CreateBitmapFromMemory,
1056     ImagingFactory_CreateBitmapFromHBITMAP,
1057     ImagingFactory_CreateBitmapFromHICON,
1058     ImagingFactory_CreateComponentEnumerator,
1059     ImagingFactory_CreateFastMetadataEncoderFromDecoder,
1060     ImagingFactory_CreateFastMetadataEncoderFromFrameDecode,
1061     ImagingFactory_CreateQueryWriter,
1062     ImagingFactory_CreateQueryWriterFromReader,
1063 #ifndef __REACTOS__
1064     ImagingFactory_CreateImageEncoder,
1065 #endif
1066 };
1067 
ComponentFactory_QueryInterface(IWICComponentFactory * iface,REFIID iid,void ** ppv)1068 static HRESULT WINAPI ComponentFactory_QueryInterface(IWICComponentFactory *iface, REFIID iid, void **ppv)
1069 {
1070     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1071     return IWICImagingFactory2_QueryInterface(&This->IWICImagingFactory2_iface, iid, ppv);
1072 }
1073 
ComponentFactory_AddRef(IWICComponentFactory * iface)1074 static ULONG WINAPI ComponentFactory_AddRef(IWICComponentFactory *iface)
1075 {
1076     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1077     return IWICImagingFactory2_AddRef(&This->IWICImagingFactory2_iface);
1078 }
1079 
ComponentFactory_Release(IWICComponentFactory * iface)1080 static ULONG WINAPI ComponentFactory_Release(IWICComponentFactory *iface)
1081 {
1082     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1083     return IWICImagingFactory2_Release(&This->IWICImagingFactory2_iface);
1084 }
1085 
ComponentFactory_CreateDecoderFromFilename(IWICComponentFactory * iface,LPCWSTR filename,const GUID * vendor,DWORD desired_access,WICDecodeOptions options,IWICBitmapDecoder ** decoder)1086 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename(IWICComponentFactory *iface, LPCWSTR filename,
1087     const GUID *vendor, DWORD desired_access, WICDecodeOptions options, IWICBitmapDecoder **decoder)
1088 {
1089     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1090     return IWICImagingFactory2_CreateDecoderFromFilename(&This->IWICImagingFactory2_iface, filename, vendor,
1091         desired_access, options, decoder);
1092 }
1093 
ComponentFactory_CreateDecoderFromStream(IWICComponentFactory * iface,IStream * stream,const GUID * vendor,WICDecodeOptions options,IWICBitmapDecoder ** decoder)1094 static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(IWICComponentFactory *iface, IStream *stream,
1095     const GUID *vendor, WICDecodeOptions options, IWICBitmapDecoder **decoder)
1096 {
1097     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1098     return IWICImagingFactory2_CreateDecoderFromStream(&This->IWICImagingFactory2_iface, stream, vendor,
1099         options, decoder);
1100 }
1101 
ComponentFactory_CreateDecoderFromFileHandle(IWICComponentFactory * iface,ULONG_PTR hFile,const GUID * vendor,WICDecodeOptions options,IWICBitmapDecoder ** decoder)1102 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFileHandle(IWICComponentFactory *iface, ULONG_PTR hFile,
1103     const GUID *vendor, WICDecodeOptions options, IWICBitmapDecoder **decoder)
1104 {
1105     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1106     return IWICImagingFactory2_CreateDecoderFromFileHandle(&This->IWICImagingFactory2_iface, hFile, vendor,
1107         options, decoder);
1108 }
1109 
ComponentFactory_CreateComponentInfo(IWICComponentFactory * iface,REFCLSID component,IWICComponentInfo ** info)1110 static HRESULT WINAPI ComponentFactory_CreateComponentInfo(IWICComponentFactory *iface, REFCLSID component,
1111     IWICComponentInfo **info)
1112 {
1113     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1114     return IWICImagingFactory2_CreateComponentInfo(&This->IWICImagingFactory2_iface, component, info);
1115 }
1116 
ComponentFactory_CreateDecoder(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,IWICBitmapDecoder ** decoder)1117 static HRESULT WINAPI ComponentFactory_CreateDecoder(IWICComponentFactory *iface, REFGUID format, const GUID *vendor,
1118     IWICBitmapDecoder **decoder)
1119 {
1120     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1121     return IWICImagingFactory2_CreateDecoder(&This->IWICImagingFactory2_iface, format, vendor, decoder);
1122 }
1123 
ComponentFactory_CreateEncoder(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,IWICBitmapEncoder ** encoder)1124 static HRESULT WINAPI ComponentFactory_CreateEncoder(IWICComponentFactory *iface, REFGUID format, const GUID *vendor,
1125     IWICBitmapEncoder **encoder)
1126 {
1127     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1128     return IWICImagingFactory2_CreateEncoder(&This->IWICImagingFactory2_iface, format, vendor, encoder);
1129 }
1130 
ComponentFactory_CreatePalette(IWICComponentFactory * iface,IWICPalette ** palette)1131 static HRESULT WINAPI ComponentFactory_CreatePalette(IWICComponentFactory *iface, IWICPalette **palette)
1132 {
1133     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1134     return IWICImagingFactory2_CreatePalette(&This->IWICImagingFactory2_iface, palette);
1135 }
1136 
ComponentFactory_CreateFormatConverter(IWICComponentFactory * iface,IWICFormatConverter ** converter)1137 static HRESULT WINAPI ComponentFactory_CreateFormatConverter(IWICComponentFactory *iface, IWICFormatConverter **converter)
1138 {
1139     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1140     return IWICImagingFactory2_CreateFormatConverter(&This->IWICImagingFactory2_iface, converter);
1141 }
1142 
ComponentFactory_CreateBitmapScaler(IWICComponentFactory * iface,IWICBitmapScaler ** scaler)1143 static HRESULT WINAPI ComponentFactory_CreateBitmapScaler(IWICComponentFactory *iface, IWICBitmapScaler **scaler)
1144 {
1145     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1146     return IWICImagingFactory2_CreateBitmapScaler(&This->IWICImagingFactory2_iface, scaler);
1147 }
1148 
ComponentFactory_CreateBitmapClipper(IWICComponentFactory * iface,IWICBitmapClipper ** clipper)1149 static HRESULT WINAPI ComponentFactory_CreateBitmapClipper(IWICComponentFactory *iface, IWICBitmapClipper **clipper)
1150 {
1151     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1152     return IWICImagingFactory2_CreateBitmapClipper(&This->IWICImagingFactory2_iface, clipper);
1153 }
1154 
ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory * iface,IWICBitmapFlipRotator ** fliprotator)1155 static HRESULT WINAPI ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory *iface, IWICBitmapFlipRotator **fliprotator)
1156 {
1157     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1158     return IWICImagingFactory2_CreateBitmapFlipRotator(&This->IWICImagingFactory2_iface, fliprotator);
1159 }
1160 
ComponentFactory_CreateStream(IWICComponentFactory * iface,IWICStream ** stream)1161 static HRESULT WINAPI ComponentFactory_CreateStream(IWICComponentFactory *iface, IWICStream **stream)
1162 {
1163     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1164     return IWICImagingFactory2_CreateStream(&This->IWICImagingFactory2_iface, stream);
1165 }
1166 
ComponentFactory_CreateColorContext(IWICComponentFactory * iface,IWICColorContext ** context)1167 static HRESULT WINAPI ComponentFactory_CreateColorContext(IWICComponentFactory *iface, IWICColorContext **context)
1168 {
1169     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1170     return IWICImagingFactory2_CreateColorContext(&This->IWICImagingFactory2_iface, context);
1171 }
1172 
ComponentFactory_CreateColorTransformer(IWICComponentFactory * iface,IWICColorTransform ** transformer)1173 static HRESULT WINAPI ComponentFactory_CreateColorTransformer(IWICComponentFactory *iface, IWICColorTransform **transformer)
1174 {
1175     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1176     return IWICImagingFactory2_CreateColorTransformer(&This->IWICImagingFactory2_iface, transformer);
1177 }
1178 
ComponentFactory_CreateBitmap(IWICComponentFactory * iface,UINT width,UINT height,REFWICPixelFormatGUID pixel_format,WICBitmapCreateCacheOption option,IWICBitmap ** bitmap)1179 static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface, UINT width, UINT height, REFWICPixelFormatGUID pixel_format,
1180     WICBitmapCreateCacheOption option, IWICBitmap **bitmap)
1181 {
1182     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1183     return IWICImagingFactory2_CreateBitmap(&This->IWICImagingFactory2_iface, width, height, pixel_format, option, bitmap);
1184 }
1185 
ComponentFactory_CreateBitmapFromSource(IWICComponentFactory * iface,IWICBitmapSource * source,WICBitmapCreateCacheOption option,IWICBitmap ** bitmap)1186 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface, IWICBitmapSource *source,
1187     WICBitmapCreateCacheOption option, IWICBitmap **bitmap)
1188 {
1189     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1190     return IWICImagingFactory2_CreateBitmapFromSource(&This->IWICImagingFactory2_iface, source, option, bitmap);
1191 }
1192 
ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory * iface,IWICBitmapSource * source,UINT x,UINT y,UINT width,UINT height,IWICBitmap ** bitmap)1193 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory *iface, IWICBitmapSource *source,
1194     UINT x, UINT y, UINT width, UINT height, IWICBitmap **bitmap)
1195 {
1196     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1197     return IWICImagingFactory2_CreateBitmapFromSourceRect(&This->IWICImagingFactory2_iface, source, x, y, width, height, bitmap);
1198 }
1199 
ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory * iface,UINT width,UINT height,REFWICPixelFormatGUID format,UINT stride,UINT size,BYTE * buffer,IWICBitmap ** bitmap)1200 static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface, UINT width, UINT height,
1201     REFWICPixelFormatGUID format, UINT stride, UINT size, BYTE *buffer, IWICBitmap **bitmap)
1202 {
1203     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1204     return IWICImagingFactory2_CreateBitmapFromMemory(&This->IWICImagingFactory2_iface, width, height, format, stride,
1205         size, buffer, bitmap);
1206 }
1207 
ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory * iface,HBITMAP hbm,HPALETTE hpal,WICBitmapAlphaChannelOption option,IWICBitmap ** bitmap)1208 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface, HBITMAP hbm, HPALETTE hpal,
1209     WICBitmapAlphaChannelOption option, IWICBitmap **bitmap)
1210 {
1211     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1212     return IWICImagingFactory2_CreateBitmapFromHBITMAP(&This->IWICImagingFactory2_iface, hbm, hpal, option, bitmap);
1213 }
1214 
ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory * iface,HICON hicon,IWICBitmap ** bitmap)1215 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface, HICON hicon, IWICBitmap **bitmap)
1216 {
1217     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1218     return IWICImagingFactory2_CreateBitmapFromHICON(&This->IWICImagingFactory2_iface, hicon, bitmap);
1219 }
1220 
ComponentFactory_CreateComponentEnumerator(IWICComponentFactory * iface,DWORD component_types,DWORD options,IEnumUnknown ** enumerator)1221 static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *iface, DWORD component_types,
1222     DWORD options, IEnumUnknown **enumerator)
1223 {
1224     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1225     return IWICImagingFactory2_CreateComponentEnumerator(&This->IWICImagingFactory2_iface, component_types,
1226         options, enumerator);
1227 }
1228 
ComponentFactory_CreateFastMetadataEncoderFromDecoder(IWICComponentFactory * iface,IWICBitmapDecoder * decoder,IWICFastMetadataEncoder ** encoder)1229 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromDecoder(IWICComponentFactory *iface, IWICBitmapDecoder *decoder,
1230     IWICFastMetadataEncoder **encoder)
1231 {
1232     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1233     return IWICImagingFactory2_CreateFastMetadataEncoderFromDecoder(&This->IWICImagingFactory2_iface, decoder, encoder);
1234 }
1235 
ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(IWICComponentFactory * iface,IWICBitmapFrameDecode * frame_decode,IWICFastMetadataEncoder ** encoder)1236 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(IWICComponentFactory *iface,
1237     IWICBitmapFrameDecode *frame_decode, IWICFastMetadataEncoder **encoder)
1238 {
1239     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1240     return IWICImagingFactory2_CreateFastMetadataEncoderFromFrameDecode(&This->IWICImagingFactory2_iface, frame_decode, encoder);
1241 }
1242 
ComponentFactory_CreateQueryWriter(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,IWICMetadataQueryWriter ** writer)1243 static HRESULT WINAPI ComponentFactory_CreateQueryWriter(IWICComponentFactory *iface, REFGUID format, const GUID *vendor,
1244     IWICMetadataQueryWriter **writer)
1245 {
1246     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1247     return IWICImagingFactory2_CreateQueryWriter(&This->IWICImagingFactory2_iface, format, vendor, writer);
1248 }
1249 
ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory * iface,IWICMetadataQueryReader * reader,const GUID * vendor,IWICMetadataQueryWriter ** writer)1250 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory *iface, IWICMetadataQueryReader *reader,
1251     const GUID *vendor, IWICMetadataQueryWriter **writer)
1252 {
1253     ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1254     return IWICImagingFactory2_CreateQueryWriterFromReader(&This->IWICImagingFactory2_iface, reader, vendor, writer);
1255 }
1256 
ComponentFactory_CreateMetadataReader(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,DWORD options,IStream * stream,IWICMetadataReader ** reader)1257 static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface,
1258         REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
1259 {
1260     FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor),
1261         options, stream, reader);
1262     return E_NOTIMPL;
1263 }
1264 
ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,DWORD options,IStream * stream,IWICMetadataReader ** reader)1265 static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface,
1266         REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
1267 {
1268     HRESULT hr;
1269     IEnumUnknown *enumreaders;
1270     IUnknown *unkreaderinfo;
1271     IWICMetadataReaderInfo *readerinfo;
1272     IWICPersistStream *wicpersiststream;
1273     ULONG num_fetched;
1274     GUID decoder_vendor;
1275     BOOL matches;
1276     LARGE_INTEGER zero;
1277 
1278     TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor),
1279         options, stream, reader);
1280 
1281     if (!format || !stream || !reader)
1282         return E_INVALIDARG;
1283 
1284     zero.QuadPart = 0;
1285 
1286     hr = CreateComponentEnumerator(WICMetadataReader, WICComponentEnumerateDefault, &enumreaders);
1287     if (FAILED(hr)) return hr;
1288 
1289     *reader = NULL;
1290 
1291 start:
1292     while (!*reader)
1293     {
1294         hr = IEnumUnknown_Next(enumreaders, 1, &unkreaderinfo, &num_fetched);
1295 
1296         if (hr == S_OK)
1297         {
1298             hr = IUnknown_QueryInterface(unkreaderinfo, &IID_IWICMetadataReaderInfo, (void**)&readerinfo);
1299 
1300             if (SUCCEEDED(hr))
1301             {
1302                 if (vendor)
1303                 {
1304                     hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &decoder_vendor);
1305 
1306                     if (FAILED(hr) || !IsEqualIID(vendor, &decoder_vendor))
1307                     {
1308                         IWICMetadataReaderInfo_Release(readerinfo);
1309                         IUnknown_Release(unkreaderinfo);
1310                         continue;
1311                     }
1312                 }
1313 
1314                 hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, format, stream, &matches);
1315 
1316                 if (SUCCEEDED(hr) && matches)
1317                 {
1318                     hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
1319 
1320                     if (SUCCEEDED(hr))
1321                         hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, reader);
1322 
1323                     if (SUCCEEDED(hr))
1324                     {
1325                         hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream);
1326 
1327                         if (SUCCEEDED(hr))
1328                         {
1329                             hr = IWICPersistStream_LoadEx(wicpersiststream,
1330                                 stream, vendor, options & WICPersistOptionMask);
1331 
1332                             IWICPersistStream_Release(wicpersiststream);
1333                         }
1334 
1335                         if (FAILED(hr))
1336                         {
1337                             IWICMetadataReader_Release(*reader);
1338                             *reader = NULL;
1339                         }
1340                     }
1341                 }
1342 
1343                 IUnknown_Release(readerinfo);
1344             }
1345 
1346             IUnknown_Release(unkreaderinfo);
1347         }
1348         else
1349             break;
1350     }
1351 
1352     if (!*reader && vendor)
1353     {
1354         vendor = NULL;
1355         IEnumUnknown_Reset(enumreaders);
1356         goto start;
1357     }
1358 
1359     IEnumUnknown_Release(enumreaders);
1360 
1361     if (!*reader && !(options & WICMetadataCreationFailUnknown))
1362     {
1363         hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
1364 
1365         if (SUCCEEDED(hr))
1366             hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void**)reader);
1367 
1368         if (SUCCEEDED(hr))
1369         {
1370             hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream);
1371 
1372             if (SUCCEEDED(hr))
1373             {
1374                 hr = IWICPersistStream_LoadEx(wicpersiststream, stream, NULL, options & WICPersistOptionMask);
1375 
1376                 IWICPersistStream_Release(wicpersiststream);
1377             }
1378 
1379             if (FAILED(hr))
1380             {
1381                 IWICMetadataReader_Release(*reader);
1382                 *reader = NULL;
1383             }
1384         }
1385     }
1386 
1387     if (*reader)
1388         return S_OK;
1389     else
1390         return WINCODEC_ERR_COMPONENTNOTFOUND;
1391 }
1392 
ComponentFactory_CreateMetadataWriter(IWICComponentFactory * iface,REFGUID format,const GUID * vendor,DWORD options,IWICMetadataWriter ** writer)1393 static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface,
1394         REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer)
1395 {
1396     FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer);
1397     return E_NOTIMPL;
1398 }
1399 
ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory * iface,IWICMetadataReader * reader,const GUID * vendor,IWICMetadataWriter ** writer)1400 static HRESULT WINAPI ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory *iface,
1401         IWICMetadataReader *reader, const GUID *vendor, IWICMetadataWriter **writer)
1402 {
1403     FIXME("%p,%p,%s,%p: stub\n", iface, reader, debugstr_guid(vendor), writer);
1404     return E_NOTIMPL;
1405 }
1406 
ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory * iface,IWICMetadataBlockReader * block_reader,IWICMetadataQueryReader ** query_reader)1407 static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory *iface,
1408         IWICMetadataBlockReader *block_reader, IWICMetadataQueryReader **query_reader)
1409 {
1410     TRACE("%p,%p,%p\n", iface, block_reader, query_reader);
1411 
1412     if (!block_reader || !query_reader)
1413         return E_INVALIDARG;
1414 
1415     return MetadataQueryReader_CreateInstance(block_reader, NULL, query_reader);
1416 }
1417 
ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory * iface,IWICMetadataBlockWriter * block_writer,IWICMetadataQueryWriter ** query_writer)1418 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface,
1419         IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer)
1420 {
1421     FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer);
1422     return E_NOTIMPL;
1423 }
1424 
ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory * iface,PROPBAG2 * options,UINT count,IPropertyBag2 ** property)1425 static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface,
1426         PROPBAG2 *options, UINT count, IPropertyBag2 **property)
1427 {
1428     TRACE("(%p,%p,%u,%p)\n", iface, options, count, property);
1429     return CreatePropertyBag2(options, count, property);
1430 }
1431 
1432 static const IWICComponentFactoryVtbl ComponentFactory_Vtbl = {
1433     ComponentFactory_QueryInterface,
1434     ComponentFactory_AddRef,
1435     ComponentFactory_Release,
1436     ComponentFactory_CreateDecoderFromFilename,
1437     ComponentFactory_CreateDecoderFromStream,
1438     ComponentFactory_CreateDecoderFromFileHandle,
1439     ComponentFactory_CreateComponentInfo,
1440     ComponentFactory_CreateDecoder,
1441     ComponentFactory_CreateEncoder,
1442     ComponentFactory_CreatePalette,
1443     ComponentFactory_CreateFormatConverter,
1444     ComponentFactory_CreateBitmapScaler,
1445     ComponentFactory_CreateBitmapClipper,
1446     ComponentFactory_CreateBitmapFlipRotator,
1447     ComponentFactory_CreateStream,
1448     ComponentFactory_CreateColorContext,
1449     ComponentFactory_CreateColorTransformer,
1450     ComponentFactory_CreateBitmap,
1451     ComponentFactory_CreateBitmapFromSource,
1452     ComponentFactory_CreateBitmapFromSourceRect,
1453     ComponentFactory_CreateBitmapFromMemory,
1454     ComponentFactory_CreateBitmapFromHBITMAP,
1455     ComponentFactory_CreateBitmapFromHICON,
1456     ComponentFactory_CreateComponentEnumerator,
1457     ComponentFactory_CreateFastMetadataEncoderFromDecoder,
1458     ComponentFactory_CreateFastMetadataEncoderFromFrameDecode,
1459     ComponentFactory_CreateQueryWriter,
1460     ComponentFactory_CreateQueryWriterFromReader,
1461     ComponentFactory_CreateMetadataReader,
1462     ComponentFactory_CreateMetadataReaderFromContainer,
1463     ComponentFactory_CreateMetadataWriter,
1464     ComponentFactory_CreateMetadataWriterFromReader,
1465     ComponentFactory_CreateQueryReaderFromBlockReader,
1466     ComponentFactory_CreateQueryWriterFromBlockWriter,
1467     ComponentFactory_CreateEncoderPropertyBag
1468 };
1469 
ImagingFactory_CreateInstance(REFIID iid,void ** ppv)1470 HRESULT ImagingFactory_CreateInstance(REFIID iid, void** ppv)
1471 {
1472     ImagingFactory *This;
1473     HRESULT ret;
1474 
1475     TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
1476 
1477     *ppv = NULL;
1478 
1479     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1480     if (!This) return E_OUTOFMEMORY;
1481 
1482     This->IWICImagingFactory2_iface.lpVtbl = &ImagingFactory_Vtbl;
1483     This->IWICComponentFactory_iface.lpVtbl = &ComponentFactory_Vtbl;
1484     This->ref = 1;
1485 
1486     ret = IWICImagingFactory2_QueryInterface(&This->IWICImagingFactory2_iface, iid, ppv);
1487     IWICImagingFactory2_Release(&This->IWICImagingFactory2_iface);
1488 
1489     return ret;
1490 }
1491 
WICCreateBitmapFromSectionEx(UINT width,UINT height,REFWICPixelFormatGUID format,HANDLE section,UINT stride,UINT offset,WICSectionAccessLevel wicaccess,IWICBitmap ** bitmap)1492 HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height,
1493         REFWICPixelFormatGUID format, HANDLE section, UINT stride,
1494         UINT offset, WICSectionAccessLevel wicaccess, IWICBitmap **bitmap)
1495 {
1496     SYSTEM_INFO sysinfo;
1497     UINT bpp, access, size, view_offset, view_size;
1498     void *view;
1499     HRESULT hr;
1500 
1501     TRACE("%u,%u,%s,%p,%u,%u,%#x,%p\n", width, height, debugstr_guid(format),
1502           section, stride, offset, wicaccess, bitmap);
1503 
1504     if (!width || !height || !section || !bitmap) return E_INVALIDARG;
1505 
1506     hr = get_pixelformat_bpp(format, &bpp);
1507     if (FAILED(hr)) return hr;
1508 
1509     switch (wicaccess)
1510     {
1511     case WICSectionAccessLevelReadWrite:
1512         access = FILE_MAP_READ | FILE_MAP_WRITE;
1513         break;
1514 
1515     case WICSectionAccessLevelRead:
1516         access = FILE_MAP_READ;
1517         break;
1518 
1519     default:
1520         FIXME("unsupported access %#x\n", wicaccess);
1521         return E_INVALIDARG;
1522     }
1523 
1524     if (!stride) stride = (((bpp * width) + 31) / 32) * 4;
1525     size = stride * height;
1526     if (size / height != stride) return E_INVALIDARG;
1527 
1528     GetSystemInfo(&sysinfo);
1529     view_offset = offset - (offset % sysinfo.dwAllocationGranularity);
1530     view_size = size + (offset - view_offset);
1531 
1532     view = MapViewOfFile(section, access, 0, view_offset, view_size);
1533     if (!view) return HRESULT_FROM_WIN32(GetLastError());
1534 
1535     offset -= view_offset;
1536     hr = BitmapImpl_Create(width, height, stride, 0, view, offset, format, WICBitmapCacheOnLoad, bitmap);
1537     if (FAILED(hr)) UnmapViewOfFile(view);
1538     return hr;
1539 }
1540 
WICCreateBitmapFromSection(UINT width,UINT height,REFWICPixelFormatGUID format,HANDLE section,UINT stride,UINT offset,IWICBitmap ** bitmap)1541 HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height,
1542         REFWICPixelFormatGUID format, HANDLE section,
1543         UINT stride, UINT offset, IWICBitmap **bitmap)
1544 {
1545     TRACE("%u,%u,%s,%p,%u,%u,%p\n", width, height, debugstr_guid(format),
1546         section, stride, offset, bitmap);
1547 
1548     return WICCreateBitmapFromSectionEx(width, height, format, section,
1549         stride, offset, WICSectionAccessLevelRead, bitmap);
1550 }
1551