/*
 * Copyright 2009 Vincent Povirk for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "objbase.h"
#include "wincodec.h"

#include "wincodecs_private.h"

#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/list.h"

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

static WCHAR const mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0};
static WCHAR const pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};

static HRESULT ComponentInfo_GetStringValue(HKEY classkey, LPCWSTR value,
    UINT buffer_size, WCHAR *buffer, UINT *actual_size)
{
    LONG ret;
    DWORD cbdata=buffer_size * sizeof(WCHAR);

    if (!actual_size)
        return E_INVALIDARG;

    ret = RegGetValueW(classkey, NULL, value, RRF_RT_REG_SZ|RRF_NOEXPAND, NULL,
        buffer, &cbdata);

    if (ret == 0 || ret == ERROR_MORE_DATA)
        *actual_size = cbdata/sizeof(WCHAR);

    if (!buffer && buffer_size != 0)
        /* Yes, native returns the correct size in this case. */
        return E_INVALIDARG;

    if (ret == ERROR_MORE_DATA)
        return WINCODEC_ERR_INSUFFICIENTBUFFER;

    return HRESULT_FROM_WIN32(ret);
}

typedef struct {
    IWICBitmapDecoderInfo IWICBitmapDecoderInfo_iface;
    LONG ref;
    HKEY classkey;
    CLSID clsid;
} BitmapDecoderInfo;

static inline BitmapDecoderInfo *impl_from_IWICBitmapDecoderInfo(IWICBitmapDecoderInfo *iface)
{
    return CONTAINING_RECORD(iface, BitmapDecoderInfo, IWICBitmapDecoderInfo_iface);
}

static HRESULT WINAPI BitmapDecoderInfo_QueryInterface(IWICBitmapDecoderInfo *iface, REFIID iid,
    void **ppv)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IWICComponentInfo, iid) ||
        IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
        IsEqualIID(&IID_IWICBitmapDecoderInfo ,iid))
    {
        *ppv = This;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI BitmapDecoderInfo_AddRef(IWICBitmapDecoderInfo *iface)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI BitmapDecoderInfo_Release(IWICBitmapDecoderInfo *iface)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        RegCloseKey(This->classkey);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BitmapDecoderInfo_GetComponentType(IWICBitmapDecoderInfo *iface,
    WICComponentType *pType)
{
    TRACE("(%p,%p)\n", iface, pType);
    *pType = WICDecoder;
    return S_OK;
}

static HRESULT WINAPI BitmapDecoderInfo_GetCLSID(IWICBitmapDecoderInfo *iface, CLSID *pclsid)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
    TRACE("(%p,%p)\n", iface, pclsid);

    if (!pclsid)
        return E_INVALIDARG;

    memcpy(pclsid, &This->clsid, sizeof(CLSID));

    return S_OK;
}

