makefiles: Explicitly create destination dirs when installing symlinks.
[wine/zf.git] / dlls / windowscodecs / imgfactory.c
blob0ad8bc6ee15423af69326283dfdb06a999c1cf43
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2012 Dmitry Timoshkov
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
22 #include <assert.h>
23 #include <stdarg.h>
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winreg.h"
30 #include "objbase.h"
31 #include "shellapi.h"
33 #include "wincodecs_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
39 typedef struct {
40 IWICImagingFactory2 IWICImagingFactory2_iface;
41 IWICComponentFactory IWICComponentFactory_iface;
42 LONG ref;
43 } ImagingFactory;
45 static inline ImagingFactory *impl_from_IWICComponentFactory(IWICComponentFactory *iface)
47 return CONTAINING_RECORD(iface, ImagingFactory, IWICComponentFactory_iface);
50 static inline ImagingFactory *impl_from_IWICImagingFactory2(IWICImagingFactory2 *iface)
52 return CONTAINING_RECORD(iface, ImagingFactory, IWICImagingFactory2_iface);
55 static HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory2 *iface, REFIID iid,
56 void **ppv)
58 ImagingFactory *This = impl_from_IWICImagingFactory2(iface);
59 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
61 if (!ppv) return E_INVALIDARG;
63 if (IsEqualIID(&IID_IUnknown, iid) ||
64 IsEqualIID(&IID_IWICImagingFactory, iid) ||
65 IsEqualIID(&IID_IWICComponentFactory, iid))
67 *ppv = &This->IWICComponentFactory_iface;
69 else if (IsEqualIID(&IID_IWICImagingFactory2, iid))
71 *ppv = &This->IWICImagingFactory2_iface;
73 else
75 *ppv = NULL;
76 return E_NOINTERFACE;
79 IUnknown_AddRef((IUnknown*)*ppv);
80 return S_OK;
83 static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory2 *iface)
85 ImagingFactory *This = impl_from_IWICImagingFactory2(iface);
86 ULONG ref = InterlockedIncrement(&This->ref);
88 TRACE("(%p) refcount=%u\n", iface, ref);
90 return ref;
93 static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory2 *iface)
95 ImagingFactory *This = impl_from_IWICImagingFactory2(iface);
96 ULONG ref = InterlockedDecrement(&This->ref);
98 TRACE("(%p) refcount=%u\n", iface, ref);
100 if (ref == 0)
101 HeapFree(GetProcessHeap(), 0, This);
103 return ref;
106 static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename(
107 IWICImagingFactory2 *iface, LPCWSTR wzFilename, const GUID *pguidVendor,
108 DWORD dwDesiredAccess, WICDecodeOptions metadataOptions,
109 IWICBitmapDecoder **ppIDecoder)
111 IWICStream *stream;
112 HRESULT hr;
114 TRACE("(%p,%s,%s,%u,%u,%p)\n", iface, debugstr_w(wzFilename),
115 debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder);
117 hr = StreamImpl_Create(&stream);
118 if (SUCCEEDED(hr))
120 hr = IWICStream_InitializeFromFilename(stream, wzFilename, dwDesiredAccess);
122 if (SUCCEEDED(hr))
124 hr = IWICImagingFactory2_CreateDecoderFromStream(iface, (IStream*)stream,
125 pguidVendor, metadataOptions, ppIDecoder);
128 IWICStream_Release(stream);
131 return hr;
134 static HRESULT find_decoder(IStream *pIStream, const GUID *pguidVendor,
135 WICDecodeOptions metadataOptions, IWICBitmapDecoder **decoder)
137 IEnumUnknown *enumdecoders = NULL;
138 IUnknown *unkdecoderinfo = NULL;
139 GUID vendor;
140 HRESULT res, res_wine;
141 ULONG num_fetched;
142 BOOL matches, found;
144 *decoder = NULL;
146 res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
147 if (FAILED(res)) return res;
149 found = FALSE;
150 while (IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched) == S_OK)
152 IWICBitmapDecoderInfo *decoderinfo = NULL;
153 IWICWineDecoder *wine_decoder = NULL;
155 res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void**)&decoderinfo);
156 if (FAILED(res)) goto next;
158 if (pguidVendor)
160 res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
161 if (FAILED(res) || !IsEqualIID(&vendor, pguidVendor)) goto next;
164 res = IWICBitmapDecoderInfo_MatchesPattern(decoderinfo, pIStream, &matches);
165 if (FAILED(res) || !matches) goto next;
167 res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, decoder);
168 if (FAILED(res)) goto next;
170 /* FIXME: should use QueryCapability to choose a decoder */
172 found = TRUE;
173 res = IWICBitmapDecoder_Initialize(*decoder, pIStream, metadataOptions);
174 if (FAILED(res))
176 res_wine = IWICBitmapDecoder_QueryInterface(*decoder, &IID_IWICWineDecoder, (void **)&wine_decoder);
177 if (FAILED(res_wine))
179 IWICBitmapDecoder_Release(*decoder);
180 *decoder = NULL;
181 goto next;
184 res_wine = IWICWineDecoder_Initialize(wine_decoder, pIStream, metadataOptions);
185 if (FAILED(res_wine))
187 IWICBitmapDecoder_Release(*decoder);
188 *decoder = NULL;
189 goto next;
192 res = res_wine;
195 next:
196 if (wine_decoder) IWICWineDecoder_Release(wine_decoder);
197 if (decoderinfo) IWICBitmapDecoderInfo_Release(decoderinfo);
198 IUnknown_Release(unkdecoderinfo);
199 if (found) break;
202 IEnumUnknown_Release(enumdecoders);
203 if (!found) res = WINCODEC_ERR_COMPONENTNOTFOUND;
204 return res;
207 static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream(
208 IWICImagingFactory2 *iface, IStream *pIStream, const GUID *pguidVendor,
209 WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
211 HRESULT res;
212 IWICBitmapDecoder *decoder = NULL;
214 TRACE("(%p,%p,%s,%u,%p)\n", iface, pIStream, debugstr_guid(pguidVendor),
215 metadataOptions, ppIDecoder);
217 if (pguidVendor)
218 res = find_decoder(pIStream, pguidVendor, metadataOptions, &decoder);
219 if (!decoder)
220 res = find_decoder(pIStream, NULL, metadataOptions, &decoder);
222 if (decoder)
224 *ppIDecoder = decoder;
225 return S_OK;
227 else
229 if (WARN_ON(wincodecs))
231 LARGE_INTEGER seek;
232 BYTE data[4];
233 ULONG bytesread;
235 WARN("failed to load from a stream %#x\n", res);
237 seek.QuadPart = 0;
238 if (IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL) == S_OK)
240 if (IStream_Read(pIStream, data, 4, &bytesread) == S_OK)
241 WARN("first %i bytes of stream=%x %x %x %x\n", bytesread, data[0], data[1], data[2], data[3]);
244 *ppIDecoder = NULL;
245 return res;
249 static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle(
250 IWICImagingFactory2 *iface, ULONG_PTR hFile, const GUID *pguidVendor,
251 WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder)
253 IWICStream *stream;
254 HRESULT hr;
256 TRACE("(%p,%lx,%s,%u,%p)\n", iface, hFile, debugstr_guid(pguidVendor),
257 metadataOptions, ppIDecoder);
259 hr = StreamImpl_Create(&stream);
260 if (SUCCEEDED(hr))
262 hr = stream_initialize_from_filehandle(stream, (HANDLE)hFile);
263 if (SUCCEEDED(hr))
265 hr = IWICImagingFactory2_CreateDecoderFromStream(iface, (IStream*)stream,
266 pguidVendor, metadataOptions, ppIDecoder);
268 IWICStream_Release(stream);
270 return hr;
273 static HRESULT WINAPI ImagingFactory_CreateComponentInfo(IWICImagingFactory2 *iface,
274 REFCLSID clsidComponent, IWICComponentInfo **ppIInfo)
276 TRACE("(%p,%s,%p)\n", iface, debugstr_guid(clsidComponent), ppIInfo);
277 return CreateComponentInfo(clsidComponent, ppIInfo);
280 static HRESULT WINAPI ImagingFactory_CreateDecoder(IWICImagingFactory2 *iface,
281 REFGUID guidContainerFormat, const GUID *pguidVendor,
282 IWICBitmapDecoder **ppIDecoder)
284 IEnumUnknown *enumdecoders;
285 IUnknown *unkdecoderinfo;
286 IWICBitmapDecoderInfo *decoderinfo;
287 IWICBitmapDecoder *decoder = NULL, *preferred_decoder = NULL;
288 GUID vendor;
289 HRESULT res;
290 ULONG num_fetched;
292 TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
293 debugstr_guid(pguidVendor), ppIDecoder);
295 if (!guidContainerFormat || !ppIDecoder) return E_INVALIDARG;
297 res = CreateComponentEnumerator(WICDecoder, WICComponentEnumerateDefault, &enumdecoders);
298 if (FAILED(res)) return res;
300 while (!preferred_decoder)
302 res = IEnumUnknown_Next(enumdecoders, 1, &unkdecoderinfo, &num_fetched);
303 if (res != S_OK) break;
305 res = IUnknown_QueryInterface(unkdecoderinfo, &IID_IWICBitmapDecoderInfo, (void **)&decoderinfo);
306 if (SUCCEEDED(res))
308 GUID container_guid;
310 res = IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo, &container_guid);
311 if (SUCCEEDED(res) && IsEqualIID(&container_guid, guidContainerFormat))
313 IWICBitmapDecoder *new_decoder;
315 res = IWICBitmapDecoderInfo_CreateInstance(decoderinfo, &new_decoder);
316 if (SUCCEEDED(res))
318 if (pguidVendor)
320 res = IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo, &vendor);
321 if (SUCCEEDED(res) && IsEqualIID(&vendor, pguidVendor))
323 preferred_decoder = new_decoder;
324 new_decoder = NULL;
328 if (new_decoder && !decoder)
330 decoder = new_decoder;
331 new_decoder = NULL;
334 if (new_decoder) IWICBitmapDecoder_Release(new_decoder);
338 IWICBitmapDecoderInfo_Release(decoderinfo);
341 IUnknown_Release(unkdecoderinfo);
344 IEnumUnknown_Release(enumdecoders);
346 if (preferred_decoder)
348 *ppIDecoder = preferred_decoder;
349 if (decoder) IWICBitmapDecoder_Release(decoder);
350 return S_OK;
353 if (decoder)
355 *ppIDecoder = decoder;
356 return S_OK;
359 *ppIDecoder = NULL;
360 return WINCODEC_ERR_COMPONENTNOTFOUND;
363 static HRESULT WINAPI ImagingFactory_CreateEncoder(IWICImagingFactory2 *iface,
364 REFGUID guidContainerFormat, const GUID *pguidVendor,
365 IWICBitmapEncoder **ppIEncoder)
367 static int fixme=0;
368 IEnumUnknown *enumencoders;
369 IUnknown *unkencoderinfo;
370 IWICBitmapEncoderInfo *encoderinfo;
371 IWICBitmapEncoder *encoder=NULL;
372 HRESULT res=S_OK;
373 ULONG num_fetched;
374 GUID actual_containerformat;
376 TRACE("(%p,%s,%s,%p)\n", iface, debugstr_guid(guidContainerFormat),
377 debugstr_guid(pguidVendor), ppIEncoder);
379 if (pguidVendor && !fixme++)
380 FIXME("ignoring vendor GUID\n");
382 res = CreateComponentEnumerator(WICEncoder, WICComponentEnumerateDefault, &enumencoders);
383 if (FAILED(res)) return res;
385 while (!encoder)
387 res = IEnumUnknown_Next(enumencoders, 1, &unkencoderinfo, &num_fetched);
389 if (res == S_OK)
391 res = IUnknown_QueryInterface(unkencoderinfo, &IID_IWICBitmapEncoderInfo, (void**)&encoderinfo);
393 if (SUCCEEDED(res))
395 res = IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo, &actual_containerformat);
397 if (SUCCEEDED(res) && IsEqualGUID(guidContainerFormat, &actual_containerformat))
399 res = IWICBitmapEncoderInfo_CreateInstance(encoderinfo, &encoder);
400 if (FAILED(res))
401 encoder = NULL;
404 IWICBitmapEncoderInfo_Release(encoderinfo);
407 IUnknown_Release(unkencoderinfo);
409 else
410 break;
413 IEnumUnknown_Release(enumencoders);
415 if (encoder)
417 *ppIEncoder = encoder;
418 return S_OK;
420 else
422 WARN("failed to create encoder\n");
423 *ppIEncoder = NULL;
424 return WINCODEC_ERR_COMPONENTNOTFOUND;
428 static HRESULT WINAPI ImagingFactory_CreatePalette(IWICImagingFactory2 *iface,
429 IWICPalette **ppIPalette)
431 TRACE("(%p,%p)\n", iface, ppIPalette);
432 return PaletteImpl_Create(ppIPalette);
435 static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory2 *iface,
436 IWICFormatConverter **ppIFormatConverter)
438 return FormatConverter_CreateInstance(&IID_IWICFormatConverter, (void**)ppIFormatConverter);
441 static HRESULT WINAPI ImagingFactory_CreateBitmapScaler(IWICImagingFactory2 *iface,
442 IWICBitmapScaler **ppIBitmapScaler)
444 TRACE("(%p,%p)\n", iface, ppIBitmapScaler);
446 return BitmapScaler_Create(ppIBitmapScaler);
449 static HRESULT WINAPI ImagingFactory_CreateBitmapClipper(IWICImagingFactory2 *iface,
450 IWICBitmapClipper **ppIBitmapClipper)
452 TRACE("(%p,%p)\n", iface, ppIBitmapClipper);
453 return BitmapClipper_Create(ppIBitmapClipper);
456 static HRESULT WINAPI ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory2 *iface,
457 IWICBitmapFlipRotator **ppIBitmapFlipRotator)
459 TRACE("(%p,%p)\n", iface, ppIBitmapFlipRotator);
460 return FlipRotator_Create(ppIBitmapFlipRotator);
463 static HRESULT WINAPI ImagingFactory_CreateStream(IWICImagingFactory2 *iface,
464 IWICStream **ppIWICStream)
466 TRACE("(%p,%p)\n", iface, ppIWICStream);
467 return StreamImpl_Create(ppIWICStream);
470 static HRESULT WINAPI ImagingFactory_CreateColorContext(IWICImagingFactory2 *iface,
471 IWICColorContext **ppIColorContext)
473 TRACE("(%p,%p)\n", iface, ppIColorContext);
474 return ColorContext_Create(ppIColorContext);
477 static HRESULT WINAPI ImagingFactory_CreateColorTransformer(IWICImagingFactory2 *iface,
478 IWICColorTransform **ppIColorTransform)
480 TRACE("(%p,%p)\n", iface, ppIColorTransform);
481 return ColorTransform_Create(ppIColorTransform);
484 static HRESULT WINAPI ImagingFactory_CreateBitmap(IWICImagingFactory2 *iface,
485 UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat,
486 WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
488 TRACE("(%p,%u,%u,%s,%u,%p)\n", iface, uiWidth, uiHeight,
489 debugstr_guid(pixelFormat), option, ppIBitmap);
490 return BitmapImpl_Create(uiWidth, uiHeight, 0, 0, NULL, 0, pixelFormat, option, ppIBitmap);
493 static HRESULT create_bitmap_from_source_rect(IWICBitmapSource *piBitmapSource, const WICRect *rect,
494 WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap)
496 IWICBitmap *result;
497 IWICBitmapLock *lock;
498 IWICPalette *palette;
499 UINT width, height;
500 WICPixelFormatGUID pixelformat = {0};
501 HRESULT hr;
502 WICRect rc;
503 double dpix, dpiy;
504 IWICComponentInfo *info;
505 IWICPixelFormatInfo2 *formatinfo;
506 WICPixelFormatNumericRepresentation format_type;
508 assert(!rect || option == WICBitmapCacheOnLoad);
510 if (!piBitmapSource || !ppIBitmap)
511 return E_INVALIDARG;
513 if (option == WICBitmapNoCache && SUCCEEDED(IWICBitmapSource_QueryInterface(piBitmapSource,
514 &IID_IWICBitmap, (void **)&result)))
516 *ppIBitmap = result;
517 return S_OK;
520 hr = IWICBitmapSource_GetSize(piBitmapSource, &width, &height);
522 if (SUCCEEDED(hr) && rect)
524 if (rect->X >= width || rect->Y >= height || rect->Width == 0 || rect->Height == 0)
525 return E_INVALIDARG;
527 width = min(width - rect->X, rect->Width);
528 height = min(height - rect->Y, rect->Height);
531 if (SUCCEEDED(hr))
532 hr = IWICBitmapSource_GetPixelFormat(piBitmapSource, &pixelformat);
534 if (SUCCEEDED(hr))
535 hr = CreateComponentInfo(&pixelformat, &info);
537 if (SUCCEEDED(hr))
539 hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void**)&formatinfo);
541 if (SUCCEEDED(hr))
543 hr = IWICPixelFormatInfo2_GetNumericRepresentation(formatinfo, &format_type);
545 IWICPixelFormatInfo2_Release(formatinfo);
548 IWICComponentInfo_Release(info);
551 if (SUCCEEDED(hr))
552 hr = BitmapImpl_Create(width, height, 0, 0, NULL, 0, &pixelformat, option, &result);
554 if (SUCCEEDED(hr))
556 hr = IWICBitmap_Lock(result, NULL, WICBitmapLockWrite, &lock);
557 if (SUCCEEDED(hr))
559 UINT stride, buffersize;
560 BYTE *buffer;
562 if (rect)
564 rc.X = rect->X;
565 rc.Y = rect->Y;
567 else
568 rc.X = rc.Y = 0;
569 rc.Width = width;
570 rc.Height = height;
572 hr = IWICBitmapLock_GetStride(lock, &stride);
574 if (SUCCEEDED(hr))
575 hr = IWICBitmapLock_GetDataPointer(lock, &buffersize, &buffer);
577 if (SUCCEEDED(hr))
578 hr = IWICBitmapSource_CopyPixels(piBitmapSource, &rc, stride,
579 buffersize, buffer);
581 IWICBitmapLock_Release(lock);
584 if (SUCCEEDED(hr) && (format_type == WICPixelFormatNumericRepresentationUnspecified ||
585 format_type == WICPixelFormatNumericRepresentationIndexed))
587 hr = PaletteImpl_Create(&palette);
589 if (SUCCEEDED(hr))
591 hr = IWICBitmapSource_CopyPalette(piBitmapSource, palette);
593 if (SUCCEEDED(hr))
594 hr = IWICBitmap_SetPalette(result, palette);
595 else
596 hr = S_OK;
598 IWICPalette_Release(palette);
602 if (SUCCEEDED(hr))
604 hr = IWICBitmapSource_GetResolution(piBitmapSource, &dpix, &dpiy);
606 if (SUCCEEDED(hr))
607 hr = IWICBitmap_SetResolution(result, dpix, dpiy);
608 else
609 hr = S_OK;
612 if (SUCCEEDED(hr))
613 *ppIBitmap = result;
614 else
615 IWICBitmap_Release(result);
618 return hr;
621 static HRESULT WINAPI ImagingFactory_CreateBitmapFromSource(IWICImagingFactory2 *iface,
622 IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option,
623 IWICBitmap **ppIBitmap)
625 TRACE("(%p,%p,%u,%p)\n", iface, piBitmapSource, option, ppIBitmap);
627 return create_bitmap_from_source_rect(piBitmapSource, NULL, option, ppIBitmap);
630 static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory2 *iface,
631 IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height,
632 IWICBitmap **ppIBitmap)
634 WICRect rect;
636 TRACE("(%p,%p,%u,%u,%u,%u,%p)\n", iface, piBitmapSource, x, y, width,
637 height, ppIBitmap);
639 rect.X = x;
640 rect.Y = y;
641 rect.Width = width;
642 rect.Height = height;
644 return create_bitmap_from_source_rect(piBitmapSource, &rect, WICBitmapCacheOnLoad, ppIBitmap);
647 static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory2 *iface,
648 UINT width, UINT height, REFWICPixelFormatGUID format, UINT stride,
649 UINT size, BYTE *buffer, IWICBitmap **bitmap)
651 HRESULT hr;
653 TRACE("(%p,%u,%u,%s,%u,%u,%p,%p\n", iface, width, height,
654 debugstr_guid(format), stride, size, buffer, bitmap);
656 if (!stride || !size || !buffer || !bitmap) return E_INVALIDARG;
658 hr = BitmapImpl_Create(width, height, stride, size, NULL, 0, format, WICBitmapCacheOnLoad, bitmap);
659 if (SUCCEEDED(hr))
661 IWICBitmapLock *lock;
663 hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
664 if (SUCCEEDED(hr))
666 UINT buffersize;
667 BYTE *data;
669 IWICBitmapLock_GetDataPointer(lock, &buffersize, &data);
670 memcpy(data, buffer, buffersize);
672 IWICBitmapLock_Release(lock);
674 else
676 IWICBitmap_Release(*bitmap);
677 *bitmap = NULL;
680 return hr;
683 static BOOL get_16bpp_format(HBITMAP hbm, WICPixelFormatGUID *format)
685 BOOL ret = TRUE;
686 BITMAPV4HEADER bmh;
687 HDC hdc;
689 hdc = CreateCompatibleDC(0);
691 memset(&bmh, 0, sizeof(bmh));
692 bmh.bV4Size = sizeof(bmh);
693 bmh.bV4Width = 1;
694 bmh.bV4Height = 1;
695 bmh.bV4V4Compression = BI_BITFIELDS;
696 bmh.bV4BitCount = 16;
698 GetDIBits(hdc, hbm, 0, 0, NULL, (BITMAPINFO *)&bmh, DIB_RGB_COLORS);
700 if (bmh.bV4RedMask == 0x7c00 &&
701 bmh.bV4GreenMask == 0x3e0 &&
702 bmh.bV4BlueMask == 0x1f)
704 *format = GUID_WICPixelFormat16bppBGR555;
706 else if (bmh.bV4RedMask == 0xf800 &&
707 bmh.bV4GreenMask == 0x7e0 &&
708 bmh.bV4BlueMask == 0x1f)
710 *format = GUID_WICPixelFormat16bppBGR565;
712 else
714 FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask,
715 bmh.bV4GreenMask, bmh.bV4BlueMask);
716 ret = FALSE;
719 DeleteDC(hdc);
720 return ret;
723 static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory2 *iface,
724 HBITMAP hbm, HPALETTE hpal, WICBitmapAlphaChannelOption option, IWICBitmap **bitmap)
726 BITMAP bm;
727 HRESULT hr;
728 WICPixelFormatGUID format;
729 IWICBitmapLock *lock;
730 UINT size, num_palette_entries = 0;
731 PALETTEENTRY entry[256];
733 TRACE("(%p,%p,%p,%u,%p)\n", iface, hbm, hpal, option, bitmap);
735 if (!bitmap) return E_INVALIDARG;
737 if (GetObjectW(hbm, sizeof(bm), &bm) != sizeof(bm))
738 return WINCODEC_ERR_WIN32ERROR;
740 if (hpal)
742 num_palette_entries = GetPaletteEntries(hpal, 0, 256, entry);
743 if (!num_palette_entries)
744 return WINCODEC_ERR_WIN32ERROR;
747 /* TODO: Figure out the correct format for 16, 32, 64 bpp */
748 switch(bm.bmBitsPixel)
750 case 1:
751 format = GUID_WICPixelFormat1bppIndexed;
752 break;
753 case 4:
754 format = GUID_WICPixelFormat4bppIndexed;
755 break;
756 case 8:
757 format = GUID_WICPixelFormat8bppIndexed;
758 break;
759 case 16:
760 if (!get_16bpp_format(hbm, &format))
761 return E_INVALIDARG;
762 break;
763 case 24:
764 format = GUID_WICPixelFormat24bppBGR;
765 break;
766 case 32:
767 switch (option)
769 case WICBitmapUseAlpha:
770 format = GUID_WICPixelFormat32bppBGRA;
771 break;
772 case WICBitmapUsePremultipliedAlpha:
773 format = GUID_WICPixelFormat32bppPBGRA;
774 break;
775 case WICBitmapIgnoreAlpha:
776 format = GUID_WICPixelFormat32bppBGR;
777 break;
778 default:
779 return E_INVALIDARG;
781 break;
782 case 48:
783 format = GUID_WICPixelFormat48bppRGB;
784 break;
785 default:
786 FIXME("unsupported %d bpp\n", bm.bmBitsPixel);
787 return E_INVALIDARG;
790 hr = BitmapImpl_Create(bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, 0, NULL, 0, &format,
791 WICBitmapCacheOnLoad, bitmap);
792 if (hr != S_OK) return hr;
794 hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
795 if (hr == S_OK)
797 BYTE *buffer;
798 HDC hdc;
799 char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
800 BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
802 IWICBitmapLock_GetDataPointer(lock, &size, &buffer);
804 hdc = CreateCompatibleDC(0);
806 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
807 bmi->bmiHeader.biBitCount = 0;
808 GetDIBits(hdc, hbm, 0, 0, NULL, bmi, DIB_RGB_COLORS);
809 bmi->bmiHeader.biHeight = -bm.bmHeight;
810 GetDIBits(hdc, hbm, 0, bm.bmHeight, buffer, bmi, DIB_RGB_COLORS);
812 DeleteDC(hdc);
813 IWICBitmapLock_Release(lock);
815 if (num_palette_entries)
817 IWICPalette *palette;
818 WICColor colors[256];
819 UINT i;
821 hr = PaletteImpl_Create(&palette);
822 if (hr == S_OK)
824 for (i = 0; i < num_palette_entries; i++)
825 colors[i] = 0xff000000 | entry[i].peRed << 16 |
826 entry[i].peGreen << 8 | entry[i].peBlue;
828 hr = IWICPalette_InitializeCustom(palette, colors, num_palette_entries);
829 if (hr == S_OK)
830 hr = IWICBitmap_SetPalette(*bitmap, palette);
832 IWICPalette_Release(palette);
837 if (hr != S_OK)
839 IWICBitmap_Release(*bitmap);
840 *bitmap = NULL;
843 return hr;
846 static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory2 *iface,
847 HICON hicon, IWICBitmap **bitmap)
849 IWICBitmapLock *lock;
850 ICONINFO info;
851 BITMAP bm;
852 int width, height, x, y;
853 UINT stride, size;
854 BYTE *buffer;
855 DWORD *bits;
856 BITMAPINFO bi;
857 HDC hdc;
858 BOOL has_alpha;
859 HRESULT hr;
861 TRACE("(%p,%p,%p)\n", iface, hicon, bitmap);
863 if (!bitmap) return E_INVALIDARG;
865 if (!GetIconInfo(hicon, &info))
866 return HRESULT_FROM_WIN32(GetLastError());
868 GetObjectW(info.hbmColor ? info.hbmColor : info.hbmMask, sizeof(bm), &bm);
870 width = bm.bmWidth;
871 height = info.hbmColor ? abs(bm.bmHeight) : abs(bm.bmHeight) / 2;
872 stride = width * 4;
873 size = stride * height;
875 hr = BitmapImpl_Create(width, height, stride, size, NULL, 0,
876 &GUID_WICPixelFormat32bppBGRA, WICBitmapCacheOnLoad, bitmap);
877 if (hr != S_OK) goto failed;
879 hr = IWICBitmap_Lock(*bitmap, NULL, WICBitmapLockWrite, &lock);
880 if (hr != S_OK)
882 IWICBitmap_Release(*bitmap);
883 goto failed;
885 IWICBitmapLock_GetDataPointer(lock, &size, &buffer);
887 hdc = CreateCompatibleDC(0);
889 memset(&bi, 0, sizeof(bi));
890 bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
891 bi.bmiHeader.biWidth = width;
892 bi.bmiHeader.biHeight = info.hbmColor ? -height: -height * 2;
893 bi.bmiHeader.biPlanes = 1;
894 bi.bmiHeader.biBitCount = 32;
895 bi.bmiHeader.biCompression = BI_RGB;
897 has_alpha = FALSE;
899 if (info.hbmColor)
901 GetDIBits(hdc, info.hbmColor, 0, height, buffer, &bi, DIB_RGB_COLORS);
903 if (bm.bmBitsPixel == 32)
905 /* If any pixel has a non-zero alpha, ignore hbmMask */
906 bits = (DWORD *)buffer;
907 for (x = 0; x < width && !has_alpha; x++, bits++)
909 for (y = 0; y < height; y++)
911 if (*bits & 0xff000000)
913 has_alpha = TRUE;
914 break;
920 else
921 GetDIBits(hdc, info.hbmMask, 0, height, buffer, &bi, DIB_RGB_COLORS);
923 if (!has_alpha)
925 DWORD *rgba;
927 if (info.hbmMask)
929 BYTE *mask;
931 mask = HeapAlloc(GetProcessHeap(), 0, size);
932 if (!mask)
934 IWICBitmapLock_Release(lock);
935 IWICBitmap_Release(*bitmap);
936 DeleteDC(hdc);
937 hr = E_OUTOFMEMORY;
938 goto failed;
941 /* read alpha data from the mask */
942 GetDIBits(hdc, info.hbmMask, info.hbmColor ? 0 : height, height, mask, &bi, DIB_RGB_COLORS);
944 for (y = 0; y < height; y++)
946 rgba = (DWORD *)(buffer + y * stride);
947 bits = (DWORD *)(mask + y * stride);
949 for (x = 0; x < width; x++, rgba++, bits++)
951 if (*bits)
952 *rgba = 0;
953 else
954 *rgba |= 0xff000000;
958 HeapFree(GetProcessHeap(), 0, mask);
960 else
962 /* set constant alpha of 255 */
963 for (y = 0; y < height; y++)
965 rgba = (DWORD *)(buffer + y * stride);
966 for (x = 0; x < width; x++, rgba++)
967 *rgba |= 0xff000000;
973 IWICBitmapLock_Release(lock);
974 DeleteDC(hdc);
976 failed:
977 DeleteObject(info.hbmColor);
978 DeleteObject(info.hbmMask);
980 return hr;
983 static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory2 *iface,
984 DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
986 TRACE("(%p,%u,%u,%p)\n", iface, componentTypes, options, ppIEnumUnknown);
987 return CreateComponentEnumerator(componentTypes, options, ppIEnumUnknown);
990 static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromDecoder(
991 IWICImagingFactory2 *iface, IWICBitmapDecoder *pIDecoder,
992 IWICFastMetadataEncoder **ppIFastEncoder)
994 FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder);
995 return E_NOTIMPL;
998 static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode(
999 IWICImagingFactory2 *iface, IWICBitmapFrameDecode *pIFrameDecoder,
1000 IWICFastMetadataEncoder **ppIFastEncoder)
1002 FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder);
1003 return E_NOTIMPL;
1006 static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory2 *iface,
1007 REFGUID guidMetadataFormat, const GUID *pguidVendor,
1008 IWICMetadataQueryWriter **ppIQueryWriter)
1010 FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat),
1011 debugstr_guid(pguidVendor), ppIQueryWriter);
1012 return E_NOTIMPL;
1015 static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory2 *iface,
1016 IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor,
1017 IWICMetadataQueryWriter **ppIQueryWriter)
1019 FIXME("(%p,%p,%s,%p): stub\n", iface, pIQueryReader, debugstr_guid(pguidVendor),
1020 ppIQueryWriter);
1021 return E_NOTIMPL;
1024 static HRESULT WINAPI ImagingFactory_CreateImageEncoder(IWICImagingFactory2 *iface, ID2D1Device *device, IWICImageEncoder **encoder)
1026 FIXME("%p,%p,%p stub.\n", iface, device, encoder);
1027 return E_NOTIMPL;
1030 static const IWICImagingFactory2Vtbl ImagingFactory_Vtbl = {
1031 ImagingFactory_QueryInterface,
1032 ImagingFactory_AddRef,
1033 ImagingFactory_Release,
1034 ImagingFactory_CreateDecoderFromFilename,
1035 ImagingFactory_CreateDecoderFromStream,
1036 ImagingFactory_CreateDecoderFromFileHandle,
1037 ImagingFactory_CreateComponentInfo,
1038 ImagingFactory_CreateDecoder,
1039 ImagingFactory_CreateEncoder,
1040 ImagingFactory_CreatePalette,
1041 ImagingFactory_CreateFormatConverter,
1042 ImagingFactory_CreateBitmapScaler,
1043 ImagingFactory_CreateBitmapClipper,
1044 ImagingFactory_CreateBitmapFlipRotator,
1045 ImagingFactory_CreateStream,
1046 ImagingFactory_CreateColorContext,
1047 ImagingFactory_CreateColorTransformer,
1048 ImagingFactory_CreateBitmap,
1049 ImagingFactory_CreateBitmapFromSource,
1050 ImagingFactory_CreateBitmapFromSourceRect,
1051 ImagingFactory_CreateBitmapFromMemory,
1052 ImagingFactory_CreateBitmapFromHBITMAP,
1053 ImagingFactory_CreateBitmapFromHICON,
1054 ImagingFactory_CreateComponentEnumerator,
1055 ImagingFactory_CreateFastMetadataEncoderFromDecoder,
1056 ImagingFactory_CreateFastMetadataEncoderFromFrameDecode,
1057 ImagingFactory_CreateQueryWriter,
1058 ImagingFactory_CreateQueryWriterFromReader,
1059 ImagingFactory_CreateImageEncoder,
1062 static HRESULT WINAPI ComponentFactory_QueryInterface(IWICComponentFactory *iface, REFIID iid, void **ppv)
1064 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1065 return IWICImagingFactory2_QueryInterface(&This->IWICImagingFactory2_iface, iid, ppv);
1068 static ULONG WINAPI ComponentFactory_AddRef(IWICComponentFactory *iface)
1070 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1071 return IWICImagingFactory2_AddRef(&This->IWICImagingFactory2_iface);
1074 static ULONG WINAPI ComponentFactory_Release(IWICComponentFactory *iface)
1076 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1077 return IWICImagingFactory2_Release(&This->IWICImagingFactory2_iface);
1080 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFilename(IWICComponentFactory *iface, LPCWSTR filename,
1081 const GUID *vendor, DWORD desired_access, WICDecodeOptions options, IWICBitmapDecoder **decoder)
1083 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1084 return IWICImagingFactory2_CreateDecoderFromFilename(&This->IWICImagingFactory2_iface, filename, vendor,
1085 desired_access, options, decoder);
1088 static HRESULT WINAPI ComponentFactory_CreateDecoderFromStream(IWICComponentFactory *iface, IStream *stream,
1089 const GUID *vendor, WICDecodeOptions options, IWICBitmapDecoder **decoder)
1091 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1092 return IWICImagingFactory2_CreateDecoderFromStream(&This->IWICImagingFactory2_iface, stream, vendor,
1093 options, decoder);
1096 static HRESULT WINAPI ComponentFactory_CreateDecoderFromFileHandle(IWICComponentFactory *iface, ULONG_PTR hFile,
1097 const GUID *vendor, WICDecodeOptions options, IWICBitmapDecoder **decoder)
1099 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1100 return IWICImagingFactory2_CreateDecoderFromFileHandle(&This->IWICImagingFactory2_iface, hFile, vendor,
1101 options, decoder);
1104 static HRESULT WINAPI ComponentFactory_CreateComponentInfo(IWICComponentFactory *iface, REFCLSID component,
1105 IWICComponentInfo **info)
1107 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1108 return IWICImagingFactory2_CreateComponentInfo(&This->IWICImagingFactory2_iface, component, info);
1111 static HRESULT WINAPI ComponentFactory_CreateDecoder(IWICComponentFactory *iface, REFGUID format, const GUID *vendor,
1112 IWICBitmapDecoder **decoder)
1114 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1115 return IWICImagingFactory2_CreateDecoder(&This->IWICImagingFactory2_iface, format, vendor, decoder);
1118 static HRESULT WINAPI ComponentFactory_CreateEncoder(IWICComponentFactory *iface, REFGUID format, const GUID *vendor,
1119 IWICBitmapEncoder **encoder)
1121 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1122 return IWICImagingFactory2_CreateEncoder(&This->IWICImagingFactory2_iface, format, vendor, encoder);
1125 static HRESULT WINAPI ComponentFactory_CreatePalette(IWICComponentFactory *iface, IWICPalette **palette)
1127 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1128 return IWICImagingFactory2_CreatePalette(&This->IWICImagingFactory2_iface, palette);
1131 static HRESULT WINAPI ComponentFactory_CreateFormatConverter(IWICComponentFactory *iface, IWICFormatConverter **converter)
1133 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1134 return IWICImagingFactory2_CreateFormatConverter(&This->IWICImagingFactory2_iface, converter);
1137 static HRESULT WINAPI ComponentFactory_CreateBitmapScaler(IWICComponentFactory *iface, IWICBitmapScaler **scaler)
1139 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1140 return IWICImagingFactory2_CreateBitmapScaler(&This->IWICImagingFactory2_iface, scaler);
1143 static HRESULT WINAPI ComponentFactory_CreateBitmapClipper(IWICComponentFactory *iface, IWICBitmapClipper **clipper)
1145 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1146 return IWICImagingFactory2_CreateBitmapClipper(&This->IWICImagingFactory2_iface, clipper);
1149 static HRESULT WINAPI ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory *iface, IWICBitmapFlipRotator **fliprotator)
1151 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1152 return IWICImagingFactory2_CreateBitmapFlipRotator(&This->IWICImagingFactory2_iface, fliprotator);
1155 static HRESULT WINAPI ComponentFactory_CreateStream(IWICComponentFactory *iface, IWICStream **stream)
1157 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1158 return IWICImagingFactory2_CreateStream(&This->IWICImagingFactory2_iface, stream);
1161 static HRESULT WINAPI ComponentFactory_CreateColorContext(IWICComponentFactory *iface, IWICColorContext **context)
1163 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1164 return IWICImagingFactory2_CreateColorContext(&This->IWICImagingFactory2_iface, context);
1167 static HRESULT WINAPI ComponentFactory_CreateColorTransformer(IWICComponentFactory *iface, IWICColorTransform **transformer)
1169 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1170 return IWICImagingFactory2_CreateColorTransformer(&This->IWICImagingFactory2_iface, transformer);
1173 static HRESULT WINAPI ComponentFactory_CreateBitmap(IWICComponentFactory *iface, UINT width, UINT height, REFWICPixelFormatGUID pixel_format,
1174 WICBitmapCreateCacheOption option, IWICBitmap **bitmap)
1176 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1177 return IWICImagingFactory2_CreateBitmap(&This->IWICImagingFactory2_iface, width, height, pixel_format, option, bitmap);
1180 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSource(IWICComponentFactory *iface, IWICBitmapSource *source,
1181 WICBitmapCreateCacheOption option, IWICBitmap **bitmap)
1183 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1184 return IWICImagingFactory2_CreateBitmapFromSource(&This->IWICImagingFactory2_iface, source, option, bitmap);
1187 static HRESULT WINAPI ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory *iface, IWICBitmapSource *source,
1188 UINT x, UINT y, UINT width, UINT height, IWICBitmap **bitmap)
1190 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1191 return IWICImagingFactory2_CreateBitmapFromSourceRect(&This->IWICImagingFactory2_iface, source, x, y, width, height, bitmap);
1194 static HRESULT WINAPI ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory *iface, UINT width, UINT height,
1195 REFWICPixelFormatGUID format, UINT stride, UINT size, BYTE *buffer, IWICBitmap **bitmap)
1197 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1198 return IWICImagingFactory2_CreateBitmapFromMemory(&This->IWICImagingFactory2_iface, width, height, format, stride,
1199 size, buffer, bitmap);
1202 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory *iface, HBITMAP hbm, HPALETTE hpal,
1203 WICBitmapAlphaChannelOption option, IWICBitmap **bitmap)
1205 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1206 return IWICImagingFactory2_CreateBitmapFromHBITMAP(&This->IWICImagingFactory2_iface, hbm, hpal, option, bitmap);
1209 static HRESULT WINAPI ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory *iface, HICON hicon, IWICBitmap **bitmap)
1211 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1212 return IWICImagingFactory2_CreateBitmapFromHICON(&This->IWICImagingFactory2_iface, hicon, bitmap);
1215 static HRESULT WINAPI ComponentFactory_CreateComponentEnumerator(IWICComponentFactory *iface, DWORD component_types,
1216 DWORD options, IEnumUnknown **enumerator)
1218 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1219 return IWICImagingFactory2_CreateComponentEnumerator(&This->IWICImagingFactory2_iface, component_types,
1220 options, enumerator);
1223 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromDecoder(IWICComponentFactory *iface, IWICBitmapDecoder *decoder,
1224 IWICFastMetadataEncoder **encoder)
1226 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1227 return IWICImagingFactory2_CreateFastMetadataEncoderFromDecoder(&This->IWICImagingFactory2_iface, decoder, encoder);
1230 static HRESULT WINAPI ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(IWICComponentFactory *iface,
1231 IWICBitmapFrameDecode *frame_decode, IWICFastMetadataEncoder **encoder)
1233 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1234 return IWICImagingFactory2_CreateFastMetadataEncoderFromFrameDecode(&This->IWICImagingFactory2_iface, frame_decode, encoder);
1237 static HRESULT WINAPI ComponentFactory_CreateQueryWriter(IWICComponentFactory *iface, REFGUID format, const GUID *vendor,
1238 IWICMetadataQueryWriter **writer)
1240 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1241 return IWICImagingFactory2_CreateQueryWriter(&This->IWICImagingFactory2_iface, format, vendor, writer);
1244 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory *iface, IWICMetadataQueryReader *reader,
1245 const GUID *vendor, IWICMetadataQueryWriter **writer)
1247 ImagingFactory *This = impl_from_IWICComponentFactory(iface);
1248 return IWICImagingFactory2_CreateQueryWriterFromReader(&This->IWICImagingFactory2_iface, reader, vendor, writer);
1251 static HRESULT WINAPI ComponentFactory_CreateMetadataReader(IWICComponentFactory *iface,
1252 REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
1254 FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor),
1255 options, stream, reader);
1256 return E_NOTIMPL;
1259 static HRESULT WINAPI ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory *iface,
1260 REFGUID format, const GUID *vendor, DWORD options, IStream *stream, IWICMetadataReader **reader)
1262 HRESULT hr;
1263 IEnumUnknown *enumreaders;
1264 IUnknown *unkreaderinfo;
1265 IWICMetadataReaderInfo *readerinfo;
1266 IWICPersistStream *wicpersiststream;
1267 ULONG num_fetched;
1268 GUID decoder_vendor;
1269 BOOL matches;
1270 LARGE_INTEGER zero;
1272 TRACE("%p,%s,%s,%x,%p,%p\n", iface, debugstr_guid(format), debugstr_guid(vendor),
1273 options, stream, reader);
1275 if (!format || !stream || !reader)
1276 return E_INVALIDARG;
1278 zero.QuadPart = 0;
1280 hr = CreateComponentEnumerator(WICMetadataReader, WICComponentEnumerateDefault, &enumreaders);
1281 if (FAILED(hr)) return hr;
1283 *reader = NULL;
1285 start:
1286 while (!*reader)
1288 hr = IEnumUnknown_Next(enumreaders, 1, &unkreaderinfo, &num_fetched);
1290 if (hr == S_OK)
1292 hr = IUnknown_QueryInterface(unkreaderinfo, &IID_IWICMetadataReaderInfo, (void**)&readerinfo);
1294 if (SUCCEEDED(hr))
1296 if (vendor)
1298 hr = IWICMetadataReaderInfo_GetVendorGUID(readerinfo, &decoder_vendor);
1300 if (FAILED(hr) || !IsEqualIID(vendor, &decoder_vendor))
1302 IWICMetadataReaderInfo_Release(readerinfo);
1303 IUnknown_Release(unkreaderinfo);
1304 continue;
1308 hr = IWICMetadataReaderInfo_MatchesPattern(readerinfo, format, stream, &matches);
1310 if (SUCCEEDED(hr) && matches)
1312 hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
1314 if (SUCCEEDED(hr))
1315 hr = IWICMetadataReaderInfo_CreateInstance(readerinfo, reader);
1317 if (SUCCEEDED(hr))
1319 hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream);
1321 if (SUCCEEDED(hr))
1323 hr = IWICPersistStream_LoadEx(wicpersiststream,
1324 stream, vendor, options & WICPersistOptionMask);
1326 IWICPersistStream_Release(wicpersiststream);
1329 if (FAILED(hr))
1331 IWICMetadataReader_Release(*reader);
1332 *reader = NULL;
1337 IUnknown_Release(readerinfo);
1340 IUnknown_Release(unkreaderinfo);
1342 else
1343 break;
1346 if (!*reader && vendor)
1348 vendor = NULL;
1349 IEnumUnknown_Reset(enumreaders);
1350 goto start;
1353 IEnumUnknown_Release(enumreaders);
1355 if (!*reader && !(options & WICMetadataCreationFailUnknown))
1357 hr = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
1359 if (SUCCEEDED(hr))
1360 hr = UnknownMetadataReader_CreateInstance(&IID_IWICMetadataReader, (void**)reader);
1362 if (SUCCEEDED(hr))
1364 hr = IWICMetadataReader_QueryInterface(*reader, &IID_IWICPersistStream, (void**)&wicpersiststream);
1366 if (SUCCEEDED(hr))
1368 hr = IWICPersistStream_LoadEx(wicpersiststream, stream, NULL, options & WICPersistOptionMask);
1370 IWICPersistStream_Release(wicpersiststream);
1373 if (FAILED(hr))
1375 IWICMetadataReader_Release(*reader);
1376 *reader = NULL;
1381 if (*reader)
1382 return S_OK;
1383 else
1384 return WINCODEC_ERR_COMPONENTNOTFOUND;
1387 static HRESULT WINAPI ComponentFactory_CreateMetadataWriter(IWICComponentFactory *iface,
1388 REFGUID format, const GUID *vendor, DWORD options, IWICMetadataWriter **writer)
1390 FIXME("%p,%s,%s,%x,%p: stub\n", iface, debugstr_guid(format), debugstr_guid(vendor), options, writer);
1391 return E_NOTIMPL;
1394 static HRESULT WINAPI ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory *iface,
1395 IWICMetadataReader *reader, const GUID *vendor, IWICMetadataWriter **writer)
1397 FIXME("%p,%p,%s,%p: stub\n", iface, reader, debugstr_guid(vendor), writer);
1398 return E_NOTIMPL;
1401 static HRESULT WINAPI ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory *iface,
1402 IWICMetadataBlockReader *block_reader, IWICMetadataQueryReader **query_reader)
1404 TRACE("%p,%p,%p\n", iface, block_reader, query_reader);
1406 if (!block_reader || !query_reader)
1407 return E_INVALIDARG;
1409 return MetadataQueryReader_CreateInstance(block_reader, NULL, query_reader);
1412 static HRESULT WINAPI ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory *iface,
1413 IWICMetadataBlockWriter *block_writer, IWICMetadataQueryWriter **query_writer)
1415 FIXME("%p,%p,%p: stub\n", iface, block_writer, query_writer);
1416 return E_NOTIMPL;
1419 static HRESULT WINAPI ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory *iface,
1420 PROPBAG2 *options, UINT count, IPropertyBag2 **property)
1422 TRACE("(%p,%p,%u,%p)\n", iface, options, count, property);
1423 return CreatePropertyBag2(options, count, property);
1426 static const IWICComponentFactoryVtbl ComponentFactory_Vtbl = {
1427 ComponentFactory_QueryInterface,
1428 ComponentFactory_AddRef,
1429 ComponentFactory_Release,
1430 ComponentFactory_CreateDecoderFromFilename,
1431 ComponentFactory_CreateDecoderFromStream,
1432 ComponentFactory_CreateDecoderFromFileHandle,
1433 ComponentFactory_CreateComponentInfo,
1434 ComponentFactory_CreateDecoder,
1435 ComponentFactory_CreateEncoder,
1436 ComponentFactory_CreatePalette,
1437 ComponentFactory_CreateFormatConverter,
1438 ComponentFactory_CreateBitmapScaler,
1439 ComponentFactory_CreateBitmapClipper,
1440 ComponentFactory_CreateBitmapFlipRotator,
1441 ComponentFactory_CreateStream,
1442 ComponentFactory_CreateColorContext,
1443 ComponentFactory_CreateColorTransformer,
1444 ComponentFactory_CreateBitmap,
1445 ComponentFactory_CreateBitmapFromSource,
1446 ComponentFactory_CreateBitmapFromSourceRect,
1447 ComponentFactory_CreateBitmapFromMemory,
1448 ComponentFactory_CreateBitmapFromHBITMAP,
1449 ComponentFactory_CreateBitmapFromHICON,
1450 ComponentFactory_CreateComponentEnumerator,
1451 ComponentFactory_CreateFastMetadataEncoderFromDecoder,
1452 ComponentFactory_CreateFastMetadataEncoderFromFrameDecode,
1453 ComponentFactory_CreateQueryWriter,
1454 ComponentFactory_CreateQueryWriterFromReader,
1455 ComponentFactory_CreateMetadataReader,
1456 ComponentFactory_CreateMetadataReaderFromContainer,
1457 ComponentFactory_CreateMetadataWriter,
1458 ComponentFactory_CreateMetadataWriterFromReader,
1459 ComponentFactory_CreateQueryReaderFromBlockReader,
1460 ComponentFactory_CreateQueryWriterFromBlockWriter,
1461 ComponentFactory_CreateEncoderPropertyBag
1464 HRESULT ImagingFactory_CreateInstance(REFIID iid, void** ppv)
1466 ImagingFactory *This;
1467 HRESULT ret;
1469 TRACE("(%s,%p)\n", debugstr_guid(iid), ppv);
1471 *ppv = NULL;
1473 This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
1474 if (!This) return E_OUTOFMEMORY;
1476 This->IWICImagingFactory2_iface.lpVtbl = &ImagingFactory_Vtbl;
1477 This->IWICComponentFactory_iface.lpVtbl = &ComponentFactory_Vtbl;
1478 This->ref = 1;
1480 ret = IWICImagingFactory2_QueryInterface(&This->IWICImagingFactory2_iface, iid, ppv);
1481 IWICImagingFactory2_Release(&This->IWICImagingFactory2_iface);
1483 return ret;
1486 HRESULT WINAPI WICCreateBitmapFromSectionEx(UINT width, UINT height,
1487 REFWICPixelFormatGUID format, HANDLE section, UINT stride,
1488 UINT offset, WICSectionAccessLevel wicaccess, IWICBitmap **bitmap)
1490 SYSTEM_INFO sysinfo;
1491 UINT bpp, access, size, view_offset, view_size;
1492 void *view;
1493 HRESULT hr;
1495 TRACE("%u,%u,%s,%p,%u,%u,%#x,%p\n", width, height, debugstr_guid(format),
1496 section, stride, offset, wicaccess, bitmap);
1498 if (!width || !height || !section || !bitmap) return E_INVALIDARG;
1500 hr = get_pixelformat_bpp(format, &bpp);
1501 if (FAILED(hr)) return hr;
1503 switch (wicaccess)
1505 case WICSectionAccessLevelReadWrite:
1506 access = FILE_MAP_READ | FILE_MAP_WRITE;
1507 break;
1509 case WICSectionAccessLevelRead:
1510 access = FILE_MAP_READ;
1511 break;
1513 default:
1514 FIXME("unsupported access %#x\n", wicaccess);
1515 return E_INVALIDARG;
1518 if (!stride) stride = (((bpp * width) + 31) / 32) * 4;
1519 size = stride * height;
1520 if (size / height != stride) return E_INVALIDARG;
1522 GetSystemInfo(&sysinfo);
1523 view_offset = offset - (offset % sysinfo.dwAllocationGranularity);
1524 view_size = size + (offset - view_offset);
1526 view = MapViewOfFile(section, access, 0, view_offset, view_size);
1527 if (!view) return HRESULT_FROM_WIN32(GetLastError());
1529 offset -= view_offset;
1530 hr = BitmapImpl_Create(width, height, stride, 0, view, offset, format, WICBitmapCacheOnLoad, bitmap);
1531 if (FAILED(hr)) UnmapViewOfFile(view);
1532 return hr;
1535 HRESULT WINAPI WICCreateBitmapFromSection(UINT width, UINT height,
1536 REFWICPixelFormatGUID format, HANDLE section,
1537 UINT stride, UINT offset, IWICBitmap **bitmap)
1539 TRACE("%u,%u,%s,%p,%u,%u,%p\n", width, height, debugstr_guid(format),
1540 section, stride, offset, bitmap);
1542 return WICCreateBitmapFromSectionEx(width, height, format, section,
1543 stride, offset, WICSectionAccessLevelRead, bitmap);