In an older article, I presented a function that enumerates Windows Imaging Component codecs. Recently I had the idea to make a set of WIC Interfaces wrapper classes for easily enumerate and get info about all types of WIC components: bitmap decoders and encoders, metadata readers and writers, format converters, and supported pixel formats. Here are just few samples of code.
CComponentEnumT – a template class for enumerating WIC components
namespace wic { template<class TCompInfoCls, DWORD dwTypes> class CComponentEnumT { // ... public: using CompInfoList = std::list<std::shared_ptr<TCompInfoCls>>; using EnumOptions = WICComponentEnumerateOptions; CComponentEnumT() { HRESULT hr = m_spWICFactory.CoCreateInstance(CLSID_WICImagingFactory); ATLENSURE_SUCCEEDED(hr); } ~CComponentEnumT() = default; const CompInfoList& DoEnum(EnumOptions opt = WICComponentEnumerateDefault) { m_listCompInfo.clear(); CComPtr<IEnumUnknown> spEnum; HRESULT hr = m_spWICFactory->CreateComponentEnumerator(dwTypes, opt, &spEnum); ATLENSURE_SUCCEEDED(hr); ULONG cbActual = 0; CComPtr<IUnknown> spEnumElement = NULL; while (S_OK == spEnum->Next(1, &spEnumElement, &cbActual)) { auto spCompInfo = std::make_shared<TCompInfoCls>(spEnumElement); m_listCompInfo.push_back(spCompInfo); spEnumElement = nullptr; } return m_listCompInfo; } private: CompInfoList m_listCompInfo; CComPtr<IWICImagingFactory> m_spWICFactory; }; }
CComponentInfoBaseT – base class for all other component info classes
namespace wic { template <class TCompInfoInterface> class CComponentInfoBaseT { // ... protected: CComponentInfoBaseT(const CComPtr<IUnknown>& spEnumElement) { ATLASSERT(spEnumElement); m_spCompInfo = spEnumElement; } ~CComponentInfoBaseT() = default; // data CComQIPtr<TCompInfoInterface> m_spCompInfo; }; }
CPixelFormatInfoT – just one of classes getting WIC component info
namespace wic { template <class TCompInfoInterface> class CPixelFormatInfoT : public CComponentInfoT<TCompInfoInterface> { public: CPixelFormatInfoT(const CComPtr<IUnknown>& spEnumElement); ~CPixelFormatInfoT(); UINT GetBitsPerPixel() const; UINT GetChannelCount() const; GUID GetFormatGUID() const; bool SupportsTransparency() const; WICPixelFormatNumericRepresentation GetNumericRepresentation() const; }; using CPixelFormatInfo = CPixelFormatInfoT<IWICPixelFormatInfo2>; }
Just note that, for further easier using, I’ve defined here CPixelFormatInfo, an alias for CPixelFormatInfoT<IWICPixelFormatInfo2>.
CComponentEnumT specializations and aliases
namespace wic { using CAllComponentEnum = CComponentEnumT<CComponentInfo, WICAllComponents>; using CBitmapDecoderEnum = CComponentEnumT<CBitmapCodecInfo, WICDecoder>; using CBitmapEncoderEnum = CComponentEnumT<CBitmapCodecInfo, WICEncoder>; using CBitmapCodecEnum = CComponentEnumT<CBitmapCodecInfo, WICDecoder | WICEncoder>; using CPixelFormatEnum = CComponentEnumT<CPixelFormatInfo, WICPixelFormat>; using CMetadataReaderEnum = CComponentEnumT<CMetadataHandlerInfo, WICMetadataReader>; using CMetadataWriterEnum = CComponentEnumT<CMetadataHandlerInfo, WICMetadataWriter>; using CMetadataHandlerEnum = CComponentEnumT<CMetadataHandlerInfo, WICMetadataReader | WICMetadataWriter>; using CFormatConverterEnum = CComponentEnumT<CFormatConverterInfo, WICPixelFormatConverter>; }
Finally, let’s see how to use these classes!
Enumerating WIC pixel formats
void CDemo_MFCDlg::EnumWICPixelFormats(WICComponentEnumerateOptions opt) { wic::CPixelFormatEnum wicEnum; const auto& list = wicEnum.DoEnum(opt); for (const auto& spItem : list) { m_editReport.PrintComponentAttributes(spItem); m_editReport.PrintPixelFormatAttributes(spItem); } }
Quite easy, isn’t it?
Get the pixel format info
template<class T> void CWICReportEdit::PrintPixelFormatAttributes(T& spItem) { PrintLineV(_T("Bits per pixel: %u"), spItem->GetBitsPerPixel()); PrintLineV(_T("Channel count: %u"), spItem->GetChannelCount()); // ... } // Easy, as well.
You can find the complete source code in the attached demo solution.
Demo solution
Download: Enumerate WIC Components - Demo Solution.zip (1049 downloads)

The demo solution contains an MFC and a console project that use the classes described above in order to enumerate WIC components and get info about each one. The MFC one allows choosing the component type(s) as well as enum options (include the disabled components or enum only Windows built-in components). The console application is simpler and I wrote it just to demonstrate that my little library of wrapper classes can be used both in MFC and non-MFC applications.
Notes
- I hope, this article can be useful.
- If you have any observation or remarks, please do not hesitate to post a reply!
Resources and related articles
- Codexpert blog: How to enumerate WIC codecs?
- MSDN: Windows Imaging Component (WIC) Interfaces