static HRESULT WINAPI BitmapDecoderInfo_GetSigningStatus(IWICBitmapDecoderInfo *iface, DWORD *pStatus)
{
    FIXME("(%p,%p): stub\n", iface, pStatus);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetAuthor(IWICBitmapDecoderInfo *iface, UINT cchAuthor,
    WCHAR *wzAuthor, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
{
    FIXME("(%p,%p): stub\n", iface, pguidVendor);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
    WCHAR *wzVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
    WCHAR *wzSpecVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
    WCHAR *wzFriendlyName, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
    GUID *pguidContainerFormat)
{
    FIXME("(%p,%p): stub\n", iface, pguidContainerFormat);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
    UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetColorManagementVersion(IWICBitmapDecoderInfo *iface,
    UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetDeviceManufacturer(IWICBitmapDecoderInfo *iface,
    UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetDeviceModels(IWICBitmapDecoderInfo *iface,
    UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetMimeTypes(IWICBitmapDecoderInfo *iface,
    UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
        cchMimeTypes, wzMimeTypes, pcchActual);
}

static HRESULT WINAPI BitmapDecoderInfo_GetFileExtensions(IWICBitmapDecoderInfo *iface,
    UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_DoesSupportAnimation(IWICBitmapDecoderInfo *iface,
    BOOL *pfSupportAnimation)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_DoesSupportChromaKey(IWICBitmapDecoderInfo *iface,
    BOOL *pfSupportChromaKey)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_DoesSupportLossless(IWICBitmapDecoderInfo *iface,
    BOOL *pfSupportLossless)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_DoesSupportMultiframe(IWICBitmapDecoderInfo *iface,
    BOOL *pfSupportMultiframe)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_MatchesMimeType(IWICBitmapDecoderInfo *iface,
    LPCWSTR wzMimeType, BOOL *pfMatches)
{
    FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapDecoderInfo_GetPatterns(IWICBitmapDecoderInfo *iface,
    UINT cbSizePatterns, WICBitmapPattern *pPatterns, UINT *pcPatterns, UINT *pcbPatternsActual)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
    UINT pattern_count=0, patterns_size=0;
    WCHAR subkeyname[11];
    LONG res;
    HKEY patternskey, patternkey;
    static const WCHAR uintformatW[] = {'%','u',0};
    static const WCHAR patternsW[] = {'P','a','t','t','e','r','n','s',0};
    static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
    static const WCHAR lengthW[] = {'L','e','n','g','t','h',0};
    static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
    static const WCHAR maskW[] = {'M','a','s','k',0};
    static const WCHAR endofstreamW[] = {'E','n','d','O','f','S','t','r','e','a','m',0};
    HRESULT hr=S_OK;
    UINT i;
    BYTE *bPatterns=(BYTE*)pPatterns;
    DWORD length, valuesize;

    TRACE("(%p,%i,%p,%p,%p)\n", iface, cbSizePatterns, pPatterns, pcPatterns, pcbPatternsActual);

    res = RegOpenKeyExW(This->classkey, patternsW, 0, KEY_READ, &patternskey);
    if (res != ERROR_SUCCESS) return HRESULT_FROM_WIN32(res);

    res = RegQueryInfoKeyW(patternskey, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    if (res == ERROR_SUCCESS)
    {
        patterns_size = pattern_count * sizeof(WICBitmapPattern);

        for (i=0; i<pattern_count; i++)
        {
            snprintfW(subkeyname, 11, uintformatW, i);
            res = RegOpenKeyExW(patternskey, subkeyname, 0, KEY_READ, &patternkey);
            if (res == ERROR_SUCCESS)
            {
                valuesize = sizeof(ULONG);
                res = RegGetValueW(patternkey, NULL, lengthW, RRF_RT_DWORD, NULL,
                    &length, &valuesize);
                patterns_size += length*2;

                if ((cbSizePatterns >= patterns_size) && (res == ERROR_SUCCESS))
                {
                    pPatterns[i].Length = length;

                    pPatterns[i].EndOfStream = 0;
                    valuesize = sizeof(BOOL);
                    RegGetValueW(patternkey, NULL, endofstreamW, RRF_RT_DWORD, NULL,
                        &pPatterns[i].EndOfStream, &valuesize);

                    pPatterns[i].Position.QuadPart = 0;
                    valuesize = sizeof(ULARGE_INTEGER);
                    res = RegGetValueW(patternkey, NULL, positionW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
                        &pPatterns[i].Position, &valuesize);

                    if (res == ERROR_SUCCESS)
                    {
                        pPatterns[i].Pattern = bPatterns+patterns_size-length*2;
                        valuesize = length;
                        res = RegGetValueW(patternkey, NULL, patternW, RRF_RT_REG_BINARY, NULL,
                            pPatterns[i].Pattern, &valuesize);
                    }

                    if (res == ERROR_SUCCESS)
                    {
                        pPatterns[i].Mask = bPatterns+patterns_size-length;
                        valuesize = length;
                        res = RegGetValueW(patternkey, NULL, maskW, RRF_RT_REG_BINARY, NULL,
                            pPatterns[i].Mask, &valuesize);
                    }
                }

                RegCloseKey(patternkey);
            }
            if (res != ERROR_SUCCESS)
            {
                hr = HRESULT_FROM_WIN32(res);
                break;
            }
        }
    }
    else hr = HRESULT_FROM_WIN32(res);

    RegCloseKey(patternskey);

    if (hr == S_OK)
    {
        *pcPatterns = pattern_count;
        *pcbPatternsActual = patterns_size;
        if (pPatterns && cbSizePatterns < patterns_size)
            hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
    }

    return hr;
}

static HRESULT WINAPI BitmapDecoderInfo_MatchesPattern(IWICBitmapDecoderInfo *iface,
    IStream *pIStream, BOOL *pfMatches)
{
    WICBitmapPattern *patterns;
    UINT pattern_count=0, patterns_size=0;
    HRESULT hr;
    int i, pos;
    BYTE *data=NULL;
    ULONG datasize=0;
    ULONG bytesread;
    LARGE_INTEGER seekpos;

    TRACE("(%p,%p,%p)\n", iface, pIStream, pfMatches);

    hr = BitmapDecoderInfo_GetPatterns(iface, 0, NULL, &pattern_count, &patterns_size);
    if (FAILED(hr)) return hr;

    patterns = HeapAlloc(GetProcessHeap(), 0, patterns_size);
    if (!patterns) return E_OUTOFMEMORY;

    hr = BitmapDecoderInfo_GetPatterns(iface, patterns_size, patterns, &pattern_count, &patterns_size);
    if (FAILED(hr)) goto end;

    for (i=0; i<pattern_count; i++)
    {
        if (datasize < patterns[i].Length)
        {
            HeapFree(GetProcessHeap(), 0, data);
            datasize = patterns[i].Length;
            data = HeapAlloc(GetProcessHeap(), 0, patterns[i].Length);
            if (!data)
            {
                hr = E_OUTOFMEMORY;
                break;
            }
        }

        if (patterns[i].EndOfStream)
            seekpos.QuadPart = -patterns[i].Position.QuadPart;
        else
            seekpos.QuadPart = patterns[i].Position.QuadPart;
        hr = IStream_Seek(pIStream, seekpos, patterns[i].EndOfStream ? STREAM_SEEK_END : STREAM_SEEK_SET, NULL);
        if (hr == STG_E_INVALIDFUNCTION) continue; /* before start of stream */
        if (FAILED(hr)) break;

        hr = IStream_Read(pIStream, data, patterns[i].Length, &bytesread);
        if (hr == S_FALSE || (hr == S_OK && bytesread != patterns[i].Length)) /* past end of stream */
            continue;
        if (FAILED(hr)) break;

        for (pos=0; pos<patterns[i].Length; pos++)
        {
            if ((data[pos] & patterns[i].Mask[pos]) != patterns[i].Pattern[pos])
                break;
        }
        if (pos == patterns[i].Length) /* matches pattern */
        {
            hr = S_OK;
            *pfMatches = TRUE;
            break;
        }
    }

    if (i == pattern_count) /* does not match any pattern */
    {
        hr = S_OK;
        *pfMatches = FALSE;
    }

end:
    HeapFree(GetProcessHeap(), 0, patterns);
    HeapFree(GetProcessHeap(), 0, data);

    return hr;
}

static HRESULT WINAPI BitmapDecoderInfo_CreateInstance(IWICBitmapDecoderInfo *iface,
    IWICBitmapDecoder **ppIBitmapDecoder)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

    TRACE("(%p,%p)\n", iface, ppIBitmapDecoder);

    return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
        &IID_IWICBitmapDecoder, (void**)ppIBitmapDecoder);
}

static const IWICBitmapDecoderInfoVtbl BitmapDecoderInfo_Vtbl = {
    BitmapDecoderInfo_QueryInterface,
    BitmapDecoderInfo_AddRef,
    BitmapDecoderInfo_Release,
    BitmapDecoderInfo_GetComponentType,
    BitmapDecoderInfo_GetCLSID,
    BitmapDecoderInfo_GetSigningStatus,
    BitmapDecoderInfo_GetAuthor,
    BitmapDecoderInfo_GetVendorGUID,
    BitmapDecoderInfo_GetVersion,
    BitmapDecoderInfo_GetSpecVersion,
    BitmapDecoderInfo_GetFriendlyName,
    BitmapDecoderInfo_GetContainerFormat,
    BitmapDecoderInfo_GetPixelFormats,
    BitmapDecoderInfo_GetColorManagementVersion,
    BitmapDecoderInfo_GetDeviceManufacturer,
    BitmapDecoderInfo_GetDeviceModels,
    BitmapDecoderInfo_GetMimeTypes,
    BitmapDecoderInfo_GetFileExtensions,
    BitmapDecoderInfo_DoesSupportAnimation,
    BitmapDecoderInfo_DoesSupportChromaKey,
    BitmapDecoderInfo_DoesSupportLossless,
    BitmapDecoderInfo_DoesSupportMultiframe,
    BitmapDecoderInfo_MatchesMimeType,
    BitmapDecoderInfo_GetPatterns,
    BitmapDecoderInfo_MatchesPattern,
    BitmapDecoderInfo_CreateInstance
};

static HRESULT BitmapDecoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
{
    BitmapDecoderInfo *This;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapDecoderInfo));
    if (!This)
    {
        RegCloseKey(classkey);
        return E_OUTOFMEMORY;
    }

    This->IWICBitmapDecoderInfo_iface.lpVtbl = &BitmapDecoderInfo_Vtbl;
    This->ref = 1;
    This->classkey = classkey;
    memcpy(&This->clsid, clsid, sizeof(CLSID));

    *ppIInfo = (IWICComponentInfo*)This;
    return S_OK;
}

typedef struct {
    IWICBitmapEncoderInfo IWICBitmapEncoderInfo_iface;
    LONG ref;
    HKEY classkey;
    CLSID clsid;
} BitmapEncoderInfo;

static inline BitmapEncoderInfo *impl_from_IWICBitmapEncoderInfo(IWICBitmapEncoderInfo *iface)
{
    return CONTAINING_RECORD(iface, BitmapEncoderInfo, IWICBitmapEncoderInfo_iface);
}

static HRESULT WINAPI BitmapEncoderInfo_QueryInterface(IWICBitmapEncoderInfo *iface, REFIID iid,
    void **ppv)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IWICComponentInfo, iid) ||
        IsEqualIID(&IID_IWICBitmapCodecInfo, iid) ||
        IsEqualIID(&IID_IWICBitmapEncoderInfo ,iid))
    {
        *ppv = This;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI BitmapEncoderInfo_AddRef(IWICBitmapEncoderInfo *iface)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI BitmapEncoderInfo_Release(IWICBitmapEncoderInfo *iface)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        RegCloseKey(This->classkey);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI BitmapEncoderInfo_GetComponentType(IWICBitmapEncoderInfo *iface,
    WICComponentType *pType)
{
    TRACE("(%p,%p)\n", iface, pType);
    *pType = WICEncoder;
    return S_OK;
}

static HRESULT WINAPI BitmapEncoderInfo_GetCLSID(IWICBitmapEncoderInfo *iface, CLSID *pclsid)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
    TRACE("(%p,%p)\n", iface, pclsid);

    if (!pclsid)
        return E_INVALIDARG;

    memcpy(pclsid, &This->clsid, sizeof(CLSID));

    return S_OK;
}

static HRESULT WINAPI BitmapEncoderInfo_GetSigningStatus(IWICBitmapEncoderInfo *iface, DWORD *pStatus)
{
    FIXME("(%p,%p): stub\n", iface, pStatus);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetAuthor(IWICBitmapEncoderInfo *iface, UINT cchAuthor,
    WCHAR *wzAuthor, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
{
    FIXME("(%p,%p): stub\n", iface, pguidVendor);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
    WCHAR *wzVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
    WCHAR *wzSpecVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
    WCHAR *wzFriendlyName, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
    GUID *pguidContainerFormat)
{
    FIXME("(%p,%p): stub\n", iface, pguidContainerFormat);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
    UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetColorManagementVersion(IWICBitmapEncoderInfo *iface,
    UINT cchColorManagementVersion, WCHAR *wzColorManagementVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchColorManagementVersion, wzColorManagementVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetDeviceManufacturer(IWICBitmapEncoderInfo *iface,
    UINT cchDeviceManufacturer, WCHAR *wzDeviceManufacturer, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceManufacturer, wzDeviceManufacturer, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetDeviceModels(IWICBitmapEncoderInfo *iface,
    UINT cchDeviceModels, WCHAR *wzDeviceModels, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchDeviceModels, wzDeviceModels, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_GetMimeTypes(IWICBitmapEncoderInfo *iface,
    UINT cchMimeTypes, WCHAR *wzMimeTypes, UINT *pcchActual)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchMimeTypes, wzMimeTypes, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, mimetypes_valuename,
        cchMimeTypes, wzMimeTypes, pcchActual);
}

static HRESULT WINAPI BitmapEncoderInfo_GetFileExtensions(IWICBitmapEncoderInfo *iface,
    UINT cchFileExtensions, WCHAR *wzFileExtensions, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_DoesSupportAnimation(IWICBitmapEncoderInfo *iface,
    BOOL *pfSupportAnimation)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportAnimation);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_DoesSupportChromaKey(IWICBitmapEncoderInfo *iface,
    BOOL *pfSupportChromaKey)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportChromaKey);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_DoesSupportLossless(IWICBitmapEncoderInfo *iface,
    BOOL *pfSupportLossless)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportLossless);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_DoesSupportMultiframe(IWICBitmapEncoderInfo *iface,
    BOOL *pfSupportMultiframe)
{
    FIXME("(%p,%p): stub\n", iface, pfSupportMultiframe);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_MatchesMimeType(IWICBitmapEncoderInfo *iface,
    LPCWSTR wzMimeType, BOOL *pfMatches)
{
    FIXME("(%p,%s,%p): stub\n", iface, debugstr_w(wzMimeType), pfMatches);
    return E_NOTIMPL;
}

static HRESULT WINAPI BitmapEncoderInfo_CreateInstance(IWICBitmapEncoderInfo *iface,
    IWICBitmapEncoder **ppIBitmapEncoder)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);

    TRACE("(%p,%p)\n", iface, ppIBitmapEncoder);

    return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
        &IID_IWICBitmapEncoder, (void**)ppIBitmapEncoder);
}

static const IWICBitmapEncoderInfoVtbl BitmapEncoderInfo_Vtbl = {
    BitmapEncoderInfo_QueryInterface,
    BitmapEncoderInfo_AddRef,
    BitmapEncoderInfo_Release,
    BitmapEncoderInfo_GetComponentType,
    BitmapEncoderInfo_GetCLSID,
    BitmapEncoderInfo_GetSigningStatus,
    BitmapEncoderInfo_GetAuthor,
    BitmapEncoderInfo_GetVendorGUID,
    BitmapEncoderInfo_GetVersion,
    BitmapEncoderInfo_GetSpecVersion,
    BitmapEncoderInfo_GetFriendlyName,
    BitmapEncoderInfo_GetContainerFormat,
    BitmapEncoderInfo_GetPixelFormats,
    BitmapEncoderInfo_GetColorManagementVersion,
    BitmapEncoderInfo_GetDeviceManufacturer,
    BitmapEncoderInfo_GetDeviceModels,
    BitmapEncoderInfo_GetMimeTypes,
    BitmapEncoderInfo_GetFileExtensions,
    BitmapEncoderInfo_DoesSupportAnimation,
    BitmapEncoderInfo_DoesSupportChromaKey,
    BitmapEncoderInfo_DoesSupportLossless,
    BitmapEncoderInfo_DoesSupportMultiframe,
    BitmapEncoderInfo_MatchesMimeType,
    BitmapEncoderInfo_CreateInstance
};

static HRESULT BitmapEncoderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
{
    BitmapEncoderInfo *This;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(BitmapEncoderInfo));
    if (!This)
    {
        RegCloseKey(classkey);
        return E_OUTOFMEMORY;
    }

    This->IWICBitmapEncoderInfo_iface.lpVtbl = &BitmapEncoderInfo_Vtbl;
    This->ref = 1;
    This->classkey = classkey;
    memcpy(&This->clsid, clsid, sizeof(CLSID));

    *ppIInfo = (IWICComponentInfo*)This;
    return S_OK;
}

