2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wincodecsdk.h"
33 #include "wincodecs_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
40 IWICComponentFactory IWICComponentFactory_iface
;
44 static inline ComponentFactory
*impl_from_IWICComponentFactory(IWICComponentFactory
*iface
)
46 return CONTAINING_RECORD(iface
, ComponentFactory
, IWICComponentFactory_iface
);
49 static HRESULT WINAPI
ComponentFactory_QueryInterface(IWICComponentFactory
*iface
, REFIID iid
,
52 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
53 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
55 if (!ppv
) return E_INVALIDARG
;
57 if (IsEqualIID(&IID_IUnknown
, iid
) ||
58 IsEqualIID(&IID_IWICImagingFactory
, iid
) ||
59 IsEqualIID(&IID_IWICComponentFactory
, iid
))
61 *ppv
= &This
->IWICComponentFactory_iface
;
69 IUnknown_AddRef((IUnknown
*)*ppv
);
73 static ULONG WINAPI
ComponentFactory_AddRef(IWICComponentFactory
*iface
)
75 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
76 ULONG ref
= InterlockedIncrement(&This
->ref
);
78 TRACE("(%p) refcount=%u\n", iface
, ref
);
83 static ULONG WINAPI
ComponentFactory_Release(IWICComponentFactory
*iface
)
85 ComponentFactory
*This
= impl_from_IWICComponentFactory(iface
);
86 ULONG ref
= InterlockedDecrement(&This
->ref
);
88 TRACE("(%p) refcount=%u\n", iface
, ref
);
91 HeapFree(GetProcessHeap(), 0, This
);
96 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromFilename(
97 IWICComponentFactory
*iface
, LPCWSTR wzFilename
, const GUID
*pguidVendor
,
98 DWORD dwDesiredAccess
, WICDecodeOptions metadataOptions
,
99 IWICBitmapDecoder
**ppIDecoder
)
104 TRACE("(%p,%s,%s,%u,%u,%p)\n", iface
, debugstr_w(wzFilename
),
105 debugstr_guid(pguidVendor
), dwDesiredAccess
, metadataOptions
, ppIDecoder
);
107 hr
= StreamImpl_Create(&stream
);
110 hr
= IWICStream_InitializeFromFilename(stream
, wzFilename
, dwDesiredAccess
);
114 hr
= IWICComponentFactory_CreateDecoderFromStream(iface
, (IStream
*)stream
,
115 pguidVendor
, metadataOptions
, ppIDecoder
);
118 IWICStream_Release(stream
);
124 static IWICBitmapDecoder
*find_decoder(IStream
*pIStream
, const GUID
*pguidVendor
,
125 WICDecodeOptions metadataOptions
)
127 IEnumUnknown
*enumdecoders
;
128 IUnknown
*unkdecoderinfo
;
129 IWICBitmapDecoderInfo
*decoderinfo
;
130 IWICBitmapDecoder
*decoder
= NULL
;
136 res
= CreateComponentEnumerator(WICDecoder
, WICComponentEnumerateDefault
, &enumdecoders
);
137 if (FAILED(res
)) return NULL
;
141 res
= IEnumUnknown_Next(enumdecoders
, 1, &unkdecoderinfo
, &num_fetched
);
145 res
= IUnknown_QueryInterface(unkdecoderinfo
, &IID_IWICBitmapDecoderInfo
, (void**)&decoderinfo
);
151 res
= IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo
, &vendor
);
152 if (FAILED(res
) || !IsEqualIID(&vendor
, pguidVendor
))
154 IWICBitmapDecoderInfo_Release(decoderinfo
);
155 IUnknown_Release(unkdecoderinfo
);
160 res
= IWICBitmapDecoderInfo_MatchesPattern(decoderinfo
, pIStream
, &matches
);
162 if (SUCCEEDED(res
) && matches
)
164 res
= IWICBitmapDecoderInfo_CreateInstance(decoderinfo
, &decoder
);
166 /* FIXME: should use QueryCapability to choose a decoder */
170 res
= IWICBitmapDecoder_Initialize(decoder
, pIStream
, metadataOptions
);
174 IWICBitmapDecoder_Release(decoder
);
180 IWICBitmapDecoderInfo_Release(decoderinfo
);
183 IUnknown_Release(unkdecoderinfo
);
189 IEnumUnknown_Release(enumdecoders
);
194 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromStream(
195 IWICComponentFactory
*iface
, IStream
*pIStream
, const GUID
*pguidVendor
,
196 WICDecodeOptions metadataOptions
, IWICBitmapDecoder
**ppIDecoder
)
199 IWICBitmapDecoder
*decoder
= NULL
;
201 TRACE("(%p,%p,%s,%u,%p)\n", iface
, pIStream
, debugstr_guid(pguidVendor
),
202 metadataOptions
, ppIDecoder
);
205 decoder
= find_decoder(pIStream
, pguidVendor
, metadataOptions
);
207 decoder
= find_decoder(pIStream
, NULL
, metadataOptions
);
211 *ppIDecoder
= decoder
;
216 if (WARN_ON(wincodecs
))
222 WARN("failed to load from a stream\n");
225 res
= IStream_Seek(pIStream
, seek
, STREAM_SEEK_SET
, NULL
);
227 res
= IStream_Read(pIStream
, data
, 4, &bytesread
);
229 WARN("first %i bytes of stream=%x %x %x %x\n", bytesread
, data
[0], data
[1], data
[2], data
[3]);
232 return WINCODEC_ERR_COMPONENTNOTFOUND
;
236 static HRESULT WINAPI
ComponentFactory_CreateDecoderFromFileHandle(
237 IWICComponentFactory
*iface
, ULONG_PTR hFile
, const GUID
*pguidVendor
,
238 WICDecodeOptions metadataOptions
, IWICBitmapDecoder
**ppIDecoder
)
240 FIXME("(%p,%lx,%s,%u,%p): stub\n", iface
, hFile
, debugstr_guid(pguidVendor
),
241 metadataOptions
, ppIDecoder
);
245 static HRESULT WINAPI
ComponentFactory_CreateComponentInfo(IWICComponentFactory
*iface
,
246 REFCLSID clsidComponent
, IWICComponentInfo
**ppIInfo
)
248 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(clsidComponent
), ppIInfo
);
249 return CreateComponentInfo(clsidComponent
, ppIInfo
);
252 static HRESULT WINAPI
ComponentFactory_CreateDecoder(IWICComponentFactory
*iface
,
253 REFGUID guidContainerFormat
, const GUID
*pguidVendor
,
254 IWICBitmapDecoder
**ppIDecoder
)
256 IEnumUnknown
*enumdecoders
;
257 IUnknown
*unkdecoderinfo
;
258 IWICBitmapDecoderInfo
*decoderinfo
;
259 IWICBitmapDecoder
*decoder
= NULL
, *preferred_decoder
= NULL
;
264 TRACE("(%p,%s,%s,%p)\n", iface
, debugstr_guid(guidContainerFormat
),
265 debugstr_guid(pguidVendor
), ppIDecoder
);
267 if (!guidContainerFormat
|| !ppIDecoder
) return E_INVALIDARG
;
269 res
= CreateComponentEnumerator(WICDecoder
, WICComponentEnumerateDefault
, &enumdecoders
);
270 if (FAILED(res
)) return res
;
272 while (!preferred_decoder
)
274 res
= IEnumUnknown_Next(enumdecoders
, 1, &unkdecoderinfo
, &num_fetched
);
275 if (res
!= S_OK
) break;
277 res
= IUnknown_QueryInterface(unkdecoderinfo
, &IID_IWICBitmapDecoderInfo
, (void **)&decoderinfo
);
282 res
= IWICBitmapDecoderInfo_GetContainerFormat(decoderinfo
, &container_guid
);
283 if (SUCCEEDED(res
) && IsEqualIID(&container_guid
, guidContainerFormat
))
285 IWICBitmapDecoder
*new_decoder
;
287 res
= IWICBitmapDecoderInfo_CreateInstance(decoderinfo
, &new_decoder
);
292 res
= IWICBitmapDecoderInfo_GetVendorGUID(decoderinfo
, &vendor
);
293 if (SUCCEEDED(res
) && IsEqualIID(&vendor
, pguidVendor
))
295 preferred_decoder
= new_decoder
;
300 if (new_decoder
&& !decoder
)
302 decoder
= new_decoder
;
306 if (new_decoder
) IWICBitmapDecoder_Release(new_decoder
);
310 IWICBitmapDecoderInfo_Release(decoderinfo
);
313 IUnknown_Release(unkdecoderinfo
);
316 IEnumUnknown_Release(enumdecoders
);
318 if (preferred_decoder
)
320 *ppIDecoder
= preferred_decoder
;
321 if (decoder
) IWICBitmapDecoder_Release(decoder
);
327 *ppIDecoder
= decoder
;
332 return WINCODEC_ERR_COMPONENTNOTFOUND
;
335 static HRESULT WINAPI
ComponentFactory_CreateEncoder(IWICComponentFactory
*iface
,
336 REFGUID guidContainerFormat
, const GUID
*pguidVendor
,
337 IWICBitmapEncoder
**ppIEncoder
)
340 IEnumUnknown
*enumencoders
;
341 IUnknown
*unkencoderinfo
;
342 IWICBitmapEncoderInfo
*encoderinfo
;
343 IWICBitmapEncoder
*encoder
=NULL
;
346 GUID actual_containerformat
;
348 TRACE("(%p,%s,%s,%p)\n", iface
, debugstr_guid(guidContainerFormat
),
349 debugstr_guid(pguidVendor
), ppIEncoder
);
351 if (pguidVendor
&& !fixme
++)
352 FIXME("ignoring vendor GUID\n");
354 res
= CreateComponentEnumerator(WICEncoder
, WICComponentEnumerateDefault
, &enumencoders
);
355 if (FAILED(res
)) return res
;
359 res
= IEnumUnknown_Next(enumencoders
, 1, &unkencoderinfo
, &num_fetched
);
363 res
= IUnknown_QueryInterface(unkencoderinfo
, &IID_IWICBitmapEncoderInfo
, (void**)&encoderinfo
);
367 res
= IWICBitmapEncoderInfo_GetContainerFormat(encoderinfo
, &actual_containerformat
);
369 if (SUCCEEDED(res
) && IsEqualGUID(guidContainerFormat
, &actual_containerformat
))
371 res
= IWICBitmapEncoderInfo_CreateInstance(encoderinfo
, &encoder
);
376 IWICBitmapEncoderInfo_Release(encoderinfo
);
379 IUnknown_Release(unkencoderinfo
);
385 IEnumUnknown_Release(enumencoders
);
389 *ppIEncoder
= encoder
;
394 WARN("failed to create encoder\n");
396 return WINCODEC_ERR_COMPONENTNOTFOUND
;
400 static HRESULT WINAPI
ComponentFactory_CreatePalette(IWICComponentFactory
*iface
,
401 IWICPalette
**ppIPalette
)
403 TRACE("(%p,%p)\n", iface
, ppIPalette
);
404 return PaletteImpl_Create(ppIPalette
);
407 static HRESULT WINAPI
ComponentFactory_CreateFormatConverter(IWICComponentFactory
*iface
,
408 IWICFormatConverter
**ppIFormatConverter
)
410 return FormatConverter_CreateInstance(NULL
, &IID_IWICFormatConverter
, (void**)ppIFormatConverter
);
413 static HRESULT WINAPI
ComponentFactory_CreateBitmapScaler(IWICComponentFactory
*iface
,
414 IWICBitmapScaler
**ppIBitmapScaler
)
416 TRACE("(%p,%p)\n", iface
, ppIBitmapScaler
);
418 return BitmapScaler_Create(ppIBitmapScaler
);
421 static HRESULT WINAPI
ComponentFactory_CreateBitmapClipper(IWICComponentFactory
*iface
,
422 IWICBitmapClipper
**ppIBitmapClipper
)
424 FIXME("(%p,%p): stub\n", iface
, ppIBitmapClipper
);
428 static HRESULT WINAPI
ComponentFactory_CreateBitmapFlipRotator(IWICComponentFactory
*iface
,
429 IWICBitmapFlipRotator
**ppIBitmapFlipRotator
)
431 TRACE("(%p,%p)\n", iface
, ppIBitmapFlipRotator
);
432 return FlipRotator_Create(ppIBitmapFlipRotator
);
435 static HRESULT WINAPI
ComponentFactory_CreateStream(IWICComponentFactory
*iface
,
436 IWICStream
**ppIWICStream
)
438 TRACE("(%p,%p)\n", iface
, ppIWICStream
);
439 return StreamImpl_Create(ppIWICStream
);
442 static HRESULT WINAPI
ComponentFactory_CreateColorContext(IWICComponentFactory
*iface
,
443 IWICColorContext
**ppIColorContext
)
445 FIXME("(%p,%p): stub\n", iface
, ppIColorContext
);
449 static HRESULT WINAPI
ComponentFactory_CreateColorTransformer(IWICComponentFactory
*iface
,
450 IWICColorTransform
**ppIColorTransform
)
452 FIXME("(%p,%p): stub\n", iface
, ppIColorTransform
);
456 static HRESULT WINAPI
ComponentFactory_CreateBitmap(IWICComponentFactory
*iface
,
457 UINT uiWidth
, UINT uiHeight
, REFWICPixelFormatGUID pixelFormat
,
458 WICBitmapCreateCacheOption option
, IWICBitmap
**ppIBitmap
)
460 FIXME("(%p,%u,%u,%s,%u,%p): stub\n", iface
, uiWidth
, uiHeight
,
461 debugstr_guid(pixelFormat
), option
, ppIBitmap
);
465 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromSource(IWICComponentFactory
*iface
,
466 IWICBitmapSource
*piBitmapSource
, WICBitmapCreateCacheOption option
,
467 IWICBitmap
**ppIBitmap
)
469 FIXME("(%p,%p,%u,%p): stub\n", iface
, piBitmapSource
, option
, ppIBitmap
);
473 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromSourceRect(IWICComponentFactory
*iface
,
474 IWICBitmapSource
*piBitmapSource
, UINT x
, UINT y
, UINT width
, UINT height
,
475 IWICBitmap
**ppIBitmap
)
477 FIXME("(%p,%p,%u,%u,%u,%u,%p): stub\n", iface
, piBitmapSource
, x
, y
, width
,
482 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromMemory(IWICComponentFactory
*iface
,
483 UINT uiWidth
, UINT uiHeight
, REFWICPixelFormatGUID pixelFormat
, UINT cbStride
,
484 UINT cbBufferSize
, BYTE
*pbBuffer
, IWICBitmap
**ppIBitmap
)
486 FIXME("(%p,%u,%u,%s,%u,%u,%p,%p): stub\n", iface
, uiWidth
, uiHeight
,
487 debugstr_guid(pixelFormat
), cbStride
, cbBufferSize
, pbBuffer
, ppIBitmap
);
491 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHBITMAP(IWICComponentFactory
*iface
,
492 HBITMAP hBitmap
, HPALETTE hPalette
, WICBitmapAlphaChannelOption options
,
493 IWICBitmap
**ppIBitmap
)
495 FIXME("(%p,%p,%p,%u,%p): stub\n", iface
, hBitmap
, hPalette
, options
, ppIBitmap
);
499 static HRESULT WINAPI
ComponentFactory_CreateBitmapFromHICON(IWICComponentFactory
*iface
,
500 HICON hIcon
, IWICBitmap
**ppIBitmap
)
502 FIXME("(%p,%p,%p): stub\n", iface
, hIcon
, ppIBitmap
);
506 static HRESULT WINAPI
ComponentFactory_CreateComponentEnumerator(IWICComponentFactory
*iface
,
507 DWORD componentTypes
, DWORD options
, IEnumUnknown
**ppIEnumUnknown
)
509 TRACE("(%p,%u,%u,%p)\n", iface
, componentTypes
, options
, ppIEnumUnknown
);
510 return CreateComponentEnumerator(componentTypes
, options
, ppIEnumUnknown
);
513 static HRESULT WINAPI
ComponentFactory_CreateFastMetadataEncoderFromDecoder(
514 IWICComponentFactory
*iface
, IWICBitmapDecoder
*pIDecoder
,
515 IWICFastMetadataEncoder
**ppIFastEncoder
)
517 FIXME("(%p,%p,%p): stub\n", iface
, pIDecoder
, ppIFastEncoder
);
521 static HRESULT WINAPI
ComponentFactory_CreateFastMetadataEncoderFromFrameDecode(
522 IWICComponentFactory
*iface
, IWICBitmapFrameDecode
*pIFrameDecoder
,
523 IWICFastMetadataEncoder
**ppIFastEncoder
)
525 FIXME("(%p,%p,%p): stub\n", iface
, pIFrameDecoder
, ppIFastEncoder
);
529 static HRESULT WINAPI
ComponentFactory_CreateQueryWriter(IWICComponentFactory
*iface
,
530 REFGUID guidMetadataFormat
, const GUID
*pguidVendor
,
531 IWICMetadataQueryWriter
**ppIQueryWriter
)
533 FIXME("(%p,%s,%s,%p): stub\n", iface
, debugstr_guid(guidMetadataFormat
),
534 debugstr_guid(pguidVendor
), ppIQueryWriter
);
538 static HRESULT WINAPI
ComponentFactory_CreateQueryWriterFromReader(IWICComponentFactory
*iface
,
539 IWICMetadataQueryReader
*pIQueryReader
, const GUID
*pguidVendor
,
540 IWICMetadataQueryWriter
**ppIQueryWriter
)
542 FIXME("(%p,%p,%s,%p): stub\n", iface
, pIQueryReader
, debugstr_guid(pguidVendor
),
547 static HRESULT WINAPI
ComponentFactory_CreateMetadataReader(IWICComponentFactory
*iface
,
548 REFGUID format
, const GUID
*vendor
, DWORD options
, IStream
*stream
, IWICMetadataReader
**reader
)
550 FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
),
551 options
, stream
, reader
);
555 static HRESULT WINAPI
ComponentFactory_CreateMetadataReaderFromContainer(IWICComponentFactory
*iface
,
556 REFGUID format
, const GUID
*vendor
, DWORD options
, IStream
*stream
, IWICMetadataReader
**reader
)
558 FIXME("%p,%s,%s,%x,%p,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
),
559 options
, stream
, reader
);
563 static HRESULT WINAPI
ComponentFactory_CreateMetadataWriter(IWICComponentFactory
*iface
,
564 REFGUID format
, const GUID
*vendor
, DWORD options
, IWICMetadataWriter
**writer
)
566 FIXME("%p,%s,%s,%x,%p: stub\n", iface
, debugstr_guid(format
), debugstr_guid(vendor
), options
, writer
);
570 static HRESULT WINAPI
ComponentFactory_CreateMetadataWriterFromReader(IWICComponentFactory
*iface
,
571 IWICMetadataReader
*reader
, const GUID
*vendor
, IWICMetadataWriter
**writer
)
573 FIXME("%p,%p,%s,%p: stub\n", iface
, reader
, debugstr_guid(vendor
), writer
);
577 static HRESULT WINAPI
ComponentFactory_CreateQueryReaderFromBlockReader(IWICComponentFactory
*iface
,
578 IWICMetadataBlockReader
*block_reader
, IWICMetadataQueryReader
**query_reader
)
580 FIXME("%p,%p,%p: stub\n", iface
, block_reader
, query_reader
);
584 static HRESULT WINAPI
ComponentFactory_CreateQueryWriterFromBlockWriter(IWICComponentFactory
*iface
,
585 IWICMetadataBlockWriter
*block_writer
, IWICMetadataQueryWriter
**query_writer
)
587 FIXME("%p,%p,%p: stub\n", iface
, block_writer
, query_writer
);
591 static HRESULT WINAPI
ComponentFactory_CreateEncoderPropertyBag(IWICComponentFactory
*iface
,
592 PROPBAG2
*options
, UINT count
, IPropertyBag2
**property
)
594 FIXME("%p,%p,%u,%p: stub\n", iface
, options
, count
, property
);
598 static const IWICComponentFactoryVtbl ComponentFactory_Vtbl
= {
599 ComponentFactory_QueryInterface
,
600 ComponentFactory_AddRef
,
601 ComponentFactory_Release
,
602 ComponentFactory_CreateDecoderFromFilename
,
603 ComponentFactory_CreateDecoderFromStream
,
604 ComponentFactory_CreateDecoderFromFileHandle
,
605 ComponentFactory_CreateComponentInfo
,
606 ComponentFactory_CreateDecoder
,
607 ComponentFactory_CreateEncoder
,
608 ComponentFactory_CreatePalette
,
609 ComponentFactory_CreateFormatConverter
,
610 ComponentFactory_CreateBitmapScaler
,
611 ComponentFactory_CreateBitmapClipper
,
612 ComponentFactory_CreateBitmapFlipRotator
,
613 ComponentFactory_CreateStream
,
614 ComponentFactory_CreateColorContext
,
615 ComponentFactory_CreateColorTransformer
,
616 ComponentFactory_CreateBitmap
,
617 ComponentFactory_CreateBitmapFromSource
,
618 ComponentFactory_CreateBitmapFromSourceRect
,
619 ComponentFactory_CreateBitmapFromMemory
,
620 ComponentFactory_CreateBitmapFromHBITMAP
,
621 ComponentFactory_CreateBitmapFromHICON
,
622 ComponentFactory_CreateComponentEnumerator
,
623 ComponentFactory_CreateFastMetadataEncoderFromDecoder
,
624 ComponentFactory_CreateFastMetadataEncoderFromFrameDecode
,
625 ComponentFactory_CreateQueryWriter
,
626 ComponentFactory_CreateQueryWriterFromReader
,
627 ComponentFactory_CreateMetadataReader
,
628 ComponentFactory_CreateMetadataReaderFromContainer
,
629 ComponentFactory_CreateMetadataWriter
,
630 ComponentFactory_CreateMetadataWriterFromReader
,
631 ComponentFactory_CreateQueryReaderFromBlockReader
,
632 ComponentFactory_CreateQueryWriterFromBlockWriter
,
633 ComponentFactory_CreateEncoderPropertyBag
636 HRESULT
ComponentFactory_CreateInstance(IUnknown
*pUnkOuter
, REFIID iid
, void** ppv
)
638 ComponentFactory
*This
;
641 TRACE("(%p,%s,%p)\n", pUnkOuter
, debugstr_guid(iid
), ppv
);
645 if (pUnkOuter
) return CLASS_E_NOAGGREGATION
;
647 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentFactory
));
648 if (!This
) return E_OUTOFMEMORY
;
650 This
->IWICComponentFactory_iface
.lpVtbl
= &ComponentFactory_Vtbl
;
653 ret
= IWICComponentFactory_QueryInterface(&This
->IWICComponentFactory_iface
, iid
, ppv
);
654 IWICComponentFactory_Release(&This
->IWICComponentFactory_iface
);