typedef struct {
    IWICFormatConverterInfo IWICFormatConverterInfo_iface;
    LONG ref;
    HKEY classkey;
    CLSID clsid;
} FormatConverterInfo;

static inline FormatConverterInfo *impl_from_IWICFormatConverterInfo(IWICFormatConverterInfo *iface)
{
    return CONTAINING_RECORD(iface, FormatConverterInfo, IWICFormatConverterInfo_iface);
}

static HRESULT WINAPI FormatConverterInfo_QueryInterface(IWICFormatConverterInfo *iface, REFIID iid,
    void **ppv)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IWICComponentInfo, iid) ||
        IsEqualIID(&IID_IWICFormatConverterInfo ,iid))
    {
        *ppv = This;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI FormatConverterInfo_AddRef(IWICFormatConverterInfo *iface)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI FormatConverterInfo_Release(IWICFormatConverterInfo *iface)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        RegCloseKey(This->classkey);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI FormatConverterInfo_GetComponentType(IWICFormatConverterInfo *iface,
    WICComponentType *pType)
{
    TRACE("(%p,%p)\n", iface, pType);
    *pType = WICPixelFormatConverter;
    return S_OK;
}

static HRESULT WINAPI FormatConverterInfo_GetCLSID(IWICFormatConverterInfo *iface, CLSID *pclsid)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
    TRACE("(%p,%p)\n", iface, pclsid);

    if (!pclsid)
        return E_INVALIDARG;

    memcpy(pclsid, &This->clsid, sizeof(CLSID));

    return S_OK;
}

static HRESULT WINAPI FormatConverterInfo_GetSigningStatus(IWICFormatConverterInfo *iface, DWORD *pStatus)
{
    FIXME("(%p,%p): stub\n", iface, pStatus);
    return E_NOTIMPL;
}

static HRESULT WINAPI FormatConverterInfo_GetAuthor(IWICFormatConverterInfo *iface, UINT cchAuthor,
    WCHAR *wzAuthor, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchAuthor, wzAuthor, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
{
    FIXME("(%p,%p): stub\n", iface, pguidVendor);
    return E_NOTIMPL;
}

static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
    WCHAR *wzVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchVersion, wzVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
    WCHAR *wzSpecVersion, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
    WCHAR *wzFriendlyName, UINT *pcchActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI FormatConverterInfo_GetPixelFormats(IWICFormatConverterInfo *iface,
    UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, cFormats, pguidPixelFormats, pcActual);
    return E_NOTIMPL;
}

static HRESULT WINAPI FormatConverterInfo_CreateInstance(IWICFormatConverterInfo *iface,
    IWICFormatConverter **ppIFormatConverter)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);

    TRACE("(%p,%p)\n", iface, ppIFormatConverter);

    return CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER,
        &IID_IWICFormatConverter, (void**)ppIFormatConverter);
}

static BOOL ConverterSupportsFormat(IWICFormatConverterInfo *iface, const WCHAR *formatguid)
{
    LONG res;
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);
    HKEY formats_key, guid_key;

    /* Avoid testing using IWICFormatConverter_GetPixelFormats because that
        would be O(n). A registry test should do better. */

    res = RegOpenKeyExW(This->classkey, pixelformats_keyname, 0, KEY_READ, &formats_key);
    if (res != ERROR_SUCCESS) return FALSE;

    res = RegOpenKeyExW(formats_key, formatguid, 0, KEY_READ, &guid_key);
    if (res == ERROR_SUCCESS) RegCloseKey(guid_key);

    RegCloseKey(formats_key);

    return (res == ERROR_SUCCESS);
}

static const IWICFormatConverterInfoVtbl FormatConverterInfo_Vtbl = {
    FormatConverterInfo_QueryInterface,
    FormatConverterInfo_AddRef,
    FormatConverterInfo_Release,
    FormatConverterInfo_GetComponentType,
    FormatConverterInfo_GetCLSID,
    FormatConverterInfo_GetSigningStatus,
    FormatConverterInfo_GetAuthor,
    FormatConverterInfo_GetVendorGUID,
    FormatConverterInfo_GetVersion,
    FormatConverterInfo_GetSpecVersion,
    FormatConverterInfo_GetFriendlyName,
    FormatConverterInfo_GetPixelFormats,
    FormatConverterInfo_CreateInstance
};

static HRESULT FormatConverterInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
{
    FormatConverterInfo *This;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(FormatConverterInfo));
    if (!This)
    {
        RegCloseKey(classkey);
        return E_OUTOFMEMORY;
    }

    This->IWICFormatConverterInfo_iface.lpVtbl = &FormatConverterInfo_Vtbl;
    This->ref = 1;
    This->classkey = classkey;
    memcpy(&This->clsid, clsid, sizeof(CLSID));

    *ppIInfo = (IWICComponentInfo*)This;
    return S_OK;
}

static WCHAR const clsid_keyname[] = {'C','L','S','I','D',0};
static WCHAR const instance_keyname[] = {'I','n','s','t','a','n','c','e',0};

struct category {
    WICComponentType type;
    const GUID *catid;
    HRESULT (*constructor)(HKEY,REFCLSID,IWICComponentInfo**);
};

static const struct category categories[] = {
    {WICDecoder, &CATID_WICBitmapDecoders, BitmapDecoderInfo_Constructor},
    {WICEncoder, &CATID_WICBitmapEncoders, BitmapEncoderInfo_Constructor},
    {WICPixelFormatConverter, &CATID_WICFormatConverters, FormatConverterInfo_Constructor},
    {0}
};

HRESULT CreateComponentInfo(REFCLSID clsid, IWICComponentInfo **ppIInfo)
{
    HKEY clsidkey;
    HKEY classkey;
    HKEY catidkey;
    HKEY instancekey;
    WCHAR guidstring[39];
    LONG res;
    const struct category *category;
    int found=0;
    HRESULT hr;

    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
    if (res != ERROR_SUCCESS)
        return HRESULT_FROM_WIN32(res);

    for (category=categories; category->type; category++)
    {
        StringFromGUID2(category->catid, guidstring, 39);
        res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
        if (res == ERROR_SUCCESS)
        {
            res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
            if (res == ERROR_SUCCESS)
            {
                StringFromGUID2(clsid, guidstring, 39);
                res = RegOpenKeyExW(instancekey, guidstring, 0, KEY_READ, &classkey);
                if (res == ERROR_SUCCESS)
                {
                    RegCloseKey(classkey);
                    found = 1;
                }
                RegCloseKey(instancekey);
            }
            RegCloseKey(catidkey);
        }
        if (found) break;
    }

    if (found)
    {
        res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &classkey);
        if (res == ERROR_SUCCESS)
            hr = category->constructor(classkey, clsid, ppIInfo);
        else
            hr = HRESULT_FROM_WIN32(res);
    }
    else
        hr = E_FAIL;

    RegCloseKey(clsidkey);

    return hr;
}

typedef struct {
    IEnumUnknown IEnumUnknown_iface;
    LONG ref;
    struct list objects;
    struct list *cursor;
    CRITICAL_SECTION lock; /* Must be held when reading or writing cursor */
} ComponentEnum;

static inline ComponentEnum *impl_from_IEnumUnknown(IEnumUnknown *iface)
{
    return CONTAINING_RECORD(iface, ComponentEnum, IEnumUnknown_iface);
}

typedef struct {
    struct list entry;
    IUnknown *unk;
} ComponentEnumItem;

static const IEnumUnknownVtbl ComponentEnumVtbl;

static HRESULT WINAPI ComponentEnum_QueryInterface(IEnumUnknown *iface, REFIID iid,
    void **ppv)
{
    ComponentEnum *This = impl_from_IEnumUnknown(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IEnumUnknown, iid))
    {
        *ppv = This;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI ComponentEnum_AddRef(IEnumUnknown *iface)
{
    ComponentEnum *This = impl_from_IEnumUnknown(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) refcount=%u\n", iface, ref);

    return ref;
}

static ULONG WINAPI ComponentEnum_Release(IEnumUnknown *iface)
{
    ComponentEnum *This = impl_from_IEnumUnknown(iface);
    ULONG ref = InterlockedDecrement(&This->ref);
    ComponentEnumItem *cursor, *cursor2;

    TRACE("(%p) refcount=%u\n", iface, ref);

    if (ref == 0)
    {
        LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->objects, ComponentEnumItem, entry)
        {
            IUnknown_Release(cursor->unk);
            list_remove(&cursor->entry);
            HeapFree(GetProcessHeap(), 0, cursor);
        }
        This->lock.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->lock);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI ComponentEnum_Next(IEnumUnknown *iface, ULONG celt,
    IUnknown **rgelt, ULONG *pceltFetched)
{
    ComponentEnum *This = impl_from_IEnumUnknown(iface);
    int num_fetched=0;
    ComponentEnumItem *item;
    HRESULT hr=S_OK;

    TRACE("(%p,%u,%p,%p)\n", iface, celt, rgelt, pceltFetched);

    EnterCriticalSection(&This->lock);
    while (num_fetched<celt)
    {
        if (!This->cursor)
        {
            hr = S_FALSE;
            break;
        }
        item = LIST_ENTRY(This->cursor, ComponentEnumItem, entry);
        IUnknown_AddRef(item->unk);
        rgelt[num_fetched] = item->unk;
        num_fetched++;
        This->cursor = list_next(&This->objects, This->cursor);
    }
    LeaveCriticalSection(&This->lock);
    if (pceltFetched)
        *pceltFetched = num_fetched;
    return hr;
}

static HRESULT WINAPI ComponentEnum_Skip(IEnumUnknown *iface, ULONG celt)
{
    ComponentEnum *This = impl_from_IEnumUnknown(iface);
    int i;
    HRESULT hr=S_OK;

    TRACE("(%p,%u)\n", iface, celt);

    EnterCriticalSection(&This->lock);
    for (i=0; i<celt; i++)
    {
        if (!This->cursor)
        {
            hr = S_FALSE;
            break;
        }
        This->cursor = list_next(&This->objects, This->cursor);
    }
    LeaveCriticalSection(&This->lock);
    return hr;
}

static HRESULT WINAPI ComponentEnum_Reset(IEnumUnknown *iface)
{
    ComponentEnum *This = impl_from_IEnumUnknown(iface);

    TRACE("(%p)\n", iface);

    EnterCriticalSection(&This->lock);
    This->cursor = list_head(&This->objects);
    LeaveCriticalSection(&This->lock);
    return S_OK;
}

static HRESULT WINAPI ComponentEnum_Clone(IEnumUnknown *iface, IEnumUnknown **ppenum)
{
    ComponentEnum *This = impl_from_IEnumUnknown(iface);
    ComponentEnum *new_enum;
    ComponentEnumItem *old_item, *new_item;
    HRESULT ret=S_OK;
    struct list *old_cursor;

    new_enum = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
    if (!new_enum)
    {
        *ppenum = NULL;
        return E_OUTOFMEMORY;
    }

    new_enum->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
    new_enum->ref = 1;
    new_enum->cursor = NULL;
    list_init(&new_enum->objects);
    InitializeCriticalSection(&new_enum->lock);
    new_enum->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");

    EnterCriticalSection(&This->lock);
    old_cursor = This->cursor;
    LeaveCriticalSection(&This->lock);

    LIST_FOR_EACH_ENTRY(old_item, &This->objects, ComponentEnumItem, entry)
    {
        new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
        if (!new_item)
        {
            ret = E_OUTOFMEMORY;
            break;
        }
        new_item->unk = old_item->unk;
        list_add_tail(&new_enum->objects, &new_item->entry);
        IUnknown_AddRef(new_item->unk);
        if (&old_item->entry == old_cursor) new_enum->cursor = &new_item->entry;
    }

    if (FAILED(ret))
    {
        IUnknown_Release((IUnknown*)new_enum);
        *ppenum = NULL;
    }
    else
        *ppenum = (IEnumUnknown*)new_enum;

    return ret;
}

static const IEnumUnknownVtbl ComponentEnumVtbl = {
    ComponentEnum_QueryInterface,
    ComponentEnum_AddRef,
    ComponentEnum_Release,
    ComponentEnum_Next,
    ComponentEnum_Skip,
    ComponentEnum_Reset,
    ComponentEnum_Clone
};

HRESULT CreateComponentEnumerator(DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown)
{
    ComponentEnum *This;
    ComponentEnumItem *item;
    const struct category *category;
    HKEY clsidkey, catidkey, instancekey;
    WCHAR guidstring[39];
    LONG res;
    int i;
    HRESULT hr=S_OK;
    CLSID clsid;

    if (options) FIXME("ignoring flags %x\n", options);

    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, KEY_READ, &clsidkey);
    if (res != ERROR_SUCCESS)
        return HRESULT_FROM_WIN32(res);

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnum));
    if (!This)
    {
        RegCloseKey(clsidkey);
        return E_OUTOFMEMORY;
    }

    This->IEnumUnknown_iface.lpVtbl = &ComponentEnumVtbl;
    This->ref = 1;
    list_init(&This->objects);
    InitializeCriticalSection(&This->lock);
    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ComponentEnum.lock");

    for (category=categories; category->type && hr == S_OK; category++)
    {
        if ((category->type & componentTypes) == 0) continue;
        StringFromGUID2(category->catid, guidstring, 39);
        res = RegOpenKeyExW(clsidkey, guidstring, 0, KEY_READ, &catidkey);
        if (res == ERROR_SUCCESS)
        {
            res = RegOpenKeyExW(catidkey, instance_keyname, 0, KEY_READ, &instancekey);
            if (res == ERROR_SUCCESS)
            {
                i=0;
                for (;;i++)
                {
                    DWORD guidstring_size = 39;
                    res = RegEnumKeyExW(instancekey, i, guidstring, &guidstring_size, NULL, NULL, NULL, NULL);
                    if (res != ERROR_SUCCESS) break;

                    item = HeapAlloc(GetProcessHeap(), 0, sizeof(ComponentEnumItem));
                    if (!item) { hr = E_OUTOFMEMORY; break; }

                    hr = CLSIDFromString(guidstring, &clsid);
                    if (SUCCEEDED(hr))
                    {
                        hr = CreateComponentInfo(&clsid, (IWICComponentInfo**)&item->unk);
                        if (SUCCEEDED(hr))
                            list_add_tail(&This->objects, &item->entry);
                    }

                    if (FAILED(hr))
                    {
                        HeapFree(GetProcessHeap(), 0, item);
                        hr = S_OK;
                    }
                }
                RegCloseKey(instancekey);
            }
            RegCloseKey(catidkey);
        }
        if (res != ERROR_SUCCESS && res != ERROR_NO_MORE_ITEMS)
            hr = HRESULT_FROM_WIN32(res);
    }
    RegCloseKey(clsidkey);

    if (SUCCEEDED(hr))
    {
        IEnumUnknown_Reset((IEnumUnknown*)This);
        *ppIEnumUnknown = (IEnumUnknown*)This;
    }
    else
    {
        *ppIEnumUnknown = NULL;
        IUnknown_Release((IUnknown*)This);
    }

    return hr;
}

HRESULT WINAPI WICConvertBitmapSource(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst)
{
    HRESULT res;
    IEnumUnknown *enumconverters;
    IUnknown *unkconverterinfo;
    IWICFormatConverterInfo *converterinfo=NULL;
    IWICFormatConverter *converter=NULL;
    GUID srcFormat;
    WCHAR srcformatstr[39], dstformatstr[39];
    BOOL canconvert;
    ULONG num_fetched;

    res = IWICBitmapSource_GetPixelFormat(pISrc, &srcFormat);
    if (FAILED(res)) return res;

    if (IsEqualGUID(&srcFormat, dstFormat))
    {
        IWICBitmapSource_AddRef(pISrc);
        *ppIDst = pISrc;
        return S_OK;
    }

    StringFromGUID2(&srcFormat, srcformatstr, 39);
    StringFromGUID2(dstFormat, dstformatstr, 39);

    res = CreateComponentEnumerator(WICPixelFormatConverter, 0, &enumconverters);
    if (FAILED(res)) return res;

    while (!converter)
    {
        res = IEnumUnknown_Next(enumconverters, 1, &unkconverterinfo, &num_fetched);

        if (res == S_OK)
        {
            res = IUnknown_QueryInterface(unkconverterinfo, &IID_IWICFormatConverterInfo, (void**)&converterinfo);

            if (SUCCEEDED(res))
            {
                canconvert = ConverterSupportsFormat(converterinfo, srcformatstr);

                if (canconvert)
                    canconvert = ConverterSupportsFormat(converterinfo, dstformatstr);

                if (canconvert)
                {
                    res = IWICFormatConverterInfo_CreateInstance(converterinfo, &converter);

                    if (SUCCEEDED(res))
                        res = IWICFormatConverter_CanConvert(converter, &srcFormat, dstFormat, &canconvert);

                    if (SUCCEEDED(res) && canconvert)
                        res = IWICFormatConverter_Initialize(converter, pISrc, dstFormat, WICBitmapDitherTypeNone,
                            NULL, 0.0, WICBitmapPaletteTypeCustom);

                    if (FAILED(res) || !canconvert)
                    {
                        if (converter)
                        {
                            IWICFormatConverter_Release(converter);
                            converter = NULL;
                        }
                        res = S_OK;
                    }
                }

                IWICFormatConverterInfo_Release(converterinfo);
            }

            IUnknown_Release(unkconverterinfo);
        }
        else
            break;
    }

    IEnumUnknown_Release(enumconverters);

    if (converter)
    {
        *ppIDst = (IWICBitmapSource*)converter;
        return S_OK;
    }
    else
    {
        FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
        *ppIDst = NULL;
        return WINCODEC_ERR_COMPONENTNOTFOUND;
    }
}
